How to erase letters between numbers (Python) - python

I've been having a lot of difficulties with this code, and I just can't find any solutions, I will post my code below.
from tkinter import *
a = []
class test(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title('testing')
self.pack(fill=BOTH, expand=1)
self.d = DoubleVar()
self.d.set('None')
def grab():
b = ent.get()
a.append(b)
c = [s.strip('qwertyuiopasdfghjklzxcvbnm') for s in a]
self.d.set(c[-1])
if c[-1] == '':
self.d.set('None')
ent = Entry(self)
ent.grid(row=0, column=0)
but = Button(self, text='Get', command=grab)
but.grid(row=1, column=0)
Label(self, textvariable=self.d).grid(row=2, column=0)
root = Tk()
app = test(root)
root.mainloop
I guess my objective is to be able to ignore, or delete the letters that are placed inside of the entry box, as you can see, I've used the strip method, but it doesn't work the way I would like it to. If anyone could offer some advice, or a code, or link me to a question that I overlooked, that would be amazing, and I would be greatful.
EDIT: It already clears letters before and after, but nothing in between

A validator would be the correct pattern to solve this problem. Interactively validating Entry widget content in tkinter has an implementation in tkinter that you should be able to use.

A little bit of lambda should do the trick
a = "123a3456b"
filter(lambda '0' <= x <= '9', a)
print a
"1233456"

You're getting letters inside the numbers because you're putting the string into a list first.
strip() removes leading and trailing characters, so if you have a string: aaa000bbb111ccc, stripping letters from it will only remove the outer-most letters. If you split the string, however, and then strip letters from each element of the stripped string, you'll effectively remove all the letters. Then, you can join() the remaining parts of the list together to get back to your string. Consider this example:
>>> import string # string.ascii_letters returns a string of all letters (upper and lower), just easier than typing them
>>> def check(x):
return ''.join([char.strip(string.ascii_letters) for char in x])
>>> var = 'aaa000bbb111ccc'
>>> var_as_list = [var]
>>> check(var)
'000111'
>>> check(var_as_list)
'000bbb111'
So, c should be:
c = ''.join([s.strip('qwertyuiopasdfghjklzxcvbnm') for s in b.get()])
You should also consider some further validation, if you want the field to only contain floats. Here's one method to trace any changes to a StringVar() instance and restrict changes to it to only being numbers and periods:
from tkinter import *
import string
def check(*args):
# make a 'whitelist' of allowable characters
whitelist = string.digits + '.'
# set var to its current value - any characters not in whitelist
var.set(''.join([i for i in var.get() if i in whitelist]))
root = Tk()
var = StringVar()
var.set('0.0')
Entry(root, textvariable=var).grid(row=0, column=0)
Label(root, textvariable=var).grid(row=1, column=0)
var.trace('w', check) # if var changes, call check()
mainloop()

a clean way to do this is simply:
filter(lambda s: not str.isalpha(s), data)

Related

How to check input in Textbox Tkinter Python?

I am Python coder and got stuck in a question that "How to check input in textbox of tkinter python". The problem is that it is not giving output on writing this code .
def start(event):
a = main.get(1.0,END)
if a == 'ver':
print('.....')
main = Text(root)
main.pack()
root.bind('<Return>',start)
We can do this by get() method:
from tkinter import *
a=Tk()
def check():
print(x.get('1.0',END)[:-1])
x=Text(a)
b=Button(a,text='Check',command=check)
x.pack()
b.pack()
a.mainloop()
The text widget guarantees that there is always a trailing newline. When you do get(1.0,END) you're getting that trailing newline even if the user doesn't enter a newline.
If you want to get exactly what the user entered, use get("1.0", "end-1c"). That will get all of the characters up to the end, minus one character.
Note: text indexes are strings of the form line.character. Your code is using the floating point value 1.0 which is incorrect. It works fine in some cases, but it won't work in all. You should always use a string rather than a float for text indexes.
from tkinter import *
from threading import Thread
root = Tk()
def check():
while True :
a = main.get(1.0,END)[:-1]
if a == 'ver':
print('.....')
main = Text(root)
main.pack()
Thread(target=check).start()
root.mainloop()
You should write something like
def start(event):
t = var.get()
if t == 'something':
pass
var = StringVar()
e = Entry(master, textvariable=var)
e.pack()
e.bind(bind('<Return>',start)

How to validate a Tkinter entry widget to only accept string?

I am trying to work my way through Tkinter and this is a part of my code:
FirstName = Label(canvas, text="First Name")
FirstName.configure(width=30, bg="white", fg="black", border=10)
FirstName = canvas.create_window(330, 130, anchor = CENTER, window=FirstName)
FName_Entry = Entry(canvas)
canvas.create_window(850, 145, window=FName_Entry, height=35, width=300)
As you can see this is an entry widget for users to enter their first name.
how can I validate this to only accept string (letters) and if they try to enter integers, symbols or basically anything that is not a letter, it should display a message on the side of the widget urging users to enter a valid name.
I tried to check online but most of them are using classes and I am not used to classes as of yet and am new to Tkinter. other examples explain how to limit entry to integers so I am a bit confused here.
Thanks for helping!
Here is a small snippet to actually make you understand better
from tkinter import *
from tkinter import messagebox
root = Tk()
def check():
sel = e.get()
if not sel.isalpha():
messagebox.showerror('Only letters','Only letters are allowed!')
e = Entry(root)
e.pack(pady=10)
b = Button(root,text='Click Me',command=check)
b.pack(padx=10,pady=10)
root.mainloop()
Here we are checking if sel.isalpha() returns False or not, if it does, then show a messagebox saying only letters are allowed. Simple as that.
Do let me know if any errors. Happy coding
Here is more on isalpha() method
Cheers
You can use list in which you can store the letter which is to be accepted.
Then check the each letter of the input with the element in the list.
If any character not found from the input in the list(acceptable character) then it is invalid input.
# acceptable character list
accepted_characters = ['a', 'b', 'c',.....'z', 'A', 'B', 'C',...'Z']
# input from the tkinter entry widget
inp = "hello"
for i in inp:
if i not in accepted_characters:
print('Invalid data.')
Another way is using RegEx module which is built-in module. But I am not too familiar with RegEx.

Python prints { } instead of an empty space - tkinter

In this simple example, I would like the label to be displayed as "1 3":
import tkinter
window = tkinter.Tk()
A = [1," ", 3]
label = tkinter.Label(window, text = A[0:])
label.pack()
window.mainloop()
However, python displays "1 { } 3" instead.
Where is the problem?
As jonathan and Ron Norris already said, you need to pass a string to the text argument of the Label constructor.
I would suggest to transform your heterogeneous list to a string thusly:
A = [1," ", 3]
labeltext = ''.join(map(str, A))
label = tkinter.Label(window, text = labeltext)
Documentation link for map: map documentation for python 3
Documentation for str: str documentation for python 3
Documentation for the join method of string: string join method, python 3
Edit: Since you now ask for a way to do this in many code locations, with minimal code changes, I would suggest this wrapper around tkinter.Label:
def createlabel(*args, **kwargs):
if 'text' in kwargs and isinstance(kwargs['text'], list):
kwargs['text'] = ''.join(map(str, kwargs['text']))
return tkinter.Label(*args, **kwargs)
This function will pass all of its arguments unchanged to tkinter.Label, but taking care to transform a text keyword argument to a string, if it is a list.
When you have defined this, use a "Find & Replace" function in your editor to replace calls to tkinter.Label with createlabel.
Your original could would be transformed like this, for example:
import tkinter
def createlabel(*args, **kwargs):
if 'text' in kwargs and isinstance(kwargs['text'], list):
kwargs['text'] = ''.join(map(str, kwargs['text']))
return tkinter.Label(*args, **kwargs)
window = tkinter.Tk()
A = [1," ", 3]
label = createlabel(window, text = A[0:])
label.pack()
window.mainloop()
A[0:] is a heterogeneous list, tkinter.Label's documentation suggests that its text parameter should receive a string (Which the word "text" also quite strongly suggests)
https://docs.python.org/3/library/tkinter.ttk.html#label-options
If you want "1 3", try:
A = [1," ", 3]
s = ''
for c in A:
s += str(c)
label = tkinter.Label(window, text = s)

Python: User's input defining file extension

I need to code a tkinter dialog box, where user must input three letters only (file extension). I'm using my code to ask user for two different types of files within some folder, but there are files with lowercase and uppercase extension, therefore I need to transform the result into uppercase and lowercase string.Here is my code:
class ext_box(tkSimpleDialog.Dialog):
def body(self, master):
Label(master, text="First file extension:").grid(row=0)
Label(master, text="Second file extension:").grid(row=1)
self.e1 = Entry(master)
self.e2 = Entry(master)
self.e1.grid(row=0, column=1)
self.e2.grid(row=1, column=1)
return self.e1
def validate(self):
try:
ext1 = ?
ext2 = ?
self.result = ext1, ext2
return 1
except ValueError:
tkMessageBox.showwarning(
"Please try again."
)
return 0
Edit:
This code works with ext1 = self.e1.get() and ext1 = self.e2.get().My questions are:How can I define three letters as an input from the user for ext1 and ext2? After I get these results, How can I make the input uppercase and lowercase for each result?
Is your question how to transform a string to uppercase or lowercase? In that case you can use string.upper() or string.lower()
example:
>>> 'a'.upper()
'A'
>>> 'A'.lower()
'a'
In order to extract the current values from the Entry items you need something like:
ext1 = self.e1.get()
ext2 = self.e2.get()
but that's unlikely to raise a ValueError, you will need further validation code to that. Suitable validation code might look something like this.
if (len(ext1) != 3 or not ext1.isalpha()
or len(ext2) != 3 or not ext1.isalpha()):
raise ValueError

First letters of a Tkinter input

My program should check if the first three letters of the input word are similar to a predefined word.
I've made a GUI with Tkinter and want to get the letters of the input field.
Somehow I can't implement it in like I would do without Tkinter.
That's how I do it just for the shell:
text = raw_input('Enter a word: ')
if (text[0] + text[1] + text[2] == 'sag'):
print "sagen"
else:
print "error"
So, when I input the word "sagst" it checks the first three letters and should put out "sagen". Works fine.
I learned that e.g. inputfield.get() gets the input of the entry "inputfield".
But how can I check the first letters of that "inputfield"?
A small selection:
from Tkinter import*
root = Tk()
def check():
if (text[0] + text[1] + text[2] == 'sag'):
print "True"
else:
print "False"
inputfield = Entry(root)
inputfield.pack()
but = Button(root,text='Check!', command = check)
but.pack()
text = inputfield.get()
root.mainloop()
Does not work...
I hope you can understand my question and will answer soon. (Sorry for my bad english and my bad Python skills) ;-)
Thanks!
Your check function will have to retrieve the textfield after the button has been pressed:
def check():
text = inputfield.get()
print text.startswith('sag')
I've changed your test a little, using .startswith(), and directly printing the result of that test (print will turn boolean True or False into the matching string).
What happens in your code is that you define inputfield, retrieve it's contents (obviously empty), and only then show the TKInter GUI window by running the mainloop. The user never gets a chance to enter any text that way.
You can also check this without the need for a button (Now it will check whenever the user presses "Enter"):
from Tkinter import *
root = Tk()
def check(*event):
text = inputfield.get()
print text.startswith('sag')
inputfield = Entry(root)
inputfield.bind('<Return>',check)
inputfield.pack()
root.mainloop()
You can also do other things to have your widget validate the entry as you type. (The link is old, but it also points to newer features that allow you to do this without subclassing).
You're not actually putting the value in the input field into the text variable.
I renamed the value from text to input_text because it was confusing to me. I also changed from using text[0] + text[1] + text[2] to using startswith(). This will keep you from getting IndexErrors on short strings, and is much more pythonic.
from Tkinter import*
root = Tk()
def check():
input_text = inputfield.get()
if input_text.startswith('sag'):
print "True"
else:
print "False"
inputfield = Entry(root)
inputfield.pack()
input_text = inputfield.get()
print input_text # Note that this never prints a string, because it only prints once when the input is empty.
but = Button(root, text='Check!', command=check)
but.pack()
root.mainloop()
The key change is that the check function needs to actually get the value in the inputfield.
Here is a version which uses an Entry widget which validates its contents as the user types (so the user does not have to click a button or even press Return).
import Tkinter as tk
class MyApp(object):
'''
http://effbot.org/zone/tkinter-entry-validate.htm
http://effbot.org/tkinterbook/entry.htm
http://www.tcl.tk/man/tcl8.5/TkCmd/entry.htm#M-validate
'''
def __init__(self, master):
vcmd = (master.register(self.validate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.entry = tk.Entry(master, validate = 'key',
validatecommand = vcmd)
self.entry.pack()
self.entry.focus()
def validate(self, action, index, value_if_allowed,
prior_value, text, validation_type, trigger_type, widget_name):
dtype = {'0':'delete', '1':'insert', '-1':'other'}[action]
n = min(3, len(value_if_allowed))
valid = False
if dtype == 'insert':
if value_if_allowed[:n] == 'sag'[:n]: valid = True
else: valid = False
else: valid = True
print(valid)
return True
root = tk.Tk()
app = MyApp(root)
root.mainloop()

Categories

Resources