screenPicasso (Zeichenprogramm) Bitte Kritik

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Drumset
User
Beiträge: 3
Registriert: Montag 29. Januar 2007, 18:45

Hallo!

Ich bin ein totaler Anfänger bei Python, habe mich aber einmal in einem Zeichenprogramm versucht. Ist im Moment Version 2.1.
Da ich so ein Anfänger bin, bitte ich zur Kritik auch Erklärung vielen vielen Dank!

Code: Alles auswählen

# -*- coding: cp1252 -*- 
##############
#                           # 
#    Screenpicasa    # 
#    Version  2.3     # 
#     Copyright       # 
##############
from xturtle import * 

def Quadrat(): 
    fd(40) 
    rt(90) 
    fd(40) 
    rt(90) 
    fd(40) 
    rt(90) 
    fd(40) 

def Dreieck(): 
    fd(80) 
    lt(120) 
    fd(80) 
    lt(120) 
    fd(80) 
    lt(120) 

def Kreis(): 
    circle(50,360) 

def Achteck(): 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 
    fd(50) 
    lt(45) 

def Sechzehneck(): 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 
    fd(25) 
    lt(22.5) 

def Strichmaennchen(): 
    rt(45) 
    fd(45) 
    rt(90) 
    fd(45) 
    rt(180) 
    fd(45) 
    rt(45) 
    fd(50) 
    rt(90) 
    circle(15,360) 
    rt(45) 
    fd(45) 
    rt(180) 
    fd(45) 
    lt(90) 
    fd(45) 

def Smilie(): 
    fillcolor("yellow") 
    begin_fill() 
    circle(120,360) 
    end_fill() 
    penup() 
    lt(90) 
    fd(180) 
    rt(260) 
    pendown() 
    circle(65,165) 
    penup() 
    lt(5) 
    fd(40) 
    pendown() 
    circle(30,180) 
    penup() 
    rt(90) 
    fd(40) 
    rt(90) 
    pendown() 
    circle(30,180) 
    hideturtle() 
    
def Text_hi(): 
    fd(50) 
    rt(180) 
    fd(25) 
    lt(90) 
    fd(25) 
    lt(90) 
    fd(25) 
    rt(180) 
    fd(50) 
    lt(90) 
    penup() 
    fd(25) 
    lt(90) 
    pendown() 
    fd(50)

def Zufall():
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150)) 
    lt(randrange(1,150)) 
    fd(randrange(1,150))

    
    
print "Das ist das Zeichenprogramm ScreenPicasso, Version 2.3" 

user = raw_input("Wie heißt du? ") 
print "Hallo " + user + " ! Möchtest du zeichnen? Ja/Nein Gib j oder n ein!" 
print 
Hallo = raw_input() 


def spiel(): 

    if Hallo == "j": 
        print "Welche Form möchtest du,%s?\n a)Quadrat\n b)Dreieck\n c)Kreis?\n d)Achteck\n e)16-Eck\n f)Strichmännchen\n g)Smilie\n h)Text 'Hi'\n i)zufalls Muster\n Gib 'a)','b)','c)','d)','e)','f)','g)','h)' oder 'i)' ein..." %user 
    elif Hallo == "n": 
        print "Tschüß!" 
    else: 
        print "Welche Form möchtest du?\n a)Quadrat\n b)dreieck\n c)Kreis?\n d)Achteck\n e)16-Eck\n f) Strichmännchen\n g)Smilie\n h)Text 'Hi'\n Gib  'a)','b)','c)','d)','e)','f)','g)','h)' oder 'i)' ein..." 
        
    frage1 = raw_input() 
    if frage1 == "a)": 
        print "Ein Quadrat also... Soll es a) dick oder b) dünn sein?" 
    elif frage1 == "b)": 
        print "Ein Dreieck also... Soll es a) dick oder b) dünn sein?" 
    elif frage1 == "c)": 
        print "Ein Kreis also... Soll er a) dick oder b) dünn sein?" 
    elif frage1 == "d)": 
        print "Ein Achteck also... Soll es a)dick oder b) dünn sein?" 
    elif frage1 == "e)": 
        print "Ein 16-Eck also... Soll es a)dick oder b) dünn sein?" 
    elif frage1 == "f)": 
        print "Ein Strichmännchen also... Soll es a)dick oder b) dünn sein?" 
    elif frage1 == "g)": 
        print "Ein Smilie also... Soll es a)dick oder b)dünn sein?" 
    elif frage1 == "h)": 
        print "Ein Text mit Inhalt 'Hi' also... Soll er a)dick oder b) dünn sein?"
    elif frage1 == "i)":
        print "Ein zufalls Muster also...Soll es a)dick oder b) dünn sein?"
    else: 
        print "Keine Form gewählt! ScreenPicasa wählt Quadrat! Soll es\n a) Dick\n oder\n b) dünn\n sein?" 
    
