ValueError: complex() arg is a malformed string - python-3.x

I have to take complex number as an input from Entry widget of tkinter and perform the conjugate operation on that complex number. I applied explicit conversion method but my code is not able to convert Entry widget string into complex number and showing error "ValueError: complex() arg is a malformed string" Can anyone help me?
Thank you in advance.
lbl_shh=Label(second_root,text="Enter parameter Shh",fg="red").grid(column=0,row=7,padx=20,pady=20)
e_shh = Entry(second_root)
lbl_svv=Label(second_root,text="Enter parameter Svv",fg="red").grid(column=0,row=8,padx=20,pady=20)
e_svv = Entry(second_root)
e_shh.grid(column=1,row=7)
e_svv.grid(column=1,row=8)
shh=e_shh.get()
svv=e_svv.get()
shh=shh.replace(" ","")
svv=svv.replace(" ","")
shh=complex(shh)
svv=complex(svv)
#shh=complex(''.join(shh.split()))
#svv=complex(''.join(svv.split()))
shhs=np.conjugate(shh)
svvs=np.conjugate(svv)
num= svv*svvs
dem=shh*shhs
f=np.power(num/dem, 0.25)
I have to print the value of f

I think you misunderstand how to properly get information within tkinter and probably Python in general.
You cannot just use .get() when your code is just initializing. It will always return an empty string unless you have some code that sets the value prior to get and at that point its just redundant to use get.
What you need to do is have some code like a button that will pull the value of your entry(s) after someone has added something to them.
Also I noticed in your example code you have second_root and this leads me to believe you are using 2 instances of Tk() in your code. If that is the case this may also be part of your problem. You should only ever have one instance of Tk() when coding in tkinter.
To ilistrate your problem Take this example:
I added some print statements, a function and a button to show what was actually being grabbed by get() or rather to show it is an empty string. If you do not have anything in the field by the time get() is executed.
And here is an example result from when you put a proper value that complex() can use.
See below example to get an idea of how get() works:
import tkinter as tk
root = tk.Tk()
entry = tk.Entry(root)
entry.pack()
def print_entry():
print(entry.get())
tk.Button(root, text='Print Entry', command=print_entry).pack()
root.mainloop()

Related

Tkinter ValueError: could not convert string to float: ''

