Hilfe zu Dictionary

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.
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Mittwoch 23. Januar 2008, 17:06

Moin wie schon in einen anderen Thread gesagt worden ist kann man mit Dictionary den Code kleiner machen

Code: Alles auswählen

if auswahlmenue == home_ordner_einblenden:
   einblenden('''/apps/nautilus/desktop/home_icon_visible''')

if auswahlmenue == home_ordner_ausblenden:
   ausblenden('''/apps/nautilus/desktop/home_icon_visible''')

if auswahlmenue == papierkorb_einblenden:
   einblenden('''/apps/nautilus/desktop/trash_icon_visible''')

if auswahlmenue == papierkorb_ausblenden:
   ausblenden('''/apps/nautilus/desktop/trash_icon_visible''')
So ich beginne erst mit Persönlicher Ordner ein- und ausblenden.

Code: Alles auswählen

home_ordner = {
'''home_ordner_einblenden''' : einblenden('''/apps/nautilus/desktop/home_icon_visible'''),
'''home_ordner_ausblenden''' : ausblenden('''/apps/nautilus/desktop/home_icon_visible''')}
Wenn ich das abspeichere und die Funktion aufrufe so passiert nur das letze.
ZB kann ich den Home Ordner nicht mehr einblenden wenn ich ihn an letzter Stelle einfüge klappt es aber dann kann ich es nicht ausblenden.

Ich kann zwar mehrere Dictionarys für jede Funktion anlegen und das klappt aber das ist wohl nicht der Sinn der Dictionary :wink:

Deswegen wollte ich den Fehler gerne wissen und am besten wie kann ich es ausbessern.
Ich habe nur eine Vermutung dass der gar nicht drauf achtet welcher Code mit was verknüpft ist sondern einfach den letzten nimmt (<-- Ist nur eine Vermutung ;) )

Bin für jede Hilfe dankbar :D
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 23. Januar 2008, 17:17

Hallo Yoschi93!

Ich kenne die Vorgeschichte nicht. Aber wenn du schon diese Struktur hast, dann musst du so weitermachen:

Code: Alles auswählen

home_ordner = {
    'home_ordner_einblenden': (einblenden, '/apps/nautilus/desktop/home_icon_visible'),
    'home_ordner_ausblenden': (ausblenden, '/apps/nautilus/desktop/home_icon_visible'),
}
todo_function, todo_argument = home_ordner['home_ordner_einblenden']
todo_function(todo_argument)
Du darfst nicht sofort alle Funktionen ausführen lassen. Du musst dir die Referenz zur Funktion und deren Parameter vorbereiten und nur dann ausführen lassen, wenn es eine entsprechende Auswahl gibt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Mittwoch 23. Januar 2008, 17:27

Dann ist also die Variante [1] die ich zuerst gemacht habe.
Also besser?
Weil das ist ja nur mehr getippe und einen Vorteil sehe ich darin nicht. (Die Dictioniarys meine ich)

[1]

Code: Alles auswählen

if auswahlmenue == home_ordner_einblenden:
   einblenden('''/apps/nautilus/desktop/home_icon_visible''')

if auswahlmenue == home_ordner_ausblenden:
   ausblenden('''/apps/nautilus/desktop/home_icon_visible''')

if auswahlmenue == papierkorb_einblenden:
   einblenden('''/apps/nautilus/desktop/trash_icon_visible''')

if auswahlmenue == papierkorb_ausblenden:
   ausblenden('''/apps/nautilus/desktop/trash_icon_visible''')
BlackJack

Mittwoch 23. Januar 2008, 17:39

Mehr "getippe" ist nichts schlechtes, wenn man dafür eine flexiblere Lösung erhält.

Letztendlich ist es fast gleich viel Tipparbeit, nur dass man bei einem Dictionary die Struktur als Daten hat, die man einfacher erweitern kann.

Ausserdem kannst Du mal schauen was Deine Funktionen eigentlich machen. Wenn das immer nur Abbildungen von Zeichenkette auf Paare von gconf-Pfad und Wert sind, dann kann man sich Funktionen wie `einblenden()` und `ausblenden()` sparen.
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Mittwoch 23. Januar 2008, 18:19

