Jupyter Notebook: Python Advanced (2023-04-24 - 2023-04-26)

Iterator Protocol

[1]:
for i in range(3):
    print(i)
0
1
2
[2]:
for i in [0,1,2]:
    print(i)
0
1
2
[3]:
drei_millionen_ints = list(range(3_000_000))
[4]:
type(drei_millionen_ints)
[4]:
list
[5]:
r = range(3)
[6]:
print(type(r))
<class 'range'>
[7]:
it = iter(r)
[8]:
print(type(it))
<class 'range_iterator'>
[9]:
next(it)
[9]:
0
[10]:
next(it)
[10]:
1
[11]:
next(it)
[11]:
2
[12]:
try:
    next(it)
except StopIteration:
    pass
[13]:
for i in range(3):
    print(i)
0
1
2
[14]:
numbers = range(10)
[15]:
def odd_numbers(iterable):
    for number in iterable:
        if number % 2 != 0:
            print('next element')
            yield number
[16]:
for i in odd_numbers(numbers):
    print(i)
next element
1
next element
3
next element
5
next element
7
next element
9
[17]:
def odd_numbers_func(l):
    ret_nums = []
    for number in l:
        if number % 2 != 0:
            ret_nums.append(number)
    print('returning result')
    return ret_nums
[18]:
for i in odd_numbers_func(numbers):
    print(i)
returning result
1
3
5
7
9

Dynamic Features

[19]:
a = 42
[20]:
globals()['a']
[20]:
42
[21]:
globals()['numbers']
[21]:
range(0, 10)
[22]:
code = '''
eine_variable = 7
'''
[23]:
context = {}
[24]:
exec(code, context)
[25]:
context['eine_variable']
[25]:
7
[26]:
class Foo:
    def __init__(self, bar, blech):
        self.bar = bar
        self.blech = blech
[27]:
f = Foo('Joerg', 'Faschingbauer')
[28]:
f.__dict__
[28]:
{'bar': 'Joerg', 'blech': 'Faschingbauer'}
[29]:
print(type(odd_numbers))
<class 'function'>
[30]:
print(type(a))
<class 'int'>
[31]:
odd_numbers.__name__
[31]:
'odd_numbers'
[32]:
blah = odd_numbers
[33]:
blah
[33]:
<function __main__.odd_numbers(iterable)>
[34]:
blah.__name__
[34]:
'odd_numbers'

Variables

[35]:
a = 42
[36]:
print(type(a))
<class 'int'>
[37]:
a = 1.234
[38]:
type(a)
[38]:
float
[39]:
a = [1,2,'drei']
[40]:
type(a)
[40]:
list
[41]:
a = odd_numbers
[42]:
type(a)
[42]:
function
[43]:
t = (1,2)
[44]:
type(t)
[44]:
tuple
[45]:
x, y = t
[46]:
x
[46]:
1
[47]:
y
[47]:
2
[48]:
x, y = 1, 2
[49]:
x, y = (1, 2)
[50]:
x, y = 1, 2
[51]:
tmp = x
[52]:
x = y
[53]:
y = tmp
[54]:
x
[54]:
2
[55]:
y
[55]:
1
[56]:
x, y = 1, 2
[57]:
x, y = y, x
[58]:
x
[58]:
2
[59]:
y
[59]:
1
[60]:
a = 42
[61]:
b = a
[62]:
hex(id(a))
[62]:
'0x7f32ccc4c610'
[63]:
hex(id(b))
[63]:
'0x7f32ccc4c610'

Datatypes

[64]:
i = 42
[65]:
i = 2**64-1
[66]:
bin(i)
[66]:
'0b1111111111111111111111111111111111111111111111111111111111111111'
[67]:
i += 1
[68]:
i
[68]:
18446744073709551616
[69]:
bin(i)
[69]:
'0b10000000000000000000000000000000000000000000000000000000000000000'
[70]:
10**6
[70]:
1000000
[71]:
10**10
[71]:
10000000000
[72]:
10**100
[72]:
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[73]:
10**1000
[73]:
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[74]:
3/2
[74]:
1.5

