In Jupyter Notebook kann man in Zellen Python Code darstellen. Bislang bin ich so vorgegangen, dass ich in dem passenden Ordner für den Programmaufruf ein Pythonskript schreibe, welches ein Modul nutzt, welches am gleichen Ort gespeichert ist. Der Aufruf des Programmes erfolgt mittels exec_render(modulname), wobei exec_render die initiale Methode des Programmes ist, und modulname der Name des Moduls, welches das Programm nutzt. Jetzt möchte ich so vorgehen: In einer Zelle in Jupyter Notebook wird der Code des Moduls gesetzt. In der gleichen Zelle auch exec_render(), nur dass der Zelleninhalt bis auf die Zeile des Aufrufes exec_render als Modul genutzt wird.
------------------------------------------Jupyter Notebook Zelle
Modulcode
exec_render-Aufruf
_______________________________Ende Jupyter Notebook Zelle
exec_render nutzt den Modulcode
Wie geht das?
Wie kann ich in Jupyter Notebook ein Modul in einer Zelle darstellen und ein ...
@Brando: eigentlich solltest Du gar kein "exec_render" benutzen, sondern einfach nur Funktionen schreiben (entweder in einem eigenen Modul oder direkt im Notebook) (möglichst ohne Nebeneffekte, kein global, keine Widgets in Berechungsfunktionen, etc) und diese einfach aufrufen.
Mein Programm besteht aus Funktionen. Aber das Problem bleibt: Ich rufe die Funktion exec_render auf, diese ist im Dateisystem von Jupyter Notebook am richtigen Ort hinterlegt. Dann soll diese Funktion aber auf das Modul zugreifen, welches ich in eine Zelle schreibe, und nicht im Dateisystem hinterlegt ist. Das ganze soll von der entsprechenden Zelle im Jupyter Notebook aus gestartet werden.
Bisher habe ich das Modul importiert. Dann hat exec_render einen Parameter, der auf das Modul verweist. Jetzt soll das Modul in eine Jupyter Notebook Zelle geschrieben werden und exec_render aufgerufen werden. D.h. das Modul und der Aufruf exec_render stehen in derselben Zeile. Wie teile ich dem Programm von exec_render mit, das er das Modul nutzen soll, welches in der Jupyter Notebook Zelle steht und wie wird das Problem behoben, dass das Modul und der Aufruf exec_render in derselben Zelle steht?
So sieht meine Lösung bisher aus, sie funktioniert aber nicht. Globale Variablen werde ich noch beseitigen.
Code: Alles auswählen
from sympy.matrices import *
from builtins import str
from ipywidgets import widgets
from IPython.display import display, HTML, Math, Latex, clear_output
from random import randint
import sys
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
from copy import deepcopy
import numpy as np
import importlib
import matrix_mult_module as mmm
import sys
import sympy as sp
x=[]
tb_container=[]
def init_vector(matrix,m_2):
global x
x=[]
a_matrix=zeros(matrix.shape[0], matrix.shape[1])
b_matrix=zeros(matrix.shape[0], matrix.shape[1])
for i in range(matrix.shape[0]):
for j in range(matrix.shape[1]):
a_matrix[i,j]=randint(-10,10)
b_matrix[i,j]=randint(-10,10)
x.append(a_matrix)
x.append(b_matrix)
a=[]
for i in range(m_2):
b=latex(x[i])
b=b.replace("left[", "left(")
b=b.replace("right]", "right)")
a.append(b)
str1="$\langle"
for i in range(m_2):
if i==m_2-1:
str1=str1+a[i]
else:
str1=str1+a[i]+", "
str1 += "\\rangle$"
return str1
def init_containers(efeld):
global tb_container
tb_container = []
c=[]
for j in range(efeld.shape[1]):
for i in range(efeld.shape[0]):
c.append(widgets.Text(Description="Thema", width=140))
tb_container.append(widgets.HBox(children = [u for u in c]))
c=[]
return cb_container
def evaluate(Ergebnis):
global cb_container
gefunden=True
fehlerbericht=""
Lösung=zeros(Ergebnis.shape[0], Ergebnis.shape[1])
for i in range(Ergebnis.shape[0]):
for j in range(Ergebnis.shape[1]):
Lösung[i,j]=cb_container[i].children[j].value
for i in range(Lösung.shape[0]):
for j in range(Lösung.shape[1]):
if str(Ergebnis[i,j]).strip() != str(Lösung[i,j]).strip():
gefunden=False
fehlerbericht+=" Fehler in Zelle "+ str(i)+" " +str(j) + " wahrer Wert ist " + str(Ergebnis[i,j]) + "\n"
if gefunden==True:
fehlerbericht=" Richtige Lösung "
return gefunden, fehlerbericht
def rechne():
z=x[0]*x[1]
return evaluate(z)
exec_render(Matrix([[0,0],[0,0]]),"Matrixmultiplikation:", Matrix([[0,0],[0,0]]),2)
Nein, das wirst Du nach den bisherigen Erfahrungen nicht tun. Genau so wenig wie Du irgendwelche anderen Hinweise bezüglich Konventionen zu sauberer, lesbarer, wartbarer Programmierung umsetzen wirst.Brando hat geschrieben:Globale Variablen werde ich noch beseitigen.
Was soll `exec_render()` in diesem Beispiel denn überhaupt bewirken? Was soll daraufhin ausgeführt werden und wohin werden die Argumente von dem Aufruf übergeben?
Räum doch bitte mal die Importe auf, entferne dabei die Sternchen-Importe, beseitige ``global``, rücke nach Konvention ein, und lern Python! So unsinnige Sachen wie ```` kann ich echt langsam nicht mehr sehen.

