Seite 1 von 1
Stilfrage
Verfasst: Montag 27. September 2010, 22:38
von Fjunch-click-
Hallo,
ich habe mal eine kurze Frage zum Programmierstil. Ein ganz einfaches Beispiel:
Code: Alles auswählen
# Beispiel 1
n = 0
for cntr in range(0, 10):
print n
n = n + 1
# Beispiel 2
n = 0
for cntr in range(0, 10):
print n
n += 1
Und zwar geht es um die Zeile in der n erhöht wird. Was ist "eleganter"?
"n = n + 1" oder "n += 1"?
Die zweite Schreibweise kannte ich nicht, habe sie in einem Beispielprogramm im Pythonkurs des Full Circle
Magazins gesehen. Und gleich noch eine Frage:
In diesem Kurs wird, wenn einfach nur eine Leerzeile ausgegeben werden soll immer statt eines einfachen
print ein
print '\n' verwendet.
Ist dies ebenfalls erwünscht, also "besser" als nur ein
print?
Ich weiß, sind vielleicht blöde Fragen, ich möchte nur versuchen, mir von Anfang an anzugewöhnen, "guten" Code zu schreiben. Habe auch schon viel im PEP 8 gelesen, aber alles findet man da ja auch nicht.
Re: Stilfrage
Verfasst: Montag 27. September 2010, 22:40
von Leonidas
Zweiteres. Aber der Code insgesamt ist nicht sehr "pythonisch".
Re: Stilfrage
Verfasst: Montag 27. September 2010, 22:45
von Fjunch-click-
Warum?
Ist nur ein Beispiel, das ich einfach so hingeschrieben habe. Was würdest du denn anders machen?
Habe übrigens im ersten Beitrag noch etwas ergänzt.
Re: Stilfrage
Verfasst: Montag 27. September 2010, 22:50
von Leonidas
In Python ist es fast nie nötig Werte hochzuzählen, wenn man nen Counter braucht, reicht meist ``enumerate()`` oder ``itertools.count()``.
Re: Stilfrage
Verfasst: Montag 27. September 2010, 22:57
von Fjunch-click-
Ach so, alles klar.
In dem echten Beispielprogramm wird auch nicht einfach nur hochgezählt, sondern es werden verschiedene Zahlen zur Variablen addiert. Wie gesagt, ging es mir nur um die Schreibweise.
Vielleicht hast du ja Lust, mal zu gucken, ob der Code so in Ordnung ist. Das Programm erstellt einfach nur eine kleine Tabelle. Ist eigentlich nur dazu da, Stringformatierungen zu verdeutlichen
Hier ist der Originalcode aus dem Kurs:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# pprint2.py
# 27.09.2010
#
# Full Circle-Kurs
# pprint1.py
# Example of semi-useful functions
def TopOrBottom(character, width):
""" prints the top-, bottom- or separator-line
width is total width of returned line
"""
return "%s%s%s" % ("+", (character * (width - 2)), "+")
def Fmt(val1, leftbit, val2, rightbit):
""" prints two values padded with spaces
val1 is thing to print on left, val2 is thing to print on right
leftbit is width of left portion, rightbit is width of right portion
"""
part2 = "%.2f" % val2
return "%s%s%s%s" % ("| ", val1.ljust(leftbit - 2, " "), part2.rjust(rightbit - 2, " "), " |")
# Define the price of each item
itms = [["Soda", 1.45], ["Candy", .75], ["Bread", 1.95], ["Milk", 2.59]]
# Now print everything out
print TopOrBottom("=", 40)
total = 0
for cntr in range(0, 4):
print Fmt(itms[cntr][0], 30, itms[cntr][1], 10)
total += itms[cntr][1]
print TopOrBottom("-", 40)
print Fmt("Total", 30, total, 10)
print Fmt("Tax", 30, total * 0.086, 10)
print TopOrBottom("=", 40)
raw_input()
Re: Stilfrage
Verfasst: Montag 27. September 2010, 23:03
von EyDu
Und das ist auch schon der Fall, welchen Leonidas angesprochen hat. Du meinst sicherlich:
Code: Alles auswählen
total = 0
for item in itms:
print Fmt(item[0], 30, item[1], 10)
total += item[1]
Du solltest dir außerdem die unnötigen Abkürzungen abgewöhnen. Fmt ist nichtssagend, cntr kann man auch ausschreiben oder gleich richtig bennenen. als ich "itms" gelesen habe dacht ich, dass du etwas gegen Vokale hast
Ach ja: Schaue noch in PEP 8, deine Funktionsnamen solltest du in der Form "top_or_bottom" schreiben. Für "itms" möchtest du wahrscheinlich lieber ein eine Liste von Tupeln verwenden oder gleich ein Dictionary.
Sebastian
Re: Stilfrage
Verfasst: Montag 27. September 2010, 23:19
von Fjunch-click-
Danke für die Hinweise, aber wie ich geschrieben hatte, ist das der Originalcode aus dem Kurs. Den habe ich nicht geschrieben.
Ich bin ja noch totaler Anfänger und da wollte ich einfach mal hören, ob der Code in diesem Kurs OK ist oder eher nicht. Wäre ja blöd, wenn man da schlechten Code lernen würde.
Ich selber hätte auch andere Namen gewählt.
Re: Stilfrage
Verfasst: Montag 27. September 2010, 23:39
von BlackJack
@Fjunch-click-: Ich weiss nicht ob ich einem Kurs mit solchem Quelltext viel zutrauen würde. Wenn Docstrings schon dermassen falsch sind. `TopOrBottom()` ``print``\et nichts und es wird auch immer nur die gleiche Art von Linie erzeugt und nicht drei verschiedene. Warum die beiden '+' in die Zeichenkette hineinformtiert werden statt sie direkt in die Vorlage zu schreiben, ist auch etwas rätselhaft.
Zu den abgekürzten und nicht PEP8-konformen Namen wurde ja schon etwas gesagt. Es werden auch die Möglichkeiten der Zeichenkettenformatierung nicht wirklich ausgeschöpft. Das Auffüllen mit Leerzeichen und links- oder rechtsbündig ausrichten geht damit nämlich auch.
Die Schleife mittels `cntr` was nur als Index verwendet wird, ist sehr unpythonisch. Man kann in Python *direkt* über Elemente einer Liste iterieren und auch gleich "unpacking" benutzen um die Elemente der inneren Listen an aussagekräftige Namen zu binden.
Die vielen "magischen Zahlen" sind auch unschön weil schlechter anzupassen und zu verstehen, als wenn man dafür Konstanten definiert hätte.
Insgesamt sieht das aus, als wenn ein C- oder Pascal-Programmierer sich mal an Python versucht hat.
Einmal überarbeitet:
Code: Alles auswählen
def make_top_or_bottom_line(character, width):
"""Returns a line made of given character.
width is total width of returned line.
"""
return '+%s+' % (character * (width - 2))
def format_item(name, name_width, price, price_width):
"""Formats two values padded with spaces.
name is thing to print on left, price is thing to print on right.
"""
return '| %*s%*.2f |' % (- (name_width - 2), name, price_width - 2, price)
def main():
WIDTH = 40
DESCRIPTION_WIDTH = 30
PRICE_WIDTH = 10
TAX = 0.086
assert DESCRIPTION_WIDTH + PRICE_WIDTH == WIDTH
# Define the price of each item
items = [['Soda', 1.45], ['Candy', 0.75], ['Bread', 1.95], ['Milk', 2.59]]
# Now print everything out
print make_top_or_bottom_line('=', WIDTH)
total = 0
for product, price in items:
print format_item(product, DESCRIPTION_WIDTH, price, PRICE_WIDTH)
total += price
print make_top_or_bottom_line('-', WIDTH)
print format_item('Total', DESCRIPTION_WIDTH, total, PRICE_WIDTH)
print format_item('Tax', DESCRIPTION_WIDTH, total * TAX, PRICE_WIDTH)
print make_top_or_bottom_line('=', WIDTH)
if __name__ == '__main__':
main()
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 00:07
von Fjunch-click-
Hallo BlackJack, danke für deine Mühe.
Du darfst aber nicht vergessen, dass dies erst der zweite Teil eines Anfängerkurses ist, und das dieses Programm ja nur dazu da ist, einzelne Dinge zu verdeutlichen. Man kann ja nicht alles auf einmal machen.
Die '+'-Zeichen wurden z.B. in die Zeichenkette hineinformatiert, weil es in diesem Programm darum geht, zu zeigen, wie so etwas gemacht wird. Die Tabelle, die dort ausgegeben wird ist doch nur Mittel zum Zweck.
In diesem Code kommt z.B. das erste Mal in diesem Kurs eine for-Schleife vor. Es geht also um die absoluten Anfänge.
Ich denke mal, dass es später schon etwas mehr ins Eingemachte gehen wird.
Dein überarbeiteter Code ist zwar schön, verwendet aber viele Dinge, die in diesem Kurs noch gar nicht besprochen wurden, und daher für einen Anfänger gar nicht zu verstehen sind. Dies ist, wie gesagt aus dem zweiten Teil des Kurses. Jeder Teil besteht aus etwa 3 Din a A4 Seiten. Im vorigen Teil ging es um "Hello World!". Soviel, um deutlich zu machen, an welchem Punkt sich der Kurs befindet. Da wäre ein Code, wie du ihn geschrieben hast vielleicht doch etwas zu viel auf einmal, oder?
Wie gesagt, das Hauptanliegen des Beispielcodes ist es, zu zeigen, wie Strings formatiert und zusammen gesetzt werden können. Und nebenbei wurde noch eine for-Schleife eingebaut. Es geht nicht darum, wie man so eine Tabelle möglichst elegant ausgeben kann. Die Tabelle ist nur Mittel zum Zweck. Irgend etwas muss so ein Beispielprogramm ja machen. Ist vielleicht etwas blöd, wenn man den Text des Kurses nicht kennt und nur den Code der Beispiele sieht.
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 08:10
von BlackJack
@Fjunch-click-: Das ist sicher Ansichtssache, aber ich finde man sollte möglichst keinen "schlechten" Code zeigen, insbesondere nicht in Beispielen für Anfänger und dann anscheinend noch ohne Warnung. *So* eine ``for``-Schleife würde ich gar nie einem Anfänger zeigen. Was ist der Sinn es Anfängern erst "falsch" zu zeigen, wenn man es auch gleich richtig machen kann? Insbesondere wenn die "falsche" Variante sogar umständlicher ist, als die idiomatische Lösung, sollte man Anfängern doch das Einfacherere zeigen wollen!?
Und auch das mit dem '+' verstehe ich nicht? Es geht darum Zeichenkettenformatierung zu zeigen, aber ist das eine Begründung dafür total *unnötige* Zeichenkettenformatierung zu zeigen? Ich habe in Quelltexten schon so etwas wie ``print '%s' % spam`` gesehen, wobei `spam` auf jeden Fall vom Typ `str` war und frage mich dann immer wie die Leute auf so etwas kommen. Wahrscheinlich sind Tutorials die so etwas zeigen nicht ganz unschuldig daran.
Und auch die falschen Docstrings finde ich gerade in einem Tutorial nicht gut.
Die Namensgebung mit `itms` und `cntr` und diese ``for``-Schleife lassen bei mir jedenfalls erhebliche Zweifel aufkommen, ob der Autor überhaupt ein echter Python-Programmierer ist, und das irgendwann aus softwaretechnischer Sicht besser wird, oder ob das nicht ein C- oder Pascal-Programmierer ist, der in alten Mustern verharrt.
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 08:25
von ntrunk
Hallo Fjunch-click,
zum Stil allgemein ist ja bereits einiges gesagt worden, aber dazu
Fjunch-click- hat geschrieben:[...]
Und gleich noch eine Frage:
In diesem Kurs wird, wenn einfach nur eine Leerzeile ausgegeben werden soll immer statt eines einfachen print ein print '\n' verwendet.
Ist dies ebenfalls erwünscht, also "besser" als nur ein print?
möchte ich doch noch meinen Senf geben: die beiden Anweisungen sind nicht äquivalent. Der erste Code gibt eine Zeilenschaltung aus, der zweite erzeugt zwei davon.
Fjunch-click- hat geschrieben:
Ich weiß, sind vielleicht blöde Fragen, ich möchte nur versuchen, mir von Anfang an anzugewöhnen, "guten" Code zu schreiben. Habe auch schon viel im PEP 8 gelesen, aber alles findet man da ja auch nicht.
Ich bin - entgegen dem allgemein bekannten Sprichwort - durchaus der Ansicht, dass es blöde Fragen gibt (und einige davon habe ich auch selbst gestellt). Aber deine sind m.E. weit davon entfernt. Viel Spass noch mit einer wunderbaren Programmiersprache Python.
Gruß
Norbert
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 08:49
von mutetella
Fjunch-click- hat geschrieben:Da wäre ein Code, wie du ihn geschrieben hast vielleicht doch etwas zu viel auf einmal, oder?
Finde ich überhaupt nicht. Gerade ich als Anfänger muss mich doch darauf verlassen können, dass der mir gezeigte Code nicht nur funktioniert (denn das tut meiner auch oft...

), sondern auch in seiner Struktur und der Anwendung von Anweisungen, Funktionen etc. p.p. stimmig ist. Auch in vermeintlich einfachem Beispielcode für Anfänger bleibe ich immer wieder vor einer Zeile oder vor Blöcken stehen, die ich auf den ersten Blick überhaupt nicht verstehe. Aber gerade das stückweise Entziffern solch augenscheinlich "kryptischem Geheimcode" hat mich neben dem Lesen von Anleitungen bisher viel lernen lassen. Und ganz nebenbei: Mir persönlich treibt ein elegantes Stück Code immer wieder ein Lächeln ins Gesicht. Selbst wenn ich ihn nicht verstehe. Aber was guter und was weniger guter Code ist, das lernt man eben dann, wenn man viel guten Code liest. Das Verstehen kommt meist später.
Gruß
mutetella
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 12:14
von Fjunch-click-
BlackJack hat geschrieben:
Die Namensgebung mit `itms` und `cntr` und diese ``for``-Schleife lassen bei mir jedenfalls erhebliche Zweifel aufkommen, ob der Autor überhaupt ein echter Python-Programmierer ist, und das irgendwann aus softwaretechnischer Sicht besser wird, oder ob das nicht ein C- oder Pascal-Programmierer ist, der in alten Mustern verharrt.
Ja, wenn das so ist, hast du natürlich recht. Das Problem für jemanden, der keinerlei Programmiererfahrung hat, und zwar in keiner Sprache, ist es natürlich, dies überhaupt zu erkennen. Das geht ja nur, wenn man nicht nur weiß, was in Python möglich ist (z.B. die for-Schleife im Beispielcode) und wie es im Gegensatz dazu richtig gemacht wird (eben die Schleife in deinem Code).
Ich habe z.B. oft gelesen, dass "A byte of python" empfehlenswert ist. Hier wird die for-Schleife auf genau die gleiche Art erklärt, wie im Beispielcode aus dem Kurs, nämlich:
Code: Alles auswählen
for i in range(1, 5)
print i
else:
print 'Die Schleife ist zu Ende.'
Da ich das vorher gelesen hatte, habe ich mir natürlich im anderen Code nichts dabei gedacht. Und dann erfahre ich hier, dass man das so nicht macht.
Tja, alles nicht so klar. Man weiß eben als Anfänger einfach nicht, was gut ist und was nicht. Aber irgendwie wird das schon werden. Es gibt hier ja genügend Leute, die man nerven kann.

Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 12:23
von BlackJack
@Fjunch-click-: In dem Beispiel ist es ja wieder "richtig", es soll ja über die Zahlen iteriert werden. Die werden ja auch ausgegeben. Bei dem `cntr`-Beispiel sind die Zahlen aber nur ein Umweg zu dem, über das man eigentlich iterieren möchte.
Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 18:34
von Fjunch-click-
Ja, mittlerweile ist mir das auch klar geworden. Manchmal fängt man ja erst an, richtig drüber nach zu denken, nachdem man einen Beitrag geschrieben hat.
Noch eine Frage:
Du hast in deinem Code ja eine Funktion "main()" definiert und diese dann über die if-Abfrage unten aufgerufen. Sollte man dies immer so machen? Wo ist der Vorteil gegenüber der Art, den "Hauptprogrammcode (weiß nicht, wie ich das sonst nennen soll)" einfach nach der letzten Funktion unten dran zu hängen? Ich finde deine Art zwar irgendwie "schöner" und es sieht für mich auch irgendwie "richtiger" aus, ich weiß aber selber nicht, wieso.

Re: Stilfrage
Verfasst: Dienstag 28. September 2010, 18:40
von Liffi
Fjunch-click- hat geschrieben:
Noch eine Frage:
Du hast in deinem Code ja eine Funktion "main()" definiert und diese dann über die if-Abfrage unten aufgerufen. Sollte man dies immer so machen? Wo ist der Vorteil gegenüber der Art, den "Hauptprogrammcode (weiß nicht, wie ich das sonst nennen soll)" einfach nach der letzten Funktion unten dran zu hängen? Ich finde deine Art zwar irgendwie "schöner" und es sieht für mich auch irgendwie "richtiger" aus, ich weiß aber selber nicht, wieso.

Damit verhindert man, dass alles ausgefuehrt wird auch wenn man das Programm nur importiert.
Re: Stilfrage
Verfasst: Mittwoch 29. September 2010, 10:20
von Fjunch-click-
Ah, alles klar.
Wieder was gelernt.
