Making Parentheses Even? - python

I'm trying to write a program that asks the user for a string input without using global variables. If the string has parentheses only side by side, then it's even. if it has letters, numbers, or the parentheses are spaced out, then it's uneven. For example, () and ()() is even, whereas (() and (pie) is not. Below is what I've written so far. Do I have to create more than one function for this problem?
def recursion():
string = str(input("Enter your string: "))
if string == "(" or ")":
print("The string is even.")
else:
print("The string is not even.")

A really useful stdlib script shlex provides this type of parsing automatically and allows you to customize the behavior.

No, you do not need to make multiple functions for this. In fact, I would personally just do this:
def recursion():
print("The string is not even." if input("Enter your string: ").replace('()','') else "The string is even.")
There really isn't a need to have a 6 line function for this job. Instead, use a ternary statement like I did to keep it concise.
Also, just wanted to mention this, there is no need to do:
str(input())
because input always returns a string in Python 3.x.

I will collect much of the information in the comments into an answer.
First, in your posted code the line
if string == "(" or ")":
will always evaluate to True because a non-empty string is always True. What you have written is equivalent to:
if ( string == "(" ) or ")":
which is therefore equivalent to
if ( string == "(" ) or True:
which is always True.
Next, since it seems that you simply want to check if your string consists only of sets of '()', you can use Jon Clements' suggestion of not string.replace('()',''):
if not string.replace('()', ''):
Let's take a look at what this does:
>>> not '()'.replace('()', '')
True
>>> not '()()'.replace('()', '')
True
>>> not '(()'.replace('()', '')
False
>>> not '(pie)'.replace('()', '')
False
Last, you shouldn't call a variable string because it shadows a module in the standard library. Something like user_given_string might work.
Summing it all up:
def recursion():
user_given_string = input("Enter your string: ")
if not user_given_string.replace('()', ''):
print("The string is even.")
else:
print("The string is not even.")

Related

Can't wrap my head around how to remove a list of characters from another list

I've been able to isolate the list (or string) of characters I want excluded from a user entered string. But I don't see how to then remove all these unwanted characters. After I do this, I think I can try joining the user string so it all becomes one alphabet input like the instructions say.
Instructions:
Remove all non-alpha characters
Write a program that removes all non-alpha characters from the given input.
For example, if the input is:
-Hello, 1 world$!
the output should be:
Helloworld
My code:
userEntered = input()
makeList = userEntered.split()
def split(userEntered):
return list(userEntered)
if userEntered.isalnum() == False:
for i in userEntered:
if i.isalpha() == False:
#answer = userEntered[slice(userEntered.index(i))]
reference = split(userEntered)
excludeThis = i
print(excludeThis)
When I print excludeThis, I get this as my output:
-
,
1
$
!
So I think I might be on the right track. I need to figure it out how to get these characters out of the user input. Any help is appreciated.
Loop over the input string. If the character is alphabetic, add it to the result string.
userEntered = input()
result = ''
for char in userEntered:
if char.isalpha():
result += char
print(result)
This can also be done with a regular expression:
import re
userEntered = input()
result = re.sub(r'[^a-z]', '', userEntered, flags=re.I)
The regexp [^a-z] matches anything except an alphabetic character. The re.I flag makes it case-insensitive. These are all replaced with an empty string, which removes them.
There's basically two main parts to this: distinguish alpha from non-alpha, and get a string with only the former. If isalpha() is satisfactory for the former, then that leaves the latter. My understanding is that the solution that is considered most Pythonic would be to join a comprehension. This would like this:
''.join(char for char in userEntered if char.isalpha())
BTW, there are several places in the code where you are making it more complicated than it needs to be. In Python, you can iterate over strings, so there's no need to convert userEntered to a list. isalnum() checks whether the string is all alphanumeric, so it's rather irrelevant (alphanumeric includes digits). You shouldn't ever compare a boolean to True or False, just use the boolean. So, for instance, if i.isalpha() == False: can be simplified to just if not i.isalpha():.

Index out of range for string of length 1

