Validation of Enter Fields - tkinter-entry

Interactively validating Entry widget content in tkinter
the link above explains how to do validation.
I am trying to do the same thing. But somehow i am not able to do it.
It is a 10 digit string. The first two being alphabets, the next two numbers then again the next two will be alphabets and then the rest all numbers.
for example MH02UH2012.
Other question which i have is when i run this the print of S and i is coming for the first three inputs only after that there is no print. and sometimes it prints only the first entered variable. I am not able to understand what is the issue
import tkinter
tk=tkinter.Tk()
def only_numeric_input(P,S,i):
i = int(i)
print (i, S)
if S == " ":
return False
elif i < 2:
if not S.isdigit():
return True
elif i > 5:
if S.isdigit():
return True
else:
return False
elif i > 9:
return False
e1=tkinter.Entry(tk)
e1.grid(row=0,column=0)
c=tk.register(only_numeric_input)
e1.configure(validate="key",validatecommand=(c,'%P', "%S", "%i"))
tk.mainloop()

There are issues in the condition statements of the only_numeric_input function. Try the below only_numeric_input function instead.
def only_numeric_input(P,S,i):
i = int(i)
print (i, S)
if S == " ":
return False
if i < 2 or (i>3 and i<6):
if S.isalpha() and S.isupper():
return True
else:
return False
elif i<10:
if S.isdigit():
return True
else:
return False
elif i > 9:
return False

Related

How to create a perfect number function using lists

