string zu no string konvertieren ?

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.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

hallo,
kenn mich noch nicht so aus mit python.
aber ich suche nach einer möglichkeit einen string, welcher nur einem namen einer variablen besteht, zu keinem string zu konvertieren.


also mein problem sieht zurzeit etwa so aus:

s1 = ['black', (122,12), 's1']
aVar = 's1[0]'

und ich möchte gern das bVar nur aus der variablen s1 besteht:

bVar = s1[0] --> 'black'


gibt es eine möglichkeit das zu erreichen?
irgendwie hab ich das gefühl etwas grundlegendes übersehen zu haben.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Und jetzt noch mal auf Deutsch, und deutlich. So wird dir wohl niemand helfen können...

Wobei das was du suchst nach eval aussieht und evil ist.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Also, erstmal danke für die schnelle Antwort. eval ist genau die Funktion die ich gesucht hab.

Aber inwiefern bzw. warum ist es schlecht diese zu verwenden?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Weil sie Strings als Python-Code interpretiert. Wenn du keine Kontrolle über die Generierung der Strings hast ist das eine ganz schlechte Idee.

Ausserdem sieht das ganze für mich nach ganz schlechtem Stil aus und wenn das echter Code ist, solltest du auch mal über die Namensbennenung nachdenken ;)

Wenn du mal erklärst was genau du machen willst, kann man dir evtl zu einem besserem Ansatz verhelfen.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Gibt einiges an Artikeln/Posts dazu. Den da zum Beispiel:
http://www.bel.fi/~alankila/blog/2005/0 ... rmful.html

Praktisch ist eval meistens unnötig, gefährlich, schwer zu debuggen und lesen, langsam, und uncool. :wink:
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

veers hat geschrieben:Praktisch ist eval meistens unnötig, gefährlich, schwer zu debuggen und lesen, langsam, und uncool. :wink:
Vorallem uncool, da man das über einen Dict-Zugriff oft auch machen kann.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

cofi hat geschrieben:Wenn du mal erklärst was genau du machen willst, kann man dir evtl zu einem besserem Ansatz verhelfen.

Glaub nicht das du dir das antun willst, bin, wie bereits erwähnt, ein grausamer Anfänger.

Es handelt sich um einen 'aufgeklappten' Rubik Cube:

...................................y1 y2 y3
...................................y4 y5 y6
...................................y7 y8 y9
......w1 w2 w3 b1 b2 b3 s1 s2 s3 g1 g2 g3
......w4 w5 w6 b4 b5 b6 s4 s5 s6 g4 g5 g6
......w7 w8 w9 b7 b8 b9 s7 s8 s9 g7 g8 g9
...................................r1 r2 r3
...................................r4 r5 r6
...................................r7 r8 r9


Code wäre dieser:
http://paste.pocoo.org/show/89997/


Zum bedienen wichtig:

Indem man in das Entry-feld die Buchstaben "l r f b u d" eingibt kann man den Cube verdrehen.
Nachdem man eine Farbe ausgewählt hat, kann man durch einen Klicken auf ein beliebiges Feld dessen Farbe ändern.


Bei mir klappt das alles soweit ganz gut. Jetzt wollte ich gerade anfangen dem Programm die Möglichkeit zu geben den Cube auch zu lösen.


Hierzu hab ich die Funktion searchKanten() in Zeile 364 hinzugefügt.

searchKanten() soll durch den Aufruf mit zwei Farben als Parameter deren Position zurückgeben.

Beispiel:
searchKanten('green','red')

-- > findKante = ('g8','r6')

Um dies zu erreichen muss ich im jetztigem Code eval benutzen.
BlackJack

Um $GOTTES Willen! Als erstes bitte vergessen, dass es ``global`` gibt. Und dann "durchnummerierte" Variablennamen. Wenn Du anfängst an Namen laufende Nummern zu hängen, dann willst Du eigentlich eine Liste haben.