I am practicing recursive function for reversing a string.
Whenever there is no space between quotation marks in str1 == '', the code works fine.
However, if I do put a space in between the quotes in str1 == ' ', I get an error: String index out of range. (since both indices -1 and 0 are valid for str1 with space in quotes)
I do not understand why this error occurs and how to eliminate it.
def reverse(str1):
if str1 ==''
return str1
else:
return str1[-1]+reverse[:-1]
def main():
str1 = input ('Enter string')
result = reverse(str1)
print ('Reverse of string is ', result)
if __name__=='__main__':
main()
You could change reverse function like this:
return str1[::-1]
This will reverse irrespective of the length of string. Hope this works.
chars = [char for char in str1]
chars.reverse()
print(''.join(chars))
As Sam Stafford said in another answer and the comment from gilch, changing the base case and recursively calling the function on the string without the last character will allow the function to work. Something like:
def reverse(str1):
if len(str1) == 1:
return str1
else:
return str1[-1] + reverse(str1[:-1])
First: a semicolon is ;, a quotation mark is '. :)
The strings '' and ' ' are not the same -- one is an empty string, the other is a string that is one character long.
Your recursive function works by slicing the string into smaller and smaller pieces. Once it reaches an empty string, it needs to return instead of slicing it any further. This is called a "base case" -- a special check for the case that you can't solve by recursing further.
When you change your "base case" check so that it no longer catches the empty string (''), it breaks the function, because it will then continue on to attempt to slice, and that raises the exception you're seeing. The value of str1 that causes your function to break is '' (no space), and your recursion will always end in that value, so making this change to your code will always break it.

Isspace function in python

