Immer gleiche Wert in der Liste

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
Brando
User
Beiträge: 171
Registriert: Donnerstag 28. Januar 2016, 15:36

In folgendem Code wird in der init Methode in eine Liste dreimal das gleiche Objekt eingefügt. Dann werden diesen Objekten, die Vektoren sind (1*3) Zufallszahlen zugefügt. Jetzt ist es so, dass für die drei eingefügten Objekte die Zufallszahlen die gleichen sind. Hängt das damit zusammen, dass bei dem append einer Liste ein call by reference auftritt? Wie könnte man das in ein call by value verwandeln?

Code: Alles auswählen

from sympy.matrices import *
from sympy.printing import *
from IPython.display import display, HTML, Math, Latex, clear_output
from ipywidgets import widgets
from random import randint
from sympy import *
from builtins import str
 
text1 = widgets.Text()
 
button1 = widgets.Button(description="Auswerten")
button2 = widgets.Button(description="Neue Aufgabe")


x=[] 
#x[0] = Matrix()
#x[1] = Matrix()
#x[2] = Matrix()
 
latexWidget = widgets.Latex()
 
taskWidget = widgets.HTML()

 
mhbox1 = widgets.HBox((taskWidget, latexWidget))
mhbox2 = widgets.HBox((button1, button2))
 
def init_vectors(b, matrix_1, anzahl_1, matrix_2):
        global x, text1
        anzahl_matrizen=0;
        for u in range(anzahl_1):
          x.append(matrix_1)
        
        if isinstance(matrix_2,Matrix):
              x.append(matrix_2)
        for u in range(anzahl_1):
           anzahl_matrizen=anzahl_matrizen+1
           for i in range(matrix_1.shape[1]):
              for j in range(matrix_1.shape[0]):
                   x[u][j,i]=randint(-10,10)      
        
        w=widgets.Textarea(
               description='Matrix', 
               value = str(x[0]),
            )
        display(w)
        w=widgets.Textarea(
               description='Matrix', 
               value = str(x[1]),
            )
        display(w)
        if isinstance(matrix_2,Matrix):
             anzahl_matrizen+=1 
             for i in range(matrix_2.shape[1]):
                for j in range(matrix_2.shape[0]):
                    x[anzahl_1][j,i]=randint(-10,10) 
        #w=widgets.Textarea(
               #description='Matrix', 
               #value = str(x[anzahl_1]),
            #)
        #display(w)
        text1.value = ""
        display_task(anzahl_matrizen)
 
def display_task(anzahl_matrizen):
        global x, latexWidget
        a=[]
        clear_output()
        for i in range(anzahl_matrizen):
           b=latex(x[i])
           b=b.replace("left[", "left(")
           b=b.replace("right]", "right)")
           a.append(b)
        
        str1="$\langle" 
        for i in range(anzahl_matrizen):
            str1=str1+a[i]+", "
 
        str1 += "\\rangle$"
        latexWidget.value = str1
 
def evaluate(b):
        global x, y, text1
        z = x.dot(y)
 
        clear_output()
        display_task()
 
        if "{0}".format(z) == text1.value:
                display(HTML("<b><font color='green'>Richtig</font></b>"))
        else:
                display(HTML("<b><font color='red'>Falsch</font></b>"))
 
 
def exec_la_scalar(aufgabentext, matrix1, anzahl1, matrix2):
        taskWidget.value = "<b>{0}</b>".format(aufgabentext)
        init_vectors(button2, matrix1, anzahl1, matrix2)
        button2.on_click(init_vectors)
        button1.on_click(evaluate)
        display(widgets.VBox((mhbox1, text1, mhbox2)))
Zuletzt geändert von Anonymous am Mittwoch 8. Juni 2016, 14:46, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Brando: Dein Quell-Code hat immer noch die selben Probleme wie der von vor zwei Tagen. Unter anderem solltest Du keine *-Importe machen, keine globalen Variablen verwenden, numpy statt sympy verwenden, weil Du nicht symbolisch sondern mit konkreten Zahlen arbeitest.
Wenn matrix_2 einfach nur ein optionaler Parameter ist, dann gibt es in Python dafür das Singleton None, da braucht man kein isinstance oder sonstige Typprüfung. Es gibt in Python weder call-by-reference noch call-by-value, sondern nur Objekte, die sich nicht auf magische Weise vermehren. Wenn man eine Kopie haben will, dann schreibt man das einfach. Warum übergibst Du init_vectors Matrizen, wenn Du doch sowieso nur die Dimension brauchst um eine Zufallsmatrix zu erzeugen. Das geht übrigens mit einem Einzeiler:

Code: Alles auswählen

random_matrix = numpy.random.randint(-10,10, (anzahl_1,) + shape_1)
BlackJack

@Sirius3: Ich habe den Programmablauf nicht komplett verfolgt, aber die `sympy.Matrix`-Objekte werden wohl gebraucht um eine LaTeX-Darstellung für die Anzeige zu bekommen. Wobei der umgekehrte Weg da wahrscheinlich sinnvoller ist, also aus den Daten mit denen man tatsächlich arbeitet (`numpy`-Array) für die Anzeige ein `sympy.Matrix`-Objekt zu erstellen und das dann anzeigen lassen. In diese Richtung bekommt man auch keine Probleme das etwas nicht umgewandelt werden kann.
Antworten