Python code doesn't execute on first run - python

Using Spyder Python 3.6 this code does not execute, says that the method ispal is not defined. However when I run it and put in an integer first (say my string input = 0), then it will run after and recognize the method. It seems like I have to go through a branch other than the call to the method first. Thanks for the critique.
s = input('enter a string: ')
s1 = s
s1 = s1.lower()
s1 = s1.replace(',', '')
s1 = s1.replace(' ', '')
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[1:])

First, as pointed out by TGKL you're calling ispal before it's defined. So define it before calling, i.e:
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[1:])
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')
Second your palindrome recursive function is right except when you call ispal inside itself. Instead of ispal(s1[1:]) you should do ispal(s1[1:-1]) which will remove both the first and the last character, which has been just tested.

You have to define your method first, then call it:
s = raw_input('enter a string: ') #use raw_input so the text it takes will give to you directly a string without ""
s1 = s
s1 = s1.lower()
s1 = s1.replace(',', '')
s1 = s1.replace(' ', '')
def ispal(s1):
if len(s1) <= 1:
return True
else:
#if the first and last char are the same
#and if all
return s1[0] == s1[-1] and ispal(s1[2:]) # here you put ispal(s1[1:]) it doesn't work properly :/
if s1.isalpha():
if ispal(s1) == True:
print(s,' is a palindrome')
else:
print(s,' is not a palindrome')
else:
print('you entered illegal chars')

Related

double integer checker function

As the title says, this is a double integer checker, meaning it has two functions + the main. Please correct me if I do not paraphrase it correctly. Anyways, here is the model:
def is_integer(kraai):
kraai.replace(" ", "")
if len(kraai) == 1:
if kraai.isdigit():
print(valid)
else:
print(invalid)
exit()
elif len(kraai) > 1:
if roek == "-" or roek == "+" or roek.isdigit():
print(valid)
else:
print(invalid)
exit()
elif len(kraai) == 0:
print(invalid)
exit()
def remove_non_integer(kauw):
if len(kauw) >= 1:
for z in kauw:
if not z.isdigit():
ekster = kauw.replace(z, "")
print(invalid)
print(f'''\nNot all characters after the first are integers...
\nnogsteeds, vet raaf!:, {ekster}''')
if __name__ == '__main__':
valid = "valid"
invalid = "invalid"
kraai = input("Welcome to the integer tester. Please give an input: ")
if len(kraai) > 1:
roek = kraai[0]
kauw = kraai[1:]
y = "".join([roek, kauw])
corvidae = is_integer(kraai), remove_non_integer(kauw)
elif len(kraai) < 1:
corvidae = is_integer(kraai)
As you can see, one functions to check the integer while the other functions to remove every non-integer. However, three problems:
It will remove only one unique character
It will print the same message every time a non-integer is in the integer
It will print both 'valid' and 'invalid' for some reason when the remove_integer(x) function filters a non-integer.
Any help?
So yeah there were multiple errors at the time I posted this question.
def is_integer(kraai):
valid = "valid"
invalid = "invalid"
if len(kraai) == 1:
if kraai.isdigit():
print(valid)
elif not kraai.isdigit():
print(invalid)
elif len(kraai) > 1:
if kraai[0] == "-" or kraai[0] == "+" or kraai[0].isdigit():
if kraai[1:].isdigit():
print(True)
print(valid)
else:
print(False)
else:
print(invalid)
elif len(kraai) == 0:
print(invalid)
exit()
def remove_non_integer(bonte_kraai):
invalid = "invalid"
roek = bonte_kraai[0]
kauw = bonte_kraai[1:]
y = "".join([roek, kauw])
for x in kauw:
if x.isalpha():
ekster = ''.join([i for i in y if i.isdigit() or i == "-"])
print(False)
print(invalid, f'''\nNot all characters after the first are integers...
\nnogsteeds, vet raaf!: {ekster}''')
break
if __name__ == '__main__':
kraai = input("Welcome to the integer tester. Please give an input: ")
kraai.replace(" ", "")
if len(kraai) == 1:
corvidae = is_integer(kraai)
elif len(kraai) > 1:
for x in kraai[1:]:
if kraai[1:].isdigit():
corvidae = is_integer(kraai)
break
elif x.isalpha():
bonte_kraai = kraai
corvidae = remove_non_integer(bonte_kraai)
break
The difference between both codes, now, is first of all that they work individually as observable in the if name == 'main' block.
Secondly, I used the 'break' statement to break the loop after it has fulfilled its task. Otherwise it will repeat a number of times and that is unwanted (it should only run once).
Thirdly, as you can see I moved some variables to functions so that pytest doesn't return an 'x is not defined' error. I substituted the variables with indexes [].
Thanks.

Determining a Common Substring

