2022-01-17

Variables and Datatypes

Comments vs Docstrings

[1]:
# this is a comment. it tries to explain that the variable 'blah' is assigned the value 42
blah = 42    # this is the assignment
[2]:
blah
[2]:
42
[3]:
def add(l, r):
    'add: takes two parameters, and return the sum of those'
    return l+r
[4]:
add(1, 2)
[4]:
3
[5]:
print(add.__doc__)
add: takes two parameters, and return the sum of those
[6]:
help(add)
Help on function add in module __main__:

add(l, r)
    add: takes two parameters, and return the sum of those

Datatypes

Numbers

[7]:
a = 42 # int
type(a)
[7]:
int
[8]:
a
[8]:
42
[9]:
a = 1.5  # float
type(a)
[9]:
float
[10]:
a
[10]:
1.5
[11]:
a = complex(3, 4)
type(a)
[11]:
complex
[12]:
a
[12]:
(3+4j)
[13]:
a = True   # boolean
type(a)
[13]:
bool
[14]:
1 == 1
[14]:
True
[15]:
a = 1 == 1     # operator precedence: a = (1 == 1)
a
[15]:
True
[16]:
'x' == 'u'
[16]:
False

Integer (Ganze Zahl)

Unlimited range …

[17]:
number = 2**32 - 1
number
[17]:
4294967295
[18]:
number += 1
number
[18]:
4294967296
[19]:
number = 2**64 - 1
number
[19]:
18446744073709551615
[20]:
number += 1
number
[20]:
18446744073709551616
[21]:
number = 2**64
number
[21]:
18446744073709551616
[22]:
2**100
[22]:
1267650600228229401496703205376
[23]:
10**1000
[23]:
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[24]:
1234 == 1*10**3 + 2*10**2 + 3*10**1 + 4*10**0
[24]:
True
[25]:
-1234
[25]:
-1234
[26]:
0xdeadbeef
[26]:
3735928559
[27]:
0b10010011
[27]:
147

Integer Numbers: Arithmetic

Floor division: //, Division without Rest

[28]:
3/2
[28]:
1.5
[29]:
3//2
[29]:
1

Modulo: %, Rest of Division

[30]:
10%4
[30]:
2
[31]:
3%2
[31]:
1
[32]:
13%5
[32]:
3

Strings

Some Methods

[33]:
s = 'Mississippi'
s.count('ss')
[33]:
2
[34]:
s.lower()
[34]:
'mississippi'
[35]:
s.find('ss')
[35]:
2
[36]:
s.find('ss', 3)
[36]:
5
[37]:
s.split('ss')
[37]:
['Mi', 'i', 'ippi']

(many more)

String Formatting: f-Strings

[38]:
firstname = 'Joerg'
lastname = 'Faschingbauer'
address = 'Prankergasse 33'
zip = '8020'
[39]:
print(firstname, lastname, address, zip)
Joerg Faschingbauer Prankergasse 33 8020
[40]:
print(firstname, lastname, address, zip, sep=',')
Joerg,Faschingbauer,Prankergasse 33,8020
[41]:
text = firstname + ' ' + lastname + '; ' + address + ', ' + zip
print(text)
Joerg Faschingbauer; Prankergasse 33, 8020
[42]:
text = '{} {}; {}, {}'.format(firstname, lastname, address, zip)
text
[42]:
'Joerg Faschingbauer; Prankergasse 33, 8020'
[43]:
text = '{a} {b}; {c}, {d}'.format(a=firstname, b=lastname, c=address, d=zip)
text
[43]:
'Joerg Faschingbauer; Prankergasse 33, 8020'
[44]:
text = '{firstname} {lastname}; {address}, {zip}'.format(firstname=firstname, lastname=lastname, address=address, zip=zip)
text
[44]:
'Joerg Faschingbauer; Prankergasse 33, 8020'

f-Strings to the rescue

[45]:
f'{firstname} {lastname}; {address}, {zip}'
[45]:
'Joerg Faschingbauer; Prankergasse 33, 8020'

Datatype Conversions

[46]:
i = 42
s = str(i)
s
[46]:
'42'
[47]:
s = '666'
i = int(s)
i
[47]:
666
[48]:
try:
    int('joerg')    # raises an exception
except Exception as e:
    print(type(e), e)
