Seite 1 von 1

Verfasst: Montag 12. Januar 2009, 18:49
von BlackJack
Na dann… *händereib* :-)

Der Klasse `Dot` könnte man eine `__str__()`-Methode verpassen, die ein '+' oder ein '-' zurück gibt.

`create_dot_array()` ist ziemlich umständlich aufgeschrieben. Die Methode könnte man weglassen und eine kürzere "list comprehension" direkt in die `__init__()` schreiben.

Code: Alles auswählen

    def __init__(self, width=LCD_WIDTH, height=LCD_HEIGHT): 
        """Konstruktor für DotModel""" 

        self.dot_gui = None 
        self.dots = [[Dot() for dummy in xrange(width)]
                     for dummy in xrange(height)]
`__getitem__()` und `__setitem__()` sollten anders auf ungültige Koordinaten reagieren. Was spricht dagegen einfach gar nichts zu prüfen und den `IndexError`, den die Liste im Fehlerfall liefert zu verwenden? Du prüfst übrigens nicht auf negative Koordinaten. Und das `__setitem__()` überhaupt einen Rückgabewert hat, dürfte kaum jemand erwarten, das ist ungewöhnlich.

Und wenn man dem `DotModel` noch eine `__str__()`-Methode verpasst…

Code: Alles auswählen

    def __str__(self):
        result = list()
        for i, row in enumerate(self.dots):
            result.append('%03d %s' % (i, ''.join(map(str, row))))
        return '\n'.join(result)
…kann man sich die `output_dot_model()`-Funktion sparen, die wird dann nämlich zu einem einfachen:

Code: Alles auswählen

    print app_base.dot_model

Verfasst: Dienstag 13. Januar 2009, 09:24
von wuf
Hallo BlackJack

Ich habe deine lehrreichen Hinweise in mein Projekt einfliessen lassen. Hier der modifizierte Code:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Python 2.6
# Skriptname: doglcd_mod_01_04_01.py

class Dot(object):
    """Klasse: Rasterfeld"""

    def __init__(self, state=False):
        """Konstruktor für die Klasse Dot"""

        self.state = state

    def __str__(self):
        """Zustands-Symbol"""

        if self.state:
            return '+'
        else:
            return '-'

class DotModel(object):
    """Klasse: DOGM-LCD-Logic"""

    DOT_SIZE = 10       # Seitenlänge in Pixels
    LCD_WIDTH = 32 #128     # Raster
    LCD_HEIGHT = 8 #64     # Raster

    #~~ Gibt die Anzahl x-Raster-Felder (Spalten) zurück
    @property
    def width(self):
        return len(self.dots[0])

    #~~ Gibt die Anzahl y-Raster-Felder (Reihen) zurück
    @property
    def height(self):
        return len(self.dots)

    def __init__(self, width=LCD_WIDTH, height=LCD_HEIGHT):
        """Konstruktor für DotModel"""

        self.dot_gui = None
        self.dots = [[Dot() for dummy in xrange(width)]
            for dummy in xrange(height)]

    def __str__(self):
        """Test-Ausgabe der Raster-Zustands-Symbole"""

        result = list()
        for i, row in enumerate(self.dots):
            result.append('%03d %s' % (i, ''.join(map(str, row))))
        return '\n'.join(result)

    def __getitem__(self, coordinates):
        """Lese Rasterfeld-Status"""

        x, y = coordinates
        return self.dots[y][x].state

    def __setitem__(self, coordinates, state):
        """Setze Rasterfeld-Status"""

        x, y = coordinates
        self.dots[y][x].state = state

        if self.dot_gui:
            #~~ Aktualisiere den Zustand des GUI-Rasterfeldes
            self.dot_gui.update_dot_state(coordinates, state)

    def create_dot_array(self, width, height):
        """Erzeuge einen zweidimensionalen Rasterobjekt-Array"""

        temp_row_list = list()
        for  y in xrange(height):
            for x in xrange(width):
                temp_row_list.append(Dot())
            self.dots.append(temp_row_list)
            temp_row_list = list()

#--- MODUL-TEST --------------------------------------------------------------#
if __name__ == "__main__":

    import os
    import sys
    import Tkinter as tk

    from doglcd_view_01 import*

    #====== Test: Klassen & Funktionen ======#
    def test_open_side_frames():
        """Öffnet versteckte Seiten-Rahmen"""

        for frame_key in app_base.main_view.frame_dict:
            app_base.main_view.frame_control(frame_key)

    def test_open_single_frame(frame_name):
        """Öffnet einen einzelnen Seiten-Rahmen"""

        app_base.main_view.frame_control(frame_name)


    #====== Test: Tk-Hauptfenster ======#
    app_base = tk.Tk()

    #~~ Mache das Hauptfenster unsichtbar
    app_base.withdraw()

    #~~ Haupt-Fenster Titel
    app_base.title(APP_TITLE + " (" + SCRIPT_NAME + ")")

    ##~~ Erstellt die Haupt-Ansicht
    #app_base.main_view = MainView(app_base)

    #~~ Erstellt das Modell
    app_base.dot_model = DotModel()

    app_base.dot_model[16, 4] = True
    print 'State', app_base.dot_model[16, 4]

    print app_base.dot_model

    #~~ Mache das Hauptfenster sichtbar
    app_base.deiconify()

    app_base.mainloop()
Danke für deine Tipps. Gruss wuf :wink: