ubuntuusers.de

Python: Strings als Spalten ausgeben

Status: Gelöst | Ubuntu-Version: Ubuntu 9.10 (Karmic Koala)
Antworten |

jakon Team-Icon

Lokalisierungsteam

Anmeldungsdatum:
16. November 2009

Beiträge: 419

Hallo!

Ich habe vor in Python eine binäre Uhr zu programmieren, und komm nicht weiter.

Ich habe diese Variablen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    null   = "0\n0\n0\n0"
    eins   = "0\n0\n0\nX"
    zwei   = "0\n0\nX\n0"
    drei   = "0\n0\nX\nX"
    vier   = "0\nX\n0\n0"
    fuenf  = "0\nX\n0\nX"
    sechs  = "0\nX\nX\n0"
    sieben = "0\nX\nX\nX"
    acht   = "X\n0\n0\n0"
    neun   = "X\n0\n0\nX"

Und will jetzt wenn z. B. 21:04:23 ist, das ausgeben:

000000
000X00
X000XX
0X000X

Wie könnte ich das machen? Gibt es ein Modul dass das unterstüzt? Oder müsste man das selber machen? Oder gibts sowas wie "\dn" (für "delete new") oder so?

Ich bin dankbar für jede Antwort die was bringt... ☺

Liebe Grüße, jakon.

Moderiert von cLinx:

Doppelposting gelöscht. Falls Du beim Absenden eines Beitrags eine Fehlermeldung erhältst, prüfe bitte vor dem erneuten Absenden, ob er nicht doch angekommen ist.

Creshal

Avatar von Creshal

Anmeldungsdatum:
24. November 2007

Beiträge: 487

Wohnort: Aachen

Wie wärs mit einer Uhr, die richtige Binärzeit ausgibt, sprich 10101:000100:10111? Das geht afaik mit Bordmitteln.

Ansonsten pack dir die "Ziffern" in ein Array und nimm dir dann immer für jede Zeile den jeweils letzten Buchstaben raus.

diesch Team-Icon

Avatar von diesch

Anmeldungsdatum:
18. Februar 2009

Beiträge: 5072

Wohnort: Brandenburg an der Havel

t='21:04:23'
ziffern=[int(c) for c in t if '0' <= c <='9']

for i in (8,4,2,1):
    for z in ziffern:
        print ('0', 'X')[z & i == i],
    print

jakon Team-Icon

Lokalisierungsteam
(Themenstarter)

Anmeldungsdatum:
16. November 2009

Beiträge: 419

@diesch:

Cool! Danke, es funktioniert. Könntest du noch eine Erklärung dazu schreiben?

dAnjou

Avatar von dAnjou

Anmeldungsdatum:
8. Oktober 2007

Beiträge: 872

Wohnort: Berlin

diesch schrieb:

t='21:04:23'
ziffern=[int(c) for c in t if '0' <= c <='9']

for i in (8,4,2,1):
    for z in ziffern:
        print ('0', 'X')[z & i == i],
    print

WUIII, das so ganz ohne Erklärung hier abzuladen, ist ziemlich gemein 😈

EDIT: OK, ich versuch's mal, obwohl meinem Hirn dieser, ich kann es nicht anders sagen, geile Scheiß niemals entsprungen wäre.

Zeile 2 ist noch relativ einfach: Alles, was in t eine Zahl zwischen 0 und 9 ist, wird als integer-Wert in das Array ziffern gepackt. (Ergebnis kannst du ja mit einem print nachsehen.)

Das Folgende ist ziemlich harter Tobak (zumindest für mich). Zudem kann man es unkommentiert auf die Schnelle kaum nachvollziehen.

Die Schleifen dienen dazu, jede einzelne Zahl in ziffern mit jeder Zahl aus der Menge (8,4,2,1) zu vergleichen. 8, 4, 2 und 1 stellen dabei offensichtlich die Zeilen deiner Binär-Uhr dar. In z & i == i wird z mit i binär ver"und"et und anschließend mit i verglichen. Vereinfacht gesagt, wird hier geprüft, ob z binär gesehen in i enthalten ist. Wenn ja, kommt bei dem Vergleich eine 1 heraus und ein "X" wird ausgegeben.

Die Ver"und"ung geschieht dabei so:

 |8 4 2 1
-+-------
3|0 0 1 1
-+-------
2|0 0 1 0 -> 0 & 0 = 0, 0 & 0 = 0, 1 & 1 = 1, 1 & 0 = 0
  0 0 1 0 -> die 1 sagt, dass die 2 in der 3 enthalten ist
1|0 0 0 1 -> 0 & 0 = 0, 0 & 0 = 0, 0 & 1 = 0, 1 & 1 = 1
  0 0 0 1 -> die 1 sagt, dass die 1 in der 3 enthalten ist

diesch Team-Icon

Avatar von diesch

Anmeldungsdatum:
18. Februar 2009

Beiträge: 5072

Wohnort: Brandenburg an der Havel

dAnjou schrieb:

