@Mars23: Das ist alles ziemlich unübersichtlich mit den verschiedenen Repräsentationen des selben Wertes mit kryptischen Namen auf Modulebene wo das Hauptprogramm auf Modulebene steht und durch Funktionsdefinitionen unterbrochen wird. Das auf Modulebene Namen definiert sind, die in Funktionen dann als lokale Namen wiederverwendet werden hilft auch nicht. Deshalb sollten auf Modulebene nur Definitionen von Konstanten, Funktionen, und Klassen stehen und das Hauptprogramm auch in einer Funktion stehen.
`pindic` scheint als Konstante gemeint zu sein, sollte also auf Modulebene stehen und komplett in Grossbuchstaben benannt sein. Allerdings ist der Name selbst schlecht weil er zuwenig über die Bedeutung und zu viel über den Typ aussagt. Der Typ hat in dem Namen nichts zu suchen weil man, wenn man den Typ ändert überall im Programm in den Namen auch die Typinformation in Namen ändern muss die davon betroffen sind. Hier ist sogar ein schönes Beispiel, denn es werten fortlaufende ganze Zahlen als Schlüssel verwendet, was eigentlich eher für eine Liste als für ein Wörterbuch spricht, denn das wäre eine Liste mit 8 Werten wenn man konventionell bei 0 anfängt zu zählen. Insgesamt ist die Datenstruktur aber nicht nötig denn die zugehören Werte kann man ja ganz leicht ausrechnen, entweder als ``2**pin`` oder ``1 << pin`` wenn man mit der Nummerierung der Pins mit 0 beginnt.
Der Name `pin_aus()` ist mir unverständlich‽ Und die Funktion, da sie so einfach ist, auch nicht wirklich notwendig. Gleiches gilt für `laenge()` was man auch einfach als ``laenge = len`` hätte definieren können, allerdings sehe ich da den Sinn nicht. Es macht das Programm eher unklarer weil jeder weiss was `len()` macht, bei `laenge()` aber vermutet das es etwas anderes macht, denn sonst hätte man ja `len()` verwenden können.
Die `int()`-Funktion mit literalen ganzen Zahlen aufzurufen ist komplett sinnfrei. Das sind ja schon ganze Zahlen, was soll der Aufruf denn bewirken‽ `data` wird zudem nirgends verwendet. So etwas fällt unter anderem deswegen nicht so schnell auf weil das so auf Modulebene sogar bei einem so relativ kurzen Programm schon zu unübersichtlich wird was eigentlich wo verwendet wird.
`gesamt()` ist kein guter Name weil der nicht verrät was die Funktion eigentlich macht. Gute Funktionsnamen sollten dem Leser vermitteln was die Funktion tut, und ist dementsprechend in der Regel auch nach einer Tätigkeit benannt.
Einbuchstabige Namen sind keine gute Namen, abgesehen von Ausnahmen wie Index-/Zählvariablen die ganze Zahlen enthalten (`i`, `j`, `k`) oder Koordinaten (`x`, `y`, `z`), was man halt so aus der Mathematik gewohnt ist, oder bei sehr begrenzter Gültigkeit („list/dict/set comprehension“, Generatorausdruck, anonyme Funktion).
Die `gesamt()`-Funktion kann man wesentlich einfacher mit Zeichenkettenformatierung schreiben und das dann auch ohne die zwei überflüssigen Zeichen am Anfang die ja im Grunde nicht zu der Zahl gehören:
Damit ist die `gesamt()`-Funktion eigentlich überflüssig, denn das kann man auch direkt in die `pin_stand()`-Funktion schreiben.
Diese Funktion greift einfach so auf `bank` zu ohne dass das als Argument übergeben wurde. Das ist keine Konstante, dementsprechend gibt es dieses `bank` nicht auf Modulebene wenn man sauber programmiert.
Das die verschiedenen Repräsentationen vom gleichen Wert an unterschiedliche Namen gebunden unübersichtlich sind, schrieb ich ja am Anfang schon mal. Diese Umwege über Zeichekettenrepräsentation von Bits sollte man sich sowieso sparen. Bei `pin_up()` gehst Du ja auch nicht über die Zeichekettenrepräsentation sondern arbeitest mit Bitoperationen. Das sollte man bei `pin_stand()` auch einfach machen. Und die Bitmaske sollte man nicht ausserhalb dieser Funktionen berechnen sondern in den Funktionen. Das ist ein Detail das den Aufrufer nicht interessieren muss. Ausserdem ist eine solche Lösung nicht nur für 8-Bit-Werte sondern funktioniert mit beliebig grossen Ganzzahlen.
Man muss nicht jedes kleine Zwischenergebnis an einen Namen binden. Insbesondere wenn man einen einfachen, kurzen Ausdruck hat, dessen Ergebnis von der Funktion an den Aufrufer zurückgegeben wird, macht es keinen Sinn sich dafür einen Namen ausdenken zu müssen oder einen total generischen Namen zu nehmen.
Anstelle von `pin_stand()` und `pin_up()` kann man die beiden Funktionen auch allgemeiner als `get_bit()` und `set_bit()` benennen. Denn das tun sie ja. Die Mischung aus deutschen und englischen Namen ist übrigens auch unschön.
Da bleibt dann am Ende so etwas übrig:
Code: Alles auswählen
def get_bit(value, bit_number):
return (value & (1 << bit_number)) != 0
def set_bit(value, bit_number):
return value | (1 << bit_number)
def main():
bank = 0x1a
pin = 7
print bank
print type(bank)
print bin(bank)
print hex(bank)
print get_bit(bank, pin)
print set_bit(bank, pin)
if __name__ == '__main__':
main()