Und entweder machst Du aus den Buchstaben für die Seiten auch Nummern, also Indexe in eine Liste, oder Du packst das in ein Dictionary. Also das der Zugriff zum Beispiel auf "Mitte Gelb" nicht so aussieht ``print y5``, sondern so ``print cube['y'][5]`` oder ``print cube[('y', 5)]``. Noch besser wäre es den einzelnen Seiten auch zwei Koordinaten für jede Fläche zu geben, dann kann man alle Drehungen mittels Schleifen und wesentlich weniger Tipparbeit bzw. Programmieren mittels Kopieren und Einfügen machen.

Dann schau Dir mal PEP 8, den Python Style Guide bezüglich der Namensgebung an. So etwas wie "ungarische Notation" ist in Python unüblich und einem Namen ein 'o' voran zu stellen ist gleich mal total überflüssig, weil in Python *alles* was man an einen Namen binden kann, ein Objekt ist. Der Informationsgehalt von dem Präfix ist also gleich Null. Diese 'o's sind ein notwendiges Übel bei Basic-Dialekten, weil da Gross und Kleinschreibung bei Bezeichnern nicht unterschieden wird, und man nicht ``foo = new Foo()`` schreiben kann und die Leute deshalb ``oFoo = new Foo()`` als Konvention erfunden haben um das Problem zu umgehen. Aber bei Python ist das nicht nötig.

Ein ``else``-Zweig der nur ``pass`` enthält ist überflüssig -- weg damit.

In Listen sollte man nicht Objekte mit verschiedener Bedeutung mischen. Das packt man entweder in Tupel oder in Objekte und gibt den einzelnen Elementen Namen.

Last but not least: "schwarz" heisst auf Englisch "black" und man sollte die Logik und die GUI nicht vermischen.
lunar

"farbBestimmungsRootFarbenVar" ist einfach nur göttlich ;) Der coolste Name, der mir je untergekommen ist ...
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

BlackJack hat geschrieben: Und dann "durchnummerierte" Variablennamen. Wenn Du anfängst an Namen laufende Nummern zu hängen, dann willst Du eigentlich eine Liste haben.

Und entweder machst Du aus den Buchstaben für die Seiten auch Nummern, also Indexe in eine Liste, oder Du packst das in ein Dictionary. Also das der Zugriff zum Beispiel auf "Mitte Gelb" nicht so aussieht ``print y5``, sondern so ``print cube['y'][5]`` oder ``print cube[('y', 5)]``. Noch besser wäre es den einzelnen Seiten auch zwei Koordinaten für jede Fläche zu geben, dann kann man alle Drehungen mittels Schleifen und wesentlich weniger Tipparbeit bzw. Programmieren mittels Kopieren und Einfügen machen.
So das ging jetzt zu schnell :?
Haette jetzt an etwa so eine Liste gedacht:

Code: Alles auswählen

cube = [
    ['s',['schwarz',(325,80)],['schwarz',(345,80)],['schwarz',(365,80)],['schwarz',(325,100)],
     ['schwarz',(345,100)],['schwarz',(365,100)],['schwarz',(325,120)],['schwarz',(345,120)],['schwarz',(365,120)]
     ],
    ['g',['green',(385,80)],['green',(405,80)],['green',(425,80)],['green',(385,100)],
     ['green',(405,100)],['green',(425,100)],['green',(385,120)],['green',(405,120)],['green',(425,120)]
     ],
    ['w',['white',(205,80)],['white',(225,80)],['white',(245,80)],['white',(205,100)],
     ['white',(225,100)],['white',(245,100)],['white',(205,120)],['white',(225,120)],['white',(245,120)]
     ],
    ['b',['blue',(265,80)],['blue',(285,80)],['blue',(305,80)],['blue',(265,100)],
     ['blue',(285,100)],['blue',(305,100)],['blue',(265,120)],['blue',(285,120)],['blue',(305,120)]
     ],
    ['y',['yellow',(325,20)],['yellow',(345,20)],['yellow',(365,20)],['yellow',(325,40)],
     ['yellow',(345,40)],['yellow',(365,40)],['yellow',(325,60)],['yellow',(345,60)],['yellow',(365,60)]
     ],
    ['r',['red',(325,140)],['red',(345,140)],['red',(365,140)],['red',(325,160)],
     ['red',(345,160)],['red',(365,160)],['red',(325,180)],['red',(345,180)],['red',(365,180)]
     ]
	]
