Seite 1 von 2
Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 10:39
von MikeOrMichael
Hey Leute,
zuerst: danke, dass ihr das Thema angeklickt habt, und ich hoffe, ihr könnt helfen. Ich weiß, dass ihr noch am Anfang der Python-Programmation stehe, also wundert euch nicht, dass der Code recht dilletanisch geschrieben ist. Mein Problem ist folgendes: ich will eine Matrix mit Binärwerten in Pixel in Turtle umwandeln (1 -> schwarz ; 0 -> weiß), wobei jedoch die Form der Matrix erhalten bleiben soll (d.h. eine 2x4 Matrix soll bei den Koordinaten (x/y) entstehen: die Werte der Matrix werden dann je nach ihrem Wert in Pixel umgewandelt). Bsp:
0 1 0 1 -> w. s. w. s.
1 0 1 0 s. w. s. w.
Ich habe auch schon passende Funktionen:
Code: Alles auswählen
from turtle import *
def white(x, y):
speed('fastest')
up()
goto (x, y)
down()
color("white")
fillcolor("white")
i = 0
begin_fill()
while i < 4:
forward(10)
right(90)
i = i + 1
end_fill()
def black(x, y):
speed('fastest')
up()
goto (x, y)
down()
color("black")
fillcolor("black")
i = 0
begin_fill()
while i < 4:
forward(8)
right(90)
i = i + 1
end_fill()
Das Problem ist nun die Funktion, die alle Werte einer Matrix in Pixel umwandeln soll: diese ist wiefolgt:
Code: Alles auswählen
def pixel(mat, x, y):
for int in mat:
for yy in range(len(mat)): # Geht Reihe nach Reihe vor. yy = Reihe des Binärwerts i. Matirx / xx = Kolonne des Binärwerts i. Matrix
if int == 0 in mat[yy]:
xx = mat[yy].index(int)
white((x - xx)*8, (y - yy)*8) # Man subtrahiert um die relative Position des Pixels zur (x/y) Anfangsposition zu erhalten. *8 da in white/black "forward(8)"
elif int == 1 in mat[yy]:
xx = mat[yy].index(int)
black((x - xx)*8, (y - yy)*8)
else:
pass
Das x-xx scheint verwirrend, doch wenn man zum Beispiel wieder eine 2x4 Matrix hat und zu den Koordinaten (10/10) geht, dann weiß man sich der letzte Wert
der Matrix an [1][3] sich an (10-3 = 7/10-1 = 9) befindet.
Das Problem ist, wenn ich die Funktion ausführen will, passiert nichts. Nichtmal das Turtle-Modul öffnet sich. Ich habe es probiert und beide Funktionen black und white funktionieren.
Wäre nett, wenn ihr euch die Zeit nehmen könnt, kurz reinzuschauen, zu korrigieren, zu verbessern, Bei meinem letzten Post hat das auch sehr geholfen, und ich möchte allen danken, die mir das letzte Mal dabei geholfen haben, und mich entschuldigen, dass ich vergessen habe, die Lösung zu posten. ja, ich bin ziemlich verplant