WUIII, das so ganz ohne Erklärung hier abzuladen, ist ziemlich gemein 😈

Hm, so schwer finde ich den Code gar nicht - die Grundidee ist, in Zeilen statt in Spalten zu denken, dann ist der Rest eigentlich recht naheliegend. Ein bisschen was zum Nachdenken wollte ich dem Fragesteller aber natürlich lassen. ☺

Wirklich gemein wäre sowas wie

print '\n'.join(map(lambda i: ' '.join(('0','X')[int(c)&i==i] for c in t if '0' <= c <='9'), (2**i for i in range(4)[::-1])))

gewesen. Wobei sich auch das sicher noch "optimieren" lässt 😉

EDIT: OK, ich versuch's mal, obwohl meinem Hirn dieser, ich kann es nicht anders sagen, geile Scheiß niemals entsprungen wäre.

Zeile 2 ist noch relativ einfach: Alles, was in t eine Zahl zwischen 0 und 9 ist, wird als integer-Wert in das Array ziffern gepackt. (Ergebnis kannst du ja mit einem print nachsehen.)

Das Folgende ist ziemlich harter Tobak (zumindest für mich). Zudem kann man es unkommentiert auf die Schnelle kaum nachvollziehen.

Du hast das doch sehr gut hinbekommen ☺

Die Schleifen dienen dazu, jede einzelne Zahl in ziffern mit jeder Zahl aus der Menge (8,4,2,1) zu vergleichen. 8, 4, 2 und 1 stellen dabei offensichtlich die Zeilen deiner Binär-Uhr dar. In z & i == i wird z mit i binär ver"und"et und anschließend mit i verglichen. Vereinfacht gesagt, wird hier geprüft, ob z binär gesehen in i enthalten ist.

Da i immer eine Zweierpotenz > 0 ist, ist in i immer genau ein Bit gesetzt, und z & i == i prüft, ob dieses Bit auch in z gesetzt ist.

Wenn ja, kommt bei dem Vergleich eine 1 heraus und ein "X" wird ausgegeben.

Eigentlich kommt bei dem Vergleich dann True heraus, aber als Index auf das Tupel kommt das auf das Gleiche raus.

print ('0', 'X')[z & i == i],

ist also einfach eine kürzere Schreibweise für

if z & i == i:
  print 'X',
else:
  print '0',

Die Ver"und"ung geschieht dabei so:

 |8 4 2 1
-+-------
3|0 0 1 1
-+-------
2|0 0 1 0 -> 0 & 0 = 0, 0 & 0 = 0, 1 & 1 = 1, 1 & 0 = 0
  0 0 1 0 -> die 1 sagt, dass die 2 in der 3 enthalten ist
1|0 0 0 1 -> 0 & 0 = 0, 0 & 0 = 0, 0 & 1 = 0, 1 & 1 = 1
  0 0 0 1 -> die 1 sagt, dass die 1 in der 3 enthalten ist

Man kann sich das als eine Art Bit-Filter vorstellen: a & b lässt nur die Bits aus a durch, die in b gesetzt sind, und setzt den Rest auf 0.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4683

Wohnort: Berlin

Ja, wenn man Code-Golf spielen wollte, wäre es so kürzer ausgedrückt:

1
2
t='21:04:23'
for i in(8,4,2,1):print' '.join('0X'[int(c)&i>0]for c in t if'/'<c<':')

diesch Team-Icon

Avatar von diesch

Anmeldungsdatum:
18. Februar 2009

Beiträge: 5072

Wohnort: Brandenburg an der Havel

Marc 'BlackJack' Rintsch schrieb:

Ja, wenn man Code-Golf spielen wollte,

Ich dachte eher an sowas wie Obfuscated Python.

BTW, kürzer: ☺

for i in(8,4,2,1):print' '.join('0X'[int(c)&i>0]for c in t if c!=':')

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4683

Wohnort: Berlin

Na da geht noch ein Zeichen:

1
for i in(8,4,2,1):print' '.join('0X'[int(c)&i>0]for c in t if':'!=c)

jakon Team-Icon

Lokalisierungsteam
(Themenstarter)

Anmeldungsdatum:
16. November 2009

Beiträge: 419

So, nach 10 Monaten verstehe ich den Code. Sowohl den »normalen« als auch den »Obfuscated Python«-Code 😊

So, meine kommentierte Version von dem »normalen«:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python

t = '21:04:23'
ziffern = [int(c) for c in t if '0' <= c <= '9']
# alle Ziffern in t werden nach 'ziffern' geschrieben

for i in (8, 4, 2, 1):
# iteriert fuer die 'binaeren Zahlen'
    for z in ziffern:
    # iteriert fuer jede Ziffer in ziffern
        print ('0', 'X')[z & i == i],
        # wenn z >= i dann ist's True, sonst False
    print

Der normale ist eigentlich »recht simpel« 😈 D.h. ich verstehe ihn nun vollständig; aber selbstständig hätte ich den wohl nicht geschrieben. Der »Obfuscated Python«-Code ist da sogar einfacher für mich. 😬

Antworten |