Kann ich so Kindern Python-Klassen erklären ? Kritik bitte

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Samstag 15. September 2007, 20:28

Hi, unterrichte am Dienstag Python für Kinder und möchte Ihnen diesmal das arbeiten mit Klassen beibringen. Sie kennen schon das random-modul und sollten auch wissen was eine Funktion ist.

Dieses Beispiel soll später einmal ein Rollenspiel werden mit lauter Dieben, die sich gegenseitig bestehlen.

Ich bitte um Kritik bzw Verbesserungsvorschläge. Was mich am meisten beschäftigt:
*)Wäre es besser die Klasse "Dieb" in eine Überklasse "Diebe" zu packen und mittels __iter__ zu arbeiten als alle Diebe in eine Liste zu stopfen und mittels for - Schleife zu arbeiten ? Ich bin mit dem __iter__ und next nicht ganz vertraut..

*) Abgesehen von den fehlenden Docstrings, stimmt die Gross/Kleinschreibung soweit ?

*) geht das ganze eleganter, denke ich zu verworren ? Ich fürchte es wird zu kompliziert für die Kinder (ca. 11 Jahre alt).

Code: Alles auswählen

# -*- coding: utf-8 -*-
import random

class Dieb:
    
    def __init__(self, name):
        self.Name = name
        self.Geld = 100
        self.Diebstahl = 25 + random.randrange(-20,20) 
        self.Aufpassen = 25 + random.randrange(-20,20)
        self.Ruf = 25 + random.randrange(-5,5)
        self.Zustand = "lungert herum"
        
    def saghallo(self):
        return "ich bin " + self.Name + " und habe " + str(self.Geld) + " Euro und " + str(self.Ruf) + " Ruf."

    def stehlen(self, GegnerVerteidigung):
        if random.randrange(0,20) + self.Diebstahl > random.randrange(0,20) + GegnerVerteidigung:
            return True
        else:
            return False

    def verteidigung(self):
        if self.Zustand == "abgelenkt":
            return self.Aufpassen * 0,5
        else:
            return self.Aufpassen

def Diebstahl(Taeter, Opfer):
    if Taeter.stehlen(Opfer.verteidigung()) == True:
        Betrag = round(Opfer.Geld * 0.5,0 ) # Taeter nimmt 
        Opfer.Geld  -= Betrag               # dem Opfer das 
        Taeter.Geld += Betrag               # halbe Geld weg
        return "Diebstahl erfolgreich. \n" + Taeter.Name + " stiehlt von " + Opfer.Name + " " + str(Betrag)
    else:
        Taeter.Ruf -= round(Taeter.Ruf * .6, 0) # Taeter verliert Ruf
        return "Diebstahl erfolglos. \n" +Taeter.Name + " wurde von " + Opfer.Name + " beim stehlen erwischt und verprügelt."
        
    
def diebname():
    liste1 = ["Benno", "Beppo", "Hasso", "Luigi", "Bobo", "Ede", "Eddi",
              "NixNutz", "August", "Butch", "Ricky"]
    liste2 = ["Hasenfuss", "Flinkfinger", "Tunichtgut", "Taschenkrebs",
              "Langfinger", "Butterhand", "Riff-Raff", "Ruchlos"]
    return random.choice(liste1) + " " + random.choice(liste2)



def neuerDieb():
    while True:
        Vorschlag = diebname()
        for Kerl in Diebe:
            if Vorschlag == Kerl.Name:
                #print "diesen Namen gibt es schon"
                break #else wird NICHT ausgeführt, zurück zur while Schleife
        else: 
            Diebe.append(Dieb(Vorschlag))
            #print "Dieb wurde angefügt"
            break #raus aus der while Schleife
    print "Ein neuer Dieb erscheint ! Es gibt jetzt " + str(len(Diebe)) + " Diebe"


# -------------------mainloop---------------------
Diebe = []

for x in range(2):
    neuerDieb()
print "---" + str(len(Diebe))


