Addierwerk in Python

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.
Antworten
Benutzeravatar
anikar
User
Beiträge: 3
Registriert: Sonntag 22. Juni 2014, 20:55

Hallo liebe Leute,

ich hab ein kleines Problem mit einem Code und dachte ich frage mal ganz nett nach, ob mir jemand helfen kann. Ich entschuldige mich schonmal, falls ich die Frage in einem falschen Thread poste.

Die Aufgabe war, folgende HDL-Beschreibung in Python zu übersetzen:

##############################
CHIP Addierwerk {
IN a0,a1,b0,b1;
OUT s0,s1,s2;

PARTS:
Xor(a=a1,b=b1,out=s2);
And(a=a1,b=b1,out=carryHA);
Xor(a=a0,b=b0,out=sum1);
And(a=a0,b=b0,out=c1);
Xor(a=sum1,b=carryHA,out=s1);
And(a=sum1,b=carryHA,out=c2);

Or(a=c1,b=c2,out=s0);
}

#################################

Die "Lösung" vom Tutor liefert zwar einen guten Ansatz, funktioniert aber nicht. Leider bin ich eine totale Anfängerin in Python und kann die Fehlermeldungen nicht nachvollziehen. :cry:
Ich würd mich wahnsinnig freuen wenn mir jemand ein paar Tipps geben könnte.

##########################

Code: Alles auswählen

#Halbaddierer

def Halbaddierer (a,b):
   
    sum =a^b    # Xor
    
    carry =a&b   #And
    
    return (carry,sum)

#Volladdierer

def Volladdierer (a,b,c_in):
    sum1,carry1=Halbaddierer(a,b)
    sum2,carry2=Halbaddierer(sum,c_in)
    carry=carry1|carry2               #Or
    return(sum2,carry)

#Addierwerk

def Addierwerk (a0,a1,b0,b1):
    s2,carryHA =Halbaddierer(a1,b1)
    s1,s0=Volladdierer(a0,b0,carryHA)
    return(s0,s1,s2)

#Eingaben

print ("Dieses Addierwerk bearbeitet zweistellige Binärzahlen.\n")

a=str(input("Welches ist die erste Zweistellige Binärzahl?"))

b=str(input("Welches ist die zweite Zweistellige Binärzahl?"))

#Aufteilung in einzelne Binärziffern

a0=int(a[0])
a1=int(a[1])
b0=int(b[0])
b1=int(b[1])

#Ausführung Addierwerk und Ausgabe

print ("Die Summe von ",a,"und",b,"beträgt",end=" ")

for i in range(3):
    print(Addierwerk(a0,a1,b0,b1)[i],end=" ")
####################################
Edit:
Richtig so? Kannte Code Tags noch nicht, sehr praktisch :mrgreen:
Hier die Fehlermeldung:
Dieses Addierwerk bearbeitet zweistellige Binärzahlen.

Welches ist die erste Zweistellige Binärzahl?11
Welches ist die zweite Zweistellige Binärzahl?11
Die Summe von 11 und 11 beträgt Traceback (most recent call last):
File "D:/Dropbox/Sommer/Info/Tuts/A 8/Code.py", line 62, in <module>
print(Addierwerk(a0,a1,b0,b1),end=" ")
File "D:/Dropbox/Sommer/Info/Tuts/A 8/Code.py", line 39, in Addierwerk
s1,s0=Volladdierer(a0,b0,carryHA)
File "D:/Dropbox/Sommer/Info/Tuts/A 8/Code.py", line 31, in Volladdierer
sum2,carry2=Halbaddierer(sum,c_in)
File "D:/Dropbox/Sommer/Info/Tuts/A 8/Code.py", line 21, in Halbaddierer
sum =a^b # Xor
TypeError: unsupported operand type(s) for ^: 'builtin_function_or_method' and 'int'
Zuletzt geändert von anikar am Sonntag 22. Juni 2014, 22:14, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Du solltest deinen Code in Code-Tags setzen, dann kann man ihn hier im Forum auch vernünftig lesen und interpretieren. Ohne Einrückung ist das schwierig bis unmöglich.
anikar hat geschrieben:Leider bin ich eine totale Anfängerin in Python und kann die Fehlermeldungen nicht nachvollziehen. :cry:
Und du möchtest uns die Fehlermeldung nicht verraten, weil ...? ;-)
Das Leben ist wie ein Tennisball.
BlackJack

@anikar: Die Fehlermeldung sagt Dir das Du versuchst eine Funktion und eine Zahl mit ``^`` zu verknüpfen, was nicht geht. Es wird Dir auch gezeigt in welcher Zeile das genau passiert. Also ist `a` eine Funktion. Der Traceback zeigt Dir auch den Aufruf der davor passiert. Da wird für `a` der Wert `sum` übergeben. Und da haben wir auch schon das Problem: Das ist kein Name den Du irgendwo vorher definierst, also ist das die eingebaute `sum()`-Funktion. Vielleicht wolltest Du da `sum1` übergeben?
Benutzeravatar
anikar
User
Beiträge: 3
Registriert: Sonntag 22. Juni 2014, 20:55

Danke für die Hilfe :D
Ich wollte mit "^" die eingebaute xor funktion von Python nutzen, aber hab die Klammer vergessen :roll:
Das mit sum hätte ich bemerken müssen :oops: . Python hat es auch noch anders farblich unterlegt... Allerdings reicht es nicht sum mit sum1 zu ersetzen, das Programm läuft dann zwar, liefert aber falsche Ergebnisse. Daran werd ich jetzt arbeiten.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@anikar: liegt wohl daran, dass Carry und Sum anders zurückgegeben werden als vom Volladdierer weiterverarbeitet wird.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@anikar:
Als Hilfestellung - Du kannst die HDL-Beschreibung ziemlich 1:1 in Funktionen in Python übertragen. Die Sache mit Halb-/Volladdierer ist ja zunächst nicht in der Aufgabe genannt und vllt. eher als Bonus zu verstehen.