.
MfG, Michael
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 11:15
von Hyperion
Mir ist leider überhaupt nicht klar, was Du machen willst. Vielleicht liegt es daran, dass ich von ``turtle`` keine Ahnung habe? Was ist denn bei Dir eine "Matrix"? Wie sieht die als Datentyp aus? Und was ist dann ein "Pixel"? Wieso muss da etwas umgewandelt werden?
Diese Informationen und Zusammenhänge fehlen mir.
Zu Deinen ersten beiden Funktionen kann ich jedoch sagen: Das ist pure Copy&Paste-Programmierung! (Was ist "Programmation" btw?

) Schau Dir doch mal beide Funktionen an und frage Dich, worin die sich eigentlich unterscheiden?
Ich würde das spontan und ungetestet so umschreiben:
Code: Alles auswählen
def _paint(x, y, color):
speed('fastest')
up()
goto (x, y)
down()
# hier sind die beiden einzigen Unterschiede!
color(color)
fillcolor(color)
i = 0
begin_fill()
while i < 4:
forward(10)
right(90)
i = i + 1
end_fill()
def paint_black(x, y):
_paint(x, y, "black")
def paint_white(x, y):
_paint(x, y, "white")
In nehme mal an, dass die Zahl bei ``foward`` ein Typo ist? Oder soll da wirklich einmal 8 und einmal 10 stehen? Wenn ja, muss man das eben als zusätzlichen Parameter an ``_paint`` übergeben, wenn nein, siehst Du einen der Nachteile Deiner Vorgehensweise
Die Schleife sieht bei Dir schematisch so aus:
Das kann man viel eleganter so lösen:
Damit sparst Du Dir die Laufvarable ``i``, deren Initialisierung und das manuelle Inkrementieren im Schleifenrumpf.
Grundsätzlich kannst Du Dir merken, dass man für alle Schleifen, bei denen man die Anzahl der Durchläufe im voraus kennt, immer ``for`` benutzen sollte.
Bitte beachte darüber hinaus PEP8 und verwende vier Leerzeichen für die Einrückung. Du verwendest vermutlich Tabs, die hier im Forum dann in 8 Leerzeichen resultieren.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 11:21
von EyDu
Hallo.
Ohne mir den Code jetzt im Detail angeschaut zu haben, würe ich zwei mögliche Fehlerquellen Vermuten: black/white arbeiten nicht richtig oder du rufst die pixel-Funktion falsch auf. Die beiden erstgenannten Funktionen solltest du direkt testen und prüfen, ob die Ergebnisse den Erwartungen entsprechen. Erst dann lohnt es sich über die pixel-Funktion nachzudenken. Bei letzterer wäre es interessant, wie genau du sie aufrufst. Dazu könntest du den gesamten Code
hier posten und verlinken, dann kann man sich ein besseres Bild von deinem Programm machen. Hilfreich sind auch immer ein paar print-Anweisungen um zu testen, ob eine bestimmte Funktion überhaupt erreicht wird.
An deinem Code selbst gibt es noch sehr viel zu verbessern, da fehlt mir aber gerade ein wenig die Zeit zu. Es wird sich aber sicher jemand anderes finden (oder bereits gefunden haben, wie ich sehe).
Sebastian
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 12:20
von snafu
Hyperion hat geschrieben:Grundsätzlich kannst Du Dir merken, dass man für alle Schleifen, bei denen man die Anzahl der Durchläufe im voraus kennt, immer ``for`` benutzen sollte.
IMHO eine sehr ungewöhnliche Definition. Es gibt sooo viele Fälle, wo man die Anzahl der Durchläufe nicht kennt und trotzdem `for` benutzt...
`while` kommt halt immer dann ins Spiel, wenn es keinen Sinn macht, über die Elemente eines Iterables zu gehen. Das ist das einzige, was mir als Faustregel dazu einfällt. Alles weitere ist situationsabhängig.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 12:50
von BlackJack
@snafu: Ich verstehe Deinen Einwand nicht? So kenne ich das auch. Wenn man vor Schleifenbeginn weiss oder bestimmen kann wie viele Durchläufe die Schleife haben wird, verwendet man ``for`` und nicht ``while``.
Du scheinst daraus den Umkehrschluss ziehen zu wollen, was natürlich Unsinn ist. Wenn man nicht weiss wie viele Durchläufe es geben wird, folgt aus der Aussage ja nicht, dass man dafür kein ``for`` verwenden soll. Das hat aber auch niemand behauptet.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 12:58
von snafu
Mir war tatsächlich nicht klar, dass sich die Aussage wohl mehr oder weniger auf das `for _ in xrange(4)`-Konstrukt bezogen hat. Missverständnis meinerseits. Sorry.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Mittwoch 11. April 2012, 13:10
von Hyperion
snafu hat geschrieben:Mir war tatsächlich nicht klar, dass sich die Aussage wohl mehr oder weniger auf das `for _ in xrange(4)`-Konstrukt bezogen hat. Missverständnis meinerseits. Sorry.
Nein. Die Aussage steht so, wie sie ist und BlackJack es ebenfalls noch einmal formuliert hat! Das hat nichts mit diesem Spezialfall oben zu tun. Du machst - vermutlich - immer noch den Fehler aus "b" auf "a" schließen zu wollen... ich habe ja nie gesagt, dass man in anderen Fällen kein ``for`` benutzen sollte! Das wäre ja eben falsch.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Donnerstag 12. April 2012, 19:58
von MikeOrMichael
Zur Verständlichkeit des Themas kommt hier ein von mir meisterhaft gezeichnetes Schema(keine Ahnung wieso der Titel so ist, hab den Anfangstitel des Whitescreens genommen):
Die Umrandungen sollen später nicht da sein.
Die Funktion geht Reihe nach Reihe vor (Reihe = yy), überprüft den Wert der Zahl und ordnet ihr eine Farbe zu.
@Hyperion: Danke, werde ich in Betracht ziehen. Btw, stimmt, typo