for x in range(5):
    print "Diebstahl " + str(x)
    print Diebstahl(Diebe[0], Diebe[1])
    print Diebe[0].saghallo()
    print Diebe[1].saghallo()
    
http://spielend-programmieren.at
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Samstag 15. September 2007, 21:20

Hi!

Also die Klasse "Dieb" find' ich super!

Der untere Teil ist für mich als Neuling² auch ein wenig verworren. Mein größtes Manko ist ja, dass ich nicht gut logisch Denken kann (ja und ich versuche trotzdem zu programmieren :oops: ) und mir gerade die Sachen mit Listen immer wieder Probleme bereiten.

Ansonsten finde ich es toll. Eine gute Idee.

Wenn du den Kiddies erklären kannst, dass die Klasse, also ein "Dieb" nur ne "Vorlage" ist und ein Objekt dann ein "bestimmter" Dieb (also einer mit einem Namen), dann klappt das ganz sicher!

Weiter so und viel Erfolg!
Gruß!
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Samstag 15. September 2007, 21:28

C4S3 hat geschrieben:Hi!
Wenn du den Kiddies erklären kannst, dass die Klasse, also ein "Dieb" nur ne "Vorlage" ist und ein Objekt dann ein "bestimmter" Dieb (also einer mit einem Namen), dann klappt das ganz sicher!
Weiter so und viel Erfolg!
Danke ! Erklären werde ich es schon können, aber wahrscheinlich quälen Sie mich dann mit Tkinter-Fragen weil "nur Text ist fad"... *seufz*

Ich plane dann mit pygame weiterzumachen, wobei ein Dieb = ein Sprite...
http://spielend-programmieren.at
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Samstag 15. September 2007, 21:36

Tkinter-Fragen weil "nur Text ist fad"... *seufz*
Dabei ist die Konsole sowas schönes!
Ich plane dann mit pygame weiterzumachen, wobei ein Dieb = ein Sprite...
Wo läuft der Unterricht und wo kann ich mich anmelden!?

Klingt ja spannend! Du solltest ein "Pygame für Kids" schreiben. Ich habe aus der "für Kids" Reihe hier etliche Bücher rum stehen und finde die eigentlich bis auf ein paar Ausnahmen sehr gelungen.
Umschlagtext der 'für Kids'-Reihe hat geschrieben:.. oder für Erwachsene, die eine wirklich einfache Einführung suchen!
IMHO bei Pygame unbedingt notwendig (für mich).
Gruß!
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Samstag 15. September 2007, 23:55

Huff ... ich habe nun 4x schon versucht eine Kritik zu schreiben, die nicht feindseelig klingt ... bin leider immer gescheitert :twisted: ... also probier ich es noch einmal.

JA ... auch wenn ich kein Pädagoge bin, aber es wird für die kleinen Kids der 5. oder 6. Klasse weit aus zu schwer/kompliziert werden.

Spiele als Kind spielen ist normal, aber eines zu programmieren geht doch ein wenig zu weit.

Programmier-Paradigmen und Techniken zu erklären geht auch ohne ein komplexes Projekt aufzuziehen, wie es deinem "Computerspiel" nunmal leider zu Grunde liegt (Tic, Tac, Toe ist ja schon nicht mal ganz so trivial für Normalsterbliche PC-Benutzer).

