Benutzer-Werkzeuge

Webseiten-Werkzeuge


ws1920:dokumentierter_code_finale_version

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ws1920:dokumentierter_code_finale_version [2020/03/18 14:54]
richard.wonneberger
ws1920:dokumentierter_code_finale_version [2020/03/26 22:50] (aktuell)
Labo neuste Version
Zeile 1: Zeile 1:
-Das Programm besteht aus zwei Dateien +Das Programm besteht aus zwei Dateien:
-1. die Klassendatei GameOfLife.py +
-2. die Ausführungsdatei+
  
-In der ersten sind das Game of life und seine Regeln implementiert und die zweite greift darauf zu und erstellt eine Animation, mit der man interagieren kann.+  * 1. die GameOfLife.py Datei 
 +  * 2. die Ausführungsdatei
  
 +In der ersten sind das Game of life und seine Regeln implementiert (sie sollte gameoflife.py heißen) und die zweite greift darauf zu und erstellt eine Animation mit der man interagieren kann.
  
  
 +
 +gameoflife.py:​
  
 <​code>​ <​code>​
-inhalt ​der GoL+import random 
 +import numpy as np 
 +import matplotlib.pyplot as plt 
 +import time 
 + 
 +class GameOfLife(object):​ 
 +    """​  
 +    Diese Klasse beschreibt einen Zustand eines Game of Lifes und stellt Funktionen dazu bereit.  
 + 
 +    Attribute:​ 
 +        zustand: ​der aktuelle Zustand des Game of Life 
 +        groesse: die Seitenlänge des Spielfeldes 
 +        tem: die Tripleeinheitsmatrix,​ die zur Berechnung benötigt wird 
 +    """​ 
 + 
 +    def __init__(self,​ zustand): 
 +        """​ 
 +        Erzeugt ein neues GameOfLife-Objekt. 
 + 
 +        Parameter:​ 
 +            zustand: der initiale Zustand 
 +        """​ 
 +        self.zustand = zustand 
 +        self.groesse = zustand.shape[0] 
 +        self.generiereTripleeinheitsmatrix() 
 + 
 +    def generiereTripleeinheitsmatrix(self):​ 
 +        self.tem = np.zeros((self.groesse,​ self.groesse)) 
 +        for i in range(0, self.groesse):​ 
 +            for j in range(0, self.groesse):​ 
 +                if i == j: 
 +                    self.tem[(i,​j)] = 1 
 +                else: 
 +                    self.tem[(i,​j)] = 0 
 +                     
 +        for i in range(0, self.groesse):​ 
 +            for j in range(0, self.groesse):​ 
 +                if i == (j + 1): 
 +                    self.tem[(i,​j)] = 1 
 +        for i in range(0, self.groesse):​ 
 +            for j in range(0, self.groesse):​ 
 +                if j == (i + 1): 
 +                    self.tem[(i,​j)] = 1 
 +                     
 +        self.tem[0, self.tem.shape[1] - 1] = 1 
 +        self.tem[self.tem.shape[1] - 1, 0] = 1 
 +                     
 +    def berechneAnzahlNachbarn(self):​ 
 +        # Zum Aufsummieren der Nachbarn multipliziert man die vorher mit Tripleeinheitsmatrix(z,​s) erstellte Tridiagonalmatrix von beiden Seiten  
 +        # an die Matrix, in der die Zustaende der zellen gespeichert sind (einmal um die horizontalen und einmal um die vertikalen Partner zu addieren) 
 +        # als gleichung sieht das ungefaehr so aus:(tem steht hier fuer die tridiagonalmatrix) 
 +        # anzahlnachbarn = tem*Zustand*tem 
 +        # mit diesen zwei Matrixmultiplikationen kann man sehr recheneffektiv die 9 nachbarn(zelle selbst mitgezaehlt) 
 +        # aller Zellen gleichzeitig aufsummieren und dabei haben wir auch noch direkt etwas ueber lineare Algebra gelernt! 
 +        z = np.dot(self.tem,​ self.zustand) ​       
 +        k = np.dot(z, self.tem) 
 +        anzahlNachbarn = k - self.zustand 
 +             
 +        return anzahlNachbarn 
 + 
 +    def schritt(self):​ 
 +        """​ Führt einen Berechnungsschritt aus und gibt den neuen Zustand zurück. """​ 
 +        anzahlNachbarn = self.berechneAnzahlNachbarn() 
 + 
 +        # berechne neuen Zustand 
 + 
 +        # Ursprungszelle Tod + genau 3 lebende Nachbarn = lebend 
 +        # Ursprungszelle Lebend + genau 1 lebenden Nachbarn = tot 
 +        # Ursprungszelle Lebend + 2 o. 3 Nachbarn = lebend 
 +        # Ursprungszelle lebend + 4 oder mehr Nachbarn = tot 
 +         
 +        for i in range(0, self.groesse):​ 
 +            for j in range(0, self.groesse):​ 
 +                if self.zustand[(i,​j)] == 1 and (anzahlNachbarn[(i,​j)] in range(2) or anzahlNachbarn[(i,​j)] in range(4,​9)):​ 
 +                    self.zustand[(i,​j)] = 0 
 +                elif self.zustand[(i,​j)] == 0 and anzahlNachbarn[(i,​j)] == 3: 
 +                    self.zustand[(i,​j)] = 1 
 +                         
 +        return self.zustand
 </​code>​ </​code>​
  
  