My perfect number function is not working as intended :(. It prints false even though it should print true :(
def perfect_check(number):
z = []
for i in range(1, number):
if number % i == 0:
z.append(i)
if sum(z) == number:
return True
else:
return False
print(perfect_check(6))
def perfect_check(number):
z = []
for i in range(1, number):
if number % i == 0:
z.append(i)
if sum(z) == number:
return True
else:
return False
print(perfect_check(6))
You have put the if-else statement inside your for loop. It should be outside the for loop. Then, your code will work correctly.

Checking if a number is palindrome

I have this code for checking if a number is a palindrome and for some reason it returns false for number=1 even though it is palindrome. Why is that? The code works for other cases such as 12321.
def palindrome_integer(number):
if number != int:
return False
elif str(number) == str(number)[::-1]:
return True
else:
return False
If you want to check if number is integer, you should use isistance.
def palindrome_integer(number):
if not isinstance(number, int):
return False
elif str(number) == str(number)[::-1]:
return True
else:
return False
The rest of your code seems to work fine.
One-liner:
return isinstance(n, int) and str(n) == str(n)[::-1]
Or slightly more contrived:
import re
x = str(n)
return re.match(r”\d+“, x) and x == x[::-1]
solution without string
def palindrome_integer(num):
copy = num
rev = 0
while num!= 0:
rev = rev*10+num%10
num = num//10
return rev == copy
def palindrome_integer(number):
return type(number) == int and str(number)[::-1] == str(number)
Don't hesitate to comment if you have problem in understanding the solution.

def function to compare two strings

we need to define a function that compares two strings and if they are different we want to know the index. the problem is that no matter what insert we use we always get -1 even when they are not the same.
def mutation_detector(seq1,seq2):
if DNAval(seq1) and DNAval(seq2) == True:
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return(i)
else:
return(-1)
else:
return('Wrong input')
else:
return('Wrong input')
print(mutation_detector('ATCGGGTA','ATCGGCTA'))
Basically you're using and wrong and have some basic Logic errors I think:
and doesn't say "do A and B" but rather"if A is True and B is True"
My attempt at fixing it is as follows:
if DNAval(seq1) and DNAval(seq2):
if len(seq1) == len(seq2):
for (i, (elem1, elem2)) in enumerate(zip(seq1, seq2)):
if elem1 != elem2:
return i
return -1
Your if-else in the loop always returns in the First loop iteration: it takes the first two chars and compares them; are they equal? No -> return -1
If you follow the logic, it begins comparing strings. If the two letters are the same, it goes for the ELSE (because they are not different) and ends the routine after checking only the first letter.
You only want the routine to return -1 if it makes it all the way through the for loop without returning an index number. So,
Change as below:
def test(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return(i)
return(-1)
else:
return('Wrong input')
print( test('Hello1', 'Hello2'))
print('done')
The problem is, that you are returning -1 on the first time you run through the for loop, because the else-clause is immediately entered.
Use the else clause with the for loop itself instead.
For example:
def compare_strings(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return i
else:
return -1
else:
return 'Wrong input'
(mind you, raising a custom exception might be better than returning "Wrong input" here...)
Here's how I would do it
def mutation_detector(seq1, seq2):
if not DNAval(seq1) or not DNAval(seq2) or len(seq1) != len(seq2):
return "Wrong input" # maybe raise ValueError if DNAval fails instead?
for index, (base1, base2) in enumerate(zip(seq1, seq2)):
if base1 != base2:
return index
return -1
Try this,
It will return index when unable to compare otherwise it will compare two character and to print equal again compare it with length of string.
def mutation_detector(seq1,seq2):
count=0
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return i
else:
count=count+1
if count==len(seq1):
return 'Equal'
print(mutation_detector('ATCGGCTA','ATCGGCTA'))
def comp_string(string1,string2):
if len(string1)!=len(string2):
return "length not equal"
else:
for i in range(len(string1)):
if string1[i] != string2[i]:
return i
return "equal"

Write a Python function squareprime(l)

Write a Python function squareprime(l) that takes a non-empty list of integers and returns True if the elements of l alternate between perfect squares and prime numbers, and returns False otherwise. Note that the alternating sequence of squares and primes may begin with a square or with a prime.
Here are some examples to show how your function should work.
>>> primesquare([4])
True
>>> primesquare([4,5,16,101,64])
True
>>> primesquare([5,16,101,36,27])
False
Function prime_checker checks if a number is prime or not.
Function is_square checks if a number is prefect_square or not.
If the number at index 0 is square, then the chain is like [square, prime, square...]
else the sequence goes like [prime, square, prime, square..]
If the input sequence is not either of the two, then it is not a valid sequence and it will return False.
import math
def prime_checker(num):
flag = True
if num == 2:
return True
elif num < 2:
return False
else:
for i in range(2, int(num/2)):
if num % i == 0:
flag = False
break
return flag
def is_square(integer):
if integer == 0:
return false
root = math.sqrt(integer)
if int(root + 0.5) ** 2 == integer:
return True
return False`
def primesquare(list_nums):
if len(list_nums) == 0:
return False
if len(list_nums) == 1:
if (is_square(list_nums[0]) or prime_checker(list_nums[0])):
return True
else:
return False
else:
flag = True
if is_square(list_nums[0]):
check_for = 'prime'
elif prime_checker(list_nums[0]):
check_for = 'square'
else:
return False
for i in range(1,len(list_nums)):
if (check_for == 'prime' and prime_checker(list_nums[i])):
check_for = 'square'
elif (check_for == 'square' and is_square(list_nums[i])):
check_for = 'prime'
else:
flag = False
break
if flag:
return True
else:
return False
Update:
As the element at the 0th index has already been checked, we are not concerned about that number anymore. Hence, if the 0th element is a prime number, then the sequence will be [prime, square, prime, square,...].
If it is a perfect square, then the sequence will be [square, prime, square, prime...].
If it is neither of the two, then it is not a valid sequence and hence, false is returned.
Now, if the first number was either of the two, and the length of the list is greater than 1, then we will iterate over the remaining elements and check if they are similar to what we expected, but changing the value of check_for variable.
If the value of check_for is prime and the value that we encountered is also prime, then we know that the next number of the sequence should be a square number for the sequence to be a valid sequence. The similar thing happens when a square number is encountered.
from math import sqrt
def square(n):
if(sqrt(n) % 1 == 0):
return True
else:
return False
def isprime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
def primesquare(list_nums):
if len(list_nums) == 0:
return False
if len(list_nums) == 1:
if (square(list_nums[0]) or isprime(list_nums[0])):
return True
else:
return False
else:
flag = True
if square(list_nums[0]):
check_for = 'prime'
elif isprime(list_nums[0]):
check_for = 'square'
else:
return False
for i in range(1,len(list_nums)):
if (check_for == 'prime' and isprime(list_nums[i])):
check_for = 'square'
elif (check_for == 'square' and square(list_nums[i])):
check_for = 'prime'
else:
flag = False
break
if flag:
return True
else:
return False
from math import sqrt
def isprime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
def primesquare(l):
flag=0
if len(l)==1:
n=l[0]
if(sqrt(n)%1==0):
return True
else:
for i in range(0,len(l)):
if(sqrt(l[i])%1==0):
if(i==0):
if(isprime(l[i+1])==True):
flag=1
else:
if(isprime(l[i-1])==True):
if(isprime[i+1]==True):
flag=1
else:
flag=0
else:
flag=0
if(flag==0):
return False
else:
return True
from math import sqrt
def square(n):
if(sqrt(n) % 1 == 0):
return True
else:
return False
def isprime(n):
if (n == 1):
return(False)
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
def squareprime(l):
s=l[0]
if(isprime(s)):
for i in range(0,len(l),2):
if(isprime(l[i])==False):
return False
for i in range(1,len(l),2):
if(square(l[i])==False):
return False
return True
elif(square(s)):
for i in range(0,len(l),2):
if(square(l[i])==False):
return False
for i in range(1,len(l),2):
if(isprime(l[i])==False):
return False
return True
else:
return False

Python: only two decimal places after user entered number

How do you make sure that the user only entered a float that has two decimal places. The number cannot be 4 or 4.999 it has to be 4.00 or 4.99 otherwise an error should appear.
while looping:
try:
number = float(input("Number: "))
string_number = (str(number)).split(".")
check_length = len(string_number)
if check_length != 2:
print ("ERROR!")
looping = True
else:
looping = False
except ValueError:
looping = True
You are currently only checking that there is currently just one decimal point.
number.split(".") will return a list. If number is 4.323, it will return ['4', '323'].
What you really want to check in your if clause is that the length of the second element is 2.
if len(string_number[1]) != 2:
Check the second part of the number.
while True:
try:
number = input('Number:')
integral, fractional = number.split('.')
number = float(number)
if len(fractional) == 2:
break
except ValueError:
pass
print('ERROR!')
looping = True
while looping:
number = input("Number: ")
string_number = number.split(".")
if len(string_number) != 2:
print ("ERROR: Needs exactly one decimal point!")
looping = True
elif len(string_number[1]) != 2:
print ("ERROR: Two numbers are required after decimal point!")
looping = True
else:
try:
number = float(number)
looping = False
except ValueError:
print("ERROR: Number is not valid!")
looping = True
Making some minor changes eliminates the need for the variable looping. Since our goal is to get a valid number, we can just test for that:
number = None
while not number:
s = input("Number: ")
string_number = s.split(".")
if len(string_number) != 2:
print ("ERROR: Needs exactly one decimal point!")
continue
elif len(string_number[1]) != 2:
print ("ERROR: Two numbers are required after decimal point!")
continue
try:
number = float(s)
except ValueError:
print("ERROR: Number is not valid!")
I would write this way:
while True:
try:
str_num=input("Number: ")
num=float(str_num) # ValueError if cannot be converted
i, f=str_num.split('.') # also ValueError if not two parts
if len(f)==2:
break # we are done!!!
except ValueError:
pass
print('ERROR! ') # either cannot be converted or not 2 decimal places
print(num)

Resources