Seite 1 von 1

Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 11:21
von Brando
Folgender Codeausschnitt:

Code: Alles auswählen

cb_container=[]
        #cb_container = widgets.HBox()
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())

        #for j in range(3):
        for j in range(3):
           text.append(widgets.Text(width=40))
           text.append(widgets.Text(width=40))
           text.append(widgets.Text(width=40))
           cb_container[j].children=[i for i in text]
           text=[]

wie kann ich jetzt den Text.value in Abhängigkeit von cb_container lesen?

bspw. vom zweiten containerelement die erste textbox: cb_container[1][0].value

Funktioniert aber nicht

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 12:19
von Brando
Noch ein Code der nicht funktioniert:

Code: Alles auswählen

for c in cb_container[2].children:
            w=widgets.Textarea(Description='Lösung GLS',
                 value=c.value
                 )
            display(w)

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 13:25
von Sirius3
@Brando: funktioniert nicht, ist eine sehr schlechte Fehlerbeschreibung. Was funktioniert nicht? Was erwartest Du? Was bekommst Du? Welche Fehlermeldung, etc?

Wie man etwas reinschreibt, so kann man es normalerweise auch weider auslesen, also per cb_container[1].children[0].value. Von daher funktioniert bei mir Dein zweiter Code so wie ich es erwarten würde. Aber vielleicht erwartest Du ja etwas anderes.

Ansonsten gelten auch bei iPython die selben Python-Konventionen wie sonst auch: Man iteriert nicht über einen Index, sondern direkt über die Liste; Variablen werden dann initialisiert, wenn man sie braucht und nicht reinitialisiert, wenn man mit ihnen fertig ist. Variablennamen sollten ausdrücken, was deren Aufgabe ist und nicht aus unverständlichen Abkürzungen und nichtssagenden Anhängseln bestehen: was heißt z.b. cb in cb_container?

Also in nicht ganz so umständlich:

Code: Alles auswählen

cb_container = [widgets.HBox() for _ in range(3)]

for cb in cb_container:
    cb.children = [widgets.Text(width=40) for _ in range(3)]
    display(cb)

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 13:39
von Brando
Hallo Sirius,

deine Vorschläge vielen Dank. Aber jetzt funktioniert mein Code auch nur so, dass er den Value ausgibt, mit dem die Textbox initialisiert wurde und nicht den Wert der in die Textbox hineingeschrieben wurde. Der gesamte Code ist:

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
import numpy as np
from builtins import str
from ipywidgets import *
import ast
from copy import deepcopy

text1 = widgets.Text()
text=[] 

button1 = widgets.Button(description="Auswerten")
button2 = widgets.Button(description="Neue Aufgabe")
 
#x = np.arange(9).reshape(3,3)
#y = np.arange(3).reshape(3,1)
x=Matrix()
y=Matrix()
latexWidget = widgets.Latex()
 
taskWidget = widgets.HTML()
taskWidget.value = "<b>Berechnen Sie:</b>"
 
mhbox1 = widgets.HBox((taskWidget, latexWidget))
mhbox2 = widgets.HBox((button1, button2))
cb_container= []


 
def init_vectors(b):
        global x, y, text1, text, cb_container
        cb_container=[]
        text_copy=[]
        #cb_container = widgets.HBox()
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())

        #for j in range(3):
        for j in range(3):
           text=deepcopy(text_copy)
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           cb_container[j].children=[i for i in text]
           
        
        
        x=zeros(3,3)
        y=zeros(3,1)
        for i in range(3):
           for j in range(3):
             x[j,i]=randint(-10,10)

        for i in range(1):
            for j in range(3):
               y[j,i]=randint(-10,10)
        
        #n_matrix_x=np.eye(3)
        n_matrix_x=np.matrix(x).astype(float)
        
        gefunden=False
        if np.linalg.det(n_matrix_x)==0:
            init_vectors(b)
        else: 
            A,B=np.linalg.eig(n_matrix_x)
            for i in range(3):
               if A[i].real==0 or A[i].imag!=0:
                 gefunden=True
                 break
               
            
            
            #n_matrix_x=np.matrix(x).astype(float)
            #n_matrix_y=np.matrix(y).astype(float)
            #z = np.linalg.solve(n_matrix_x,n_matrix_y)
            #for i in range(3):
                #if z[i,0]!= int(z[i,0]):
                   #gefunden=True
                   #break
            
            if gefunden:
                 init_vectors(b)      
                 
        text1.value = ""
        display_task()
 
