Seite 1 von 4

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 12:56
von meego
Ich muss sagen: Meine Grenze ist wohl langsam erreicht. Die mehrstufigen Loops bei den Dictionaries waren mir zu schnell. Didaktisch war das bestimmt auch nicht ganz optimal von Scott. Jedenfalls nicht für Newbies.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 15:34
von mcdwerner
@meego: ich denke Du meinst diese Funktion, richtig?

Code: Alles auswählen

# CIPHER und message sind globale Variabalen
def decode():
    dmsg = ""
    for ch in message:
        for key, value in CIPHER.items():
            if ch == value:
                dmsg += key
    print message, "decodes to", dmsg
Das Hantieren mit globalen Variablen ist natürlich nicht so gut überschaubar, leider mussten sie deren "simplegui" dranbringen, bevor Sie Objekte/Klassen durchnehmen...

Er wählt auch u.a. die Bezeichner nicht einsteigerfreundlich, da muss ich auch oft 2x überlegen:

Code: Alles auswählen

def decode():
    decoded_message = ""
    for character in encoded_message:
        for key, value in CIPHER.items():
            if character == value:
                decoded_message += key
    print encoded_message, "decodes to", decoded_message
Ansonsten finde ich diese doppelte for-Schleife nicht so schwierig, die 2. Schleife brauchst Du ja nur, weil man Dictionarys nicht nach Values durchsuchen kann, deshalb musst Du Dir jedes Item einzeln ansehen.

Hoffe geholfen zu haben :-)

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 15:45
von Sirius3
Warum kann man in Kursen nicht mit den Grundfunktionen anfangen, »join«, »map«, wozu Dictionaries einzig und alleine da sind?

Code: Alles auswählen

DECIPHER = dict((value, key) for key, value in CIPHER.items())
def decode(encoded_message):
    return ''.join(map(DECIPHER.get, encoded_message))

print encoded_message, "decodes to", decode(encoded_message)

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 15:53
von mcdwerner
@Sirius: ich denke die haben einen eigenen Parser/Crosscompiler gebaut, der zu Javascript kompiliert:
http://www.codeskulptor.org/docs.html