Beispiel Xor(a, b, out):

Code: Alles auswählen

def xor(a, b):
    return a ^ b # => out
Benutzeravatar
anikar
User
Beiträge: 3
Registriert: Sonntag 22. Juni 2014, 20:55

:shock: Bingo, jetzt passt es, danke danke danke \(^.^)/

Hier das Endergebnis:

Code: Alles auswählen

#Halbaddierer

def Halbaddierer (a,b):
   
    sum2 =(a^b)    # Xor
    
    carry =(a&b)   #And
    
    return (sum2,carry)

#Volladdierer

def Volladdierer (a,b,c_in):
    sum1,carry1=Halbaddierer(a,b)
    sum2,carry2=Halbaddierer(sum1,c_in)
    carry=carry1|carry2               #Or
    return(sum2,carry)

#Addierwerk

def Addierwerk (a0,a1,b0,b1):
    s2,carryHA =Halbaddierer(a1,b1)
    s1,s0=Volladdierer(a0,b0,carryHA)
    return(s0,s1,s2)

#Eingaben

print ("Dieses Addierwerk bearbeitet zweistellige Binärzahlen.\n")

a=str(input("Welches ist die erste Zweistellige Binärzahl?"))

b=str(input("Welches ist die zweite Zweistellige Binärzahl?"))

#Aufteilung in einzelne Binärziffern

a0=int(a[0])
a1=int(a[1])
b0=int(b[0])
b1=int(b[1])

#Ausführung Addierwerk und Ausgabe

print ("Die Summe von ",a,"und",b,"beträgt",end=" ")

for i in range(3):
    print(Addierwerk(a0,a1,b0,b1)[i],end=" ")
BlackJack

@anikar: Wie jerch schon angemerkt hat sieht das nicht nach einer Umsetzung von dem gezeigten HDL-Quelltext aus. Im Endeffekt macht es das natürlich schon, aber wenn Du da die Funktionen Halb- und Volladdierer hast, dann hätte ich auch erwartet im ``CHIP Addierwerk`` diese Chips in den PARTS zu lesen, statt der Grundbausteine. Und dann auch entsprechende CHIP-Definitionen für `Halbaddierer` und `Volladdierer`. Also da hätte ich eher so etwas als Vorgabe zum Übersetzen erwartet:

Code: Alles auswählen

CHIP Halbaddierer {
    IN a, b;
    OUT out, carry;
    
    PARTS:
    Xor(a=a, b=b, out=out);
    And(a=a, b=b, out=carry);
}

CHIP Volladdierer {
    IN a, b, carry_in;
    OUT out, carry_out;

    PARTS:
    Halbaddierer(a=a, b=b, out=t0, carry=c1);
    Halbaddierer(a=t0, b=carry_in, out=out, carry=c2);
    Or(a=c1, b=c2, out=carry_out);
}

CHIP Addierwerk {
    IN a0, a1, b0, b1;
    OUT s0, s1, s2;

    PARTS:
    Halbaddierer(a=a1, b=b1, out=s2, carry=carry);
    Volladdierer(a=a0, b=b0, carry_in=carry, out=s1, carry_out=s0);
}
Zum Quelltext selber: Du gehst ziemlich unregelmässig mit Leerraum um, sowohl was die Zeilen als auch was Leerzeichen angeht. Üblich sind keine unnötigen Leerzeilen zwischen zusammengehörenden Quelltextzeilen, zwei Leerzeilen zwischen Funktionen, ein Leerzeichen vor und nach ``=`` von Zuweisungen (ausserhalb von Argumentlisten) und binären Operatoren. Kein Leerzeichen zwischen Funktionsnamen und der öffnenden Klammer von den Argumenten. Ein Leerzeichen nach ``return``, damit das nicht irreführender weise nach einem Funktionsaufruf aussieht. Ein Leerzeichen nach Kommas.

Die Kommentare vor den Funktionsdefinitionen die einfach nur den Funktionsnamen enthalten sind überflüssig. Der Funktionsname steht ja schon nach dem ``def``, den noch mal zu kommentieren bringt keinen Mehrwert.

Der `str()`-Aufruf bei den beiden Eingaben ist überflüssig. Die `input()`-Funktion liefert als Ergebnis doch schon eine Zeichenkette.

Die Funktion `Addierwerk()` wird drei mal mit den gleichen Argumenten aufgerufen und liefert drei mal das gleiche Ergebnis, aus dem dann immer nur ein Element ausgegeben wird. Das ist nicht wirklich sinnvoll. Schleifen über einen Laufindex mit dem dann nur auf eine Sequenz zugegriffen wird sind ausserdem „unpythonisch” weil man in Python *direkt* über die Elemente von Sequenztypen iterieren kann, ohne den Umweg über einen Index. Das würde man also eher so schreiben:

Code: Alles auswählen

for i in Addierwerk(a0, a1, b0, b1):
    print(i, end=' ')
oder falls man nach dem letzten Bit kein Leerzeichen haben möchte:

Code: Alles auswählen

print(
    'Die Summe von {0} und {1} beträgt {2}.'.format(
        a, b, ' '.join(str(i) for i in Addierwerk(a0, a1, b0, b1))
    )
)
Antworten