def display_task():
        global x, y, latexWidget
 
        clear_output()
 
        a1 = latex(x)
        a2 = latex(y)
 
        a1 = a1.replace("left[", "left(")
        a2 = a2.replace("left[", "left(")
        a1 = a1.replace("right]", "right)")
        a2 = a2.replace("right]", "right)")
 
        str1 = "$\langle" + a1 + ", " + a2 + "\\rangle$"
        latexWidget.value = str1
 
def evaluate(b):
        global x, y, text1, cb_container, text
        n_matrix_x=np.matrix(x).astype(float)
        n_matrix_y=np.matrix(y).astype(float)
        z = np.linalg.solve(n_matrix_x,n_matrix_y)
        w=widgets.Textarea(Description='Lösung GLS',
                 value=str(z)
                 )
        display(w)
 
        clear_output()
        display_task()
        loesung_gefunden=True
        i=0
        for c in cb_container[2].children:
            w=widgets.Textarea(Description = 'Lösung GLS',
                 value = c.value
                 )
            display(w)
            #if round(z[i,0],1)!= float(c.value):
               #loesung_gefunden=False
               #break
            #i=i+1
            
        if loesung_gefunden:
                display(HTML("<b><font color='green'>Richtig</font></b>"))
        else:
                display(HTML("<b><font color='red'>Falsch</font></b>"))
 
 
def exec_la_scalar_1():
        global cb_container
        init_vectors(button2)
        button2.on_click(init_vectors)
        button1.on_click(evaluate)
        display(widgets.VBox((mhbox1,cb_container[0])))
        display(widgets.VBox((cb_container[1],cb_container[2], mhbox2)))
       

        
Die kritischen Stellen im Code sind in init_vectors:

Code: Alles auswählen

cb_container=[]
        text_copy=[]
        #cb_container = widgets.HBox()
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())
        cb_container.append(widgets.HBox())

        #for j in range(3):
        for j in range(3):
           text=deepcopy(text_copy)
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           text.append(widgets.Text(Description="Thema", value="True", width=40))
           cb_container[j].children=[i for i in text]
           

und in evaluate:

Code: Alles auswählen

for c in cb_container[2].children:
            w=widgets.Textarea(Description = 'Lösung GLS',
                 value = c.value
                 )
            display(w)
Wie erreiche ich es, dass die Werte die in der Textbox drinstehen auch wieder ausgegeben werden in w? Irgendwie muss man das System dazu zwingen die Werte, die ich in die Textbox eingetragen habe auch dem c.value zuzuweisen. Das geschieht aber nicht.

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 14:54
von Sirius3
@Brando: zum Zeitpunkt des Auslesens ist der Wert von c.value schon aktuell, aber natürlich ändert sich nicht auf magische Weise alle Stellen, wo irgendwann einmal der Wert von c.value eingetragen wurde.

