Schulprojekt: Zeichner 2

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

Guten Morgen,

In der Schule haben wir nun mit der Python-Programmierung angefangen. Vorkenntnisse sind praktisch keine vorhanden.
Nach 4 Schulstunden a 45min habe ich nun folgendes programmiert und möchte es euch gerne vorstellen.
Mein kleines Programm heisst Zeichner 2. Der Anwender steuert die Turtle und kann beliebig oft von vorne beginnen.

Für Tipps, Anregungen und Anmerkungen bin ich natürlich offen.


Bild

Uploaded with ImageShack.us
Zuletzt geändert von frecker am Dienstag 19. Juli 2011, 01:22, insgesamt 1-mal geändert.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ok,
0. Willkommen im Forum

1. Lade sowas bitte im hiesigen Pastebin(ist oben verlinkt) hoch und nicht bei einem FileHoster.

2. Für längere Kommentare, wie für den Header eines Moduls gibt es Docstrings, diese beginnen einfach mit 3 Anführungszeichen und sind Mehrzeilig.

3. Kommentare hinter dem Quellcode sehen nicht schön aus, mag Geschackssache sein, IMHO sind sie über dem Befehl schöner. Zu dem sollte man die 80 Spalten einhalten.

4. Du hast den Sinn einer Funktion noch nicht ganz verstanden, es sollte eine Funktion für die Bewegung reichen. Du machst für jede Richtung eine Funktion und das geht am Sinn vorbei. Schreib dir eine Funktion wie "move" und übergebe das "heading" und die "forward" Werte als Parameter.

5. Die langen Kommazahlen sind mir etwas suspect, importiere dir das "math" Modul und mach dort immer eine saubere Berechnung der Hypothenuse.

6. Circle, existiert bereits im "turtle" Modul.
Edit: Sry, hatte das wegen der Schleife übersehen, das du den schon nutzt.

7. "global" sollte nur im Notfall, bzw. nie benutzt werden, ersetz es durch einen Parameter, in diesem Fall ist auch keine Integer Variable gefragt, sondern eine Boolsche.

8. Klammern um "if"s sind in Python nicht notwendig.

9. Ansonsten schaut es schon ganz gut aus, hier noch zwei Hinweise. Du solltest den "main"-Bereich eines Moduls mit

Code: Alles auswählen

if __name__ == "__main__":
Kennzeichnen und von *-Importen absehen.

edit:
10. Wenn du Python 2.x nutzt, dann bitte "xrange" statt "range" in Schleifen nutzen, zumal deine Schleifen unötig sind, da sie nur einen Durchlauf haben.

11. Weise deinen Editor bitte an TABs durch 4 Leerzeichen zu ersetzen.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

1. Ich habe es bei wegen der beiden zugehörigen Bilddateien bei einem Filehoster hochgeladen

2. + 3. Werde ich mir für die nächste Version merken

4. Kannst du mir das eventuell etwas genauer erklären

5. Habe mir das math Modul eben mal kurz angesehen und werde dies wohl jetzt einbauen

7. Habe an dieser Stelle sehr lange gesessen und dann mit der Hilfe eines Blogs diese Lösung gefunden mit der es erstmals funktionierte

deinen 9. Punkt verstehe ich auch noch nicht ganz (das mit dem * ist klar)

Programmierung ist für mich völliges Neuland. Daher bin ich auf meinen geringen Wissensstand und Hilfe von anderen angewisen
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

1. Bilder kann man auch in den Python Quellcode einbetten, aber bei dem Bild war es so nat. besser, dennoch hätte man den Quellcode seperate in das pastebin hochladen können, denn für die Kritiken oben, brauchte es die Bilder nicht :wink:

4. Klar gerne doch, hierzu muss ich dich allerdings fragen, weißt du was Parameter sind ? Wenn nicht solltest du das dringend nachholen. Theoretisch muss deine Funktion nur so ausehen:

Code: Alles auswählen

def move(heading, forward):
    seth(heading)
    forward(forward)