<class 'ValueError'> invalid literal for int() with base 10: 'joerg'
[49]:
int('0xdeadbeef', 16)
[49]:
3735928559
[50]:
int('0b0101', 2)
[50]:
5
[51]:
int('0101', 2)
[51]:
5
[52]:
float('12.3')
[52]:
12.3
[53]:
bool(0)
[53]:
False
[54]:
bool(1)
[54]:
True
[55]:
bool(42)
[55]:
True
[56]:
if 42:     # bool(42)
    print('teifl!')
teifl!

Boolean

Boolean operators: and, or, not

[57]:
1 == 2 and 3 == 3
[57]:
False
[58]:
1 == 2 or 3 == 3
[58]:
True

Short Circuit Evaluation

[59]:
def fun1():
    print('fun1')
    return False
def fun2():
    print('fun2')
    return True
[60]:
value = fun1()
fun1
[61]:
value
[61]:
False
[62]:
fun1() and fun2()
fun1
[62]:
False
[63]:
fun2() and fun1()
fun2
fun1
[63]:
False
[64]:
fun1() or fun2()
fun1
fun2
[64]:
True
[65]:
not True
[65]:
False
[66]:
not False
[66]:
True
[67]:
not not False
[67]:
False

More about Strings

[68]:
'das ist ein string'
[68]:
'das ist ein string'
[69]:
"das ist ein string"
[69]:
'das ist ein string'
[70]:
len('das ist ein string')
[70]:
18
[71]:
"was'n das fuer ein string?"
[71]:
"was'n das fuer ein string?"
[72]:
'er sagte "DEPP" zu mir!!!'
[72]:
'er sagte "DEPP" zu mir!!!'
[73]:
"er sagte \"DEPP\" zu mir, was'n das fuer'n Depp?!"
[73]:
'er sagte "DEPP" zu mir, was\'n das fuer\'n Depp?!'
[74]:
print('first line\nsecond line')    # linefeed
first line
second line
[75]:
print('first\rline')    # carriage return
linet

Raw String (aka DOS path names, Regular Expressions)

[76]:
windows_path = 'C:\Dokumente\neuer ordner'
print(windows_path)
C:\Dokumente
euer ordner
<>:1: SyntaxWarning: invalid escape sequence '\D'
<>:1: SyntaxWarning: invalid escape sequence '\D'
/tmp/ipykernel_258993/837361033.py:1: SyntaxWarning: invalid escape sequence '\D'
  windows_path = 'C:\Dokumente\neuer ordner'
[77]:
windows_path = r'C:\Dokumente\neuer ordner'
print(windows_path)
C:\Dokumente\neuer ordner
[78]:
line = 'Faschingbauer  ;        Joerg ;        1037190666              '
[79]:
regex_str = r'^\s*(.+)\s*;\s*(.+)\s*;\s*(.+)\s*$'
[80]:
import re
match = re.search(regex_str, line)
[81]:
match.group(0)
[81]:
'Faschingbauer  ;        Joerg ;        1037190666              '
[82]:
match.group(1)
[82]:
'Faschingbauer  '
[83]:
match.group(2)
[83]:
'Joerg '
[84]:
match.group(3)
[84]:
'1037190666              '

Multiline Strings

[85]:
def f():
    '''This function is rather stupid.
    Rather than letting the user write a simple
    True/False, it calims that it is much better
    to call the function instead.'''
    return True
[86]:
help(f)
Help on function f in module __main__:

f()
    This function is rather stupid.
    Rather than letting the user write a simple
    True/False, it calims that it is much better
    to call the function instead.

Kontrollstrukturen

if

[87]:
answer = 42
if answer == 42:
    print('yaaay!!')
yaaay!!
[88]:
answer = 1
if answer == 42:
    print('yaaay!!')
else:
    print('bad')
bad
[89]:
# possible answers: 41, 42, 43 -> elif

answer = 43

if answer == 41:
    print('yaaay!! (41)')
elif answer == 42:
    print('yaaay!! (42)')
elif answer == 43:
    print('yaaay!! (43)')
else:
    print('bad')
yaaay!! (43)

2022-01-18

Miscellanea

Braces: Single Element Tuples?

[90]:
l = ['eins', 2, 3.0]
l
[90]:
['eins', 2, 3.0]

Mutability

[91]:
l.append(4)
l
[91]:
['eins', 2, 3.0, 4]

Immutability