is vs. ==

[75]:
l1 = [1,2,3]
[76]:
l2 = [3,4,5]
[77]:
id(l1)
[77]:
139855258515840
[78]:
id(l2)
[78]:
139856078033344
[79]:
l1 is l2
[79]:
False
[80]:
l1 == l2
[80]:
False
[81]:
l3 = [1,2,3]
[82]:
id(l3)
[82]:
139856078226432
[83]:
l1 is l3
[83]:
False
[84]:
l1 == l3
[84]:
True
[85]:
l1.append(4)
[86]:
l1
[86]:
[1, 2, 3, 4]
[87]:
l3
[87]:
[1, 2, 3]
[88]:
i1 = 42
[89]:
i2 = i1
[90]:
id(i1)
[90]:
139856160540176
[91]:
id(i2)
[91]:
139856160540176
[92]:
i1 is i2
[92]:
True
[93]:
i1 == i2
[93]:
True
[94]:
i1 = 42
[95]:
i2 = 42
[96]:
i1 is i2
[96]:
True
[97]:
i3 = 10**1000
[98]:
i4 = 10**1000
[99]:
i3 is i4
[99]:
False
[100]:
b = False
[101]:
if b is False:
    print('yay')
yay
[102]:
if b == False:
    print('yay')
yay
[103]:
if b:
    print('nope')
[104]:
l3
[104]:
[1, 2, 3]
[105]:
if l3:
    print('yay')
yay
[106]:
if []:
    print('yay')
[107]:
s = 'abc'
[108]:
if s:
    print('yay')
yay
[109]:
if '':
    print('yay')

Datatype Conversions

[110]:
s = 'abc'
[111]:
print(type(s))
<class 'str'>
[112]:
i = 42
[113]:
s = str(i)
[114]:
s
[114]:
'42'
[115]:
s == i
[115]:
False
[116]:
str()
[116]:
''
[117]:
int()
[117]:
0
[118]:
i = int('42')
[119]:
i
[119]:
42
[120]:
int('42', 16)
[120]:
66
[121]:
int('0101010101010', 2)
[121]:
2730
[122]:
print(type(l1))
<class 'list'>
[123]:
list()
[123]:
[]
[124]:
list('abc')
[124]:
['a', 'b', 'c']
[125]:
for c in 'abc':
    print(c)
a
b
c
[126]:
l = []
for c in 'abc':
    l.append(c)
[127]:
l
[127]:
['a', 'b', 'c']
[128]:
list(range(3))
[128]:
[0, 1, 2]
[129]:
type(l)
[129]:
list
[130]:
type(42)
[130]:
int
[131]:
print(int)
<class 'int'>
[132]:
print(type(int))
<class 'type'>
[133]:
int = 666
[134]:
try:
    int('42')
except TypeError as e:
    print(e, type(e))
'int' object is not callable <class 'TypeError'>
[135]:
import os
os.listdir('/home/jfasch')
[135]:
['.bash_logout',
 '.bash_profile',
 '.cache',
 '.config',
 '.local',
 'Desktop',
 'Downloads',
 'Templates',
 'Public',
 'Documents',
 'Music',
 'Pictures',
 'Videos',
 'old-home',
 'Homebrain',
 '.thunderbird',
 '.mozilla',
 'work',
 'venv',
 '.emacs.d',
 '.bashrc~',
 '.emacs',
 '.gnupg',
 'tmp',
 '.wget-hsts',
 '.cups',
 '.gitconfig',
 '.pki',
 '.var',
 '.zoom',
 '.mplayer',
 '.ipython',
 '.jupyter',
 'hello.~1~',
 'x-tools',
 'cross',
 'build',
 '.dia',
 '.bashrc.~1~',
 '.bashrc.~2~',
 '.bashrc',
 'raspi-home',
 'daham',
 'C++-Training-2023-03-20',
 '.ssh',
 '#*message*-20230403-222915#',
 'blink-home',
 'can.log',
 '.bash_history',
 '.python_history',
 '.lesshst']