.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Freitag 13. April 2012, 04:45
von Leonidas
MikeOrMichael hat geschrieben:
Lädt bei mir nicht.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Freitag 13. April 2012, 07:13
von BlackJack
Bei mir auch nicht — da war ein Schrägstrich zu viel am Ende der URL. Das hier sollte gehen:

Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Freitag 13. April 2012, 12:26
von Hyperion
Ok, nur wird mir aus dem Bild immer noch nicht klar, wieso man da irgend etwas mit Pixeln und "komplizierten" Rechungen macht.
Man bräuchte doch nur die "Matrix" durchgehen und eben für jeden schwarzen Eintrag die `paint_black` und für jeden weißen die `paint_white` Funktion aufrufen :K
Das würde mit meinem Vorschlag dann trivialer Weise so aussehen:
Code: Alles auswählen
paint_mapping = {0: paint_black, 1: paint_white}
for x, row in enumerate(matrix):
for y, color in enumerate(row):
paint_mapping[color](x, y)
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Freitag 13. April 2012, 21:09
von MikeOrMichael
@BlackJack: Danke dir

.
Ich habe die Funktion jetzt so geschrieben nach Hyperions Methode:
Code: Alles auswählen
def px(matrix, x, y):
paint_mapping = {0: paint_black, 1: paint_white}
for x, row in enumerate(matrix):
for y, color in enumerate(row):
paint_mapping[color](x, y)
Leider steht das hier:
Code: Alles auswählen
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
px(mat, 10, 10)
File "<pyshell#35>", line 5, in px
paint_mapping[color](x, y)
File "<pyshell#27>", line 2, in paint_white
_paint(x, y, "white")
File "<pyshell#24>", line 6, in _paint
color(color)
TypeError: 'str' object is not callable
Kann mir jemand die Funktion ganz kurz erklären und warum sie nicht funktioniert ? Ich wäre sehr dankbar.
Wo ich zum ersten nicht verstehe, warum color am Ende der FUnktion wiederholt wird.
Außerdem ist mir gerade aufgefallen, dass die Farben verwechselt wurden