[92]:
s = 'lower'
s
[92]:
'lower'
[93]:
s.upper()
[93]:
'LOWER'
[94]:
s
[94]:
'lower'
[95]:
t = ('eins', 2, 3.0)    # tuple
t
[95]:
('eins', 2, 3.0)
[96]:
try:
    t.append(4)
except Exception as e:
    print(type(e), e)
<class 'AttributeError'> 'tuple' object has no attribute 'append'

Single element tuples

[97]:
t = ('eins')
t
[97]:
'eins'
[98]:
type(t)
[98]:
str

Braces are special

[99]:
2*5%3
[99]:
1
[100]:
(2*5)%3
[100]:
1
[101]:
2*(5%3)
[101]:
4

Single element tuples, done right

[102]:
t = ('eins',)
t
[102]:
('eins',)

Ranges -> range() (hour_of_day)

[103]:
hour_of_day = 2
if 0 <= hour_of_day <= 9:
    print('Good morning, ')
Good morning,

Range

[104]:
for number in range(0,4):
    print(number)
0
1
2
3
[105]:
hour_of_day = 2
if 0 <= hour_of_day < 10:
    print('Good morning, ')
Good morning,

while Loops

Sum of number 0 .. 10 (inclusive)

[106]:
# 0 + 1 + 2 + ... + 10
[107]:
sum = 0
num = 0
while num <= 10:
    sum += num
    num += 1
print(sum)
55
[108]:
sum = 0
for num in range(0, 11):
    sum += num
print(sum)
55

break and continue

[109]:
import random
[110]:
random.randrange(100)   # evenly distributed random number in range(0, 100)
[110]:
33

Search needle in infinite haystack

[111]:
# search for needle in haystack
needle = 42
while True:
    number = random.randrange(100)
    if number == needle:
        print('yay!!')
        break
print('found')
yay!!
found
[112]:
# search for needle in haystack
needle = 42
while True:
    number = random.randrange(100)
    if number != needle:
        continue
    else:
        print('yay!!')
        break

print('found')
yay!!
found

And finite haystacks?

[113]:
needle = 42
haystack_size = 100
run = 0
found = False

while run < haystack_size:
    run += 1

    number = random.randrange(100)
    if number == needle:
        found = True
        break

if found:
    print('found')
else:
    print('not found')
not found

while and else

[114]:
needle = 42
haystack_size = 100
run = 0

while run < haystack_size:
    run += 1

    number = random.randrange(100)
    if number == needle:
        print('found')
        break
else:
    print('not found')
not found

yield, Generator, Iteration Protocol

[115]:
for num in range(3):
    print(num)
0
1
2
[116]:
for num in [0,1,2]:
    print(num)
0
1
2
[117]:
r = range(3)
r     # wtf?
[117]:
range(0, 3)

Iterator protocol

[118]:
r = range(3)
it = iter(r)
it
[118]:
<range_iterator at 0x7fe78c576ee0>
[119]:
num = next(it)
num
[119]:
0
[120]:
next(it)
[120]:
1
[121]:
next(it)
[121]:
2
[122]:
try:
    next(it)
except StopIteration as e:
    print(type(e), e)
<class 'StopIteration'>
[123]:
for num in range(3):    # <-- iterator protocol
    print(num)
0
1
2
[124]:
l = [0,1,2]
[125]:
for num in l:
    print(num)
0
1
2
[126]:
it = iter(l)
[127]:
it
[127]:
<list_iterator at 0x7fe78c577910>
[128]:
next(it)
[128]:
0
[129]:
next(it)
[129]:
1
[130]:
next(it)
[130]:
2
[131]:
try:
    next(it)
except StopIteration:
    pass

Sequential Datatypes

[132]:
s = 'abc'
for unicode_code_point in s:
    print(unicode_code_point)
a
b
c
[133]:
s[1]
[133]:
'b'
[134]:
l = [1, 'zwei', 3.0, [0,1,2,3]]
for element in l:
    print(element)
1
zwei
3.0
[0, 1, 2, 3]
[135]:
l[3]
[135]:
[0, 1, 2, 3]

Concatenation

[136]:
l_new = [5, 6, 'seven']
[137]:
l + l_new
[137]:
[1, 'zwei', 3.0, [0, 1, 2, 3], 5, 6, 'seven']

Original lists remain unmodified

[138]:
l
[138]:
[1, 'zwei', 3.0, [0, 1, 2, 3]]
[139]:
l_new
[139]:
[5, 6, 'seven']

As opposed to +=