[136]:
import os
os.listdir = lambda d: []
[137]:
os.listdir('/home/jfasch')
[137]:
[]
[138]:
os.listdir = None
[139]:
try:
    os.listdir('/home/jfasch')
except TypeError as e:
    print(e, type(e))
'NoneType' object is not callable <class 'TypeError'>

Compound DataTypes

List, Tuple

[140]:
l = [1,2,3]
[141]:
l.append(4)
[142]:
l
[142]:
[1, 2, 3, 4]
[143]:
l.extend([5,6,7])
[144]:
l
[144]:
[1, 2, 3, 4, 5, 6, 7]
[145]:
l.extend('abc')
l
[145]:
[1, 2, 3, 4, 5, 6, 7, 'a', 'b', 'c']
[146]:
try:
    l.extend(666)
except TypeError as e:
    print(e, type(e))
'int' object is not iterable <class 'TypeError'>
[147]:
l.append([8,9,10])
l
[147]:
[1, 2, 3, 4, 5, 6, 7, 'a', 'b', 'c', [8, 9, 10]]
[148]:
l[0]
[148]:
1
[149]:
l[1]
[149]:
2
[150]:
l1 = [1,2,3]
[151]:
id(l1)
[151]:
139855258795072
[152]:
l2 = [4,5,6]
[153]:
l1 + l2
[153]:
[1, 2, 3, 4, 5, 6]
[154]:
id(l1)
[154]:
139855258795072
[155]:
l1 += l2
[156]:
l1
[156]:
[1, 2, 3, 4, 5, 6]
[157]:
id(l1)     # <--- mutable
[157]:
139855258795072
[158]:
t = (1,2,3)
print(type(t))
<class 'tuple'>
[159]:
t
[159]:
(1, 2, 3)
[160]:
t[0]
[160]:
1
[161]:
t[1]
[161]:
2
[162]:
try:
    t.append(4)
except AttributeError as e:
    print(e, type(e))
'tuple' object has no attribute 'append' <class 'AttributeError'>
[163]:
id(t)
[163]:
139855260513728
[164]:
t += (4,5,6)
[165]:
id(t)
[165]:
139856085569920

Dictionary

[166]:
d = {
    'one': 1,
    'two': 2,
}
[167]:
d['one']
[167]:
1
[168]:
'one' in d
[168]:
True
[169]:
'four' in d
[169]:
False
[170]:
'four' not in d
[170]:
True
[171]:
d['four'] = 'vier'
[172]:
d
[172]:
{'one': 1, 'two': 2, 'four': 'vier'}
[173]:
del d['four']
[174]:
'four' in d
[174]:
False
[196]:
d['four'] = 'vier'

pop

[197]:
elem = d['four']
del d['four']
elem
[197]:
'vier'
[198]:
d['four'] = 'vier'
[199]:
elem = d.pop('four')
elem
[199]:
'vier'
[177]:
try:
    d.pop('four')
except Exception as e:
    print(e, type(e))
'four' <class 'KeyError'>

get

[201]:
try:
    elem = d['four']
except KeyError:
    elem = None
if elem is None:
    print('nix')
else:
    print('yay')
nix
[205]:
elem = d.get('four')
if elem is None:
    print('nix')
else:
    print('yay')
nix

Doppelt gemoppelt:

[217]:
if 'four' in d:     # <--- constant time
    elem = d['four']
else:
    elem = 4
print(elem)
4

Einfach gemoppelt:

[218]:
elem = d.get('four', 4)
print(elem)
4

keys()? in?

[219]:
if 'four' in d.keys():    # <--- sequential search!
    elem = d['four']
else:
    elem = 4
print(elem)
4
[211]:
keys = d.keys()
type(keys)
[211]:
dict_keys