.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 00:50
von derdon
Kann es sein, dass paint_black und paint_white bei dir keine Funktionen, sondern strings sind? Warum?
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 04:56
von BlackJack
@derdon: Nein, das Problem liegt in der `_paint()`-Funktion von Hyperion. Es kann halt immer nur ein Wert zur gleichen Zeit an einen Namen gebunden sein und der Aufruf ``color(color)``, der versucht die Funktion `color()` mit der Zeichenkette `color` als Argument aufzurufen geht natürlich nicht weil `color` nur an *ein* Objekt gebunden werden kann — in diesem Fall ist es die Zeichenkette 'black' oder 'white'.

Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 07:41
von Hyperion
Ooops... ja, das kommt davon, wenn man Code nicht selber testet
Na gut, dann ändert man eben den Namen des Parameters von `color` in `colorname` o.ä.. Dann klappt's auch mit dem Aufruf von `color()`

Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 10:47
von EyDu
Hyperion hat geschrieben:Na gut, dann ändert man eben den Namen des Parameters von `color` in `colorname` o.ä.. Dann klappt's auch mit dem Aufruf von `color()`

Oder noch besser: man lässt die *-Importe sein.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 11:38
von MikeOrMichael
@Hyperion: Okay

.
Ich habe das jetzt so umgeschrieben:
Code: Alles auswählen
def _paint(x, y, bcolor):
speed('fastest')
up()
goto (x, y)
down()
color(bcolor)
fillcolor(bcolor)
i = 0
begin_fill()
while i < 4:
forward(10)
right(90)
i = i + 1
end_fill()
def px(matrix, x, y):
paint_mapping = {0: paint_black, 1: paint_white}
for x, row in enumerate(matrix):
for y, bcolor in enumerate(row):
paint_mapping[bcolor](x, y)
Er malt mir dann genau ein schwarzes Viereck, dann läuft da nix mehr und es hängt.
Außerdem erkennt er mir nicht xrange, was ich doch schon sehr komisch finde. Range() erkennt er tadellos.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 12:22
von Hyperion
Dann verwendest Du vermutlich Python 3.x. Dort wurde aus `xrange` einfach `range`.
Wieso er hängt kann ich nicht sagen. Lass Dir halt mal die Werte der Schleifendurchläufe ausgeben. Dann siehst Du ja, ob er alles druchläuft, wie er soll. Wenn ja, dann liegt es an etwas anderem. Ich vermute mal, dass Du bei den Koordinaten noch einen Offset addieren / multiplizieren musst? Schließlich gehe ich ja nur Indexe durch... die laufen also von 0 bis 4 o.ä. `forward(10)` und `right(90)` hantieren da ja mit recht großen Zahlen. Wenn analog zu x und y die selbe Auflösung haben, ist ja klar, dass Du nicht viel siehst...
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 20:28
von MikeOrMichael
@Hyperion: Könntest du mir ganz kurz die beiden for- Schleifen und die enumerate-Funktion erklären ? Ich verstehe zum Bsp. nicht, warum x,row im selben Loop sind, da x,y die Koordinaten sind und row halt die Reihe ist.
Muss nicht lang sein, ich will halt nur verstehen, um zu lernen

.
Re: Turtle: Binärwerte in Matrizen in Pixel umwandeln
Verfasst: Samstag 14. April 2012, 20:53
von BlackJack
@MikeOrMichael: `enumerate()` liefert Tupel mit einer laufenden Nummer als erstes Element und dem dazugehörigen Element aus dem übergebenen iterierbaren Objekt. Die Matrix besteht aus Zeilen und die Zeilen aus den einzelnen Spaltenwerten in der Zeile. Traditionell hätte zu den Zeilen eher die `y`-Koordinate gehört, aber das bewirkt ja erst einmal nur, dass die Matrix 90° gedreht gezeichnet wird. Probier doch einfach in einer Python-Shell mal aus was die Funktion so macht:
Code: Alles auswählen
In [214]: matrix = [[1, 0, 1, 0], [1, 0, 0, 1]]
In [216]: for item in enumerate(matrix):
.....: print item
.....:
(0, [1, 0, 1, 0])
(1, [1, 0, 0, 1])
In [217]: for y, row in enumerate(matrix):
.....: for x, cell in enumerate(row):
.....: print x, y, cell
.....:
0 0 1
1 0 0
2 0 1
3 0 0
0 1 1
1 1 0
2 1 0
3 1 1