#Farbe? 

    frage2 = raw_input() 
    if frage2 == "a)": 
        print "OK. Welche Farbe soll es haben?\n a)schwarz\n b)grün\n c)rot\n d)blau\n e)gelb\n f)grau\n" 
        hideturtle() 
        pensize(5)  
    elif frage2 == "b)": 
        print "OK. Welche Farbe soll es haben?\n a)schwarz\n b)grün\n c)rot\n d)blau\n e)gelb\n f)grau\n"  
        hideturtle() 
        pensize(1) 
    else: 
        print "Keine Stärke gewählt! ScreenPicasso nimmt dünn!\n OK. Welche Farbe soll es haben?\n a)schwarz\n b)grün\n c)rot\n d)blau\n e)gelb\n f)grau\n" 
        pensize(1) 
        hideturtle() 
    frage3 = raw_input() 
    if frage3 == "b)": 
        print "Farbe = grün" 
        pencolor("green") 
    elif frage3 == "a)": 
        print "Farbe = Schwarz" 
    elif frage3 == "c)": 
        print "Farbe = rot" 
        pencolor("red") 
    elif frage3 == "d)": 
        print "Farbe = blau" 
        pencolor("blue") 
    elif frage3 == "e)": 
        print "Farbe = gelb" 
        pencolor("yellow") 
    elif frage3 == "f)": 
        print "Farbe = grau" 
        pencolor("grey") 
    else: 
        print "Keine Farbe gewählt ScreenPicasso nimmt Schwarz!" 
        pencolor("black") 
    frage4 = raw_input 

#zeichnen 

    if frage1 == "a)": 
        print "In Arbeit....." 
        Quadrat()  
    elif frage1 == "b)": 
        print "In Arbeit....." 
        Dreieck()  
    elif frage1 == "c)": 
        print "In Arbeit....." 
        Kreis() 
    elif frage1 == "d)": 
        print "In Arbeit....." 
        Achteck() 
    elif frage1 == "e)": 
        print "In Arbeit...." 
        Sechzehneck() 
    elif frage1 == "f)": 
        print "In Arbeit...." 
        Strichmaennchen() 
    elif frage1 == "g)": 
        print "In Arbeit...." 
        Smilie() 
    elif frage1 == "h)": 
        print "In Arbeit...." 
        Text_hi()
    elif frage1 == "i)":
        print "In Arbeit...."
        Zufall()
    else: 
        print "In Arbeit...." 
        Quadrat() 

  
        print "Möchtest du deine bisherige Zeichnung löschen? j/n?" 
        frage7 = raw_input() 
        if frage7 == "j": 
            reset() 
            home() 
            hideturtle() 
            print "Die Zeichnung wurde gelöscht." 
        elif frage7 == "n": 
            print "Ok. Zeichnung wurde nicht gelöscht." 
            home() 
            spiel() 

    if Hallo == "j": 
        print "Möchtest du noch etwas zeichnen? j/n?" 
        frage6 = raw_input() 
        if frage6 == "j": 
            spiel() 
        elif frage6 != "j": 
            print "OK!\nAuf Wiedersehen." 
            exit() 
        else: 
            spiel() 

    

