Fehler beim umrechnen von Dual nach Dezimalzahlen

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.
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Freitag 17. Oktober 2008, 22:23

Ich hab gestern aus langeweile ein Script geschrieben, welches Dualzahl in Dezimalzahlen umrechnet.

Code: Alles auswählen

zahl = raw_input("Geben sie eine beliebege Zahl im Dualsystem ein: ")
dezimal = 0
max_potenz = len(zahl)
stelle = 0
while (stelle <= len(zahl)):
    if (zahl[stelle] == "1"):
       dezimal = dezimal + 2**(max_potenz - stelle)
    stelle = stelle + 1
print dezimal
Leider kommt jedes Mal die Meldung "string index out of range" für die Zeile

Code: Alles auswählen

    if (zahl[stelle] == "1"):
Was mach ich falsch?
Dies ist keine Signatur!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Freitag 17. Oktober 2008, 22:33

Das bedeutet, dass stelle in dem Term zahl[stelle] einen Index anspricht, der zu groß ist! Lass Dir doch mal den Wert von "stelle" vorher ausgeben und vergleiche den dann mit der Länge von "zahl". Dann überlege Dir, was der kleinste und der größte mögliche Index für "zahl" sein kann (Denke daran, dass hier bei 0 angefangen wird zu zählen!).
lunar

Freitag 17. Oktober 2008, 22:38

"zahl[len(zahl)]" gibt es nicht. Die Zählung fängt nämlich bei 0 an. Die Bedingung in der Schleife ist folglich falsch. Außerdem frage ich mich, wieso du "len(zahl)" an einen Namen bindest, diesen Namen in der Schleifenbedingung aber nicht nutzt.

Besser wäre es aber, auf die Schleife ganz zu verzichten. Zeichenketten sind iterierbar, und enumerate() erlaubt den komfortablen Zugriff auf den Index:

Code: Alles auswählen

number = raw_input("Geben sie eine beliebege Zahl im Dualsystem ein: ")
decimal = 0
max = len(zahl)
for index, char in enumerate(number):
    if (char == "1"):
       dezimal = dezimal + 2**(max - index)
print dezimal
Benutzeravatar
snafu
User
Beiträge: 5466
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Freitag 17. Oktober 2008, 22:58

Warum machst du's nicht so:

Code: Alles auswählen

dual = raw_input("Geben sie eine beliebege Zahl im Dualsystem ein: ")
potency = len(dual) - 1
sum = 0
for digit in dual:
    sum += int(digit) * (2 ** potency)
    potency -= 1
print sum
@lunar: Hab deinen Beitrag nicht gesehen.
Zuletzt geändert von snafu am Freitag 17. Oktober 2008, 22:59, insgesamt 1-mal geändert.
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Freitag 17. Oktober 2008, 22:59

zahl[len(zahl)] steht auch nirgendwo.
Naja, bin ziemlicher Anfänger. Iteratoren kenn ich (noch) nicht. Was der Fehler bedeutet weiß ich auch, nur warum wird er ausgegeben. Stelle ist gleich Null. Bestimmt gibt es einen eleganter geschriebenen Code, aber dieser ist im Rahmen meiner Fähigkeiten geschrieben. Wo liegt jetzt also genau der Fehler in diesem Code?

EDIT: Der letzte Code funktioniert, danke für die Hilfe. Jetzt weiß ich nur immernoch nicht warum mein Code einen Fehler ausgibt ^^"
Dies ist keine Signatur!
lunar

Freitag 17. Oktober 2008, 23:06

Shaldy hat geschrieben:zahl[len(zahl)] steht auch nirgendwo.
Du hast es so nicht hingeschrieben, dass ist wohl wahr. Allerdings läuft deine Schleife, bis "stelle" kleiner gleich "len(zahl)" ist ... was glaubst du, was dann in Zeile sechs ausgeführt wird, wenn "stelle" gleich "len(zahl)" ist?

Befolge doch einfach mal Hyperions Tipp, und lass die "stelle" in der Schleife per "print" ausgeben.
Zuletzt geändert von lunar am Freitag 17. Oktober 2008, 23:08, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 17. Oktober 2008, 23:07

Shaldy hat geschrieben:zahl[len(zahl)] steht auch nirgendwo.
Doch, "stelle" nimmt den Wert im letzten Schleifendurchlauf an.

Code: Alles auswählen

sum([int(x)*2**i for (i,x) in enumerate(zahl[::-1])])
oder natürlich die ultimative Lösung:

Code: Alles auswählen

int(zahl, 2)
Benutzeravatar
snafu
User
Beiträge: 5466
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Freitag 17. Oktober 2008, 23:11

@lunar: Dein Code scheint nicht richtig zu funktionieren. Selbst wenn man die Tippfehler bei den Variablen ausbessert bekomme ich z.B. für 1101 als Ergebnis 26 statt 13 zurück.
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Freitag 17. Oktober 2008, 23:12

Okay, habs verstanden, danke!

Kann geschlossen werden.
Dies ist keine Signatur!
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 17. Oktober 2008, 23:14

snafu hat geschrieben:@lunar: Dein Code scheint nicht richtig zu funktionieren. Selbst wenn man die Tippfehler bei den Variablen ausbessert bekomme ich z.B. für 1101 als Ergebnis 26 statt 13 zurück.
Du bist aber auch echt nicht kreativ ;-) Statt "max - index" müsste es bei lunar "max - index - 1" heißen.
lunar

Freitag 17. Oktober 2008, 23:20

snafu hat geschrieben:@lunar: Dein Code scheint nicht richtig zu funktionieren. Selbst wenn man die Tippfehler bei den Variablen ausbessert bekomme ich z.B. für 1101 als Ergebnis 26 statt 13 zurück.
Jo ... mir ging es ja auch nur darum, die Nutzung von enumerate zu zeigen. Dazu hab ich halt einfach den Code des OP entsprechend umgeschrieben. Ob der nun tatsächlich korrekt war, hab ich gar nicht überprüft.
Benutzeravatar
snafu
User
Beiträge: 5466
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Freitag 17. Oktober 2008, 23:24

EyDu hat geschrieben:Du bist aber auch echt nicht kreativ ;-) Statt "max - index" müsste es bei lunar "max - index - 1" heißen.
:o Ich musste doch schon meine ganze geistige Energie für die Variablen benutzen. Da blieb wohl nichts mehr übrig. :(
Benutzeravatar
snafu
User
Beiträge: 5466
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Freitag 17. Oktober 2008, 23:27

Welcher Weg ist hier eigentlich der bessere: Die Multiplikation mit Null draufrechnen oder - wie vom OP getan - auf "1" zu prüfen?
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Freitag 17. Oktober 2008, 23:41

snafu hat geschrieben:Welcher Weg ist hier eigentlich der bessere: Die Multiplikation mit Null draufrechnen oder - wie vom OP getan - auf "1" zu prüfen?
Ich finde meins schöner (sonst hätte ich es auch nicht so geschrieben ;-) ) da der Code so an Symmetrie gewinnt.

Du solltest aber nicht vergessen zu testen, dass auch wirklich nur Nullen und Einsen eingegeben wurden, sonst schlagen beide Varianten fehl.

BTW: Es heißt "power" und nicht "potency" ;-)
Benutzeravatar
snafu
User
Beiträge: 5466
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Samstag 18. Oktober 2008, 00:04

Wenn ich es mir recht überlege, ist es vielleicht auch nicht gerade prickelnd, 0 * 2 ^ 3456 draufzuschlagen. Also wäre wohl die vorherige Prüfung schon sinnvoller.

EDIT: Nein, "may the potency be with you" ist schön. :)
Antworten