Wenn 'four' nicht in d, dann trag 4 ein (und gib 4 zurueck). Wenn doch drin, gib dessen Wert zurueck.

[220]:
if 'four' not in d:
    d['four'] = 4
    value = 4
else:
    value = d['four']
print(value)
4
[221]:
del d['four']

setdefault

Exakt das gleiche:

[222]:
value = d.setdefault('four', 4)
print(value)
4

Dictionary constructor

[226]:
d = {
    'one': 1,
    'two': 2,
    'three': 3,
}
[227]:
d
[227]:
{'one': 1, 'two': 2, 'three': 3}
[229]:
d = dict([('one', 1), ('two', 2), ('three', 3)])
[230]:
d
[230]:
{'one': 1, 'two': 2, 'three': 3}

Dictionary iteration

Key iteration, implizit

[233]:
for elem in d:
    print(elem)
one
two
three

Key iteration, explizit

[234]:
for k in d.keys():
    print(k)
one
two
three

Value iteration

[235]:
for v in d.values():
    print(v)
1
2
3

Paarweise iteration (keys, values)

[237]:
for elem in d.items():
    print(elem)
('one', 1)
('two', 2)
('three', 3)

Tuple unpacking

[238]:
x, y = (1,2)
[239]:
x
[239]:
1
[240]:
y
[240]:
2
[241]:
for elem in d.items():
    k = elem[0]
    v = elem[1]
    print(f'key: {k}, value: {v}')
key: one, value: 1
key: two, value: 2
key: three, value: 3
[242]:
for k, v in d.items():
    print(f'key: {k}, value: {v}')
key: one, value: 1
key: two, value: 2
key: three, value: 3

Set

[178]:
s = {1,2,3}
[179]:
s = set()
[180]:
s = set('abc')
s
[180]:
{'a', 'b', 'c'}
[181]:
'a' in s
[181]:
True
[182]:
s.add('d')
[183]:
'd' in s
[183]:
True
[184]:
s.remove('a')
[185]:
'a' in s
[185]:
False
[186]:
s = frozenset('abc')
[187]:
try:
    s.add('d')
except Exception as e:
    print(e, type(e))
'frozenset' object has no attribute 'add' <class 'AttributeError'>
[188]:
for elem in s:
    print(elem)
b
a
c
[189]:
s1 = {1,2,3}
s2 = {2,3,4,5}
[190]:
s1 | s2
[190]:
{1, 2, 3, 4, 5}
[191]:
s1 & s2
[191]:
{2, 3}
[192]:
s1 ^ s2
[192]:
{1, 4, 5}

Mutability

[243]:
a = [1,2,3]
b = a
[245]:
a is b
[245]:
True
[246]:
id(a) == id(b)
[246]:
True
[247]:
b.append(4)
b
[247]:
[1, 2, 3, 4]
[248]:
a
[248]:
[1, 2, 3, 4]
[250]:
a = [1,2,3]
b = a[:]
[251]:
a is b
[251]:
False
[252]:
b.append(4)
[254]:
b
[254]:
[1, 2, 3, 4]
[255]:
a
[255]:
[1, 2, 3]

Nested lists?

[256]:
a = [1, [2,3,4], 5]
len(a)
[256]:
3
[257]:
b = a[:]
[258]:
b[0] = 666
[259]:
b
[259]:
[666, [2, 3, 4], 5]
[260]:
a
[260]:
[1, [2, 3, 4], 5]
[261]:
b[1].append(666)
[262]:
b
[262]:
[666, [2, 3, 4, 666], 5]
[263]:
a
[263]:
[1, [2, 3, 4, 666], 5]

File I/O

[269]:
f = open('/etc/passwd')
[270]:
block = f.read(10)
[272]:
len(block)
[272]:
10
[274]:
block
[274]:
'root:x:0:0'
[275]:
f.readline()
[275]:
':root:/root:/bin/bash\n'
[276]:
f.readline()
[276]:
'bin:x:1:1:bin:/bin:/sbin/nologin\n'
[277]:
f.readline()
[277]:
'daemon:x:2:2:daemon:/sbin:/sbin/nologin\n'