exec_render ist mein Interface zur Darstellung der Eingabevektoren und zur Darstellung der Lösung. Die Eingabevektoren der Matrixmultiplikation werden aber in dem Modul erzeugt, welches ich oberhalb von exec_render eingefügt habe, ebenso das Ergebnis. exec_render ist also ein Programmfunktion eines Programmes, welches das in der Zelle angegebene Modul nutzt.
@Brando: Das ist komplett wirr! Wenn das da ein ”Modul” sein soll, dessen Quelltext in der Zelle steht, dann ist der Aufruf in der letzten Zeile *Teil* dieses ”Moduls”. Und Du willst dem Aufruf irgendwie das Modul mitgeben in dem er selber am Ende ausgeführt wird? Da beisst sich doch irgendwas in den Schwanz…
Das Problem fängt aber wohl da an, das einzelne Zelleninhalte keine Module sind. Warum muss das dort in einer Zelle stehen? Warum kannst Du nicht endlich mal den ganzen ``global``-Mist entfernen und dabei lernen wie man Funktionen und gegebenenfalls Klassen richtig verwendet? Denn dann würdest Du ziemlich sicher nicht *noch gruseligere* Magie als ``global`` ausprobieren, sondern der Funktion da einfach alles was sie braucht als Argumente übergeben. Die normale Lösung halt, die jeder Programmierer versteht, und bei der Du auch nach einem Jahr noch weisst was da wie zusammenhängt und funktioniert. Oder zumindest kannst Du Dich nach einem Jahr da leicht wieder einlesen ohne zu verzweifeln.
Das Problem fängt aber wohl da an, das einzelne Zelleninhalte keine Module sind. Warum muss das dort in einer Zelle stehen? Warum kannst Du nicht endlich mal den ganzen ``global``-Mist entfernen und dabei lernen wie man Funktionen und gegebenenfalls Klassen richtig verwendet? Denn dann würdest Du ziemlich sicher nicht *noch gruseligere* Magie als ``global`` ausprobieren, sondern der Funktion da einfach alles was sie braucht als Argumente übergeben. Die normale Lösung halt, die jeder Programmierer versteht, und bei der Du auch nach einem Jahr noch weisst was da wie zusammenhängt und funktioniert. Oder zumindest kannst Du Dich nach einem Jahr da leicht wieder einlesen ohne zu verzweifeln.
soll ich dann exec_render aufrufen mit dem Quelltext des Programmes quelltext als Übergabeparameter von exec_render(quelltext)? Aber wie verarbeitet dann ipython diesen Quelltext als Modul, welches in dem Programm von exec_render benutzt wird?
@Brando: Nein, Du sollst das ganz anders lösen. Ganz normal halt. Ohne irgendwelche Magie mit implizitem übergeben von Modulen oder gar dem Quelltext von einem Modul.
Ganz normal würde bedeuten, dass ich im Dateisystem ein Modul hinterlege, welches dann im Programm von exec_render eingebunden wird und ausgewertet wird. Das Problem ist nur, dass ich nach Aufgabenstgellung das Dateisystem nicht anrühren soll. Ich muss also irgendwie in eine Zelle einen Code als Modul schreiben, welches dann vom Interface mit der Initialmethode exec_render genutzt wird.
@Brando: was macht denn nun exec_render? Warum bekommt diese Funktion nicht alles, was sie braucht per Argumente? Solche blödsinnigen Abhängigkeiten kommen doch nur daher, dass Du alles per globaler Variablen machst und Deine def-Programm-Abschnitte (Funktionen darf man dazu nicht sagen) undurchsichtige Abhängigkeiten haben.
exec_render ist die initiale Funktion eines Programmes la_scalar_8.py. Dieses Programm ist im für Jupyter Notebook relevanten Ordner abgelegt. Das Programm wird also mit exec_render gestartet, und nutzt ein Modul. Wie gesagt: Wenn ich das Modul am gleichen Ort wie la_scalar_8 speichere und dann exec_render(modulname) aufrufe funktioniert alles. Aber eben das darf ich nicht. Mein Modul soll in eine Zelle geschrieben werden, und ausgehend von dieser Zelle soll la_scalar_8 mittels exec_render dieses Modul nutzen. Im Grunde wäre das Problem gelöst, wenn ich lösen könnte wie die Funktionen eines Moduls in einer Zelle von einem externen Programm aus genutzt werden können.
@Brando: Was ist eine „initiale Funktion“? Was macht diese Funktion? Wenn die ein Modul importiert, dann solltest Du ihr halt ein Modul zum importieren zur Verfügung stellen, und zwar so und dort wie die Funktion das erwartet. Wenn Du das nicht darfst, kannst, oder willst, dann hast Du halt Pech gehabt, oder musst zu gruseligem Voodoo greifen und im Import-Mechanismus von Python herum hacken. Dazu müsste man aber Python können und nicht schon an einfachen Funktionen scheitern. Und wenn man genug Python-Kenntnisse hat, um so etwas umzusetzen, dann macht man das nicht, weil man dann Python gut genug beherrscht um solche komischen Verrenkungen gar nicht erst machen zu müssen.
In Jupyter Notebook haben die aufgerufenen Programme keine main Methode. Sie werden von einer initialen Methode heraus gestartet. Das meine ich mit initial. Das Interface, welches so angesprochen wird greift dann theoretisch auf die Modulinhalte zu, die in einer jupyter cell niedergelegt werden. Der Aufruf dieser Methoden vom Interface aus ist aber nicht zu bewerkstelligen, weil der Zellinhalt nicht als relevant für das Interface erkannt wird.
Selbst der Code funktioniert nicht:
Code: Alles auswählen
from sympy.matrices import *
from builtins import str
from ipywidgets import widgets
from IPython.display import display, HTML, Math, Latex, clear_output
from random import randint
import sys
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
from copy import deepcopy
import numpy as np
import importlib
import matrix_mult_module as mmm
import sys
import sympy as sp
sys.path.insert(0,"/home/Brando/.ipython/profile_default/startup")
x=[]
tb_container=[]
def init_vector(matrix,m_2):
global x
x=[]
a_matrix=zeros(matrix.shape[0], matrix.shape[1])
b_matrix=zeros(matrix.shape[0], matrix.shape[1])
for i in range(matrix.shape[0]):
for j in range(matrix.shape[1]):
a_matrix[i,j]=randint(-10,10)
b_matrix[i,j]=randint(-10,10)
x.append(a_matrix)
x.append(b_matrix)
a=[]
for i in range(m_2):
b=latex(x[i])
b=b.replace("left[", "left(")
b=b.replace("right]", "right)")
a.append(b)
str1="$\langle"
for i in range(m_2):
if i==m_2-1:
str1=str1+a[i]
else:
str1=str1+a[i]+", "
str1 += "\\rangle$"
return str1
def init_containers(efeld):
global tb_container
tb_container = []
c=[]
for j in range(efeld.shape[1]):
for i in range(efeld.shape[0]):
c.append(widgets.Text(Description="Thema", width=140))
tb_container.append(widgets.HBox(children = [u for u in c]))
c=[]
return tb_container
def evaluate(Ergebnis):
global tb_container
gefunden=True
fehlerbericht=""
Lösung=zeros(Ergebnis.shape[0], Ergebnis.shape[1])
for i in range(Ergebnis.shape[0]):
for j in range(Ergebnis.shape[1]):
Lösung[i,j]=tb_container[i].children[j].value
for i in range(Lösung.shape[0]):
for j in range(Lösung.shape[1]):
if str(Ergebnis[i,j]).strip() != str(Lösung[i,j]).strip():
gefunden=False
fehlerbericht+=" Fehler in Zelle "+ str(i)+" " +str(j) + " wahrer Wert ist " + str(Ergebnis[i,j]) + "\n"
if gefunden==True:
fehlerbericht=" Richtige Lösung "
return gefunden, fehlerbericht
def rechne():
z=x[0]*x[1]
return evaluate(z)
def initialisiere():
i_progr=importlib.import_module("la_scalar_8")
i_progr.exec_render(Matrix([[0,0],[0,0]]),"Matrixmultiplikation:", Matrix([[0,0],[0,0]]),2)
initialisiere()
@Brando: wenn la_scalar_8 ein Modul ist, das Du einfach importieren kannst, dann mach das doch mit "import" und mach nicht solche Verrenkungen.
Dass inzwischen alle Importe doppelt sind, macht die Sache nicht besser. Ein "funktioniert nicht" ist bei der Fehlersuche nicht sehr hilfreich. Bisher ist glaube ich noch niemandem hier klar, was eigentlich Dein Problem ist.
Dass inzwischen alle Importe doppelt sind, macht die Sache nicht besser. Ein "funktioniert nicht" ist bei der Fehlersuche nicht sehr hilfreich. Bisher ist glaube ich noch niemandem hier klar, was eigentlich Dein Problem ist.
Ein einfaches import löst das Problem auch nicht. Es wird nicht erkannt, was ich an Methoden in die Zelle geschrieben habe. Die Fehlermeldung lautet:
NameError: name 'init_vector' is not defined.
Also genau die Methode, die ich in der Zelle verwende wird nicht erkannt.
NameError: name 'init_vector' is not defined.
Also genau die Methode, die ich in der Zelle verwende wird nicht erkannt.
@Brando: Also mir ist immer noch nicht ganz klar wie das funktionieren soll. Diese Meldung kommt vom importieren des Moduls? Dann fehlt dem diese Funktion, oder aber es läuft Code mit Nebeneffekten beim importieren, was nicht sein sollte, denn dann kann man das Modul nicht sinnvoll als Modul verwenden.
@Sirius3: Also das eigentliche Problem ist mir schon klar, und das sitzt IMHO eindeutig vor dem Rechner.
@Sirius3: Also das eigentliche Problem ist mir schon klar, und das sitzt IMHO eindeutig vor dem Rechner.