spiel() 
Zuletzt geändert von Drumset am Freitag 5. Juni 2009, 12:19, insgesamt 10-mal geändert.
abgdf

Oje, was soll ich sagen ? Immerhin funktioniert es irgendwie ... wenn nicht der Bildschirm sofort gelöscht würde, wenn das Objekt gezeichnet ist, weil das Programm dann sofort endet ...
Wofür Funktionen gut sind, und was es mit der Parameterübergabe an diese auf sich hat, solltest Du auch noch lernen.
Auch die Rechtschreib- und Zeichensetzungsfehler in den ausgegebenen Texten sprechen den Benutzer nicht gerade an.

Manchmal machst Du es Dir auch schwerer, als Python es verlangt. Es geht am Anfang z.B. einfach:

Code: Alles auswählen

from xturtle import *

print "Das ist das Zeichenprogramm ScreenPicasso, Version 1.4."

user = raw_input("Wie heißt du ? ") 
print "Hallo " + user + " !"
print
Und, und, und. Dennoch: Nicht aufgeben !

Viele Grüße
Drumset
User
Beiträge: 3
Registriert: Montag 29. Januar 2007, 18:45

Achtung ich hab jetzt auf Status 1.8 upgedatet
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Drumset hat geschrieben:Status 1.8
Sowas nennt man Version.

Von mir kommt Feedback, wenn die die "Design-Patterns"-Seite im Wiki angelegt habe. Dann ist es konstruktiver und auch für andere nützlich.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
abgdf

Hallo Drumset,

hier ein etwas längerer Erklärungsversuch: Versuche doch, Deine Daten in Listen (z.B. unten: Liste "forms") oder Dictionaries (z.B. unten: Dictionary "choices") zu organisieren und Codewiederholungen in Funktionen zu kapseln. Ein Beispiel (als Skript lauffähig):

Code: Alles auswählen

def getAuswahlstring(forms):

    # Erzeugt "Gib a, b, .... ein" .... Ok, der Zweck dieser Funktion ist etwas seltsam :)

    a = "Gib "

    for i in range(len(forms)):
        a += "'"
        a += chr(97 + i)
        a += "'"

        if i == len(forms) - 2:
            a += " oder "
        elif i == len(forms) - 1:
            pass
        else:
            a += ","

    a += " ein..."

    return a


def changeToNumber(a):

    a = a.rstrip(")")
    a = ord(a) - 97
    return a

user = "User"
choices = {}
forms = ["Quadrat", "Dreieck", "Kreis", "Achteck", "16-Eck"]

print "Welche Form möchtest du, " + user +" ?"
print 

for i in range(len(forms)):
    print chr(97 + i) + ") " + forms[i]

print 

auswstring = getAuswahlstring(forms)

print auswstring 

choices["form"] = raw_input()

choices["form"] = changeToNumber(choices["form"])

if choices["form"] < 0 or choices["form"] > len(forms) - 1:
    print "Keine Form gewählt! ScreenPicasso wählt Quadrat!"
    choices["form"] = 0
else:
    print "Ein " + forms[choices["form"]] +" also.",

auswstring ="Soll "

if choices["form"] == 2:
    auswstring += "er"
else:
    auswstring += "es"

auswstring += " a) dick oder b) dünn sein ?"

print auswstring
Dadurch wird der Code kürzer (normalerweise jedenfalls :) ) und läßt sich besser warten.
Das heißt, wenn Du später Dein Programm erweitern willst, mußt Du viel weniger Zeilen ändern als bei vielen Wiederholungen.
Z.B. solltest Du hier recht schnell in "forms" etwa noch "Sechseck" einfügen können.

Wenn das alles zu hoch für Dich ist, macht nichts !
Mach immer einen Schritt nach dem anderen. So kann man recht weit kommen.

Viele Grüße
Drumset
User
Beiträge: 3
Registriert: Montag 29. Januar 2007, 18:45