allerdings traegt diese sicherlich nichts zur lesbarkeit des Programmen bei.
Ganz im Gegenteil. Was spricht dagegen viele Variablen zu benuetzen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

smashed to pieces hat geschrieben:allerdings traegt diese sicherlich nichts zur lesbarkeit des Programmen bei.
Wenn Listenkonstruktionen unübersichtlich werden, sind Objekte oftmals hinfreich.
smashed to pieces hat geschrieben:Was spricht dagegen viele Variablen zu benuetzen?
Listen kannst du durch Zähler hochzählen und adressieren, nummerierte Variablen nicht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Leonidas hat geschrieben:
smashed to pieces hat geschrieben:allerdings traegt diese sicherlich nichts zur lesbarkeit des Programmen bei.
Wenn Listenkonstruktionen unübersichtlich werden, sind Objekte oftmals hinfreich.
smashed to pieces hat geschrieben:Was spricht dagegen viele Variablen zu benuetzen?
Listen kannst du durch Zähler hochzählen und adressieren, nummerierte Variablen nicht.
Ach was, das geht mit Variablen und eval doch viel besser und leserlicher!

Code: Alles auswählen

In [1]: x1, x2, x3 = range(3)
In [2]: x =  lambda n: eval("x" + str(n))
In [3]: def all_x():
    for i in xrange(1, 2**30):
        try:
            yield x(i)
        except NameError:
            break
In [4]: sum(all_x())
Out[4]: 3
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
lunar

Eine alternative Implementierung führt über "globals()" und String-Formatting für die Index-Zugriffe ;)

smashed to pieces, bitte nicht die Ironie in diesen Postings übersehen.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Code: Alles auswählen

In [10]: x1, x2, x3 = (15,20,25)

In [12]: for i in range(1, 4):
   ....:     locals()["x%s" % i]
   ....:
   ....:
Out[12]: 15
Out[12]: 20
Out[12]: 25
^__^
BlackJack

@smashed to pieces: Ich denke wenn Du die Liste so in den Quelltext schreibst hast Du in Punkto Übersichtlichkeit nichts gewonnen, das ist genau so unübersichtlich wie Deine ganzen nummerierten Namen.

Nur wenn Du statt durch nummerierter Namen, echte Datenstrukturen verwendest, kannst Du die auch ohne so viel Tipparbeit *programmatisch* erstellen und manipulieren. Als Programmierer solltest Du immer bestrebt sein Wiederholungen im Quelltext zu eliminieren und Werte zu berechnen, statt sie hart in den Quelltext zu tippen. Das macht die Programme kürzer und flexibler. Beispiel:

Code: Alles auswählen

from pprint import pprint


def create_side(width, color):
    return [[color] * width for dummy in xrange(width)]


def create_cube(width, colors):
    sides = ['front', 'top', 'left',  'right', 'bottom', 'back']
    return dict((side, create_side(width, color))
                for side, color in zip(sides, colors))


def main():
    width = 3
    colors = ['black', 'yellow', 'blue', 'green', 'red', 'white']
    cube = create_cube(width, colors)
    pprint(cube)
Ausgabe:

Code: Alles auswählen

{'back': [['white', 'white', 'white'],
          ['white', 'white', 'white'],
          ['white', 'white', 'white']],
 'bottom': [['red', 'red', 'red'],
            ['red', 'red', 'red'],
            ['red', 'red', 'red']],
 'front': [['black', 'black', 'black'],
           ['black', 'black', 'black'],
           ['black', 'black', 'black']],
 'left': [['blue', 'blue', 'blue'],
          ['blue', 'blue', 'blue'],
          ['blue', 'blue', 'blue']],
 'right': [['green', 'green', 'green'],
           ['green', 'green', 'green'],
           ['green', 'green', 'green']],
 'top': [['yellow', 'yellow', 'yellow'],
         ['yellow', 'yellow', 'yellow'],
         ['yellow', 'yellow', 'yellow']]}