Was ist eigentlich der Gedankengang hinter dem deepcopy einer leeren Liste?

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 15:10
von Brando
Das deepcopy hatte ich eingefügt, weil ich gefürchtet habe, dass eine Referenz auf die Textboxen zurückgegeben werden, und somit alle neun werte mit Textboxen der gleichen Referenz initialisiert werden. Das hat sich nicht bewahrheitet, ist also überflüssig. Nun aber zu der eigentlichen Problematik: Textboxen in ipywidgets haben ja den Sinn, das man etwas hineinschreibt. value als Eigenschaft der Textbox müsste dann geändert werden. Das geschieht aber nicht. Wie kann ich erreichen, dass der in die Box geschriebene Wert auch als relevanter Wert erkannt wird?

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 15:43
von Sirius3
Wie schon geschrieben enthält bei mir c.value den aktuellen Wert. Kannst Du ein vollständiges Minimalbeispiel posten, das Dein beschriebenes Verhalten eindeutig zeigt?

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 16:47
von Brando
Es ist das Beispiel im 4. Post, das erste. Es ist in Jupyter Notebook zum Laufen zu bringen.

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 18:09
von Sirius3
@Brando: das ist zum Einen kein Minimalbeispiel, weil es vieles enthält, was gar nicht gebraucht wird, um das Problem nachzuvollziehen und zum Zweiten fehlen die Angaben, wo etwas passiert, was Du so nicht willst.

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Dienstag 14. Juni 2016, 18:13
von Brando
starten kann man das Programm mit exec_la_scalar_1(). Und die Stelle in der das unvorhergesehene eintritt ist in evaluate:

Code: Alles auswählen

for c in cb_container[2].children:
            w=widgets.Textarea(Description = 'Lösung GLS',
                 value = c.value
                 )
            display(w)
Es wird immer der initialisierte Wert ausgegeben und nicht der, der in die Textbox geschrieben wurde.

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Mittwoch 15. Juni 2016, 08:07
von Brando
Hallo Sirius,

folgender kleiner Code funktioniert wieder. Es wäre also die Frage, warum das in dem Ausgangscode nicht funktioniert:

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
import numpy as np
from builtins import str
from ipywidgets import *
import ast
from copy import deepcopy


tb_container=[]


def eingabe_ueberpruefung(b):
  for c in tb_container[2].children:
            w=widgets.Textarea(Description = 'Lösung GLS', value = c.value)
            display(w)


def display_container():
  global tb_container
  button1 = widgets.Button(description="Auswerten")
  display(button1)
  button1.on_click(eingabe_ueberpruefung)
      

def fill_container():
  global tb_container
  tb_container=[]
  for j in range(3):
           c1 = widgets.Text(Description="Thema", value=str(randint(-20,20)), width=140)
           c2 = widgets.Text(Description="Thema", value=str(randint(-20,20)), width=140)
           c3 = widgets.Text(Description="Thema", value=str(randint(-20,20)), width=140)
           tb_container.append(widgets.HBox(children = [c1, c2, c3]))


def render():
    global tb_container
    fill_container()
    display_container()
    display(widgets.VBox((tb_container[0],tb_container[1],tb_container[2])))

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Mittwoch 15. Juni 2016, 08:23
von Sirius3
@Brando: der Code mag zwar funktionieren, aber wie schon den nicht-funktionierenden mag den niemand anschauen. Wie einfach man Fehler finden kann, hängt im wesentlichen davon ab, wie komplex der Code ist. Komplexität ergibt sich entweder aus dem Problem an sich, dann hilft es nur möglichst gute Testcases zu schreiben, oder wie bei Dir kommt die Komplexität einfach davon, dass der Code so grottenschlecht geschrieben ist. Ich möchte hier jetzt nicht zum x-ten mal die ganzen Punkte wiederholen, die stehen in Deinen anderen Threads schon zur genüge. Das einfachste wäre wohl, alles zu löschen und neu zu beginnen, ohne *-importe, ohne global, mit sinnvollen Variablennamen.

Re: Wie kann ich children Eigenschaft lesen?

Verfasst: Mittwoch 15. Juni 2016, 08:42
von snafu
@Brando:
Du gehst anscheinend nach wie vor davon aus, dass jeder deine Entwicklungsumgebung samt Bibliotheken benutzt. Dem ist leider nicht so. An der Resonanz auf deine Threads siehst du ja, dass nur rech wenige Leute dir helfen können bw wollen und die Antworten auch oft recht allgemein gehalten sind. Wenn du bessere Antworten haben willst, dann solltest du dein Frageverhalten anspassen. Die Knackpunkte hatte Sirius3 bereits beschrieben.