Zudem solltest du, wenn du Python als produktive Programmiersprache für die Veranschaulichung und Umsetzung verwenden möchtest, deine Beispiele und Kentnisse in Hinsicht der "pythonischen" Syntax und Semantik nochmal überarbeiten und up-to-date bringen. Programmierst du sonst in einer C-Style orientierten Sprache (C, C++, C#, Java ...)?
  • - unvollständige Magic-Lines
    - ughh ... CamelCase (Tipp: Style Guide for Python Code)
    - funktionaler Code auf direkter Modulebene (autsch, wenn das jemand mal importiert, das könnte in die Hose gehen)
    - umständliche Konkatenation und Typumwandlung von Strings (x = "Number " + str(15) + " is bigger than " + str(2), anstelle der hübsch pragmatischen Formatierung (x = "Number %s is bigger than %s" % (15, 2)
    - etc. ;)
Möchtest du eigentlich den Kids *OOP* oder die *Programmierung mit Python* näher bringen?

"OOP oder Python?" ... "Schlagsahne oder Schokosauce?"

Wobei das eine, nicht das andere unbedingt ausschließt ... ebenso natürlich umgekehrt.
BlackJack

Sonntag 16. September 2007, 00:38

@HorstJENS: Die Gross-/Kleinschreibung stimmt nach dem Style Guide zumindest nicht. Der schlägt Klassennamen in "MixedCase" und Funktionen, Methoden und Attribute in kleinschreibung_mit_unterstrichen vor. Was auch immer Du machst, sei wenigstens konsequent. Mit `Diebstahl()`, `diebname()` und `neuerDieb()` hast Du bei Funktionsnamen ja fast alle Möglichkeiten ohne Unterstriche mal durchprobiert. :-)

Den Startbetrag könnte man einem `Dieb` vielleicht als Argument mit Default-Wert mit auf den Weg geben.

Die Namen `Diebstahl` und `Aufpassen` sind IMHO nicht gut gewählt. Diese Attribute beschreiben Eigenschaften des Diebes. `geschicklichkeit` und `aufmerksamkeit` wären passender. Die Findung der Anfangswerte lässt sich vereinfachen. Statt ``25 + random.randrange(-20,20)`` z.B. einfach ``random.randrange(5, 45)``.

Bei `saghallo` würde ich vom Namen her erwarten dass die Methode aktiv etwas tut und nicht nur ein Ergebnis liefert. Ich würde die Methode in `__str__()` umbenennen. Dann kann man `Dieb`\e einfach mit ``print`` ausgeben und bekommt diesen Text.

`stehlen()` klingt auch eher nach einer Tätigkeit als nach einer Abfrage ob erfolgreich geklaut werden kann. Im Englischen haben Methoden, die einen Wahrheitswert liefern in der Regel einen Namen der mit `is_*`, `has_*` oder selteneren Fällen auch `can_*` beginnt. Vielleicht so etwas wie `kann_erfolgreich_bestehlen()`. Als zweites Argument sollte man hier den anderen Dieb übergeben. Und dieses Muster mit ``if irgendwas:`` und dann ein einfaches ``return True`` in einem Zweig und ``return False`` im anderen, ist kein guter Stil weil redundant. ``irgendwas`` ist ja schon ein Wahrheitswert den man direkt zurück geben kann. Da gab's hier schonmal irgendwo Diskussionen drüber, aber ich hätte dafür in der Schule Punktabzug bekommen und in der Uni sowieso. Gleiches gilt für das explizite Testen auf ``True`` oder ``False``, was Du in `Diebstahl()` gemacht hast. Ein ``if Taeter.kann_erfolgreich_bestehlen(Opfer):`` ist dann aussagekräftig genug.

In `verteidigung()` ist ein kleiner aber feiner Tippfehler, der dafür sorgt, dass im ersten ``if``-Zweig immer das Tupel ``(0, 5)`` zurückgegeben wird. :-) Die Methode ist ein guter Kandidat für ein `property()`.

Wenn ich mir die Berechnungen so ansehe: Durch zwei zu teilen erscheint mir irgendie einfacher als mit 0.5 zu multiplizieren. Und statt ``round(x, 0)`` tuts auch ein ``int(x)``.

`Diebstahl` wäre auch eine prima Methode auf `Dieb`-Objekten. Problem ist hier die Vermischung von Logik und GUI. Man könnte den gestohlenen Betrag zurückgeben lassen und 0 Euro gilt als Misserfolg. Das ist auch das Ergebnis wenn der Diebstahl selber erfolgreich war, aber das Opfer kein Geld mehr hatte, aber das ist aus Sicht eines Diebes ja auch ein Misserfolg.