Die Koordinaten haben in der Datenstruktur IMHO nichts zu suchen, die gehören zur Darstellung.

Als nächstes würde man jetzt Funktionen schreiben, die eine Seite links bzw. rechts rotieren, einzelne Zeilen und Spalten abfragen und setzen, und darauf aufbauend dann Funktionen zum Rotieren des Würfels.

Das ist in dem Dictionary auch nicht so optimal, da sollte man dann, wie von Leonidas vorgeschlagen das ganze in Klassen kapseln. Zum Beispiel eine die eine Seite repräsentiert und eine für den Würfel, der aus sechs solcher Seiten besteht.
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Aja ok. Hab noch nie Klassen verwendet, also bin ich mir jetzt ziemlich unsicher.
Hab mir jetzt vergestellt, dass ich 4 Klassen definiere eine zum erstellen des Cubes, eine zum Verdrehen, eine zum Loesen und schlussendlich eine zum Abbilden. Sollte man das so aufteilen. Oder verwendet man normalerweise mehr Klassen?
Das Graphisch ist eine eigene Klasse, somit auch vom rechnerischem getrennt:

http://paste.pocoo.org/show/90474/

Code: Alles auswählen

    def root_building(self):
        self.root = Tk()
        self.canvas = Canvas(self.root, width=650, height=220, bg='grey')
        self.canvas.place(x=30,y=30)

    def build_field(self, color, position):
        self.canvas.create_rectangle(position[0],position[1],position[2],position[3],fill=color)#,outline=color)
    
    def placing_fields(self):
        self.build_field('red', (325,20,345,40))##versuch
Allerdings komm ich mit Klassen noch nicht ganz so zurecht. Wie kann ich in der Funktion build_field jetzt auf canvas zugreifen, welches in einer anderen Funktion definiert ist?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

In dem Code sind ein paar grausame Dinger.
Klassen sind dazu da um Objekte logisch abzubilden.
Im Klartext heisst das hier: Du hast eine Klasse Würfel und der Würfel hat die Methoden die du - warum auch immer - in andere Klassen packst.

Les am besten mal die Seiten im Tutorial zur OOP.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Kleine Faustregel: Alle Methoden, in dessen Rumpf du das `self`-Objekt nicht verwendest, kannst du in Funktionen umwandeln.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

smashed to pieces hat geschrieben:Hab mir jetzt vergestellt, dass ich 4 Klassen definiere eine zum erstellen des Cubes, eine zum Verdrehen, eine zum Loesen und schlussendlich eine zum Abbilden. Sollte man das so aufteilen. Oder verwendet man normalerweise mehr Klassen?
Nein, für sowas verwendet man 0 Klassen. Klassen repräsentieren Dinge, deine Klassen sind Aktionen. Dafür gibt es andere Strukturen, man nennt die Teile die etwas machen "Funktionen".
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
smashed to pieces
User
Beiträge: 38
Registriert: Samstag 24. November 2007, 16:50

Ok, das heisst ich brauche nur 2 Klassen. Eine fuer den Cube und eine fuer das Graphische, ja? :? .
Ist es auch ok wenn ich die erste 'Cube_building' und die zweite 'Presentating' nenne oder sind Unterstriche in Klassennamen schlecht?

Weiters:
wie schafft man es in einer for-Schleife, das iVar den Wert von iWert annimmt und gleichzeitig auch oVar den Wert von oWert?
Hab schon solche Sachen ausprobiert:

Code: Alles auswählen

for iVar, oVar in iWert, oWert:
    ...
oder
for iVar and oVar in iWert and oWert:
    ...
Hab auch mit Klammern rumprobiert. Aber ja, hoffe ihr versteht wenigstens was ich meine :/ .
Antworten