Jedenfalls passiert alles im Browser, und der kann ja leider kein Python :(
map() gibt's da nicht (genausowenig wie enumerate() :evil: )

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 16:21
von BlackJack
Dann ist die Kursbeschreibung aber ziemlich irreführend. Da kann man ja gar nicht wirklich Python lernen.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Freitag 24. Mai 2013, 17:43
von Sirius3
Python 2.7 hat ungefähr 50 Builtin-Funktionen von denen die meisten in einer Zeile implementiert sind:

Code: Alles auswählen

def map(func, *iterables):
    return [func(*el) for el in zip(*iterables)]

def enumerate(iterable, start=0):
    i=start
    for el in iterable:
        yield i, el
        i+=1
:K
Das Schreiben, dass sie »unsupported« sind, dauert da wahrscheinlich länger.
http://www.codeskulptor.org/docs.html hat geschrieben:Unsupported Sequence & Iterable Operations
max() and min() with key argument. zip() with one argument. map() filter() reduce()
Wobei zip mit einem Argument tut, und max,min den key einfach ignorieren anstatt eine ordentliche Fehlermeldung zu melden.

Der Code sieht etwas umständlich aus, aber es gibt noch weitere Einschränkungen:

Code: Alles auswählen

def max(*args, **kw):
    if kw and 'key' not in kw:
        raise TypeError("max() got an unexpected keyword argument")
    if len(args)==1:
        args=args[0]
    if not args:
        raise ValueError("max() arg is an empty sequence")
    key = kw.get('key', lambda x: x)
    max_k = undef = []
    for el in args:
        k = key(el)
        if max_k is undef or max_k<k: max_el, max_k = el, k
    return max_el 

def filter(func, seq):
    if func is None: func=bool
    result = [func(el) for el in seq]
    if isinstance(seq,str):
        return ''.join(result)
    if isinstance(seq,tuple):
        return tuple(result)
    return result

Re: Anfängerkurs in Python bei Coursera

Verfasst: Samstag 25. Mai 2013, 10:40
von mcdwerner
Mit der neuen Lektion "Object-oriented Programming" wird's tatsächlich noch unpythonischer :-(
Zitat aus dem Video zu dieser Klasse:
"...i've created an interface ... i've given you no way to decrease the health of this character..."

Code: Alles auswählen

class Character:
    def __init__(self, name, initial_health):
        self.name = name
        self.health = initial_health
        self.inventory = []
        
    def __str__(self):
        s  = "Name: " + self.name
        s += " Health: " + str(self.health)
        s += " Inventory: " + str(self.inventory)
        return s
    
    def grab(self, item):
        self.inventory.append(item)
        
    def get_health(self):
        return self.health

Re: Anfängerkurs in Python bei Coursera

Verfasst: Samstag 25. Mai 2013, 14:53
von meego
mcdwerner hat geschrieben:@meego: ich denke Du meinst diese Funktion, richtig?

Code: Alles auswählen

def decode():
    decoded_message = ""
    for character in encoded_message:
        for key, value in CIPHER.items():
            if character == value:
                decoded_message += key
    print encoded_message, "decodes to", decoded_message
Exakt. Ich glaube es ungefähr verstanden zu haben. Eine Schleife über jeden Buchstaben des Wortes. Und darin nochmal eine Schleife über das ganze Dictionary für jeden Buchstaben.

Aber anwenden könnte ich das selber noch nicht.

Ansonsten bin ich immer noch mit Memory beschäftigt. Wenn ich mir den Einblick in nächste Woche so anschaue vergeht mir die Lust.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 14:23
von meego
Hier nimmt Scott Stellung zu eurem Religionskrieg:
https://class.coursera.org/interactivep ... ad_id=5787

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 14:38
von BlackJack
@meego: Der Link führt mich auf die Kursübersichtsseite. Um das Forum lesen zu können muss man wahrscheinlich dort angemeldet sein.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 15:10
von mcdwerner
dann zitier ich hier mal sein Hauptargument:
This allows you to achieve isolation and encapsulation and leads to more robust programs.
Edit: eigentlich ist es sein einziges Argument

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 15:14
von /me
mcdwerner hat geschrieben:dann zitier ich hier mal sein Hauptargument:
This allows you to achieve isolation and encapsulation and leads to more robust programs.
Edit: eigentlich ist es sein einziges Argument
Mal abgesehen davon, dass es in Python so etwas wie private Attribute überhaupt nicht gibt. Es gibt sie zumindest nicht in der Form, dass ein Zugriff technisch unterbunden wird.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 15:40
von mcdwerner
Ich hab jetzt nochmal eingehender drüber nachgedacht.

Das Argument, das ja immer für "ungeschützte Attribute" ins Feld gebracht wird ist doch:
"We are all consenting adults"
auf gut deutsch: "Wenn Du ein Attribut veränderst, dann überleg Dir zuerst, was Du da tust"
In Python geht das ja auch, da ich den Quellcode aller verwendeten Klassen zur Verfügung habe (was auf kompilierte Sprachen nicht immer zutrifft).
Ein Anfänger ist davon jedoch schnell überfordert und froh, wenn er eine setter-Methode hat, die ihm (für's Erste) das Denken abnimmt...

nur meine 50ct...

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 18:22
von meego
Dann zitier ich ihn mal auf die Frage hin: "By default in python it seems that you can add fields to an existing class and alter the value of an objects fields directly without method calls. [...] Is there a way to protect fields and classes so that they cannot be externally altered?"

"Python classes do not provide any real protection here. As you've pointed out, you can access fields directly from outside the class. In my opinion, this is bad. In many Python programmers' opinions, this is great. It depends, I suppose on what you are hoping to achieve with a class.

My strong recommendation is "don't do this". Certainly for this class (especially if you are a beginner) you should not access fields directly like this. Only access fields through class methods. This allows you to achieve isolation and encapsulation and leads to more robust programs.

The Pythonic way of "hiding" fields is to prefix them with "_" or "__". When you use "_", such as "self._hidden", you are giving a hint to anyone reading the code that they should never access that field directly. It doesn't actually prevent such access. When you use "__", such as "self.__hidden", Python actually changes (or mangles) the variable name. The mangling, however, is predictable, so it still doesn't prevent external access."

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 19:56
von /me
meego hat geschrieben:Dann zitier ich ihn mal auf die Frage hin: "[...]

My strong recommendation is "don't do this". Certainly for this class (especially if you are a beginner) you should not access fields directly like this. Only access fields through class methods. This allows you to achieve isolation and encapsulation and leads to more robust programs."
Wenn man eine Bondage&Discipline-Sprache haben möchte, dann kann man Java nehmen. Python gibt einem viel Freiheit und damit viel Flexibilität.

In Python gewinnt man nichts dadurch, dass man den Zugriff auf Instanzattribute nur über Getter und Setter zulässt. Der typische angesprochene Anwendungsfall bezieht sich darauf, dass es ja irgendwann sein kann, dass man beim Zugriff auf das Attribut noch zusätzliche Berechnungen durchführen möchte. In Java wäre das tatsächlich ein Problem, da bei der Umstellung von einem direkten Zugriff auf den Zugriff mit Getter/Setter die Kompatibilität der Klasse dahin ist. In Python ist das nicht so. Dort kann man problemlos später auf Properties umstellen ohne dass sich irgendetwas für den zugreifenden Code ändert.

Python erlaubt einem unglaublich viel. Man sollte nur den Satz aus Spider-Man beachten: "With great power comes great responsibility".

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 20:34
von meego
Dann hat sein Stabilitätsargument schon etwas.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 22:12
von Sirius3
mal ganz sachlich betrachtet: was gewinne ich, wenn ich auf Attribute mit einem Getter zugreife?
- z.B: »game.get_level()«, heißt soviel wie, oh dafür gibt es eine Funktion, also darf ich das Attribut auch lesen.
Das sagt mir aber noch nicht, dass das für meinen Anwendungsfall auch sinnvoll ist. Genauso gut könnte ich auch direkt »game.level« schreiben und in die Klassendokumentation schreiben, dass »level« ein öffentliches Attribut ist und dies und das bedeutet.
Was kann ich falsch machen? Ich kann mich verschreiben, was in beiden Fällen zu einem AttributeError führt.
Fazit: ein Getter bietet mir keinen Vorteil, es führt nur zu umständlicherem, komplexerem und langsamerem Code.

Nun zu den Settern: »game.set_level(3)«. Wenn es diese Methode nicht gibt, heißt das soviel wie, das Attribut ist von außen read-only. Aber das kann ich genauso gut erreichen, wenn ich in die Dokumentation hinter »level« „read-only“ schreibe. Wenn sich dann jemand nicht daran hält, wird er schon genau wissen, was er tut, oder eben nicht, dann ist ihm aber auch nicht mehr zu helfen.
Wenn ich mich beim Setzen verschreibe kann das zu schwer auffindbaren Fehlern führen, weil das Problem nicht sofort gemeldet wird. Ein falsch geschriebener Setter meldet sich sofort mit einem AttributeError. Andererseits sollten Programmteile sowieso nicht so komplex und nicht getestet sein, dass sich ein solcher Fehler lange verstecken kann.
Fazit: auch Setter haben nicht wirklich einen Vorteil.

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 22:23
von Leonidas
meego hat geschrieben:Dann hat sein Stabilitätsargument schon etwas.
Das wurde doch eben von /me widerlegt…

Was wir brauchen sind Getter für Setter! Denn Getter sind ja auch nur Attribute, auf die kann man ja auch zugreifen oder sie *gasp* editieren. Da würde ich empfehlen auf Nummer sicher zu gehen und für die Setter auch Getter schreiben, ``class.get_setter('level').set(42)``. Ohnein, jetzt ist der ``get_setter`` auch ein öffentliches Attribut das man ebenfalls editieren kann, und dann gehen alle Setter kaputt! Wir brauchen einen ``class.get_setter_getter().get_setter('level').set(42)``. Verdammt, nun wiederholt sich das Problem. Vielleicht eine ``GetSetterFactory`` probieren? Wir könnten die Getter und Setter aber auch aus dem Quellcode rausnehmen und in einer XML-Datei konfigurieren. ;)

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 23:07
von Sirius3
Ein bißchen off-topic, aber zum Kapseln ganz wichtig:

Code: Alles auswählen

import inspect

def protected(func):
    def check(self, *args,**kw):
        caller=inspect.stack()[1][0]
        caller_cls=type(caller.f_locals.get('self'))
        assert caller_cls in self._FRIENDS, "protected method call"
        return func(self, *args,**kw)
    return check

class MyFriend(object):
    def __init__(self, obj):
        print obj.get_value()

class ILikeCpp(object):
    _FRIENDS = [MyFriend]
    
    def __init__(self, value):
        self.__value = value # double __ for extra security
    
    @protected
    def get_value(self):
        return self.__value
    
if __name__ == '__main__':
    obj = ILikeCpp(23)
    MyFriend(obj)
    print obj.get_value()  # not allowed

Re: Anfängerkurs in Python bei Coursera

Verfasst: Montag 3. Juni 2013, 23:30
von /me
meego hat geschrieben:Dann hat sein Stabilitätsargument schon etwas.
Nicht im Kontext von Python.