Mehr braucht man im Grunde nicht. Nun aber möchte die Turtle-Funktion "onkey" aber eine Funktion und keinen Wert dieser, dafür gibt es einen einfachen Trick per "lambda"-Funktionen.

5. hier gibt es gleich die Funktion "hypot".

7. Bist hier nicht gut beraten, da "global" dann halt wirklich global ist und wenn die häufig genug genutzt wird, wirst du bald feststellen das du nicht mehr mitbekommst wo sie geändert wird, in diesem kleinen Script natürlich egal. Zugegeben ist das hier nicht ganz einfach, da man keinen Rückgabewert erhält. Ich habe hier mal eine Klasse dafür missbraucht(siehe unten), ist AFAIK immer noch besser als global, aber auch nicht hübsch. Vieleicht fällt jemand anderem noch was besseres ein.

9. Ok ich habe mal deinen Script umgeschrieben, sieh ihn dir genau an.

Code: Alles auswählen

#! /usr/bin/env python
"""
02.02.2011
"""
# importiert das Mathe und Turtle Modul
import math
import turtle
                    
# Definitionen zum Bewegen
def move(forward, heading):
    turtle.seth(heading)
    turtle.forward(forward)

# Hilfe an/aus  
# Hier noch mal der Hinweis, das ist auch nicht schön, aber für Turtle fällt mir nichst besseres ein
# Vieleicht hat ja noch jemand eine Idee
class Background(object):
    help_pic = True 
    
# Definition zum Wechseln des Hintergrundbildes
def changebg():
    turtle.bgpic('bg.gif' if Background.help_pic else 'bg2.gif')
    Background.help_pic = not Background.help_pic

if __name__ == "__main__":
    # bestimmt Fenstergroesse
    turtle.setup(width=800, height=600)
    # Titelzeile des Fensters
    turtle.title('Einfaches Zeichenprogramm')
    # Stiftfarbe und Hintergrundbild
    turtle.color('black')
    changebg()

    # Schrittgeschwindigkeit der Schildkroete
    step = 100

    # Tastensteuerung
    turtle.listen()
    # Richtungen
    turtle.onkey(lambda: move(step, 0), 'd')
    turtle.onkey(lambda: move(math.hypot(step, step), 45), 'o')
    turtle.onkey(lambda: move(step, 90), 'w')
    turtle.onkey(lambda: move(math.hypot(step, step), 135), 'i')
    turtle.onkey(lambda: move(step, 180), 'a')
    turtle.onkey(lambda: move(math.hypot(step, step), 225), 'k')
    turtle.onkey(lambda: move(step, 270), 's')
    turtle.onkey(lambda: move(math.hypot(step, step), 315), 'l')
    # Taste c um einen Kreis zu zeichnen
    turtle.onkey(lambda: turtle.circle(step), 'c')  
    
    # Leertaste zum Loeschen der Zeichnung
    turtle.onkey(turtle.reset, 'space')                         
    # Taste h um den Hintergrund zu wechseln
    turtle.onkey(changebg, 'h')                        

    turtle.mainloop()
Edit: Auf Wunsch vom OP seinen Namen aus dem Programmcode entfernt.
frecker hat geschrieben:Programmierung ist für mich völliges Neuland. Daher bin ich auf meinen geringen Wissensstand und Hilfe von anderen angewisen
Wollte dich nicht verschrecken :mrgreen:
Zuletzt geändert von Xynon1 am Dienstag 19. Juli 2011, 08:06, insgesamt 1-mal geändert.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

1. Aber die Bilder gehörten für mich natürlich unbedingt dazu ;)

4. auf die Funktion

Code: Alles auswählen

def bewegung(winkel, strecke):
    for k in range(1):
        seth(winkel)
        forward(strecke)
bin ich jetzt auch gekommen gewesen und hing genau an diesem Problem...hatte glaube ich das ganze sogar zu allererst so versucht..


5. habe ich in meiner offline Version schon geändert