`vornamen` und `nachnamen` wären sprechendere Bezeichner für `liste1` und `liste2` in `diebname()`.

`neuerDieb()`: Diese Art Namen zu finden ist nicht so toll, weil der Algorithmus umso länger braucht, je mehr Namen man schon hat. Im schlimmsten Fall ist das eine Endlosschleife wenn es alle Namen schon gibt. Die Funktion manipuliert die globale Liste `Diebe`; das ist nicht gut. Bei der Schleife auf Modulebene habe ich mich nämlich gefragt wieso Du die Diebe nicht zur Liste hinzufügst.
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Sonntag 16. September 2007, 08:17

Danke für die Kritik !
Das ging schnell... posten, einschlafen, aufwachen, Feedback lesen :-)

Werde mir die Anregungen zu Herzen nehmen und demnächst eine verbesserte Version posten (lese mich gerade durch den Style-Guide).
Danke für das Auffinden des 2,5 Bugs...*schämt sich*

@Was ich eigentlich will: die Kinder pygame-fähig machen. Und mit pygame Spiele programmieren, echte Spiele.

@ "abc %s defg" %x anstelle von abc"+str(x)+"defg" ... hab ich mir durch zu viel Visual Basic programmieren angewöhnt. Erschien mir Anfangs logischer als das "%" von C, aber so langsam gewöhne ich mich um.
http://spielend-programmieren.at
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Sonntag 16. September 2007, 08:22

BlackJack hat geschrieben: `neuerDieb()`: Diese Art Namen zu finden ist nicht so toll, weil der Algorithmus umso länger braucht, je mehr Namen man schon hat. Im schlimmsten Fall ist das eine Endlosschleife wenn es alle Namen schon gibt. Die Funktion manipuliert die globale Liste `Diebe`; das ist nicht gut. Bei der Schleife auf Modulebene habe ich mich nämlich gefragt wieso Du die Diebe nicht zur Liste hinzufügst.
Stimmt. Habe bei diesem Punkt irgendwie eine Denkblockade ... Ich will beliebig viele Diebe erzeugen können die alle einen Namen haben sollen. Möglicherweise ist es unsinnig zu versuchen jedem einen einzigartigen Namen zu geben. Mir schwebt auch so etwas im Kopf herum wo ein Diebes-Name der schon einmal vorkommt hinten dann eine Nummer dazubekommt ("Schappfuss Strauchdieb 2") aber ich weiss noch nicht wie ich das lösen soll. Wahrscheinlich lebe ich am Besten damit das manchmal Namen doppelt vorkommen.
http://spielend-programmieren.at
BlackJack

Sonntag 16. September 2007, 08:45

Ich hab's mal so umgesetzt, wie ich es machen würde: http://paste.pocoo.org/show/3954/

Die `Namen`-Klasse sorgt dafür, dass jeder Name mit `namen.naechster_name()` nur einmal vorkommt. Wenn alle aufgebraucht sind, gibt es einen `IndexError`. Mit den vorgegebenen Namen(steilen) sind immerhin 88 verschiedene Namen möglich. Kann man mit ``len(namen)`` auch abfragen.

Die möglichen Zustände eines `Dieb`\s sind als Konstanten definiert, so kann man sich nicht unbemerkt vertippen wenn man sie benutzt.
Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

Sonntag 16. September 2007, 11:21

Wow, danke !
genau so ein Beispiel mit __iter__ habe ich gesucht.. super!
lg,
-Horst
http://spielend-programmieren.at
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Sonntag 16. September 2007, 11:35

HorstJENS hat geschrieben:Danke für die Kritik !
Das ging schnell... posten, einschlafen, aufwachen, Feedback lesen :-)

Werde mir die Anregungen zu Herzen nehmen und demnächst eine verbesserte Version posten (lese mich gerade durch den Style-Guide).
Danke für das Auffinden des 2,5 Bugs...*schämt sich*