I'm having trouble trying to execute this code, I want the user to input a value, the program checks if that value is a string then it returns the length.
If the value contains whitespaces the programs remove the whitespace and print the length.
But if it contains any integer values the program returns "No Integers is Allowed"
This is the code:
def length(Name):
long = len(Name)
return long
new_length = input("Please Enter Your name You can use Spaces: ")
value1 = new_length
if value1.isspace() == True:
print("This is Before Removing Spaces: " + value1)
value2 = value1.replace(" ", "")
print("This is After Removing Spaces: " + value2)
elif value1.isalpha() == True:
print("Here is The Length: ", length(value1))
elif value1.isdigit() == True:
print("Integers are not allowed! ")
else:
print("There's someting wrong with "+ value1)
So if you can help me with that I appreciate it.
Thanks
I don't think the str.isspace, str.isalpha and str.isdigit methods do what you expect them to do. To start with, they all test if all the characters in the string you enter are of the type that is described in their name. Your code seems to be expecting them to be return True if any of the characters match. That is, if there are any spaces, you want to remove them and show the two lengths, before and after.
There's no single string method that will do that test for you in Python. You could use regular expressions (which are more powerful, but much more complicated), or you could write some slightly more elaborate code to do the test. I'd suggest using the any function, and passing it a generator expression that calls the method you want on each character in the string.
if any(c.isspace() for c in user_str):
...
This may not be exactly what you want for all of your tests. The desired logic of your code is not entirely obvious, as there are a number of corner cases that your output doesn't specifically address. Is a string that contains both letters and numbers valid? How about one that has spaces in between numbers, but no letters at all? You may need to reorder the conditions of your if/elif/else statements so that they match what you intend.
I'd also note that the variable name you used for user input, new_length, is very misleading. It's not a length, its the string you want to measure the length of! It's a lot easier to make logic errors about variables that have misleading or unclear variable names, so taking time to go back and reconsider names you chose earlier is sometimes a good idea, as it can improve the clarity of your code a lot! Descriptive variable names are good, but it's a tradeoff between clarity and brevity, as long names are tedious to type (and prone to typos). They also can lead to line length issues, which can make it less convenient to see all your code on your editor screen at once.
You can use this function to check if the input string contains a number:
def hasNumbers(inputString):
return any(char.isdigit() for char in inputString)
It returns true if there is a number and false if there is not.
As for the whitespaces you can ommit isspace(). Using replace() alone will do the job, even if there are no whitespaces.
stri='jshsb sjhsvs jwjjs'
stri=stri.replace(' ','')
I suggest reading the documentation in these cases. For isspace, note here that
Return True if there are only whitespace characters in the string and there is at least one character, False otherwise.
That is, if there's anything that's not a space there, it will be False. Which is annoying, but why check in the first place? Just do the replacement! If there's no whitespace, it won't do nothing. If you need to print those statements, you can do
if ' ' in value1:
...
(of course, this doesn't consider all the possible kinds of whitespaces, check the other answers for doing the for loop if you need that)
Next, I believe you need to remove the elifs and just use if statements, since note that if you input a name with a space, it will print the name with the spaces removed... and nothing after that. Not even if it has integers in it. This is because elif statements don't execute once another above them did.
There are many other things you need to consider, but these two I think you should consider first. Hope it's useful!
You can use the re module in Python to check for white spaces in your string. It returns True if there are white spaces and False otherwise.
import re
def length(Name):
long = len(Name)
return long
new_length = input("Please Enter Your name You can use Spaces: ")
value1 = new_length
if re.search('\s', value1):
print("This is Before Removing Spaces: " + value1)
value2 = value1.replace(" ", "")
print("This is After Removing Spaces: " + value2)
print("Here is The Length: ", length(value2))
elif value1.isalpha() == True:
print("Here is The Length: ", length(value1))
elif value1.isdigit() == True:
print("Integers are not allowed! ")
else:
print("There's someting wrong with "+ value1)

My user input takes uppercase letters different as lower case letters. It interferes with the results. Any tips?

def palindrome(): #Before I had parameter s, but it is repetitive.
s=raw_input ("Enter a phrase : ") #Raw input makes the input not considered as a variable but as a string
s.lower()
return s[::-1]==s
palindrome()
2 questions.
Does the raw_input makes an input considered like a string?
And also I used the s.lower because when I tried to run "Eat Tae", it would say it wasn't a palindrome. The s.lower did not work. How do I solve this?
lower() is not in-place, it returns a new string.
You should either reassign it to s (s = s.lower()) or call lower on the input itself:
s = raw_input("Enter a phrase : ").lower()
In python, the two main ways of taking input is through raw_input, which takes the input in as a string, and input, which takes the variable in as the type entered like a int.
The s.lower() function returns a string so the proper format would be
s = s.lower()

re.rompile returns true with false, not allow symbols

Im trying to use regex do check a variable for accepted letters and numbers. This is my def:
def special_match(strg, search=re.compile(r'[a-z0-9]').search):
if bool(search(strg)) is True:
print ('Yes: ' + strg)
elif:
print ('nej: ')
while 1:
variabel = raw_input('Enter something: ')
special_match(variabel)
sys.exit()
And it seems that is accepts not allow symbols in combination with allow symbols:
Enter something: qwerty
Yes: qwerty
Enter something: 1234
Yes: 1234
Enter something: !!!!
nej!
Enter something: 1234qwer!!!!
Yes: 1234qwer!!!!
Enter something:
The last one should not be accepted.. What I'm doing wrong??
All your regular expression search is doing is checking to see if at least one of the characters is present.
If you want to require that the entire string contains nothing but those characters, then you can use:
r'^[a-z0-9]*$'
That anchors the pattern at both the start and end of the string, and only matches if all of the characters in between are in the specified set of characters.
Note that this will also match the empty string. If you wish to require at least one character, then you can change the * to +.
the search method finds for regex you gave and if it finds then returns a Match object here 1234qwer!!! has [a-z0-9] but !!!! doesnt.
Try a!!!. that will also return True.
You could try doing
re.search(r"[^a-z0-9]",word)
and if this returns True that means your word has something other than digits and alphabets and that should be rejected.
NOTE: ^ means not.
The only thing that regex does is check that there is a number or a letter in your string. If you want to check that it only has numbers and letters, you need to anchor your pattern at the start and end, and add a repeat: r'^[a-z0-9]+$'
Note though that there is no need to use regex for this: the string isalnum() method will do the same thing.
There are a couple of other odd things in your code; you should definitely not be compiling a regex in the function signature and passing on the resulting search method; also you should not be converting the result to bool explicitly, and you should not compare bools with is True. A more Pythonic version, assuming you wanted to stick to the regex, would be:
def special_match(strg, search=None):
if not search:
search = re.compile(r'[a-z0-9]').search
if search(strg):
print ('Yes: ' + strg)
else:
print ('nej: ')
Also note elif is a syntax error on its own.

Categories