@BlackJack
Achso diese Vorteile kannte ich nicht :D

Ja meine sind dauernd nur Zeichenkette auf Paare von gconf-Pfad und Wert.
Wie könnte ich also einblenden und ausblenden sparen?

Könnte ich auch machen wenn ich 2 wähle dass er Mülleimer einblendet lässt und
bei 1ausblenden lässt bei 3 Home Ordner einblenden lässt usw statt nur eine Funktion zur Verfügung stellen?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 23. Januar 2008, 19:35

Hallo Yoschi93!

Nimm immer das was dir in der Situation am natürlichsten und einfachsten vorkommt. Und lass dir nicht einreden, dass du bei fünf oder sechs IFs untereinander schon Funktionen oder ein Dictionary brauchst.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 23. Januar 2008, 19:42

gerold hat geschrieben:Und lass dir nicht einreden, dass du bei fünf oder sechs IFs untereinander schon Funktionen oder ein Dictionary brauchst.
Genau. Code-Duplication rules.

Was ich dadurch sagen will: warum nicht eine Lösung verwenden, die universeller ist. if-Abfragen untereinander zu klatschen ist nicht schön, nicht elegant und bietet keinen Lerneffekt. Warum also nicht etwas nehmen, was der Aufgabe eher entspricht?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Mittwoch 23. Januar 2008, 20:09

Nimm immer das was dir in der Situation am natürlichsten und einfachsten vorkommt. Und lass dir nicht einreden, dass du bei fünf oder sechs IFs untereinander schon Funktionen oder ein Dictionary brauchst.
Das mache ich auch und dannach versuche ich schwierigere und bessere Sachen auszuprobieren um mehr zu lernen :wink:
Was ich dadurch sagen will: warum nicht eine Lösung verwenden, die universeller ist. if-Abfragen untereinander zu klatschen ist nicht schön, nicht elegant und bietet keinen Lerneffekt. Warum also nicht etwas nehmen, was der Aufgabe eher entspricht?
Ich nehme erstmal den leichteren Weg und dannach versuche ich das Programm durch bessere Funktion zu ersetzen. Wie zb dieser wo ich jedoch diesmal hilfe brauche :oops:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 23. Januar 2008, 20:51

Ok, der Vorschlag kam ja von mir, daher will ich mich auch mal äußern: Das war nur nen Tipp, damit die Sache übersichtlicher wird. Mehr nicht. Ich hab also nie jemandem etwas eingeredet ;)

Und ich (als Python Laie ;) ) würde es so machen:

Code: Alles auswählen

funktionen = {
1:["Home Ordner einblenden","/apps/nautilus/desktop/home_icon_visible"],
2:[...]
}
Da er im Menü über Nummern geht!
Man muss sich nur etwas für den Fall überlegen, dass nach der Befehlsauswahl noch ne Benutzerabfrage kommt. In dem Fall muss man den Parameterstring ja erst holen. Könnte man ggf. über ein "None" im zweiten Teil der Liste regeln, oder über ein callable?

Auf jeden Fall ist das strukturierter, als einfach ifs untereinander zu knallen. Und es ist fehlerfreier, weil die Darstellung des Menüs nun direkt über das dict erfolgen kann und somit dabei Inkonsistenzen bei einer Erweiterung der Befehlsoptionen rausfallen!

Später wäre es sogar möglich diese in eine config Datei auszulagern! Insofern ist der Weg das über ein dict zu regeln imho nicht verkehrt.

Außerdem funzte das Basis-programm ja schon, Also kann man doch jetzt den Weg gehen, das zu optimieren und eleganter und sicherer zu machen.

Naja, nur so meine Ansicht ;)
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Donnerstag 24. Januar 2008, 18:49

Ok, der Vorschlag kam ja von mir, daher will ich mich auch mal äußern: Das war nur nen Tipp, damit die Sache übersichtlicher wird. Mehr nicht. Ich hab also nie jemandem etwas eingeredet Wink
Das habe ich auch nicht behauptet dass jemand mir was aufzwingt :wink: und ich hoffe das dieser Eindruck nicht enstanden ist.
Außerdem funzte das Basis-programm ja schon, Also kann man doch jetzt den Weg gehen, das zu optimieren und eleganter und sicherer zu machen.
Ganz deiner Meinung :)
Und ich (als Python Laie Wink ) würde es so machen:

Code: Alles auswählen

funktionen = {
1:["Home Ordner einblenden","/apps/nautilus/desktop/home_icon_visible"],
2:[...]
}
Also das klappt nicht.
Habs aber so ausgebessert

Code: Alles auswählen

funktionen = {
1:['''home_ordner_einblenden''',einblenden('''/apps/nautilus/desktop/home_icon_visible''')],
2:['''home_ordner_ausblenden''',ausblenden('''/apps/nautilus/desktop/home_icon_visible''')],
3:['''papierkorb_einblenden''',einblenden('''/apps/nautilus/desktop/trash_icon_visible''')],
4:['''papierkorb_ausblenden''',ausblenden('''/apps/nautilus/desktop/trash_icon_visible''')],
}
Das Problem besteht immernoch dass er nur die letze Funktion nimmt :?
BlackJack

Donnerstag 24. Januar 2008, 19:02

Es wird nicht das letzte "genommen" sondern alle vier werden ausgeführt. In der Liste steht dann als zweites Element das Ergebnis dieses Aufrufs.
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Samstag 15. März 2008, 00:20

BlackJack hat geschrieben:Es wird nicht das letzte "genommen" sondern alle vier werden ausgeführt. In der Liste steht dann als zweites Element das Ergebnis dieses Aufrufs.
Aber wenn er alle ausführt ist es dann doch ohne Sinn ein Dictionary zu machen?
Weil er dann doch alles ein/ausblendet obwohl man nur eins ein/ausblenden will.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Samstag 15. März 2008, 01:45

Code: Alles auswählen

funktionen = {
1:['home_ordner_einblenden',einblenden, '/apps/nautilus/desktop/home_icon_visible' ],
2:['home_ordner_ausblenden',ausblenden, '/apps/nautilus/desktop/home_icon_visible' ],
3:['papierkorb_einblenden' ,einblenden, '/apps/nautilus/desktop/trash_icon_visible'],
4:['papierkorb_ausblenden' ,ausblenden, '/apps/nautilus/desktop/trash_icon_visible'],
}

choices = ""
for c, (desc, function, argument) in funktionen.iteritems():
    choices += "%d -> %s" % (c, desc)
userchoice = int(raw_input('Auswahl treffen: '))

if not userchoice in funktionen:
    print "Falsche Auswahl!"
else:
    (desc, function, argument) = funktionen[userchoice]
    function(argument)
Das sollte so klappen und ist auch ne recht ordentliche Möglichkeit. Schau dir
mal an, was bei deinem Dictionary die Methode `iteritems` macht und was
Referenzen sind.
Noch ein Beispiel zu Referenzen:

Code: Alles auswählen

In [2]: a = ['Nur', 'eine', 'Liste']

In [3]: b = a

In [4]: print b
['Nur', 'eine', 'Liste']

In [5]: a.append('mit einem Element mehr!')

In [6]: print a
['Nur', 'eine', 'Liste', 'mit einem Element mehr!']

In [7]: print b
['Nur', 'eine', 'Liste', 'mit einem Element mehr!']

Code: Alles auswählen

In [1]: def foo():
   ...:     print "Ich bin foo!"
   ...:     
   ...:     

In [2]: foo()
Ich bin foo!

In [3]: bar = foo

In [4]: bar()
Ich bin foo!
Und jetzt lies Doku ;)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Samstag 15. März 2008, 11:33

Wenn es darum geht, die Funktionen bei der Initialisierung des dict nicht auszuführen, halte ich diese Lösung für besser:

Code: Alles auswählen

f = {
  'foo1': lambda: bar('whatever1'),
  'foo2': lambda: baz('whatever2'),
}

f[choice]()
Stefan
Yoschi93
User
Beiträge: 17
Registriert: Sonntag 20. Januar 2008, 13:19

Samstag 15. März 2008, 11:38

Danke jetzt funktioniert es.
Und jetzt lies Doku Wink ;)
Ob dus glaubts oder nicht ich hab mir sogar ein Buch gekauft um Python besser zu lernen ;)
Antworten