9. werde ich jetzt mal machen und mir noch ein bisschen wissen über lambda aneignen :D
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Du hast schon wieder "for k in range(1)" drin, nochmal hierzu:
1. Eine Schleife die nur einmal durchläuft, braucht man nicht.
2. Nutzt du Python 3.x?, denn ansonsten muss es "xrange" heißen.
3. Wenn man eine Zählvariable(dein k) nicht braucht, also wie hier nimmt man in Python typischer Weise einen Unterstrich "_".

Achso es gibt Pythontags für Quellcodes [python][/python]
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

Code: Alles auswählen

from math import hypot

from turtle import forward, setup, title, color, bgpic, listen, onkey, seth, mainloop

def bewegung(strecke, winkel):
    seth(winkel)
    forward(strecke)

step = 100

listen()

onkey(lambda:bewegung(hypot(step, step), 45), 'o')
onkey(lambda:bewegung(step, 90), 'w')
onkey(lambda:bewegung(hypot(step, step), 135), 'i')
onkey(lambda:bewegung(step,180), 'a')
onkey(lambda:bewegung(hypot(step, step), 225), 'k')
onkey(lambda:bewegung(step,270), 's')
onkey(lambda:bewegung(hypot(step, step), 315), 'l')
onkey(lambda:bewegung(step,  0), 'd')

mainloop()
benutze python 2.x
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Bei so vielen imports von turtle, würde ich schlicht "turtle" importieren, wenn die turtle zu lang ist kannst du es auch mit "as" kürzen.

Code: Alles auswählen

import turtle as tu
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

man muss alles einmal ausprobieren...

Durch den Bereich mit dem Hintergrund ausblenden bin ich leider noch nicht so ganz durchgestiegen..

Code: Alles auswählen

class Background(object):
    help_pic = True 

if __name__ == "__main__":
    changebg()
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ist auch nicht wirklich schön, besser wäre es hier dann wohl eine komplette Klasse "BackgroundChanger" oder so was zu haben. Dazu musst du dich aber erst in OOP einarbeiten. Hier ein Beispiel.

Code: Alles auswählen

# Definiert die Klasse BackgroundChanger, abgeleitet von "object" - sollte man in Python < 3.x immer davon ableiten.
class BackgroundChanger(object):

    # Konstrucktor
    def __init__(self, status=True):
        # Attribute der den Status des Bildes anzeigt
        # True - wird angezeigt
        # False - wird nicht angezeigt
        self.status = status

    # Methode zum wechseln des Status mit einem Wert, welchen man selbst uebergeben kann
    def change(self, status=True):
        # Den Parameter "status" im Objektstatus uebernehmen
        self.status = status
        # Bild wechseln, je nach status
        turtle.bgpic('bg.gif' if status else 'bg2.gif')
  
    # Methode um automatisch von True auf False un zurueck wechseln
    def switch(self):
        # Status vertauschen
        self.status = not self.status
        # Die Methode change oben aufrufen und den Status wechseln
        self.change(self.status)
Aufrufen würde man das ganze so hier:

Code: Alles auswählen

# Eine Instanz von der BackgroundChanger Klasse anlegen
changebg = BackgroundChanger()
# Hilfe Bild anzeigen
changebg.change(True)
# Methode zum automatischen Wechseln übergeben.
turtle.onkey(changebg.switch, 'h')
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

frecker hat geschrieben:Programmierung ist für mich völliges Neuland. Daher bin ich auf meinen geringen Wissensstand und Hilfe von anderen angewisen
Kein Problem.

Es gibt manchmal Leute die hier ihr Programm vorstellen und furchtbar beleidigt sind wenn man dann auf mögliche Verbesserungen hinweist. Bei dir ist das anders. Du nimmst die Kritik nicht als "Runtermachen", sondern als Anstoß, dich noch mehr mit dem Thema zu beschäftigen. In so einem Fall hilft man gerne.
frecker
User
Beiträge: 8
Registriert: Mittwoch 2. Februar 2011, 15:23

Jetzt mal endlich wieder ne Antwort von mir.
Liege krank im Bett.

Habt ihr denn eine schöne Idee, was man nach diesem Zeichner schönes mit Python programmieren könnte?
Antworten