Jetzt ist es Version 2.0.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hi und willkommen im Python-Forum.
Drumset hat geschrieben:Jetzt ist es Version 2.0.
Ein wenig Konstruktive Kritik:

Es gibt etwas das nennt sich ``if __name__ == '__main__':``.
Das benutzt man in einem Modul, um Testcode bzw. Beispielcode in dem Block zu schreiben, der ausgeführt wird, wenn man das Modul startet und nur dann ausgeführt wird. Wenn man das Modul dann importiert, mit ``import``, wird solcher Code, der sich in einen ``if __name__ == '__main__':``-Block befindet, nicht ausgeführt.

Weiterhin ist deine Strukturierung auch total konfus:
  • Zeile 3 - 8 wir ausgeführt. Schön und gut, aber warum definierst du danach eine Funktion? Funktionen gehören am Anfang des Codes und ausführbarer Code am ende! Codesaausführungen und Definitionen von Funktionen/Klassen gehören nicht verstreut in einem Script, sondern geordnet.

    Die klare Strukturierung sieht in genau dieser Reihenfolge aus:
    1. imports von Modulen (Und nicht verstreut im Modul, auch wenn es einigen machen!)
    3. Konstanten Definitionen (Falls vorhanden)
    2. Klassendefinitionen (Falls vorhanden)
    3. Funktionsdefinitionen (Falls vorhanden)
    4. 2 und 3 Kann auch verstreut sein. Das heißt das mal eine Klassendefinition kommt und danach eine Funktionsdefinition und danach wider ein Klassendefinition. Ich persönlich halte das aber auch oft für schlecht und vermeidbar. Lieber eine Klare Struktur.
    5. (Optional) Am ende gehört dann eventuell ausführbarer Code der für das Modul wichtig ist (Konfigurative Aufgaben). -- Zu 99% nicht erforderlich.
    6. (Optional) An aller letzter stelle kommt dann eine Definition von ``main()`` das "Testcode" bzw. Beispielcode zur Benutzung vom Modul erhält. Diese main() Funktion wird dann in den ``if __name__ == '__main__':``-Block geschrieben.

    Beispiel:

    Code: Alles auswählen

    [...]
    def main():
        print 'foobar'
    
    if __name__ == '__main__':
        main()
    Alternativ kann man sich die Definition von ``main()`` sparen und gleich den Code im ``if __name__ == '__main__':``-Block verlagern. -- Das ist IMHO Geschmacksachen.
  • Wie gesagt kommt nun in Zeile 11 die Definition der Funktion ``spiel()``. Was daran falsch ist habe ich oben bereits erwähnt. Noch viel schlimmer ist aber, das deine Funktion direkt auf eine globale Variable zurückgreift; Und zwar auf die Variable ``Hallo`` in Zeile 8. Eine Funktion die Eingabedaten erwartet (Parameter), anhand dessen sie ihre Aufgab erfüllen kann, sollte gefälligst solche dann als Parameter (Funktionsargument(e)) übergeben bekommen werden, damit keine Seiteneffekte entstehen. Eine Funktion hat auch nicht das Recht darauf, globale Variablen (Variablen außerhalb ihres Namensraumes), zu verändern. -- Sowas zu missachten bringt immer Seiteneffekte mit sich und fördert die Unübersichtlichkeit.
  • Deine Funktion ``spiel()`` macht erstens zuviel und zweitens sind viele Redundanzen vorhanden. Gegen beides kann man was tun in dem du die Funktion in weitere Funktionen einteilst.
  • PEP8 sollte man gelesen haben und sich auch daran halten (zumindest größtenteils).
  • Nicht aufgeben und am Ball beleiben.
lg
abgdf

Hi,

ich hab Drumset per PM nochmal ein Code-Beispiel geschickt, wie man sein Programm kürzer machen könnte.

Muß ja nicht unbedingt hierher, ist ja sein Showcase-Posting.

Viele Grüße
Antworten