… und so weiter …

[291]:
f = open('/etc/passwd')
[292]:
for line in f:
    print(line.rstrip())   # <--- strip trailing newline
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/usr/sbin/nologin
systemd-oom:x:999:999:systemd Userspace OOM Killer:/:/usr/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/usr/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
polkitd:x:998:997:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
unbound:x:997:995:Unbound DNS resolver:/etc/unbound:/sbin/nologin
nm-openconnect:x:996:994:NetworkManager user for OpenConnect:/:/sbin/nologin
geoclue:x:995:993:User for geoclue:/var/lib/geoclue:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
gluster:x:994:992:GlusterFS daemons:/run/gluster:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
chrony:x:993:990::/var/lib/chrony:/sbin/nologin
saslauth:x:992:76:Saslauthd user:/run/saslauthd:/sbin/nologin
dnsmasq:x:991:989:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
colord:x:990:988:User for colord:/var/lib/colord:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
openvpn:x:989:987:OpenVPN:/etc/openvpn:/sbin/nologin
nm-openvpn:x:988:986:Default user for running openvpn spawned by NetworkManager:/:/sbin/nologin
pipewire:x:987:985:PipeWire System Daemon:/var/run/pipewire:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
flatpak:x:986:983:User for flatpak system helper:/:/sbin/nologin
gdm:x:42:42:GNOME Display Manager:/var/lib/gdm:/sbin/nologin
gnome-initial-setup:x:985:982::/run/gnome-initial-setup/:/sbin/nologin
vboxadd:x:984:1::/var/run/vboxadd:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
jfasch:x:1000:1000:Joerg Faschingbauer:/home/jfasch:/bin/bash
systemd-coredump:x:978:978:systemd Core Dumper:/:/usr/sbin/nologin
systemd-timesync:x:977:977:systemd Time Synchronization:/:/usr/sbin/nologin
mosquitto:x:976:976:Mosquitto Broker:/etc/mosquitto:/sbin/nologin
[293]:
f.close()
[294]:
def read_lines_of_file(filename):
    f = open('/etc/passwd')
    lines = f.readlines()
    return lines
[295]:
lines = read_lines_of_file('/etc/passwd')
[296]:
with open('/etc/passwd') as f:
    # read file
    pass
[298]:
try:
    f = open('/etc/passwd', 'w')
except Exception as e:
    print(e, type(e))
[Errno 13] Permission denied: '/etc/passwd' <class 'PermissionError'>

enumerate()

[299]:
l = ['Joerg', 'Faschingbauer', 'blah']
[301]:
for elem in l:
    print(elem)
Joerg
Faschingbauer
blah
[305]:
for elem in enumerate(l):
    print(elem)
(0, 'Joerg')
(1, 'Faschingbauer')
(2, 'blah')
[306]:
for pos, elem in enumerate(l):
    print(f'[{pos}]: {elem}')
[0]: Joerg
[1]: Faschingbauer
[2]: blah
[307]:
'-'.join(['Joerg', 'Faschingbauer', 'blah'])
[307]:
'Joerg-Faschingbauer-blah'

class

[308]:
class Foo:
    pass
[309]:
f = Foo()
[312]:
print(type(f))
<class '__main__.Foo'>
[314]:
f.__dict__
[314]:
{}
[317]:
f.bar = 'Blah'
[319]:
f.__dict__
[319]:
{'bar': 'Blah'}
[321]:
f
[321]:
<__main__.Foo at 0x7f32c7d8d390>
[326]:
class Foo:
    def __init__(self, bar):
        self.bar = bar
[327]:
f = Foo('blah')
[324]:
f.bar
[324]:
'blah'
[325]:
f.__dict__['bar']
[325]:
'blah'