[140]:
l += l_new
[141]:
l
[141]:
[1, 'zwei', 3.0, [0, 1, 2, 3], 5, 6, 'seven']

Mixing types?

[142]:
l = [1,2,3]
s = 'abc'
[143]:
l += s
[144]:
l
[144]:
[1, 2, 3, 'a', 'b', 'c']

Sequence Membership

[145]:
l = [100, 2, 3, 6]
[146]:
if 100 in l:
    print('yay')
yay
[147]:
100 in l
[147]:
True
[148]:
6 in l
[148]:
True
[149]:
2000 in l
[149]:
False
[150]:
not 2000 in l
[150]:
True
[151]:
2000 not in l
[151]:
True

Compound Datatypes

list (mutable)

[152]:
l = []   # empty list
l = list()   # empty list
[153]:
l = list('abc')
l
[153]:
['a', 'b', 'c']
[154]:
l = ['abc']
l
[154]:
['abc']
[155]:
l = ['a', 'b', 'c']
l
[155]:
['a', 'b', 'c']
[156]:
l.append('D')
l
[156]:
['a', 'b', 'c', 'D']
[157]:
l.extend(['e', 'f'])
l
[157]:
['a', 'b', 'c', 'D', 'e', 'f']
[158]:
l += ['g', 'h']
l
[158]:
['a', 'b', 'c', 'D', 'e', 'f', 'g', 'h']
[159]:
l += 'ijk'
l
[159]:
['a', 'b', 'c', 'D', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
[160]:
try:
    l += 666
except Exception as e:
    print(type(e), e)
<class 'TypeError'> 'int' object is not iterable
[161]:
del l[0]
l
[161]:
['b', 'c', 'D', 'e', 'f', 'g', 'h', 'i', 'j', 'k']

tuple (immutable)

[162]:
t = ()   # empty tuple
t = tuple()  # empty tuple
[163]:
t = (1, 2, 'drei')
t
[163]:
(1, 2, 'drei')
[164]:
t = tuple('abc')
t
[164]:
('a', 'b', 'c')
[165]:
try:
    t = tuple(666)
except Exception as e:
    print(type(e), e)
<class 'TypeError'> 'int' object is not iterable
[166]:
t = (1,2,3)
[167]:
try:
    t.append(666)
except Exception as e:
    print(type(e), e)
<class 'AttributeError'> 'tuple' object has no attribute 'append'

dict (mutable)

[168]:
d = {}   # empty dictionary
d = dict()  # empty dictionary
[169]:
d = {
    1: 'one',
    2: 'two',
}
[170]:
len(d)
[170]:
2

Lookup (in constant time - independent of number of elements)

[171]:
d[1]
[171]:
'one'
[172]:
2 in d
[172]:
True
[173]:
d[4] = 'vier'
4 in d
[173]:
True
[174]:
d
[174]:
{1: 'one', 2: 'two', 4: 'vier'}
[175]:
d[4] = 'four'
d
[175]:
{1: 'one', 2: 'two', 4: 'four'}
[176]:
del d[4]
4 in d
[176]:
False

set (mutable)

[177]:
s = {}   # attention: empty DICTIONARY
s = set()  # empty set
[178]:
s = {1, 2, 3}
s
[178]:
{1, 2, 3}
[179]:
s = set('abc')
s
[179]:
{'a', 'b', 'c'}
[180]:
'b' in s
[180]:
True
[181]:
5 in s
[181]:
False
[182]:
s.add('b')
s
[182]:
{'a', 'b', 'c'}
[183]:
s.add('d')
s
[183]:
{'a', 'b', 'c', 'd'}
[184]:
s.remove('a')
s
[184]:
{'b', 'c', 'd'}

set operation (Mengenlehre)

[185]:
s1 = {1, 2, 3}
s2 = {2, 3, 4}
[186]:
s1 | s2    # union
[186]:
{1, 2, 3, 4}
[187]:
s1 & s2   # intersection
[187]:
{2, 3}
[188]:
s1 - s2
[188]:
{1}

Not ordered

[189]:
s = set()
[190]:
s.add(1000)
s.add(10)
s.add(1)
[191]:
for i in s:
    print(i)
1000
1
10

Why Index Based Iteration is not Always the Best Way to Iterate

[192]:
l = [10, 20, 32, 2, 6]
[193]:
for index in range(len(l)):    # indices: 0,1,2,3,4
    print(l[index])
10
20
32
2
6
[194]:
for element in l:
    print(element)
10
20
32
2
6

How to get Indexes if There are None? (enumerate(), and Tuple Unpacking)

[195]:
names = ['Gunnar', 'Liam', 'Joerg']
for name in names:
    print(name)
Gunnar
Liam
Joerg

And Positions?

[196]:
i = 0
for name in names:
    print(i, name)
    i += 1
0 Gunnar
1 Liam
2 Joerg
[197]:
for i in range(len(names)):
    print(i, names[i])
0 Gunnar
1 Liam
2 Joerg
[198]:
for i, name in enumerate(names):   # tuple unpacking
    print(i, name)
0 Gunnar
1 Liam
2 Joerg
[199]:
for element in enumerate(names):
    print(element)
(0, 'Gunnar')
(1, 'Liam')
(2, 'Joerg')
[200]:
for element in enumerate(names):
    i, name = element    # tuple unpacking
    print(i, name)
0 Gunnar
1 Liam
2 Joerg

Functions

[201]:
def maximum(a, b):
    '''Diese extrem komplexe Funktion berechnet das Maximumum ihrer beiden Parameter.
    Ganz zum Unterschied der built-in Funktion max() nimmt sie nur zwei Parameter und
    nicht beliebig viele.'''
    if a < b:
        return b
    else:
        return a
[202]:
max = maximum(2, 3)
max
[202]:
3
[203]:
variable = 100
type(variable)
[203]:
int
[204]:
variable = [1, 2, 3]
type(variable)
[204]:
list
[205]:
variable2 = variable
[206]:
variable.append(4)
variable
[206]:
[1, 2, 3, 4]
[207]:
variable2
[207]:
[1, 2, 3, 4]
[208]:
type(maximum)
[208]:
function
[209]:
maximum(3, 4)
[209]:
4
[210]:
maximum2 = maximum
type(maximum2)
[210]:
function
[211]:
maximum2(4, 5)
[211]:
5
[212]:
import sys
type(sys)
[212]:
module
[213]:
maximum(2, 1)
[213]:
2
[214]:
maximum('aaa', 'bbb')
[214]:
'bbb'
[215]:
try:
    maximum(1, '2')
except Exception as e:
    print(type(e), e)
<class 'TypeError'> '<' not supported between instances of 'int' and 'str'

Default Parameters

[216]:
def greet(phrase, mrmrs, name):
    print(f'{phrase}, {mrmrs} {name}')
[217]:
greet('Good morning', 'Mr.', 'Joerg')
Good morning, Mr. Joerg
[218]:
greet('Good morning', 'Mr.', 'Liam')
Good morning, Mr. Liam
[219]:
try:
    greet('Good morning')
except Exception as e:
    print(type(e), e)
<class 'TypeError'> greet() missing 2 required positional arguments: 'mrmrs' and 'name'
[220]:
def greet(phrase, mrmrs='Mr.', name='Joerg'):
    print(f'{phrase}, {mrmrs} {name}')
[221]:
greet('Good morning')
Good morning, Mr. Joerg
[222]:
greet('Good morning', 'XXX.')
Good morning, XXX. Joerg
[223]:
greet('Good morning', 'Liam')
Good morning, Liam Joerg

Keyword Arguments

[224]:
greet('Good evening', 'Mr.', 'Liam')
Good evening, Mr. Liam
[225]:
greet(mrmrs='Mr.', name='Liam', phrase='Seas')
Seas, Mr. Liam

More on Lists

[226]:
l = [3, 2, 'eins']
l
[226]:
[3, 2, 'eins']
[227]:
l.append(4)
l
[227]:
[3, 2, 'eins', 4]
[228]:
l1 = l
l.append(5)
l
[228]:
[3, 2, 'eins', 4, 5]
[229]:
l1
[229]:
[3, 2, 'eins', 4, 5]
[230]:
l.extend([6, 7])
l
[230]:
[3, 2, 'eins', 4, 5, 6, 7]
[231]:
l.extend('abc')
l
[231]:
[3, 2, 'eins', 4, 5, 6, 7, 'a', 'b', 'c']
[232]:
try:
    l.extend(666)
except Exception as e:
    print(type(e), e)
<class 'TypeError'> 'int' object is not iterable
[233]:
l.insert(0, 'minus eins')
l
[233]:
['minus eins', 3, 2, 'eins', 4, 5, 6, 7, 'a', 'b', 'c']
[234]:
l.insert(3, 'vor dem einser')
l
[234]:
['minus eins', 3, 2, 'vor dem einser', 'eins', 4, 5, 6, 7, 'a', 'b', 'c']
[235]:
del l[3]
[236]:
l
[236]:
['minus eins', 3, 2, 'eins', 4, 5, 6, 7, 'a', 'b', 'c']
[237]:
elem = l[4]
elem
[237]:
4
[238]:
l
[238]:
['minus eins', 3, 2, 'eins', 4, 5, 6, 7, 'a', 'b', 'c']
[239]:
elem = l.pop(4)
elem
[239]:
4
[240]:
l
[240]:
['minus eins', 3, 2, 'eins', 5, 6, 7, 'a', 'b', 'c']

sorted() etc. wants non-mixed lists

[241]:
l = [1, 2.3, 100, 10, 5]
[242]:
sorted(l)
[242]:
[1, 2.3, 5, 10, 100]
[243]:
l
[243]:
[1, 2.3, 100, 10, 5]
[244]:
l.sort()
[245]:
l
[245]:
[1, 2.3, 5, 10, 100]

List Comprehensions

Problem: transform [1,2,3,4] into [1,4,9,16]

[246]:
numbers = [1, 2, 3, 4]
square_numbers = []
for n in numbers:
    square_numbers.append(n**2)
for n in square_numbers:
    print(n)
1
4
9
16
[247]:
def squares(numbers):
    ret = []
    for n in numbers:
        ret.append(n**2)
    return ret
[248]:
numbers = [1, 2, 3, 4]
square_numbers = squares(numbers)
for n in square_numbers:
    print(n)
1
4
9
16
[249]:
numbers = [1, 2, 3, 4]
square_numbers = [n**2 for n in numbers]
for n in square_numbers:
    print(n)
1
4
9
16

Generator Expressions

[250]:
def squares_generator(numbers):
    for n in numbers:
        yield n**2
[251]:
numbers = [1, 2, 3, 4]
square_numbers = squares_generator(numbers)
for n in square_numbers:
    print(n)
1
4
9
16
[252]:
numbers = [1, 2, 3, 4]
square_numbers = (n**2 for n in numbers)
for n in square_numbers:
    print(n)
1
4
9
16

More on Dictionaries

[253]:
d = {'zero': 0,
    'one': 1,
    'two': 2}
[254]:
d['zero']
[254]:
0
[255]:
d['three'] = 3
[256]:
d
[256]:
{'zero': 0, 'one': 1, 'two': 2, 'three': 3}
[257]:
try:
    d['seven']
except Exception as e:
    print(type(e), e)
<class 'KeyError'> 'seven'
[258]:
value = d.get('zero')
value
[258]:
0
[259]:
value = d.get('seven')
print(value)
None
[260]:
value = d.get('seven')
if value:
    print(value)
else:
    print('nix')
    d['seven'] = 7
nix
[261]:
value = d.get('eight', 8)
value
[261]:
8
[262]:
value = d.setdefault('eight', 8)
value
[262]:
8
[263]:
d
[263]:
{'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'seven': 7, 'eight': 8}
[264]:
other_d = {
    'three': 'drei',
    'four': 4,
    'nine': 'nove'
}
[265]:
d.update(other_d)
d
[265]:
{'zero': 0,
 'one': 1,
 'two': 2,
 'three': 'drei',
 'seven': 7,
 'eight': 8,
 'four': 4,
 'nine': 'nove'}

Iteration over Dictionaries

[266]:
d
[266]:
{'zero': 0,
 'one': 1,
 'two': 2,
 'three': 'drei',
 'seven': 7,
 'eight': 8,
 'four': 4,
 'nine': 'nove'}
[267]:
for element in d:    # iteration over keys
    print(element)
zero
one
two
three
seven
eight
four
nine
[268]:
for element in d.keys():
    print(element)
zero
one
two
three
seven
eight
four
nine
[269]:
for element in d.values():
    print(element)
0
1
2
drei
7
8
4
nove
[270]:
for element in d.items():
    print(element)
('zero', 0)
('one', 1)
('two', 2)
('three', 'drei')
('seven', 7)
('eight', 8)
('four', 4)
('nine', 'nove')
[271]:
for element in d.items():
    key = element[0]
    value = element[1]
    print(f'Key: {key}, Value: {value}')
Key: zero, Value: 0
Key: one, Value: 1
Key: two, Value: 2
Key: three, Value: drei
Key: seven, Value: 7
Key: eight, Value: 8
Key: four, Value: 4
Key: nine, Value: nove
[272]:
for element in d.items():
    key, value = element     # tuple unpacking
    print(f'Key: {key}, Value: {value}')
Key: zero, Value: 0
Key: one, Value: 1
Key: two, Value: 2
Key: three, Value: drei
Key: seven, Value: 7
Key: eight, Value: 8
Key: four, Value: 4
Key: nine, Value: nove
[273]:
for key, value in d.items():     # tuple unpacking
    print(f'Key: {key}, Value: {value}')
Key: zero, Value: 0
Key: one, Value: 1
Key: two, Value: 2
Key: three, Value: drei
Key: seven, Value: 7
Key: eight, Value: 8
Key: four, Value: 4
Key: nine, Value: nove

Building Dictionaries

[274]:
d = {}   # empty dictionary
s = set() # empty set
d = {1: 2, 2: 3}
d
[274]:
{1: 2, 2: 3}
[275]:
items = [(1, 2), (2, 3)]
d = dict(items)
d
[275]:
{1: 2, 2: 3}
[276]:
items = list(d.items())
items
[276]:
[(1, 2), (2, 3)]

More on Sets

[277]:
s = {}  # empty dictionary
type(s)
[277]:
dict
[278]:
s = set() # empty set
s = {1, 2, 3}
[279]:
s = set('abc')
s
[279]:
{'a', 'b', 'c'}
[280]:
s = set([3, 4, 2, 1, 5])
s
[280]:
{1, 2, 3, 4, 5}

Miscellaneous String Methods

[281]:
s = '      \n\t   \r'   # only whitespace
s.isspace()
[281]:
True
[282]:
s = 'abc'
s.isalpha()
[282]:
True
[283]:
'12345'.isdigit()
[283]:
True
[284]:
'buchhaltung.csv'.endswith('.csv')
[284]:
True
[285]:
'buchhaltung.csv'.startswith('buch')
[285]:
True
[286]:
'OOOO'.center(100)
[286]:
'                                                OOOO                                                '
[287]:
'Joerg'.isupper()
[287]:
False
[288]:
'Mississippi'.count('ss')
[288]:
2
[289]:
'Mississippi'.find('ss')
[289]:
2
[290]:
'Mississippi'.find('ss', 3)
[290]:
5
[291]:
'Mississippi'.find('zz')
[291]:
-1
[292]:
if 'Mississippi'.find('zz') == -1:
    print('traurig')
else:
    print('yay')
traurig
[293]:
try:
    'Mississippi'.index('zz')
except Exception as e:
    print(type(e), e)
<class 'ValueError'> substring not found
[294]:
row = 'jfasch:x:1000:1000:Joerg Faschingbauer:/home/jfasch:/bin/bash'
fields = row.split(':')
fields
[294]:
['jfasch',
 'x',
 '1000',
 '1000',
 'Joerg Faschingbauer',
 '/home/jfasch',
 '/bin/bash']

Tuple unpacking:

[295]:
user, passwd, uid, gid, descr, home, shell = row.split(':')
user
[295]:
'jfasch'
[296]:
'-'.join(['hello', 'world', 'und', 'sonst', 'alle'])
[296]:
'hello-world-und-sonst-alle'
[297]:
'    \n \t     irgendwas    \r'.strip()
[297]:
'irgendwas'
[298]:
'    \n \t     irgendwas    \r'.lstrip()
[298]:
'irgendwas    \r'
[299]:
'    \n \t     irgendwas    \r'.rstrip()
[299]:
'    \n \t     irgendwas'

with: Context Managers

[300]:
def count_bytes(filename):
    f = open(filename)
    content = f.read()    # <-- exception might be raised
    f.close()   # <-- might not be reached, for that reason
    return len(content)
[301]:
nbytes = count_bytes('/etc/passwd')
nbytes
[301]:
2706
[302]:
def count_bytes(filename):
    f = open(filename)
    try:
        content = f.read()    # <-- exception might be raised
    except Exception:
        f.close()
        raise
    f.close()   # <-- might not be reached, for that reason
    return len(content)
[303]:
nbytes = count_bytes('/etc/passwd')
nbytes
[303]:
2706
[304]:
def count_bytes(filename):
    with open(filename) as f:
        content = f.read()    # <-- exception might be raised
        return len(content)