It's the whole day I'm trying to solve this ridiculous problem, but without success; in this forum there is a lot of material, but usually they are enormous amounts of code and I cannot understand what's going on. On the internet they generally suggest casting but it doesn't work. To make things easy I wrote a sample code to illustrate the issues I'm having in a bigger code
import tkinter as tk
from tkinter import *
#from tkinter import ttk
my_window = tk.Tk()
my_label = tk.Label(master=my_window,text="N")
my_label.pack()
my_entry = tk.Entry(master=my_window)
my_entry.pack()
N = my_entry.get()
print(float(N))
my_window.mainloop()
Very nice and simple, but I get the following message
ValueError: could not convert string to float: ''
I tried many possibilities, but anything worked. Any little suggestion is very much appreciated. Thanks
Edit:
I want to understand how to assign float(N) to a global variable, say a, so I can use it later on in the code, and I just took the code of #Cool Cloud and modified it a little
import tkinter as tk
from tkinter import *
my_window = tk.Tk()
a=1.
def cast():
N = my_entry.get()
try: # Try to execute this
print(float(N))
a=float(N)
except ValueError: # If ValueError(meaning it is not a float) is triggered then print...
print('Not a number!')
my_label = tk.Label(master=my_window,text="N")
my_label.pack()
my_entry = tk.Entry(master=my_window)
my_entry.pack()
# N = my_entry.get() N will be empty as my_entry is empty when code is executed
Button(my_window,text='Click me to convert to
float',command=cast).pack() # A button to trigger event
print(a)
my_window.mainloop()
The output of this is in the following image
As you can see it directly prints 1.0 without waiting for the assignment a=float(N), so my doubt is how can I actually do this assignment, to use it later in my code. Thanks
P.S.: I understand that print(a) inside the definition of cast() would give correctly 123.0 in this case, but my problem is more general: I'm trying to understand how to entry an N value, making it float and "propagate" it to the rest of the program. My doubt is given by the fact that print(a) almost at the very last line of the program, and still doesn't wait for cast() to come in.
GUI programming is event driven, which means you will have to code based on events triggered. Every python code runs from top to bottom, and in this case all the code from top to bottom, outside functions, is executed. That means as soon as:
my_entry = tk.Entry(master=my_window)
my_entry.pack()
...is executed, the next line to be executed is N = my_entry.get(), and at the time of execution there is NOTHING inside the entry widget and hence N becomes empty string, and then you are trying to convert that empty string to a float, which will obviously give an error.
What you should be doing is, make a button and when you click it(event is triggered) and connect it to a function that will get the input and convert to float. So that when you click the button you have entered something onto the entry and now it is no longer empty.
import tkinter as tk
from tkinter import *
my_window = tk.Tk()
def cast():
N = my_entry.get()
try: # Try to execute this
print(float(N))
except ValueError: # If ValueError(meaning it is not a float) is triggered then print...
print('Not a number!')
my_label = tk.Label(master=my_window,text="N")
my_label.pack()
my_entry = tk.Entry(master=my_window)
my_entry.pack()
# N = my_entry.get() N will be empty as my_entry is empty when code is executed
Button(my_window,text='Click me to convert to float',command=cast).pack() # A button to trigger event
my_window.mainloop()
Another way, and an unpopular way, is to use DoubleVar() which will get() the text for you, in this case, your entry will accept any value but when you get() the value from the DoubleVar() it will raise a TclError if it is not a float.
def cast():
# Unlike before, error will be generated at get() and you dont need float()
# because if there is no error then it is guaranteed to be a float anyway
try:
N = var.get()
print(N)
except TclError: # If TclError is triggered then print...
print('Not a number!')
var = DoubleVar() # tkinter control variable
my_entry = tk.Entry(master=my_window,textvariable=var)
my_entry.pack()
Note: You can do my_entry.get() and it wont give any error even if the input is not a float, error comes only in the case of var.get().
From:https://www.geeksforgeeks.org/python-tkinter-entry-widget/
"get() : Returns the entry’s current text as a string."
I think that you can't just convert string to float.

How to fix tkinter validation (using regex and vcmd)

This code is a snippet of a program. I tried to do a system that validate an input, only if input is one or more numbers (r"^\d+$"). But it doesn't work, i check on my tkinter book reference, but i didnt find errors. The way that i develop it is using a vcmd function, that pass the value ("%P"), calling a function that validate the value. When it run match method of regex module, if it match the value in pattern, it get True, otherwise False. If False i want that non-numerical text wont be displayed in Entry widget, if True i want that numerical text will be displayed in Entry widget. Moreover it doesnt run invalidcommand function, and i tried to see how many time the validating function is run (only the first time).
import tkinter
import re as regex
from electronic_formulas import Electronic
class App(tkinter.Tk):
def __init__(self):
super().__init__()
self.var_r1 = tkinter.DoubleVar()
self.var_r2 = tkinter.DoubleVar()
self.pattern = regex.compile(r"^[0-9]+$")
vcmd = (self.register(self.validating_values), "%P")
self.frame_left = tkinter.Frame(self)
self.frame_left.pack(side=tkinter.LEFT)
self.frame_right = tkinter.Frame(self)
self.frame_right.pack(side=tkinter.RIGHT)
self.entry_r1 = tkinter.Entry(self.frame_left, textvariable=self.var_r1, validate="key",
validatecommand=vcmd, invalidcommand=lambda: print("Error"))
self.entry_r1.pack(side=tkinter.TOP)
self.entry_r2 = tkinter.Entry(self.frame_left, textvariable=self.var_r2, validate="key",
validatecommand=vcmd, invalidcommand=lambda: print("Error"))
self.entry_r2.pack(side=tkinter.TOP)
self.var_r1.set("")
self.var_r2.set("")
def validating_values(self, value):
return self.pattern.match(value) is not None
app = App()
if __name__ == "__main__":
app.mainloop()
No tcl errors.
There are two problems:
you've set the value to be a DoubleVar, but then you don't allow a decimal point.
your validation function doesn't allow an empty string but then you set the value to an empty string.
This is what the canonical tcl/tk documentation says about mixing validatecommand with textvariable:
In general, the textVariable and validateCommand can be dangerous to mix. Any problems have been overcome so that using the validateCommand will not interfere with the traditional behavior of the entry widget. Using the textVariable for read-only purposes will never cause problems. The danger comes when you try set the textVariable to something that the validateCommand would not accept, which causes validate to become none (the invalidCommand will not be triggered). The same happens when an error occurs evaluating the validateCommand.
You are doing exactly that: setting the textvariable to something that the validatecommand would not accept. As a consequence, the validate option is set to None.

Tkinter Entry validatation

I am writing a program in Python 3.6 using Tkinter where a customer has multiple(11) entry fields. I want these entry fields to only accept integers and also be able to define the maximum amount of characters.
I already have a function that does this. But this function only works for one entry field. I have tried entering variables with calling the function so it changes another entry field for example. I was not able to do this.
This is the function I have that works with 1 entry field.
def limitMuntgeld(self, *args):
value = self.invoerM.get()
if len(value) > 5:
self.invoerM.set(value[:5])
if value.lower() in "abcdefghijklmnopqrstuvwxyz-=[];/":
self.invoerM.set(value[:0])
This is the example entry field code that works with the function
self.invoerMuntgeld = Entry(self, font=('Arial', 14), textvariable=self.invoerM)
This is combined with a trace on the entry field posted below.
self.invoerM = StringVar()
self.invoerM.trace('w', self.limitMuntgeld)
I have also tried it with vcmd and validatecommand. However, no good results.
My endresult would be one function working with all entry fields. If anyone has any suggestions, I am all ears!
The proper way to do entry validation is with the validatecommand option rather than using trace. With the validation feature built into the widget you don't need a reference to the widget itself (though you can use it if you want).
When the validatecommand is run, you can have it pass in what the new value will be if the input is valid. You only need to check this value and then return True or False, without having to know which widget it applies to.
For example:
import tkinter as tk
def validate_input(new_value):
valid = new_value .isdigit() and len(new_value) <= 5
return valid
root = tk.Tk()
validate = root.register(validate_input)
for i in range(10):
entry = tk.Entry(root, validate="key", validatecommand=(validate, "%P"))
entry.pack(side="top", fill="x")
root.mainloop()
For information about what %P represents, and what else can be used as arguments to the command, see this question: Interactively validating Entry widget content in tkinter

tkinter scrolledtext.insert and label.configuration point of execution

I have the following python36 code wich is checking values, and then set a tkinter label that the entry values has been accepted, to then execute another threaded function. Before and after the function as well as inside the function I would like to display something in a tkinter scrolledtext box. Like it where a console/shell.
All the label.configure() as well as scrolledtext.insert() are only getting displayed all at the same time after everything has been run.
I am not able to use the scrolledtext.insert() inside the threaded function (fundamentals question, could I use it inside a function of an imported module?)
I would like to have the execution time of these functions like if I would use the print() function. So execute it as soon as the script went over it.
It would be nice if you could explain to me why this is not executed immideately since I am currently learning python or point me to the appropriate reference.
elif str(x2) == 'None' and str(x3) == 'None':
E2T = 'accepted'
E2L.configure(text=E2T, fg="green")
E2L.grid(row=5, column=2)
E3T = 'accepted'
E3L.configure(text=E3T, fg="green")
E3L.grid(row=6, column=2)
# Start scanning process
scrolledtext.insert(tkinter.INSERT, 'Start scanning....\n' )
print('testprint')
portlist = scan(E1.get(),E2.get(),E3.get())
# try work with returned value and display as in a console
print(portlist)
print('testprint')
scrolledtext.insert(tkinter.INSERT, 'Following Ports are open\n' )
scrolledtext.insert(tkinter.INSERT, str(portlist))
You can do scrolledtext.update_idletasks() after a scrolledtext.insert(), it will refresh the widget and your text will pop.
see that comment for more.
Hope it help!

Passing StringVar object from Entry to Label within functions in tkinter

Hi I've been struggling to get this to work, each time i change something I receive another error. I've been trying to create an entry box with a function and then get the variable from the entry box into a label, created by a button press. When I tried to do this often this error came up.
TypeError: get() missing 1 required positional argument: 'self'
I then put self in in the method brackets.
command = lambda: x.myFunc(self.my_variable.get(self))
Then another error, which I'm not sure how to sort out.
AttributeError: 'My_Class' object has no attribute '_tk'
Here's the full code, I'm new to classes and self, so any corrections are welcome.
from tkinter import *
import time
class My_Class:
def start(self):
self.root=Tk()
self.my_variable=StringVar
self.entry_box=Entry(self.root, textvariable=self.my_variable)
self.entry_box.pack()
self.button=Button(self.root,text="Pass variable now",
command=lambda:x.myFunc(self.my_variable.get(self)))
self.button.pack()
def myFunc(self,my_variable):
self.lab=Label(self.root,text=self.my_variable)
self.lab.pack()
x=My_Class()
x.start()
This is the correct way to create a StringVar object:
text = StringVar() # note additional ()
Can you explain me what x is in the following statement:
lambda: x.myFunc(self.my_variable.get(self))
x is not visible inside the class, because it's declared outside the class.
myFunc is not indented correctly: you should indent it like the __init__ method.
I really recommend you to watch some tutorials on OOP before proceeding. You are basically trying to guess how OOP works.
If you make myFunc A method if the class (which you might be trying to do; it's hard to know because your indentation is wrong), you don't have to pass anything to myFunc. That function has access to everything in the class, so it can get what it needs, when it needs it. That lets you eliminate the use of lambda, which helps reduce complexity.
Also, you normally don't need a StringVar at all, it's just one more thing to keep track of. However, if you really need the label and entry to show exactly the same data, have them share the same textvariable and the text is updated automatically without you having to call a function, or get the value from the widget, or set the value n the label.
Here's an example without using StringVar:
class My_Class:
def start(self):
...
self.entry_box = Entry(self.root)
self.button = Button(..., command = self.myFunc)
...
def myFunc(self):
s = self.entry_box.get()
self.lab = Label(..., text = s)
...

Resources