def reverse(string):
return string[::-1]
def isPalindrome(string):
temp=reverse(string)
if temp==string:
return True
else:
return False
string='tanmay' # input('enter a word')
ans=isPalindrome(string)
if ans==1:
print' Yes palindrome'
else:
print' no its not a palindrome'
if I ask for an input from the user the error what I got was Traceback (most recent call last):
File "C:/Python27/prac06-2.py", line 10, in <module>
string=input('enter a word')
File "<string>", line 1, in <module>
NameError: name 'tanmay' is not defined
but when I enter a string by myself the program is executed successfully
in python 2.7 input() evaluates the given input, you should use raw_input() to read in the data as a string. On another note, temp==string evaluates to a boolean so you do not need to put it in an if statement you can simply return temp==string
def reverse(string):
return string[::-1]
def isPalindrome(string):
temp=reverse(string)
return temp==string
string=raw_input('enter a word')
if isPalindrome(string):
print(' Yes palindrome')
else:
print(' no its not a palindrome')
You can simplify isPalindrome() further by removing reverse() to:
def isPalindrome(string):
return string == string[::-1]
You are returning a boolean True or False and you are trying to compare the result with a value 1. Here is how you should invoke it.
ans = isPalindrome(string)
if ans: # you can also do (if ans == True)
print 'Yes, it is a palindrome'
else:
print 'No, it is not a palindrome'
Related
first and last () is used to call a function that determines whether the first and last letters of a string are the same
def first_and_last(message):
if message[0] == message[-1]:
return True
elif message[0] != message[-1]:
return False
elif message == "":
return False
print(first_and_last("else"))
print(first_and_last("tree"))
print(first_and_last(""))
C:\Users\angel\PycharmProjects\pythonProject1\venv\Scripts\python.exe C:\Users\angel\PycharmProjects\pythonProject1\app.py
Traceback (most recent call last):
File "C:\Users\angel\PycharmProjects\pythonProject1\app.py", line 13, in <module>
print(first_and_last(""))
File "C:\Users\angel\PycharmProjects\pythonProject1\app.py", line 2, in first_and_last
if message[0] == message[-1]:
IndexError: string index out of range
True
False
Process finished with exit code 1
The issue is with the empty string input "", as python cannot find a 0th or -1st index of this, it throws an error before reaching the elif statement. If you check for an empty string first, then you will avoid this error:
def first_and_last(message):
if message == "":
return False
elif message[0] == message[-1]:
return True
elif message[0] != message[-1]:
return False
Output:
True
False
False
Edit: there are many comments on the question and this answer on shorter ways to achieve this goal, which are all valuable. This answer is just explaining why OP gets the error and how to fix it using only their code
I'm new to programming, and I was wondering how I can repeat an input section, if the user types in invalid data.
I want the application to just repeat the input section, instead of having to run the function all over again and making the user type everything all over again.
My guess is that I would have to change the "return main()" into something else.
condition = input("What is the condition of the phone(New or Used)?")
if condition not in ["New", "new", "Used", "used"]:
print("Invalid input")
return main()
gps = input("Does the phone have gps(Yes or No)?")
if gps not in ["Yes", "yes", "No", "no"]:
print("Invalid input")
return main()
You can make a method to check it in a loop:
def check_input(values, message):
while True:
x = input(message)
if x in values:
return x
print "invalid values, options are " + str(values)
You can generalise the code to use a message prompt and a validating function:
def validated_input(prompt, validate):
valid_input = False
while not valid_input:
value = input(prompt)
valid_input = validate(value)
return value
eg:
>>> def new_or_used(value):
... return value.lower() in {"new", "used"}
>>> validate_input("New, or used?", new_or_used)
Or, simpler, but less flexible, pass in the valid values:
def validated_input(prompt, valid_values):
valid_input = False
while not valid_input:
value = input(prompt)
valid_input = value.lower() in valid_values
return value
And use:
>>> validate_input("New, or used?", {"new", "used"})
You could even use the valid values to create the input prompt:
def validated_input(prompt, valid_values):
valid_input = False
while not valid_input:
value = input(prompt + ': ' + '/'.join(valid_values))
valid_input = value.lower() in valid_values
return value
Which gives a prompt:
>>> validate_input("What is the condition of the phone?", {"new", "used"})
What is the condition of the phone?: new/used
Here is a good reading about Control Flows.
Also in your case, you can use strip() and lower() for user inputs.
>>> 'HeLLo'.lower()
'hello'
>>> ' hello '.strip()
'hello'
Here is the solution for Python 3:
while True:
condition=input("What is the condition of the phone(New or Used)?")
if condition.strip().lower() in ['new', 'used']:
break
print("Invalid input")
while True:
gps=input("Does the phone have gps(Yes or No)?")
if gps.strip().lower() in ['yes','no']:
break
print("Invalid input")
Homework exercise:
Checking whether a text is a palindrome should also ignore punctuation, spaces and case. For example, "Rise to vote, sir." is also a palindrome but our current program doesn't say it is. Can you improve the above program to recognize this palindrome?
origin code:
def reverse(text):
return text[::-1]
def is_palindrome(text):
return text == reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
my try:
import re
def reverse(text):
global words
words = text.split()
return words[::-1]
def is_palindrome(text):
return words==reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
Error:
Enter text: jfldj
Traceback (most recent call last):
File "/Users/apple/PycharmProjects/Problem Solving/user_input.py", line 13, in <module>
print("Yes, it is a palindrome")
File "/Users/apple/PycharmProjects/Problem Solving/user_input.py", line 10, in is_palindrome
NameError: name 'words' is not defined
How should I change my code?
Latest code:
import string
def remove_punctuations(word):
return "".join(i.lower() for i in word if i not in string.ascii_letters)
def reverse(text):
return text[::-1]
def is_palindrome(text):
text = remove_punctuations(text)
return text == reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome"
else:
print("No, it is not a palindrome")
No matter what I input, output is Yes.
Enter text: hggjkgkkkk
Yes, it is a palindrome
What's wrong?
To ignore the punctuations, spaces and case of the given text you need to define a function remove_punctuations() which takes a word as parameter and returns a word with all lower case characters, remove punctuation marks and removed spaces.
To remove the unwanted characters we need to iterate over the given text, if the current character falls in strings.ascii_letters , then generate the character converting it to lower caps using str.lower() method. Finally using "".join() method to concatenate the generated str elements.
import string
def remove_punctuations(word):
return "".join(i.lower() for i in word if i in string.ascii_letters)
def reverse(text):
return text[::-1]
def is_palindrome(text):
text = remove_punctuations(text)
return text==reverse(text)
something = "Rise to vote, sir."
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
Since the hint says to use a tuple with forbidden punctuation marks, I created the following variant:
forbidden = (' ', ',', "'", '?', '!', '.', '’')
def reverse(text):
return text[::-1]
def cleaning(text):
clean_text = ''
for item in text:
if item not in forbidden:
clean_text += item
return clean_text
def is_palindrome(text):
lower_text = cleaning(text.lower())
return lower_text == reverse(lower_text)
example = input('Enter something: ')
if is_palindrome(example):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
The cleaning function checks each character for belonging to a tuple of forbidden characters, if not, then concatenates it to the clean_text string
I started studying for python 2 days before so that is what i come up with.
It is not so much advanced but works like a charm. :D
It is pretty straight forward what i do there. I just make a tuple with the "legal" letters (abc=). Then I define a function that 1st change all letters to lower case and then checks every character in the string with the "legal" letters. Then after this "filtering" the rawtext contains only the "legal" ones. Then the 2nd function just reverses the results of the 1st one. Compare and da da..!
# Palindrome recognize
abc='abcdefghijklmnopqrstuvwxyz'
def rawtext(text):
rawtext=''
text=text.lower()
for j in text[::1]:
for i in abc[::1]:
if j==i:
rawtext=rawtext+j
return rawtext
def reverse(text):
rev= rawtext(text)[::-1]
return rev
text=str(input('Write text:'))
if reverse(text)==rawtext:
print('The text is palindrome')
else:
print('The text is not a palindrome')
from itertools import izip_longest
def is_palindrome(s):
l = len(s)
fi = (i for i in xrange(l) if s[i].isalpha())
bi = (i for i in xrange(l-1, -1, -1) if s[i].isalpha())
for f, b in izip_longest(fi, bi):
if f >= b: return True
if s[f].lower() != s[b].lower(): return False
return True
Hope that helps
I'm currently testing my python code and have a question about raw_input. This is my function:
def answer():
ans = raw_input('enter yes or no')
if ans == 'yes':
print 'you entered yes'
return 'yes'
if ans == 'no':
some_value = raw_input('enter some value: ')
print 'you entered no'
return some_value
I'm testing the first if statement this way:
with mock.patch('__builtin__.raw_input', return_value= 'yes'):
assert answer() == 'yes'
But how do I check the no statement ? How do I make mock inside a mock ?
Using side_effect:
with mock.patch('__builtin__.raw_input', side_effect=['yes']):
assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', side_effect=['no', 'maybe']):
assert answer() == 'maybe'
According to mock documentation:
If side_effect is an iterable then each call to the mock will return the next value from the iterable.
The side_effect can also be any iterable object. Repeated calls to the mock will return values from the iterable (until the iterable is exhausted and a StopIteration is raised):
>>>
>>> m = MagicMock(side_effect=[1, 2, 3])
>>> m()
1
>>> m()
2
>>> m()
3
>>> m()
Traceback (most recent call last):
...
StopIteration
Using side effect should do the trick, I find the following quite clear and avoid multiple with-block:
def my_side_effect(*args): # each argument will be the return_value of one call
for el in args:
yield el # we use a generator to return different value each time
with mock.patch('__builtin__.raw_input') as mocked: # here the mocked object is accessible in the block
mocked.side_effect = my_side_effect('yes') # here one call that return 'yes'
assert answer() == 'yes'
mocked.side_effect = my_side_effect('no', 'maybe') # two calls, the first return 'no', the second 'maybe'
assert answer() == 'maybe'
If you just mock raw_input to return 'no', it will return 'no' both times, meaning you can assert that the function returns 'no':
with mock.patch('__builtin__.raw_input', return_value='yes'):
assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', return_value='no'):
assert answer() == 'no'
If you want to test what happens if, say, the first input is 'no' and the second one is 'maybe', you have to mock it with a function that returns different things the first time it's called and the second time it's called, and then you can assert that it returns 'maybe'. Something like this (not tested because I don't have mock installed here… but it should give you the idea):
def fake_raw_input(once=[False]):
if not once[0]:
once[0] = True
return 'no'
return 'maybe'
with mock.patch('__builtin__.raw_input', return_value='yes'):
assert answer() == 'yes'
with mock.patch('__builtin__.raw_input', new_callable=fake_raw_input):
assert answer() == 'maybe'
I want to make a function which checks whether a string starts with "Yes" or "No" but I'm not sure how.
If string begins with "Yes"
return "Yes"
Try startswith function:
if myStr.startswith("Yes"):
return "Yes"
elif myStr.startswith("No"):
return "No"
Note that there is also endswith function to check that your string is ending with the text expected.
If you need to check that string is not starts with:
if not myStr.lower().startswith("yes"):
return "Not Yes"
elif not myStr.lower().startswith("no"):
return "Not No"
Possibly more flexible is good
if s.lower().startswith("yes"):
return "Yes"
elif s.lower().startswith("no"):
return "No"
Have you tried:
yourString.startsWith("Yes")
All you need is
String.startswith("yes")
if the string doesn't start with yes it will return false and if it does, true.
name = "Yes? test"
if name.index('Yes') == 0:
print 'String find!!'
This may be the best solution:
def yesOrNo(j):
if j[0].lower() == 'y':
return True
elif j[0].lower() == 'n':
return False
else:
return None
def untilYN():
yn = input('Yes or no: ')
j = yesOrNo(yn)
while j == None:
yn = input('Please insert yes or no again; there may have been an error: ')
j = yesOrNo(yn)
return j
print(untilYN())
For example:
print(untilYN())
>> Yes or no: Maybe
>> Please insert yes or no again; there may have been an error: yeah then
True