Given two strings, determine if they share a common substring. A substring may be as small as one character.
Example:
s1 = "and"
s2 = "art"
They share the character "a". Then return a string: either YES or NO
def twoStrings(s1, s2):
UniqueChar_S1 = (char for char in s1)
UniqueChar_S2 = (char for char in s2)
SubStringExists = False
for i in set(UniqueChar_S1):
if i in set(UniqueChar_S2):
SubStringExists = True
break
else:
continue
return "YES"*int(SubStringExists) + "NO"*(1 - int(SubStringExists))
def main():
q = int(input())
for q_itr in range(q):
s1 = input()
s2 = input()
result = twoStrings(s1, s2)
if __name__ == "__main__":
main()
Example input:
4
wouldyoulikefries
abcabcabcabcabcabc
hackerrankcommunity
cdecdecdecde
jackandjill
wentupthehill
writetoyourparents
fghmqzldbc
Expected Output:
NO
YES
YES
NO
Example Input that Fails:
2
aardvark
apple
beetroot
sandals
Im not getting thrown an error and so im unsure what is the issue with my code, I cannot see any issues with the code and so Im wondering if anyone can point anything out for me. Also any improvements will be appreciated.
In its simplest form: "NO" if set(s1).isdisjoint(s2) else "YES"
Well you need to modify your code as following as it is more optimised:
def twoStrings(s1, s2):
UniqueChar_S1 = set(s1)
UniqueChar_S2 = set(s2)
for i in UniqueChar_S1:
if i in UniqueChar_S2:
return "YES"
return "NO"
def two_strings(s1, s2):
return "YES" if set(s1).intersection(set(s2)) else "NO"
def main():
q = int(input("Numbers: "))
for q_itr in range(q):
s1 = input("String 1: ")
s2 = input("String 2: ")
result = two_strings(s1, s2)
print(result)
if __name__ == "__main__":
main()
UniqueChar_S1 = (char for char in s1) is a generator.
for i in set(UniqueChar_S1):
if i in set(UniqueChar_S2):
So after checking the 'if' condition once the value of set(UniqueChar_S2) would be empty for second iteration.
So i suggest you the following code:
def twoStrings(s1, s2):
SubStringExists = set(s1)&set(s2)
return "YES" if SubStringExists else "NO"

Can you use break to validate input in python?

Like using this to validate that an input is only alpha-numeric:
while True:
str = input('')
if str.isalnum():
break
else:
print("Please include only alpha-numeric characters.\n")
This code has worked for all instances that I have tested it in, but is this bad practice?
That's fine. Here is a note, however: you can find out if the while loop exited with a break or without one by using else:
x = 0
while x < 4:
x += 1
else:
print("no break")
# prints no break
If you break, however:
x = 0
while x < 4:
x += 1
if x == 2:
break
else:
print("no break")
# Does not print
you can abstract it further
def verified_input(prompt='',test_condition=lambda x:1,err_message="Please Enter Valid Input"):
while True:
result = input(prompt)
if test_condition(result):
return result
print( err_message )
def verified_alnum(prompt,err_message="Please enter Only alpha numerics"):
return verified_input(prompt,lambda x:x.isalnum(),err_message)
result = verified_alnum("Enter Password:","A password must be only letters and numbers")
this allows you to create any number of test conditions quickly and relatively verbosely

Python Palindrome

So my task is to see and check a positive integer if its a palindrome. I've done everything correctly but need help on the final piece. And that the task of generating a new a palindrome from the one given given by the user. Am i on the right track with the while loop or should i use something else? So the result is if you put 192 it would give back Generating a palindrome....
483
867
1635
6996
"""Checks if the given, positive number, is in fact a palindrome"""
def palindrome(N):
x = list(str(N))
if (x[:] == x[::-1]):
return True
else: return False
"""Reverses the given positive integer"""
def reverse_int(N):
r = str(N)
x = r[::-1]
return int(x)
def palindrome_generator():
recieve = int(input("Enter a positive integer. "))
if (palindrome(recieve) == True):
print(recieve, " is a palindrome!")
else:
print("Generating a palindrome...")
while palindrome(recieve) == False:
reverse_int(recieve) + recieve
If I understand your task correctly, the following should do the trick:
def reverse(num):
return num[::-1]
def is_pal(num):
return num == reverse(num)
inp = input("Enter a positive number:")
if is_pal(inp):
print("{} is a palindrome".format(inp))
else:
print("Generating...")
while not is_pal(inp):
inp = str(int(inp) + int(reverse(inp)))
print(inp)
The variable inp is always a string and only converted to int for the arithmetic.
I've been using this solution for many years now to check for palindromes of numbers and text strings.
def is_palindrome(s):
s = ''.join(e for e in str(s).replace(' ','').lower() if e.isalnum())
_len = len(s)
if _len % 2 == 0:
if s[:int(_len/2)] == s[int(_len/2):][::-1]:
return True
else:
if s[int(_len/2+1):][::-1] == s[:int(_len/2)]:
return True
return False
This one is using Complement bitwise and Logical AND and OR operators
_input = 'Abba' # _input = 1221
def isPalindrome(_):
in_str = str(_).casefold() # Convert number to string + case insensitive
for _ in range(int(len(in_str) / 2)): # Loop from 0 till halfway
if in_str[_] != in_str[~_]:
return False
return True
print(_input, isPalindrome(_input) and ' is palindrome' or ' is not palindrome')
Abba is palindrome

Python: trying to check for a valid phone number

I am trying to write a program that accepts a phone number in the format XXX-XXX-XXXX and translates any letters in the entry to their corresponding numbers.
Now I have this, and it will allow you to reenter the correct number if its not correct to start, but then it translates the original number entered. how do i fix this?
def main():
phone_number= input('Please enter a phone number in the format XXX-XXX-XXXX: ')
validNumber(phone_number)
translateNumber(phone_number)
def validNumber(phone_number):
for i,c in enumerate(phone_number):
if i in [3,7]:
if c != '-':
phone_number=input('Please enter a valid phone number: ')
return phone_number
elif not c.isalnum():
phone_number=input('Please enter a valid phone number: ')
return phone_number
return phone_number
def translateNumber(phone_number):
s=""
for char in phone_number:
if char is '1':
x1='1'
s= s + x1
elif char is '-':
x2='-'
s= s + x2
elif char in 'ABCabc':
x3='2'
s= s + x3
elif char in 'DEFdef':
x4='3'
s= s + x4
elif char in 'GHIghi':
x5='4'
s= s + x5
elif char in 'JKLjkl':
x6='5'
s= s + x6
elif char in 'MNOmno':
x7='6'
s= s + x7
elif char in 'PQRSpqrs':
x8='7'
s= s + x8
elif char in 'TUVtuv':
x9='8'
s= s + x9
elif char in 'WXYZwxyz':
x10='9'
s= s + x10
print(s)
import re
def validNumber(phone_nuber):
pattern = re.compile("^[\dA-Z]{3}-[\dA-Z]{3}-[\dA-Z]{4}$", re.IGNORECASE)
return pattern.match(phone_nuber) is not None
If you don't want to use regular expressions: You can use isalnum to check if something is a number or letter. You can access the nth character in a string using mystr[n] so, you could try:
def validNumber(phone_number):
if len(phone_number) != 12:
return False
for i in range(12):
if i in [3,7]:
if phone_number[i] != '-':
return False
elif not phone_number[i].isalnum():
return False
return True
To see what phone_number[i] is doing, try this:
for i in range(len(phone_number)):
print i, phone_number[i]
Using enumerate:
def validNumber(phone_number):
for i,c in enumerate(phone_number):
if i in [3,7]:
if c != '-':
return False
elif not c.isalnum():
return False
return True
Once you have it working, you should use it later (inside of main) like:
def main():
phone_number = '' # an invalid number to initiate while loop
while not validNumber(phone_number):
phone_number = input('Please enter a phone number in the format XXX-XXX-XXXX: ')
translated_number = translateNumber(phone_number)
You should use a regex to match the text.
the string module has a translate function that will replace most of your logic
code example below. note how i cast everything into lowercase to simplify the regex and translation.
import string
import re
RE_phone = re.compile("^[a-z0-9]{3}-[a-z0-9]{3}-[a-z0-9]{4}$")
map_in = 'abcdefghijklmnprstuvwxyz'
map_out = '222333444555667778889999'
mapped = string.maketrans( map_in , map_out )
def main():
while True:
phone_number= raw_input('Please enter a phone number in the format XXX-XXX-XXXX: ')
phone_number = phone_number.lower()
if RE_phone.match(phone_number):
break
print "Error. Please try again"
print translateNumber(phone_number)
def translateNumber(phone_number):
return phone_number.translate( mapped )
main()
you can go for:-
def contact_validate(s):
try:
int(s)
return True
except ValueError:
return False
>>> print contact_validate("+12345")
True
>>> print contact_validate("75.0")
False
>>> print contact_validate("hello")
False
I think this can be helpful
def checkvalidNumber(phone_number):
T={"-":0,"+":0,"_":0}
for i in str(phone_number):
if i in list(T.keys()):
if (i=="_" or i=="-") and (T["-"]>=1 or T['_']>=1):
return False
elif i=="+" and T[i]>=1:
return False
else:
T[i]+=1
elif not i.isdigit():
return False
return True
This is a fairly pythonic way to do it in my opinion
def validNumber(phone_number):
return all([x.isdigit() for x in phone_number.split("-")])
It splits the input at "-", checks that each remaining item is a number and returns a single True or False value.
all() - returns True if bool(x) is True for all x in iterable

Categories