-Die Animationsdatei:​+Die Animationsdatei ​(anzeige.py): 
 <​code>​ <​code>​
-import GameOfLife ​as gol+from gameoflife ​import GameOfLife
 import numpy as np import numpy as np
 from matplotlib import pyplot as plt from matplotlib import pyplot as plt
 from matplotlib import animation from matplotlib import animation
 +import matplotlib.pyplot as plt
 +from PIL import Image
 +from math import floor, ceil
  
-# in dieser Datei, wird die Animation der 'Game of Life' ​Schritte ausgeführt  +class Anzeige(object):​ 
-# die vorletzte Zeile mit Funcanimation bildet das Grundgeruest, ​der Rest des Codes ist groesstenteils Vorbereitung +    """​ 
-# und die Funktionen zum Interagieren+    Diese Klasse animiert ein GameOfLife-Objekt mithilfe ​der matplotlib.
  
 +    Attribute:
 +        gol: das GameOfLife-Objekt,​ das animiert wird
 +        canvas: der matplotlib-Canvas,​ auf den gezeichnet wird
 +        im: die aktuell angezeigte Bitmap
 +        zellAlter: speichert für jede Zelle, für wie viele Generationen sie schon lebendig ist
 +        animationLaeuft:​ gibt an, ob die Animation läuft (also nicht pausiert ist)
 +        benutzerZeichnet:​ gibt an, ob der Benutzer gerade auf den Canvas zeichnet
 +        anim: das matplotlib-Animationsobjekt
 +    """​
 +    ​
 +    # unterschiedliche colourmaps (weil ein buntes Leben, lebenswerter ist)
 +    # diese werden zufaellig aufgerufen
 +    colormaps = ['​Accent',​ '​Accent_r',​ '​Blues',​ '​Blues_r',​ '​BrBG',​ '​BrBG_r',​ '​BuGn',​ '​BuGn_r',​ '​BuPu',​ '​BuPu_r',​ '​CMRmap',​ '​CMRmap_r',​ '​Dark2',​ '​Dark2_r',​ '​GnBu',​ '​GnBu_r',​ '​Greens',​ '​Greens_r',​ '​Greys',​ '​Greys_r',​ '​OrRd',​ '​OrRd_r',​ '​Oranges',​ '​Oranges_r',​ '​PRGn',​ '​PRGn_r',​ '​Paired',​ '​Paired_r',​ '​Pastel1',​ '​Pastel1_r',​ '​Pastel2',​ '​Pastel2_r',​ '​PiYG',​ '​PiYG_r',​ '​PuBu',​ '​PuBuGn',​ '​PuBuGn_r',​ '​PuBu_r',​ '​PuOr',​ '​PuOr_r',​ '​PuRd',​ '​PuRd_r',​ '​Purples',​ '​Purples_r',​ '​RdBu',​ '​RdBu_r',​ '​RdGy',​ '​RdGy_r',​ '​RdPu',​ '​RdPu_r',​ '​RdYlBu',​ '​RdYlBu_r',​ '​RdYlGn',​ '​RdYlGn_r',​ '​Reds',​ '​Reds_r',​ '​Set1',​ '​Set1_r',​ '​Set2',​ '​Set2_r',​ '​Set3',​ '​Set3_r',​ '​Spectral',​ '​Spectral_r',​ '​Wistia',​ '​Wistia_r',​ '​YlGn',​ '​YlGnBu',​ '​YlGnBu_r',​ '​YlGn_r',​ '​YlOrBr',​ '​YlOrBr_r',​ '​YlOrRd',​ '​YlOrRd_r',​ '​afmhot',​ '​afmhot_r',​ '​autumn',​ '​autumn_r',​ '​binary',​ '​binary_r',​ '​bone',​ '​bone_r',​ '​brg',​ '​brg_r',​ '​bwr',​ '​bwr_r',​ '​cividis',​ '​cividis_r',​ '​cool',​ '​cool_r',​ '​coolwarm',​ '​coolwarm_r',​ '​copper',​ '​copper_r',​ '​cubehelix',​ '​cubehelix_r',​ '​flag',​ '​flag_r',​ '​gist_earth',​ '​gist_earth_r',​ '​gist_gray',​ '​gist_gray_r',​ '​gist_heat',​ '​gist_heat_r',​ '​gist_ncar',​ '​gist_ncar_r',​ '​gist_rainbow',​ '​gist_rainbow_r',​ '​gist_stern',​ '​gist_stern_r',​ '​gist_yarg',​ '​gist_yarg_r',​ '​gnuplot',​ '​gnuplot2',​ '​gnuplot2_r',​ '​gnuplot_r',​ '​gray',​ '​gray_r',​ '​hot',​ '​hot_r',​ '​hsv',​ '​hsv_r',​ '​inferno',​ '​inferno_r',​ '​jet',​ '​jet_r',​ '​magma',​ '​magma_r',​ '​nipy_spectral',​ '​nipy_spectral_r',​ '​ocean',​ '​ocean_r',​ '​pink',​ '​pink_r',​ '​plasma',​ '​plasma_r',​ '​prism',​ '​prism_r',​ '​rainbow',​ '​rainbow_r',​ '​seismic',​ '​seismic_r',​ '​spring',​ '​spring_r',​ '​summer',​ '​summer_r',​ '​tab10',​ '​tab10_r',​ '​tab20',​ '​tab20_r',​ '​tab20b',​ '​tab20b_r',​ '​tab20c',​ '​tab20c_r',​ '​terrain',​ '​terrain_r',​ '​twilight',​ '​twilight_r',​ '​twilight_shifted',​ '​twilight_shifted_r',​ '​viridis',​ '​viridis_r',​ '​winter',​ '​winter_r'​]
  
-# unterschiedliche colourmaps ​(weil ein buntes Lebenlebenswerter ist+    def __init__(selfgol): 
-# diese werden zufaellig aufgerufen +        """​ 
-colormaps = ['​Accent',​ '​Accent_r',​ '​Blues',​ '​Blues_r',​ '​BrBG',​ '​BrBG_r',​ '​BuGn',​ '​BuGn_r',​ '​BuPu',​ '​BuPu_r',​ '​CMRmap',​ '​CMRmap_r',​ '​Dark2',​ '​Dark2_r',​ '​GnBu',​ '​GnBu_r',​ '​Greens',​ '​Greens_r',​ '​Greys',​ '​Greys_r',​ '​OrRd',​ '​OrRd_r',​ '​Oranges',​ '​Oranges_r',​ '​PRGn',​ '​PRGn_r',​ '​Paired',​ '​Paired_r',​ '​Pastel1',​ '​Pastel1_r',​ '​Pastel2',​ '​Pastel2_r',​ '​PiYG',​ '​PiYG_r',​ '​PuBu',​ '​PuBuGn',​ '​PuBuGn_r',​ '​PuBu_r',​ '​PuOr',​ '​PuOr_r',​ '​PuRd',​ '​PuRd_r',​ '​Purples',​ '​Purples_r',​ '​RdBu',​ '​RdBu_r',​ '​RdGy',​ '​RdGy_r',​ '​RdPu',​ '​RdPu_r',​ '​RdYlBu',​ '​RdYlBu_r',​ '​RdYlGn',​ '​RdYlGn_r',​ '​Reds',​ '​Reds_r',​ '​Set1',​ '​Set1_r',​ '​Set2',​ '​Set2_r',​ '​Set3',​ '​Set3_r',​ '​Spectral',​ '​Spectral_r',​ '​Wistia',​ '​Wistia_r',​ '​YlGn',​ '​YlGnBu',​ '​YlGnBu_r',​ '​YlGn_r',​ '​YlOrBr',​ '​YlOrBr_r',​ '​YlOrRd',​ '​YlOrRd_r',​ '​afmhot',​ '​afmhot_r',​ '​autumn',​ '​autumn_r',​ '​binary',​ '​binary_r',​ '​bone',​ '​bone_r',​ '​brg',​ '​brg_r',​ '​bwr',​ '​bwr_r',​ '​cividis',​ '​cividis_r',​ '​cool',​ '​cool_r',​ '​coolwarm',​ '​coolwarm_r',​ '​copper',​ '​copper_r',​ '​cubehelix',​ '​cubehelix_r',​ '​flag',​ '​flag_r',​ '​gist_earth',​ '​gist_earth_r',​ '​gist_gray',​ '​gist_gray_r',​ '​gist_heat',​ '​gist_heat_r',​ '​gist_ncar',​ '​gist_ncar_r',​ '​gist_rainbow',​ '​gist_rainbow_r',​ '​gist_stern',​ '​gist_stern_r',​ '​gist_yarg',​ '​gist_yarg_r',​ '​gnuplot',​ '​gnuplot2',​ '​gnuplot2_r',​ '​gnuplot_r',​ '​gray',​ '​gray_r',​ '​hot',​ '​hot_r',​ '​hsv',​ '​hsv_r',​ '​inferno',​ '​inferno_r',​ '​jet',​ '​jet_r',​ '​magma',​ '​magma_r',​ '​nipy_spectral',​ '​nipy_spectral_r',​ '​ocean',​ '​ocean_r',​ '​pink',​ '​pink_r',​ '​plasma',​ '​plasma_r',​ '​prism',​ '​prism_r',​ '​rainbow',​ '​rainbow_r',​ '​seismic',​ '​seismic_r',​ '​spring',​ '​spring_r',​ '​summer',​ '​summer_r',​ '​tab10',​ '​tab10_r',​ '​tab20',​ '​tab20_r',​ '​tab20b',​ '​tab20b_r',​ '​tab20c',​ '​tab20c_r',​ '​terrain',​ '​terrain_r',​ '​twilight',​ '​twilight_r',​ '​twilight_shifted',​ '​twilight_shifted_r',​ '​viridis',​ '​viridis_r',​ '​winter',​ '​winter_r'​]+        ​Erzeugt ein neues Anzeige-Objekt und beginnt die Animation.
  
 +        Parameter:
 +            gol: das GamoOfLife-Objekt
 +        """​
 +        self.gol = gol
  
-def animate(e): +        fig = plt.figure() 
-    '​''​ die Funktion, die von Funcanimation ausgefuehrt wird +        ​self.canvas = fig.canvas 
 +        plt.axis('off'
 + 
 +        #so wird bei jedem ausfuehren eine zufaellige colormap gewaehlt um ein angenehmeres,​ vielseitiges Langzeiterlebnis zu kreieren 
 +        self.im = plt.imshow(self.gol.zustand,​ animated=True,​ cmap=plt.get_cmap(Anzeige.colormaps[int(np.random.random()*len(Anzeige.colormaps))])) 
 +        self.zellAlter = np.zeros(self.gol.zustand.shape) 
 +        self.zeichne(self.gol.zustand) 
 + 
 +        #Verbinden, der interaktionsevents mit dem figure, in dem die animation laeuft 
 +        self.canvas.mpl_connect('​key_press_event'​self.onPress) 
 +        self.canvas.mpl_connect('​button_press_event',​ self.onClick) 
 +        self.canvas.mpl_connect('​button_release_event',​ self.onClickEnd) 
 +        self.canvas.mpl_connect('​motion_notify_event',​ self.onMove) 
 + 
 +        self.animationLaeuft = True 
 +        self.benutzerZeichnet = False 
 + 
 +        #die tatsaechliche Ausfuehrung:​ 
 +        self.anim = animation.FuncAnimation(fig,​ self.animationsschritt,​ interval=200) 
 +        plt.show()
     ​     ​
-    ​wie gol.Schritt funktioniert ist in der Klassendatei beschrieben ​'''​ +    ​def animationsschritt(self,​ e): 
-    gol.Schritt() +        '''​ Führt einen Animationsschritt durch. '''​ 
-    draw(gol.zustand) +        self.gol.schritt() 
-    return im,+        ​self.zeichne(self.gol.zustand) 
 +        return ​self.im,
  
-gol.Initialisiere() +    def zeichne(self, zustand): 
-fig plt.figure()+        '''​ Zeichnet den angegebenen Zustand auf den matplotlib-Canvas. '''​ 
 +        # enthaelt Werte ueber die '​Lebensdauer'​ einer Zelle 
 +        self.zellAlter ​self.zellAlter * zustand + zustand 
 +        # lebende Zellen aendern ihre Farbe, je laenger sie leben 
 +        self.im.set_array(np.ones(self.zellAlter.shape) - np.power(0.5,​ self.zellAlter)) 
 +        self.canvas.draw()
  
-def draw(zustand): +    #die vier folgenden Funktionen sind zum Interagieren mit dem Geschehen 
-    '''​ lebende Zellen aendern ihre Farbe, je laenger sie leben '''​+    ​def onPress(self, event): 
 +        # zum Pausieren mit der Leertaste 
 +        if event.key == ' '
 +            if self.animationLaeuft:​ 
 +                self.anim.event_source.stop() 
 +                self.animationLaeuft = False 
 +            else: 
 +                self.anim.event_source.start() 
 +                self.animationLaeuft = True
  
-    ​global cmap #enthaelt Werte ueber die '​Lebensdauer' ​einer Zelle +    ​def onClick(self,​ event): 
-    ​cmap ​cmap * zustand + zustand +        ​mit dem Cursor kann man den Wert einer Zelle per Klick aendern von lebend zu tot, sowie andersherum 
-    im.set_array(np.ones(cmap.shape) - np.power(0.5, cmap)) +        if event.button ​== 1 and event.xdata != None and event.ydata != None: 
-    ​fig.canvas.draw()+            self.benutzerZeichnet = True 
 +            self.anim.event_source.stop() 
 +            self.zustandNeu = np.copy(self.gol.zustand) 
 +            pos_x = int(np.round(event.xdata)) 
 +            pos_y = int(np.round(event.ydata)
 +            self.zustandNeu[pos_y,​ pos_x] = 1 self.gol.zustand[pos_y,​ pos_x] 
 +            self.zellAlter = np.zeros(self.zustandNeu.shape) 
 +            self.zeichne(self.zustandNeu) 
 +            ​ 
 +    ​def onMove(self,​ event): 
 +        # mit dem Cursor kann man den Wert mehrerer Zellen per Klick aendern, indem man die Maustaste gedrueckt haelt 
 +        # die Animation wird hierfuer pausiert 
 +        if event.button == 1 and self.benutzerZeichnet and event.xdata != None and event.ydata != None: 
 +            pos_x = int(np.round(event.xdata)) 
 +            pos_y = int(np.round(event.ydata)) 
 +            self.zustandNeu[pos_y,​ pos_x] = 1 - self.gol.zustand[pos_y,​ pos_x] 
 +            self.zellAlter = np.zeros(self.zustandNeu.shape) 
 +            self.zeichne(self.zustandNeu)
  
-zustand_neu ​None +    def onClickEnd(self,​ event): 
-anim_running ​True +        # beim loslassen der Maustaste werden die geänderten Werte an die Animation gegeben und diese wird fortgesetzt 
-drawing ​= False+        if event.button ​== 1 and self.benutzerZeichnet:​ 
 +            ​self.gol.zustand ​self.zustandNeu 
 +            ​self.zellAlter = np.zeros(self.zustandNeu.shape) 
 +            self.zeichne(self.zustandNeu) 
 +            self.benutzerZeichnet ​= False 
 +            if self.animationLaeuft:​ 
 +                self.anim.event_source.start()
  
-#die vier folgenden Funktionen sind zum Interagieren mit dem Geschehen +###### Programmeinstieg #######
-def onPress(event):​ +
-    '''​ zum Pausieren mit der Leertaste '''​ +
-    global anim_running ​    +
-    if event.key=='​ ': +
-        if anim_running:​ +
-            anim.event_source.stop() +
-            anim_running = False +
-        else: +
-            anim.event_source.start() +
-            anim_running = True+
  
 +def main():
 +    # Erzeuge ein GameOfLife-Objekt anhand der Benutzereingaben
  
-def onClick(event)+    # die 5 Konfigurationsmodi sind
-    ​'''​ mit dem Cursor kann man den Wert einer Zelle per Klick aendern +    ​# 1.zufaellig:​ hier wird jede Zelle zufaellig einen wert 1 oder 0 bekommen 
-  +    # 2.alternierend:​ hier wird das Feld in abwechselnd 1- und 0-groesse eingeteilt, mit einem kleinen Fehler in der Mitte 
-    ​von lebend ​zu tot, sowie andersherum '''​ +    ​# 3.Datei: hier kann direkt eine Konfiguration eingelesen werden. z.B. um eine gleiterkanone oder Aehnliches einzulesen 
-    ​global cmapzustand_neudrawing +    # 4.Bild: eine Bilddatei kann eingelesen und in eine annaehernd erkennbare anfangskonfiguration umgewandelt werden (da der kontrast ​zu schwarzweiss und die groesse geaendert wird)  
-    if event.button ​== 1 and event.xdata !None and event.ydata !None+    ​# 5.Leer: hier wird das Feld mit Nullen gefuellt 
-        ​drawing ​True +    modus = int(input('​Gib den Modus 1 (Zufall)2 (alternierend)3 (Datei) oder 4 (Bild) ein:  ')) 
-        ​anim.event_source.stop() + 
-        ​zustand_neu ​= np.copy(gol.zustand+    if modus == 1 or modus == 2 or modus == 5
-        ​pos_x = int(np.round(event.xdata)) +        ​groesse ​int(input('​Gib die Anzahl der Zeilen/​Spalten ein: ')) 
-        ​pos_y ​= int(np.round(event.ydata)) + 
-        ​zustand_neu[pos_ypos_x] = 1 - gol.zustand[pos_ypos_x+    if modus == 1: 
-        ​cmap np.zeros(zustand_neu.shape+        ​# Zufall 
-        ​draw(zustand_neu)+        zustand = np.round(np.random.random((groesse, groesse))).astype(int) 
 +     
 +    elif modus == 2: 
 +        ​# Alternierend 
 +        zustand ​= np.zeros((groesse, groesse)
 +        ​for i in range(0, groesse): 
 +            for j in range (0, groesse): 
 +                if j%2==0: 
 +                    zustand[(i,​j)]=0 
 +                else: 
 +                    zustand[(i,​j)]=1 
 +     
 +        if zustand[(int(groesse/2), int(groesse/2))] == 0: 
 +            ​zustand[(int(groesse/​2),​ int(groesse/​2))] ​
 +            zustand[(int((groesse/2)+1), int(groesse/​2))] = 1 
 +            ​ 
 +        ​else: 
 +            zustand[(int(groesse/​2)int(groesse/​2))] = 
 +            ​zustand[(int((groesse/​2)+1)int(groesse/​2))= 0 
 +     
 +    elif modus == 3: 
 +        ​# Datei lesen 
 +        dateiName ​input('​Was willste oeffnen? ') 
 +        datei = open(dateiName) 
 +     
 +        dateiAlsListe = [] 
 +        for line in datei: 
 +            dateiAlsListe.append([int(c) for c in list(line.rstrip())]
 +        ​dateiAlsMatrix = np.array(dateiAlsListe) 
 +         
 +        zustand = machQuadrat(dateiAlsMatrix)
         ​         ​
-def onMove(event):​ +    elif modus == 4
-    '''​ mit dem Cursor kann man den Wert mehrerer Zellen per Klick aendern, indem man die Maustaste gedrueckt haelt +        ​# Bild lesen 
-   die Animation wird hierfuer pausiert'''​ +        dateiname ​input('Gib den Bildpfad ein: '
-    global zustand_neu,​ cmap +        ​bild Image.open(dateiname
-    if event.button ​== 1 and drawing and event.xdata != None and event.ydata != None+        ​bild bild.convert('​1') 
-        ​pos_x int(np.round(event.xdata)+        ​bild.thumbnail((500,500))
-        ​pos_y int(np.round(event.ydata)+
-        ​zustand_neu[pos_y,​ pos_x] ​= 1 - gol.zustand[pos_y,​ pos_x] +
-        ​cmap = np.zeros(zustand_neu.shape) +
-        draw(zustand_neu)+
  
-def onClickEnd(event):​ +        pixel = np.array(bild)
-    '''​ beim loslassen der Maustaste werden die geänderten Werte an die Animation gegeben und diese wird fortgesetzt '''​ +
-    global zustand_neu,​ cmap, drawing +
-    if event.button == 1 and drawing: +
-        gol.zustand = zustand_neu +
-        cmap = np.zeros(zustand_neu.shape) +
-        draw(zustand_neu) +
-        drawing = False +
-        if anim_running:​ +
-            anim.event_source.start() +
-               +
-plt.axis('​off'​)+
  
-#so wird bei jedem ausfuehren eine zufaellige colormap gewaehlt um ein angenehmeres,​ vielseitiges Langzeiterlebnis zu kreieren +        ​zustand = machQuadrat(pixel
-im = plt.imshow(gol.zustand, animated=True, cmap=plt.get_cmap(colormaps[int(np.random.random()*len(colormaps))])+     
-cmap np.zeros(gol.zustand.shape) +    # erzeuge GameOfLife-Objekt 
-draw(gol.zustand)+    gol GameOfLife(zustand)
  
-#Verbinden, der interaktionsevents mit dem figure, in dem die animation laeuft +    ​initialisiere Anzeige 
-fig.canvas.mpl_connect('​key_press_event',​ onPress) +    ​Anzeige(gol)
-fig.canvas.mpl_connect('​button_press_event',​ onClick) +
-fig.canvas.mpl_connect('​button_release_event',​ onClickEnd) +
-fig.canvas.mpl_connect('​motion_notify_event',​ onMove)+
  
-#die tatsaechliche Ausfuehrung+def machQuadrat(pixel)
-anim = animation.FuncAnimation(figanimate, interval=200) +    """​ Macht das angegebene zweidimensionale Numpy-Array quadratischindem es die Ränder mit Nullen auffüllt. """​ 
-plt.show() +    breite ​pixel.shape[0] 
-</​code>​+    hoehe = pixel.shape[1] 
 +    size = max(breite, hoehe)
  
 +    links = floor((size - breite) / 2)
 +    rechts = ceil((size - breite) / 2)
 +    oben = floor((size - hoehe) / 2)
 +    unten = ceil((size - hoehe) / 2)
  
 +    pad_width = ((links, rechts), (oben, unten))
 +    pixel = np.pad(pixel,​ pad_width, mode='​constant',​ constant_values=0)
 +    return pixel
  
 +main()
 +</​code>​
ws1920/dokumentierter_code_finale_version.1584539693.txt.gz · Zuletzt geändert: 2020/03/18 14:54 von richard.wonneberger