🧑 Mario Kahlhofer
📧 mario.kahlhofer@dynatrace.com
🌎 github.com/blu3r4y/python-for-java-developers
Python is a mature, general-purpose, object-oriented, dynamically-typed programming language.
Go to python.org and install the 64-bit version of Python 3.8 or newer.
🚫 Do NOT use Python 2.7 or older anymore!
python
can be used from the command line directlypip
is the most popular package manager for Python,
pulling packages from pypi.orgThe most popular IDEs are IntelliJ PyCharm or Visual Studio Code.
If you intend to use lots of scientific packages, you can install Anaconda or Miniconda as
an alternative. numpy
/ scipy
/
sympy
/ tensorflow
/ ... usually work out of
the box with Anaconda, especially on Windows.
conda
is the package manager used by Anaconda, pulling
packages from anaconda.orgNotebooks let you mix code and documentation, usually for prototyping or documentation purposes.
Jupyter Notebooks are the "classic" notebooks and Jupyter Labs is the new IDE-like successor of them.
pip install jupyter jupyterlab
# or, if that doesn't work
python -m pip install jupyter jupyterlab
You may want to open *.ipynb
notebook files directly
within VS
Code or PyCharm.
Alternatively, you can start a stand-alone instance in the browser from
the command line.
python -m juypter notebook [--notebook-dir <path>]
python -m jupyter lab [--notebook-dir <path>]
📜 ./python/m02_jupyter_introduction.ipynb
// ./java/M03_MaximumValue.java#L5-L15
List<Integer> numbers = Arrays.asList(1, -10, 0, -5, -1000, 100, 7);
int maximum = numbers.get(0);
for (int number : numbers) {
if (number > maximum) {
= number;
maximum }
}
System.out.println("The maximum value is " + maximum);
# ./python/m03_maximum_value.py
= [1, -10, 0, -5, -1000, 100, 7]
numbers
= numbers[0]
maximum
for number in numbers:
if number > maximum:
= number
maximum
print("The maximum value is", maximum)
;
{ }
but blocks that are started by
a colon :
( )
around the
expressions[ ]
for
and if
syntax is slightly
different#
We will only look into a few non-container data types of Python,
which Java would call primitive
types. *
Find all "built-in types" at docs.python.org/3/library/stdtypes.html
💡 In Python, you do not specify types explicitly! Although, you can have type hints.
* You can think of a variable in Python as a "tag" or "name" that is attached to some object, and NOT as the "container" that holds some value. All types in Python are essentially objects, even the numeric, text, and boolean ones. However, don't wrap your head around this too much - as you will see, things turn out to behave quite similar to Java.
Unlike Java, you can re-assign values of different types to the same variable as you wish. **
= 1416787301
x = "is"
x = True x
** Speaking in the notion of "tags" and "names", this means that you can freely re-assign the "tag" or "name" to point to a different location.
There are only exist the three numeric types float
/
int
/ complex
in Python.
float
types in Python ➡ are equal to
double
types in Java *short
/ int
/
long
/ "float
" / double
types in
Python= 5
my_int = 3.141
my_float = 1 + 2j
my_complex
# there are also some useful ways to write numbers
= 299_792_458
speed_of_light = 28.9e+12
us_national_debt = 0x3f
ascii_symbol = 0b1011_1001 input_bitmask
* "Floating point numbers are usually implemented using
double
in C; information about the precision and internal
representation of floating point numbers for the machine on which your
program is running is available in sys.float_info
" - see docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
Integers in Python allow computations beyond usual integer limits without loss of precision.
# ./python/m04_arbitrary_precision_integers.py
= 9_460_730_472_580_800
lightyear_to_meter = 170_000 * lightyear_to_meter
min_milky_way_diameter
= min_milky_way_diameter + 1
min_milky_way_diameter_plus_one
print("Woooooow, the milky way is at least", min_milky_way_diameter, "meters in diameter!")
print("Adding one meter on that, we are at", min_milky_way_diameter_plus_one, "meters.")
# > Woooooow, the milky way is at least 1608324180338736000000 meters in diameter!
# > Adding one meter on that, we are at 1608324180338736000001 meters.
Find them all at docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
# ./python/m04_mathematical_expressions.py
= 10.5
x = -3
y
print("x + y =", x + y) # addition
print("x - y =", x - y) # subtraction
print("x * y =", x * y) # multiplication
print("x / y =", x / y) # normal division
print("x // y =", x // y) # integer division
print("x % y =", x % y) # modulo
print("abs(y) =", abs(y))
print("int(x) =", int(x)) # convert to integer
print("float(y) =", float(y)) # convert to float
print("complex(x, y) =", complex(x, y)) # convert to complex
print("pow(x, 3) =", pow(x, 3)) # exponentiation
print("x ** 3 =", x ** 3) # exponentiation (alternative syntax)
Find them all at docs.python.org/3/library/math.html
# ./python/m04_mathematical_functions.py
# we use function from this built-in package
import math
print("sqrt(16) =", math.sqrt(16))
print("5! =", math.factorial(5))
print("log(e) =", math.log(math.e))
print("sin(pi / 2) =", math.sin(math.pi / 2))
Strings in Python are immutable* - just like in Java. When you modify strings, new memory is allocated.
= "Hello World"
first_string = 'Hello Python'
second_string
= """This can even
multi_line_strings hold line breaks
now"""
* Immutable, i.e., unchangeable, objects can not be modified after their creation.
Many types in Python can be converted to a string with
str()
- similar to .toString()
in Java.
As seen in the example, if you concatenate a string with a non-string,
you even have to. **
// ./java/M04_StringConversion.java#L3-L4
int num = 42;
System.out.println("The number is " + num);
# ./python/m04_string_conversion.py
= 42
num print("The number is " + str(num))
# alternative, which ONLY works for print()
print("The number is", num)
# print("The number is " + num)
# 💥 TypeError: can only concatenate str (not "int") to str
Use str.join()
in Python to concatenate a large number
of strings. *
// ./java/M04_StringConcatenation.java#L3-L8
String a = "How";
String b = "to";
String c = "concatenate";
String d = "strings";
String result = String.join(" ", a, b, c, d);
# ./python/m04_string_concatenation.py#L1-L7
= "How"
a = "to"
b = "concatenate"
c = "strings"
d
# we learn more about lists in the next modules ...
= " ".join([a, b, c, d]) result
* The equivalent of a StringBuilder
in Java would be io.StringIO
in Python.
# ./python/m04_boolean_expressions.py
= True
x = False
y
print("x or y =", x or y) # logical or
print("x and y =", x and y) # logical and
print("not x =", not x) # logical not
You can also perform binary computations with bitwise
operators.
Find them all at docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types
# ./python/m04_bitwise_expressions.py
= 0b1011_1011
port = 0b0010_0000
bitmask
= port & (bitmask >> 1)
is_bit_set
# we learn more about formatting in the next module ...
print("dec:", is_bit_set)
print(f"bin: {is_bit_set:08b}")
# > dec: 16
# > bin: 00010000
We will only look into a few collection types of Python.
Find them all at docs.python.org/3/library/stdtypes.html
list
in Python (but, there is also tuple
)dict
in Pythonset
in
PythonLists hold multiple elements in a specific order. Unlike arrays, they can change in size at any time.
# ./python/m05_list_operations.py#L1-L15
= [1, 2, 3, 4, 5]
numbers = ["Janine", "Ali", "Alice"]
names = [1, 2, "Max", 3.141]
mixed
0] # get element by index
names[0] = "Peter" # set element at index
names[
-1] # use negative indexes to count from the end
names[
-5) # add element to the end of the list
names.append(1, "Bob") # add element at specific index
names.insert(
-5) # remove the first occurrence from the list
names.remove(del names[0] # remove by index
Learn about all list operations at docs.python.org/3/tutorial/datastructures.html#more-on-lists.
# ./python/m05_list_operations.py#L18-L26
"Alice" in names # check for existence
"Mario" not in names # ... and non-existence
1) # the number of times this item is in the list
numbers.count(len(numbers) # total number of elements in the list
# merge two lists into one
= [1, 2, 3] + [4, 5, 6] merged
Tuples hold two or more objects together in an efficient manner. They have NO direct equivalent in Java. Use them to group together small number of elements, e.g., when returning multiple values from a method.
= ("Jonas", 12) # create a tuple
pair 0] # get element by index, similar to lists pair[
💡 Tuples are always immutable!
You can NOT modify, append, or delete anything from them after you created one.
# pair[1] = 13
# 💥 TypeError: 'tuple' object does not support item assignment
# pair.append(123)
# 💥 AttributeError: 'tuple' object has no attribute 'append'
However, you can convert tuples to lists.
= (10, 11, 12)
numbers list(numbers)
# and back again ...
= ["A", "B", "C"]
letters tuple(letters)
Destructuring helps you to quickly retrieve elements from list-like types in Python.
# ./python/m05_destructuring.py
= 1, 2
x, y print(x, y)
# > 1 2
= [1, 2, 3]
numbers = numbers
x, y, z
print(x, y, z)
# > 1 2 3
= ("Jonas", 12)
pair = pair
name, age
print(name, age)
# > Jonas 12
,
in such contexts,
a tuple
is used implicitly.Dictionaries map keys to values.
# ./python/m05_dict_operations.py
= {
grades "math": 2,
"programming": 1,
"literature": 3
}
# alternative syntax
= dict(math=2, programming=1, literature=3)
grades
"math"] # get elements by key
grades["math"] = 5 # set elements by key
grades["electronics"] = 4 # add a new element
grades[
# remove an element (will raise an error if the key does not exist)
if "math" in grades:
del grades["math"]
# get all the keys as a list
grades.keys() # get all the values as a list grades.values()
Sets hold multiple elements, without duplicates, but also without order.
# ./python/m05_set_operations.py#L1-L10
= {1, 1, 2, 3, 5} # notice how the '1' is only appended once after all
numbers
7) # add new elements
numbers.add(1) # add elements that already exist (no effect)
numbers.add(
1 in numbers # check for existence (much faster than with lists)
# remove elements (will raise an error if the element does not exist)
if 2 in numbers:
2) numbers.remove(
💡 You can NOT retrieve elements by index from a set!
# numbers[0]
# 💥 TypeError: 'set' object is not subscriptable
You must iterate over them or convert the set to a list with
list(elements)
# ./python/m05_set_operations.py#L12-L14
# iterate over set elements
for val in numbers:
print(val)
Sets are handy when you want to apply operations from set theory.
# ./python/m05_set_arithmetic.py
= {1, 2, 3, 4, 5}
a = {4, 5, 6, 7, 8}
b
print("a | b =", a | b) # union
print("a & b =", a & b) # intersection
print("a - b =", a - b) # difference
# > a | b = {1, 2, 3, 4, 5, 6, 7, 8}
# > a & b = {4, 5}
# > a - b = {1, 2, 3}
You can read input from the command line with
input()
# ./python/m06_input.py#L1-L2
= input("Please enter your name: ")
name print("Your name is", name)
💡 Don't forget data type conversions!
# ./python/m06_input.py#L4-L11
# this function will always give you a string
= input("Please enter a number: ")
number
= int(number)
as_int = float(number)
as_float
print(as_int, as_float)
You output something to the command line with
print()
# ./python/m06_output.py#L1-L14
= 3.141
pi
print(pi)
print()
print("The value of pi is", pi)
# > 3.141
# >
# > The value of pi is 3.141
print("I hate: ", end="")
print("line breaks")
# > I hate: line breaks
Among many alternatives, format strings are the recommended way to format output.
# ./python/m06_output.py#L17-L19
print(f"The value of pi is {pi} and the value of tau is {2 * pi}")
# > The value of pi is 3.141 and the value of tau is 6.282
Look them up when you need it at gto76.github.io/python-cheatsheet/#format
# ./python/m06_number_formatting.py
= 3.14159265359
pi print(pi)
# > 3.14159265359
print(f"{pi:.0f}") # no decimal places
print(f"{pi:.2f}") # two decimal places
print(f"{pi:.3e}") # scientific notation
# > 3
# > 3.14
# > 3.142e+00
= 0.25
ratio print(f"{ratio:.1%}") # percentage
# > 25.0%
Among many, here is one way to read and write a file in Python.
Learn more at docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files.
# ./python/m06_file_io.py#L3-L11
= "m06_file_io.txt"
filename
with open(filename, "w+") as f:
"Hello\n")
f.write("File!\n")
f.write(
with open(filename, "r") as f:
for line in f.read().splitlines():
print(line)
r
for reading - use
w
for writing, w+
for reading and writing
*ascii
, use the
encoding="utf-8"
keyword
argument otherwise* Read about possible modes at gto76.github.io/python-cheatsheet/#open.
// ./java/M07_BasicControlFlow.java#L3-L17
int x = 0;
switch (x) {
case 0:
System.out.println("The value is 0");
break;
case 1:
System.out.println("The value is 1");
break;
case 2:
System.out.println("The value is 2");
break;
default:
System.out.println("The value is something else");
}
# ./python/m07_basic_control_flow.py
= 0
x
if x == 0:
print("The value is 0")
elif x == 1:
print("The value is 1")
elif x == 2:
print("The value is 2")
else:
print("The value is something else")
switch
expression, you have to make a
cascade of if
/ elif
/ else
statements ** Actually, if you are using Python 3.10 or
newer, there are the new match
and case
statements now.
// ./java/M07_SumOfAllDigits.java#L6-L18
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a number: ");
int n = scanner.nextInt();
.close();
scanner
int digitSum = 0;
while (n > 0) {
+= n % 10;
digitSum = n / 10;
n }
System.out.println("The digit sum is " + digitSum);
# ./python/m07_sum_of_all_digits.py
= int(input('Enter a number: '))
n
= 0
digit_sum
while n > 0:
+= n % 10
digit_sum = n // 10
n
print("The digit sum is ", digit_sum)
input()
and can
also output a promptwhile
loop also exists in Python//
in Python, but
use a normal division /
in Java# unlike Java, a division will alwasy give you a float data type
assert 5 / 2 == 2.5
# unless you want an explicit integer division
assert 5 // 2 == 2
* assert
will raise an
AssertionError
if the condition is False
- use
it to check assumptions in your code.
// ./java/M07_IteratingElementsByValue.java#L3-L7
String[] names = {"Lisa", "John", "Susan", "Alex"};
for (String name : names) {
System.out.println(name);
}
# ./python/m07_iterating_elements_by_value.py
= ["Lisa", "John", "Susan", "Alex"]
names
for name in names:
print(name)
// ./java/M07_IteratingElementsByIndex.java#L3-L7
int[] numbers = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
for (int i = 5; i < 8; i++) {
System.out.println(numbers[i]);
}
# ./python/m07_iterating_elements_by_index.py
= [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
numbers
for i in range(5, 8):
print(numbers[i])
x in y
syntax with a
for
looprange(start, stop)
,start
to
stop - 1
💡 Actually, range()
will give you an iterator!
If you really want the numbers in a list, you have to convert the result.
# iterators only allow getting the next element with next()
range(5, 8)
# lists allow arbitrary access by index
list(range(5, 8))
Examples like the one before are usually solved by slicing list-like
collections.
This is also very useful for mathematical applications, e.g. when
working with a lot of arrays and matrices.
# ./python/m07_sequence_slicing.py#L1-L5
= [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
numbers
5:8] # give me a new COPY of the list, starting at index 5, and ending at index 7
numbers[
# > [15, 16, 17]
The following variants are supported:
a[start:stop:step]
a[start:stop]
a[start:]
a[:stop]
a[:]
The stop
index is always exclusive,
i.e. the element at index stop
is not part of the resulting
slice.
= [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] numbers
# ./python/m07_sequence_slicing.py#L7-L14
1:] # all except the 1st item > [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
numbers[3] # the first three items > [10, 11, 12]
numbers[:
-1] # all except the last item > [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
numbers[:-2:] # the last two items > [19, 20]
numbers[
2] # every 2nd item > [10, 12, 14, 16, 18, 20]
numbers[::1::2] # every 2nd, but start at 2 > [11, 13, 15, 17, 19] numbers[
This also works with strings because they are just a list of characters.
# ./python/m07_sequence_slicing.py#L17-L20
= "Hello World"
name 1:-1]
name[
# > 'ello Worl'
reversed(a)
to iterate over the sequence in reverse
ordera.reverse()
on the object to reverse the items
in-placea[::-1]
# ./python/m07_sequence_reversing.py
= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers
# iterator that iterates the list in reverse order
reversed(numbers)
# reverse the list in-place
numbers.reverse()
# slice a reversed copy of the elements
-1] numbers[::
sorted(a)
to get a sorted list of the elementsa.sort()
to sort the sequence in-placereverse=True
keyword
argument to reverse the sorting order# ./python/m07_sequence_sorting.py
= [1, -10, 20, 11, 19, 0, -5, -1000, 100, 7]
numbers
# get a sorted list of the elements
sorted(numbers)
sorted(numbers, reverse=True)
# sort the list in-place
numbers.sort()=True) numbers.sort(reverse
// ./java/M07_EnumeratingOverElements.java#L3-L9
String[] names = {"Lisa", "John", "Susan", "Alex"};
int i = 0;
while (i < names.length) {
System.out.println(i + " " + names[i]);
++;
i}
# ./python/m07_enumerating_over_elements.py
= ["Lisa", "John", "Susan", "Alex"]
names
for i, name in enumerate(names):
print(i, name)
enumerate()
creates tuples for us here// ./java/M07_PriceTax.java#L5-L16
List<Double> prices = Arrays.asList(12.3, 5.2, 8.7, 1.2, 8.0);
List<Double> gross = new ArrayList<Double>();
for (double price : prices) {
if (price > 8) {
.add(price * 1.2);
gross}
}
for (double price : gross) {
System.out.println(price);
}
# ./python/m07_price_tax.py#L1-L8
= [12.3, 5.2, 8.7, 1.2, 8.0]
prices = []
gross
for price in prices:
if price > 8:
* 1.2)
gross.append(price
print(gross)
List comprehensions map each value in a list to a new value and thus create a new list. *
[x for x in sequence]
# ./python/m07_price_tax.py#L11-L12
= [12.3, 5.2, 8.7, 1.2, 8.0]
prices = [price * 1.2 for price in prices if price > 8] gross
* Python offers a lot of features for functional programming,
like map
/ filter
/ reduce
/ zip
/ all
/ any
/ ...
// ./java/M08_RectangleFunctions.java#L2-L16
static double area(double a, double b) {
return a * b;
}
static boolean isSquare(double a, double b) {
return a == b;
}
public static void main(String[] args) {
System.out.println("area(1, 5) = " + area(1, 5));
System.out.println("area(1.5, 2.3) = " + area(1.5, 2.3));
System.out.println("isSquare(1, 5) = " + isSquare(1, 5));
System.out.println("isSquare(5, 5) = " + isSquare(5, 5));
}
# ./python/m08_rectangle_functions.py#L1-L13
def area(a, b):
return a * b
def is_square(a, b):
return a == b
print("area(1, 5) =", area(1, 5))
print("area(1.5, 2.3) =", area(1.5, 2.3))
print("is_square(1, 5) =", is_square(1, 5))
print("is_square(5, 5) =", is_square(5, 5))
def
static
keywordIn a nutshell, Python has the same passing behavior as Java - although, Python lacks primitive types.
// ./java/M08_PassByObjectReference.java#L4-L20
static void replace(List<Integer> numbers) {
= Arrays.asList(42, 43, 44);
numbers }
static void append(List<Integer> numbers) {
.add(42);
numbers}
public static void main(String[] args) {
List<Integer> oneTwoThree = new LinkedList<>(Arrays.asList(1, 2, 3));
replace(oneTwoThree);
System.out.println(Arrays.toString(oneTwoThree.toArray()));
append(oneTwoThree);
System.out.println(Arrays.toString(oneTwoThree.toArray()));
}
# ./python/m08_pass_by_object_reference.py
def replace(numbers):
= [42, 43, 44]
numbers
def append(numbers):
42)
numbers.append(
= [1, 2, 3]
one_two_three
replace(one_two_three)print(one_two_three) # > [1, 2, 3]
append(one_two_three)print(one_two_three) # > [1, 2, 3, 42]
Arguments are ALWAYS passed by-value, in Java and
also in Python.
When your argument is an object, the reference to that object is
passed.
int
, the
value is copied.int
, the
object reference is passed and NO data is copied.int
is immutable,
you can't change the value of the original object either. ** From here on, things get complicated. Learn more about the
technical details by Robert
Heaton. 2014. "Is Python pass-by-reference or pass-by-value?"
and Sreejith
Kesavan. 2012. "Understanding Python Variables and Memory
Management".
You can specify argument names explicitly - and even change their order.
# ./python/m08_rectangle_functions.py#L17-L18
=2, b=5)
area(a=5, a=2) area(b
You can specify default values for arguments.
# ./python/m08_function_differences.py#L1-L12
def function_with_default_args(x, y, name="Unknown User", factor=1.2):
= x * y * factor
result print(f"Hello {name}, your result is {result}")
1, 2)
function_with_default_args(1, 2, name="Mario")
function_with_default_args(1, 2, factor=10)
function_with_default_args(
# > Hello Unknown User, your result is 2.4
# > Hello Mario, your result is 2.4
# > Hello Unknown User, your result is 20
You can return multiple results with tuples and destructuring.
# ./python/m08_function_differences.py#L15-L30
def function_with_two_return_values(radius):
= 3.14159
pi
= 2 * pi * radius
circumference = pi * radius ** 2
area
return circumference, area
= function_with_two_return_values(5)
c, a
print("circumference", c)
print("area", a)
# > circumference 31.4159
# > area 78.53975
*args
and **kwargs
to work with almost arbitrary
input parameters, which you already did use in the print()
function for exampleLearn more about funtions at docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions.
Python is object-oriented, but follows a more lean approach towards classes.
// ./java/M09_PassengersProgram.java#L3-L40
class Passenger {
final String firstName;
final String lastName;
Passenger(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
void display() {
System.out.printf("%s %s %n", firstName, lastName);
}
static Passenger fromInput() {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter first name: ");
String firstName = scanner.nextLine();
System.out.print("Enter last name: ");
String lastName = scanner.nextLine();
.close();
scanner
return new Passenger(firstName, lastName);
}
}
class PassengersProgram {
public static void main(String[] args) {
= new Passenger("Lisa", "Ha");
Passenger lisa = Passenger.fromInput();
Passenger user
.display();
lisa.display();
user}
}
# ./python/m09_passengers_program.py
class Passenger:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def display(self):
print(f"Passenger: {self.first_name} {self.last_name}")
@staticmethod
def from_input():
= input("Enter first name: ")
first_name = input("Enter last name: ")
last_name
return Passenger(first_name, last_name)
if __name__ == "__main__":
= Passenger("Lisa", "Ha")
lisa = Passenger.from_input()
user
lisa.display() user.display()
__init__
with a mandatory self
parameterfirst_name
and last_name
,self
parameterself.
if you want to access class
propertiesfinal
in Python@staticmethod
decorator
and omits the self
parameternew
keywordmain
method in Python is actually a condition - we
will learn more in the next modules// ./java/M09_ShapesProgram.java
interface Shape {
double area();
}
class Circle implements Shape {
final double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return 3.14159 * radius * radius;
}
}
class Square implements Shape {
final double length;
Square(double length) {
this.length = length;
}
@Override
public double area() {
return length * length;
}
}
class ShapesProgram {
public static void main(String[] args) {
Shape[] shapes = { new Circle(5), new Square(10) };
for (Shape shape : shapes) {
System.out.println(shape.area());
}
}
}
# ./python/m09_shapes_program.py
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius * self.radius
class Square(Shape):
def __init__(self, length):
self.length = length
def area(self):
return self.length * self.length
= [Circle(5), Square(10)]
shapes for shape in shapes:
print(shape.area())
interface
type in Python, instead we use a
normal class
and inhert from itShape
or renaming the area()
method ...Since there is NO type-checking at compile-time, we may also solely
rely on duck-typing.
An AttributeError
is thrown at runtime, if the method you
are calling wouldn't exist. *
# ./python/m09_shapes_duck_typing.py
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius * self.radius
class Square:
def __init__(self, length):
self.length = length
def area(self):
return self.length * self.length
= [Circle(5), Square(10)]
shapes for shape in shapes:
print(shape.area())
abc
module* Look into type hints to have better type-checking at runtime and even before you run your code.
Let's take a quick interactive look at how one would create a Python project consisting of multiple files.
📜 ./python/m10_multiple_scripts
📜 ./python/m10_demo_project
Learn about more best practices at docs.python-guide.org/writing/structure
Your code is always executed from top to bottom.
python script.py
The __main__
condition that you write, will only
evaluate to True
when that script is executed directly.
# ./python/m10_multiple_scripts/main.py#L5-L6
if __name__ == "__main__":
print("This will only run if you specifically started the interpretor on this file.")
With that, you mainly differentiate if a script is run directly, or
being imported.
Upon import, the __main__
condition of the importee will
evaluate to False
.
# ./python/m10_multiple_scripts/imports.py
import main
# you might also want to try out these:
# import script
# from main import test_variable
if __name__ == "__main__":
print("The value of the test variable is:", main.test_variable)
You should structure your code into packages ("directories") and modules ("Python files").
.
├── README.md <-- brief description
├── requirements.txt <-- list of dependencies (list package names and versions)
├── graphics
│ ├── __init__.py
│ └── parabola.py
└── user <-- a package named 'user'
├── __init__.py <-- will be executed when you 'import user'
└── app.py <-- a module named 'app'
Dependencies are usually listed in a requirements.txt
file and are installed with pip
. *
python -m pip install -r requirements.txt
You run modules when your code consists of multiple files.
python -m user.app
When you run a module, your root package is loaded into the import
path of the interpreter.
Thus, on each import
statement you write, packages and
modules will be found and imported.
* Note that pip
is a package by itself and that
we use the module mode to run it. Many modules are also added to your
system path upon installation, which allows you to run them directly
from the command line, e.g. with pip
instead of
python -m pip
.
Don't re-invent the wheel for various tasks, have a look at what packages exist already.
numpy
& scipy
- high-performance
numerical computations, multi-dimensional arraysmatplotlib
& seaborn
&
plotly
& bokeh
- graphical visualization
for mathematicianspandas
- work with tabular datasympy
- symbolic mathematicsnetworkx
- graphs and networksrequests
- network requests, download filestkinter
& pyqt
- graphical user
interfaces💡 Install new packages with pip
python -m pip install <package-name>
numpy
and
matplotlib
# ./python/m11_numpy_demo.py
import matplotlib.pyplot as plt
import numpy as np
# get 1000 numbers between -5 and 5
= np.linspace(-5, 5, 1000)
xs
# apply a function on this numpy array
= xs ** 2 - 1
ys
# show a figure
plt.plot(xs, ys) plt.show()
pandas
# ./python/m11_pandas_demo.py
import pandas as pd
# quickly read a csv file
= pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data")
df print(df)
If you ever need help, type help
- use the resources mentioned in the beginning - or, ask
Google.
help(sorted)
# > Help on built-in function sorted in module builtins:
# >
# > sorted(iterable, /, *, key=None, reverse=False)
# > Return a new list containing all items from the iterable in ascending order.
# >
# > A custom key function can be supplied to customize the sort order, and the
# > reverse flag can be set to request the result in descending order.
Never forget the Zen of Python.
import this
And also try out this one.
import antigravity