@Was ich eigentlich will: die Kinder pygame-fähig machen. Und mit pygame Spiele programmieren, echte Spiele.

@ "abc %s defg" %x anstelle von abc"+str(x)+"defg" ... hab ich mir durch zu viel Visual Basic programmieren angewöhnt. Erschien mir Anfangs logischer als das "%" von C, aber so langsam gewöhne ich mich um.
Wie lange programmieren denn deine Schüler schon? ich würde nicht zu früh mit Pygame anfanfangen.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Sonntag 16. September 2007, 11:39

Ich gebs's auf.

Wenn es hier um eine Zielgruppe von Jungerwachsenen oder Studenten ginge, jo ... kein Ding ... aber 11 Jährige?

Einfach nur grausam, sorry ... die Synapsen der Kiddies sind noch lange nicht soweit mit einander vernetzt und das mathematische und räumliche Denken ist noch soweit unausgeprägt, als dass sie die Materie verstehen könnte.

*kopfschüttel*

Auch wenn es immer einige, wenige Ausnahmen bei den Schülern geben wird, so finde ich ist das Projekt mehr ein Aufladen von Frustrationen die sich einstellen werden, als das es wirklich eher auf eine IT-Welt von morgen vorbereiten würde.

Programmiersprachen bezogene OOP und PyGame ... für 11 Jährige!!! Finde das ist einfach noch ein paar Kapitel zu weit.

Die Wahrscheinlichkeit, dass aus Freude ein "in die Ecke werfen wird", ist ja fast schon vorprogrammiert :(.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Sonntag 16. September 2007, 13:01

Masaru,
Wo ist dein Problem? Zumindest ich war mit 12 auch schon am Programmieren. Ja vor allem in Basic, später etwas C. Irgend wann habe ich dann mit Delphi angefangen was mir so nicht gepasst hat das ich das Programmieren für ein Jahr in die Ecke geschmissen habe. ;) Von dem her glaube ich durchaus das es möglich ist. Aber ich denke nicht das es mit einer "normalen" Schulklasse geht.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Sonntag 16. September 2007, 13:17

Also ich hab auch mit 13 angefangen, erst ein paar Wochen HTML, dann Javascript, was mir aber absolut nicht gepasst hat, also hab ich mit ca. 13 1/2 PHP selbsständig gelernt, und konnte es nach einem halben Jahr recht gut (auch schon etwas OOP usw)
Okay, das sind fast 3 Jahre unterschied aber wenn ich mit 13 schon so weit war, dass ich mir das alles - OHNE Lehrer, OHNE Bücher, die alles Schritt für Schritt ganz einfach erklären - aneignen konnte, wobei das Internet schon geholfen hat ;) dann kann man auch als 11-Jähriger in der Lage sein, mit einem Lehrer, der einem alles ganz genau und auch 10 mal erklären kann, und dir jede deiner Fragen direkt beantwortet, das Programmieren zu lernen.
WENN die Kinder das wirklich wollen und WENN sie auch genug Gedult haben (also nicht nach dem Motto: Ich will Spiele programmieren aber sofort!), dann bin ich der Meinung, dass das schon was werden kann.
Ich weiß nicht, ob es eine so gute Idee ist, ihnen jetzt schon OOP beibringen zu wollen und dann mit Pygame (was ja mathematisch dann wahrscheinlich auch nicht SO einfach zu verstehen sein wird - Ich sprech da aber nicht aus Erfahrung, ich denk's mir einfach mal so) weiterzumachen.
Aber klappen kann's schon. Und wenn er merkt, dass das mit den Klassen nicht so klappt, dann kann er ja immer noch mit was anderem weitermachen und das später nochmal versuchen.
Imperator
User
Beiträge: 275
Registriert: Montag 20. August 2007, 14:43
Kontaktdaten:

Sonntag 16. September 2007, 15:58

@Masaru: ich bin dreizehn, also nur 2 Jahre älter.
Antworten