2D Arrays#

Waar leeft data?

Eendimensionale arrays#

Zijn lists!

%run simulate.py
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
File /opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/IPython/core/magics/execution.py:716, in ExecutionMagics.run(self, parameter_s, runner, file_finder)
    715     fpath = arg_lst[0]
--> 716     filename = file_finder(fpath)
    717 except IndexError as e:

File /opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/IPython/utils/path.py:91, in get_py_filename(name)
     90         return py_name
---> 91 raise IOError("File `%r` not found." % name)

OSError: File `'simulate.py'` not found.

The above exception was the direct cause of the following exception:

Exception                                 Traceback (most recent call last)
Cell In[1], line 1
----> 1 get_ipython().run_line_magic('run', 'simulate.py')

File /opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/IPython/core/interactiveshell.py:2480, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
   2478     kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2479 with self.builtin_trap:
-> 2480     result = fn(*args, **kwargs)
   2482 # The code below prevents the output from being displayed
   2483 # when using magics with decorator @output_can_be_silenced
   2484 # when the last Python token in the expression is a ';'.
   2485 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):

File /opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/IPython/core/magics/execution.py:727, in ExecutionMagics.run(self, parameter_s, runner, file_finder)
    725     if os.name == 'nt' and re.match(r"^'.*'$",fpath):
    726         warn('For Windows, use double quotes to wrap a filename: %run "mypath\\myfile.py"')
--> 727     raise Exception(msg) from e
    728 except TypeError:
    729     if fpath in sys.meta_path:

Exception: File `'simulate.py'` not found.
LC = [until_a_repeat(365) for _ in range(1000)]
LC[:10]
[45, 6, 4, 10, 33, 46, 27, 16, 15, 33]
sum(LC) / len(LC)
24.498

Handelingen op data#

scores = [88, 82, 91, 79, 83, 79, 86, 92, 77, 88, 93, 82, 85, 86, 92, 79]
def compute_sum(L):
    sum_values = 0
    for i in range(len(L)):
        sum_values += L[i]
    return sum_values
def compute_avg(L):
    sum_list = compute_sum(L)
    return sum_list / len(L)
compute_avg(scores)
85.125

Tweedimensionale arrays#

Zijn overal! (en zijn LoL’s)

Scores

Denk bijvoorbeeld aan spreadsheets …

[
    ["Naam", "Vraag 1", "Vraag 2", "Vraag 3", "Vraag 4"],
    ["Peter Been", 88, 82, 91, 79],
    ["Jasper Klein", 83, 79, 86, 92],
    ["Linda Buitendijk", 77, 88, 93, 82],
    ["Myrthe Zomer", 85, 86, 92, 79]
]

while True#

Nyan Cat

Of natuurlijk afbeeldingen!

[
    [[255, 255, 255], [255, 255, 255]],
    [[0, 0, 0], [0, 0, 0]],
    [[255, 255, 255], [255, 255, 255]],
    [[0, 0, 0], [0, 0, 0]]
]

Indices#

2D indices

L = [
    [3, 2, 6, 8],
    [9, 2, 5, 7],
    [0, 3, 2, 3],
    [1, 2, 3, 4]
]
L[3]
[1, 2, 3, 4]
L[3][3]
4

2D indices B

Schaakbord

Dit lijkt veel op hoe velden op een schaakbord worden aangegeven, maar daar worden rijen (8 tot en met 1) en kolommen (a tot en met h) anders benoemd.

Data#

  • string

  • integer / float

  • list

2D arrays zijn lijsten van lijsten, LoL’s

Lists#

Lists zijn containers, ze bevatten verwijzingen naar data

L = [5, 42, "hi"]

List references

Indentiteit#

help(id)
Help on built-in function id in module builtins:

id(obj, /)
    Return the identity of an object.
    
    This is guaranteed to be unique among simultaneously existing objects.
    (CPython uses the object's memory address.)

Het geheugenadres van L

id(L)
140308598284032

De geheugenadressen van de elementen van L

id(L[0])  # 5
9468384
id(L[1])  # 42
9469568
id(L[2])  # "hi"
140308676942256

Waarde en identiteit#

a = "Astronaut wordt snel oud tijdens een reis naar Mars"
b = "Astronaut wordt snel oud tijdens een reis naar Mars"
a == b
True
a is b
False
id(a)
140308598125152
id(b)
140308598125040

Verwijzingen#

by reference

Lists bevatten verwijzingen naar geheugenadressen, niet de waarden zelf!

by value

Getallen en strings verwijzen naar de waarde

Mutabiliteit#

mutable (veranderlijk)

Lists kunnen worden aangepast

immutable (onveranderlijk)

Getallen en strings kunnen niet worden aangepast

Mutable#

Lists

L = [11, 21]
id(L)
140308598100032
L[0] = 42
id(L)
140308598100032
L
[42, 21]

Immutable#

Strings en getallen

s = "hallo "
id(s)
140308598046448
s += "wereld"
id(s)
140308598208304
x = 10
id(x)
9468544
x += 1
id(x)
9468576

Functies?#

by copy

Functies ontvangen parameters als kopie

def fav(x):
    print("fav VOOR: x is", id(x), "en heeft de waarde x", x)
    x = "Pizza quattro formaggi"
    print("fav NA: x is", id(x), "en heeft de waarde x", x)
    
def main():
    y = "Pizza salami ananas"  # bah
    print("main VOOR: y is", id(y), "en heeft de waarde", y)
    fav(y)
    print("main NA: y is", id(y), "en heeft de waarde", y)
main()
main VOOR: y is 140308598063552 en heeft de waarde Pizza salami ananas
fav VOOR: x is 140308598063552 en heeft de waarde x Pizza salami ananas
fav NA: x is 140308598064672 en heeft de waarde x Pizza quattro formaggi
main NA: y is 140308598063552 en heeft de waarde Pizza salami ananas

Shallow versus deep copy#

De ene kopie is de andere niet!

Shallow copy#

Assignment statements in Python do not copy objects, they create bindings between a target and an object.

https://docs.python.org/3/library/copy.html

Wat create bindings hier betekent laten we in het midden, duidelijk is dat geen kopie wordt gecreëerd maar iets van een verwijzing die later eenvoudig te verbreken valt.

x = "regen"
y = x
x is y
True
y = "zonneschijn"
x is y
False
print("Na", x, "komt", y)
Na regen komt zonneschijn

Lists en shallow copy#

L = [5, 42, "hi"]
M = L
M[0] = 60
M[0]
60
L[0]
60

Lists zijn mutable en de shadow copy M verwijst nog steeds naar L en een aanpassing van M zal niet leiden tot een nieuwe list (zoals je wel zag gebeuren bij strings en integers).

Deep copy#

Deep copy is alleen relevant voor containertypes als lists!

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

https://docs.python.org/3/library/copy.html

Een deep copy creëert een nieuwe container, eventuele wijzigingen zijn vervolgens alleen van toepassing op de kopie, niet het origineel.

from copy import deepcopy
L = [5, 42, "hi"]
M = deepcopy(L)
M is L
False
M[0] = 60

Wat is de waarde van L[0]?

L[0]
5

Slicing is ook diep!#

L = [5, 42, "hi"]
M = L[:]
M[0] = 60
L[0]
5

List comprehension#

List comprehension creëert een nieuwe lijst

List comprehension als strategie om mutabiliteit te vermijden!

L = [5, 42, "hi"]
M = [x for x in L]
M[0] = 60
L[0]
5

Quiz#

Vraag 1#

def conform1(fav):
    fav = 42
    return fav

def main1():
    fav = 7
    conform1(fav)
    print(fav)

Wat wordt geprint voor fav in de functie main1?

Antwoord#

main1()
7

Vraag 2#

def conform2(L):
    L = [42, 42]
    return L

def main2():
    L = [7, 11]
    conform2(L)
    print(L)

Wat wordt geprint voor L in de functie main2?

Antwoord#

main2()
[7, 11]

Vraag 3#

def conform3(L):
    L[0] = 42
    L[1] = 42
    
def main3():
    L = [7, 11]
    conform3(L)
    print(L)

Wat wordt geprint voor L in de functie main3?

Antwoord#

main3()
[42, 42]

Staat#

Waarom is mutabiliteit belangrijk?

Mutabiliteit betekent dat staat kan worden gewijzigd!

stack 1c

Een gewijzigde staat is een probleem dat je eerder hebt gezien. Met pushr en popr kon een voorgaande staat worden bewaard om later weer terug te zetten.

Overgang van staat#

Soms is een volgende staat een logisch vervolg op de vorige staat (en is mutabiliteit ok!)

Google boter kaas eieren

Typ “boter kaas en eieren” en speel tegen Google.

Boter kaas en eieren#

L = [
    ["", "", ""],
    ["", "", ""],
    ["", "", ""]
]
L[0][0] = "X"
L = [
    ["X", "", ""],
    ["", "", ""],
    ["", "", ""]
]

Conway’s Game of Life#

Game of Life

Een tweedimensionaal raster met vierkante “cellen” die “levend” of “dood” kunnen zijn, en die zich volgens vastgestelde regels ontwikkelen en daarbij allerlei patronen kunnen vormen.

Regels#

Isolatie

  1. Een cel met minder dan twee levende buren sterft (vanwege isolatie)

Blijven leven

  1. Een cel met meer dan 3 levende buren sterft (vanwege overbevolking)

Geboren worden

  1. Een dode cel met precies 3 levende buren komt weer tot leven

Blijven leven

  1. Alle andere cellen blijven in dezelfde toestand

Patronen#

Game of Life

Staat#

De vorige staat is nodig om de nieuwe staat te bepalen

Mutabiliteit is hier belangrijk!