closed or open parentheses checker - python-3.x

I am trying to write program to determine whether or not a mathematical expression contains matching parentheses. I need to check if they have the same amount of left vs right, and then from that determine if they are open. But I'm not sure how to do that. After I get the expression, nothing comes out. I know there is a better way to find out if they are closed... but I can't figure it out
an example of an expression they could check would be (5+5)/(5+2-5), or something like that
def main():
left = 0
right = 0
even = (0 or 2 or 4 or 6 or 8 or 10 or 12 or 14) #is there a better way to check if they match rather than doing even or odd?
odd = (1 or 3 or 5 or 7 or 9 or 11 or 13 or 15)
if expression == "(":
left += 1
elif expression == ")":
right -= 1
expression = input("write a mathematical expression with parentheses") #lets user input mathematical expression to evaluate for correct number of parentheses
parentheses = (left + right) #this is probably not the most efficient way, I just want to find out if my parentheses match, so suggestions here would help
if parentheses == even:
print("Your parentheses are closed")
if parentheses == odd:
print("You are missing a parenthese")
main()

There are a couple of issues in your code:
You need to iterate over each character in your input string (expression) to see if it's a parenthesis or something else, and then count them.
You need to do 1 before deciding whether parentheses are closed or open
Not a problem per se, but you can test whether something is even with the modulo operator %, rather than defining even and odd variables.
There are a couple of inefficiencies and unnecessary variables in your code
The code below should do what you're after:
def main():
left = 0
right = 0
expression = raw_input("write a mathematical expression with parentheses: ")
for character in expression:
if character == '(':
left = left + 1
elif character == ')':
right = right + 1
total = left + right
if (left < right):
missing = "left"
elif (right < left):
missing = "right"
if (total % 2) == 0:
print("Your parentheses are closed")
else:
print("You are missing a " + missing + " parentheses")
main()

Related

Python Logical Operators find the right way if(and and or or)

Can not find the mistake in logical operators, may be someone can give me a hint how to put AND OR OR.
Problem is with if data and data and data and (or or or)
in () > I need to accept code:
contains capital letters, then the number of capitals must be odd
have at least 4 letters (independent of case)
so it means: UPPER + LOWER >= 4 or UPPER >= 4 or LOWER >= 4
output should be:
checker_code("Dfgh#88$")
True
def checker_code(security_code):
data = {'upper':0, 'lower':0, 'spec':0, 'digit':0, 'sum':0}
spec_charact = ['!','#','#','$','%','^','&','*','(',')','?',',','.']
if len(security_code) < 8 or len(security_code) > 30:
return False
for i in security_code:
if any(i.isupper() for i in security_code):
data['upper'] = data['upper'] + 1
if i.islower():
data['lower'] = data['lower'] + 1
if i in spec_charact:
data['spec'] = data['spec'] + 1
if i.isdigit():
data['digit'] = data['digit'] + 1
if i.isdigit():
data['sum'] = data['sum'] + int(i)
if(data['upper'] % 2 !=0 and data['spec'] >= 2 and data['digit'] >= 2 and data['sum'] % 2 == 0 and (data['upper'] + data['lower'] >= 4 or data['upper'] >= 4 or case['lower'] >= 4)):
return True
else:
return False
Change your line
if any(i.isupper() for i in security_code):
to this:
if i.isupper():
Since you are already iterating for i in security_code in your outer for loop, it is redundant to do it again in your first if-statement. I think your code is applying whether the 1st character is upper across all letters, so it thinks your string of 8 characters has 8 upper-case characters since "D" is uppercase
Your test if any(i.isupper() for i in security_code): is adding to data["upper"] everytime through the loop because you are checking all of security_code at every iteration and since it does have a uppercase letter, it adds to the count.
Instead, just do if i.issuper(): to only check the current element of the security code.

What do squared brackets do to an argument of a function when being used inside an if/else statement?

I dont really know if the title makes sense at all but i dont really know how to ask the question in the first place so i'll just show the code and hopefully someone can make sense of it? Thank you!
My concern is the elif statement where it says ((player_input[1] - computer_input[1]) % 3 == 1):
Why is the [1] there for both inputs? I don't understand why they are there at all or even why it has to be 1?
player_score = 0
computer_score = 0
options = [('Rock',0), ('Paper',1), ('Scissors',2)]
tie_score = 0
def clicked(player_input):
global player_score, computer_score, rock_use, paper_use, scissors_use,tie_score
computer_input = get_computer_choice()
player_choice_label.config(text='Your Selected : ' + player_input[0])
computer_choice_label.config(text='Computer Selected : ' + computer_input[0])
if (player_input == computer_input):
tie_score += 1
tie_counter.config(text='Ties: ' + str(tie_score))
winner_label.config(text="Tie")
elif ((player_input[1] - computer_input[1]) % 3 == 1):
player_score += 1
winner_label.config(text="You Won!!!")
player_score_label.config(text='Your Score : ' + str(player_score))
else:
computer_score += 1
winner_label.config(text="Computer Won!!!")
computer_score_label.config(text='Computer Score : ' + str(computer_score))
def get_computer_choice():
return options[randint(0,2)]
#Buttons
rock_butt = Button(root, image=rock_photo,command=lambda:clicked(options[0]))
paper_butt = Button(root, image=paper_photo ,command=lambda:clicked(options[1]))
scissors_butt = Button(root, image=scissor_photo ,command=lambda: clicked(options[2]))
The code in question is tricky. It is a compact test to see if the player won a round of "Rock, Paper, Scissors." To understand the code you need to take it in steps:
The game options were defined as tuples: ("Rock", 0"), ("Paper", 1), ("Scissors", 2).
The fields in a tuple can be indexed using square brackets: the expression ("Rock", 0)[1] resolves as 0.
Here is the tricky part: (0 - 2) % 3, (1 - 0) % 3, and (2 - 1) % 3 all resolve as 1.
Put it all together and you can see the code in question will identify all winning combinations for the user.
elif ((player_input[1] - computer_input[1]) % 3 == 1):
player_score += 1
winner_label.config(text="You Won!!!")
player_score_label.config(text='Your Score : ' + str(player_score))
Whether the []-s are inside an if/else statement or not, they do the same thing. Which is in your case, used as an index for an iterable. Indexing starts at 0 in python, so your case is [1] refers to the second item in player_inupt and in computer_input.
It seems like either of player_input or computer input would be the following:
options[0] or options[1], or options[2] (same brackets as u can see, doing the same indexing). options[0] returns ('Rock', 0), of these two, the main function does not care for 'Rock' but it cares for the number 0 - which is the second of the two - which will be index[1]. (indexing starts at 0.)
options[0][0] is 'Rock', options[2][1] is , to further clarify the point.
Hope this helps, and as a side-note the code itself does look a bit strange, maybe look around for different tutorials if this was copied out from somewhere unreliable.

Count 2 (or more) characters recursively in string; return in (x,y) format in Python

I have written a program that will count how many ' ' single spaces or h characters in a string you enter when you call the function:
def chars(s):
if not s:
return 0
else:
return (s[0] == 'h') + chars(s[1:])
When you call chars('hello how are you here')
You will get 3.
Now, let's say I want to count the e along with the h. The h will return a 3 and the e should return a 4. Output would be (3,4).
I tried def chars(s, j=0)and set a counter but then realized, hold on, this has no connection to anything at this point deeming it pointless. I guess, how would I define what that second variable is? Because I only want 1 string as an input.
I am completely lost on how to include that second variable.
Also, just throwing it out there, would I follow the same rules as for 2 characters for more characters? Or would there be a different way?
This is what you want:
def count(s):
if not s:
return (0, 0)
else:
next_count = count(s[1:])
return ((s[0] == 'h') + next_count[0],
(s[0] == 'e') + next_count[1])
count("hello how are you here") # => (3, 4)
The base case returns the tuple (0, 0) and the recursive step looks at both of the values of the next count and adds one to each if necessary.
If you want more than 2 characters, just make the tuples bigger (probably using loops).

IndexError: string index out of range, can't figure out why

I want in this part of my code, to cut out any non alphabetical symbol in the words I get from a read file.
I get that there is probably an empty string being tested on, that the error is happening,
but I can't figure out why after numerous different codes I tried.
Here's what I have now for it:
for i in given_file:
cut_it_out = True
while cut_it_out:
if len(i) == 0:
cut_it_out = False
else:
while (len(i) != 0) and cut_it_out:
if i.lower()[0].isalpha() and i.lower()[len(i) - 1].isalpha():
cut_it_out = False
if (not i.lower()[len(i) - 1].isalpha()):
i = i[:len(i) - 2]
if (not i.lower()[0].isalpha()):
i = i[1:]
Can anyone help me figure this out?
thanks.
Thanks for the interesting answers :), I want it to be even more precise, but there is an endless loop problem on I can't seem to get rid of.
Can anyone help me figure it out?
all_words = {} # New empty dictionary
for i in given_file:
if "--" in i:
split_point = i.index("--")
part_1 = i[:split_point]
part_2 = i[split_point + 2:]
combined_parts = [part_1, part_2]
given_file.insert(given_file.index(i)+2, str(part_1))
given_file.insert(given_file.index(part_1)+1, str(part_2))
#given_file.extend(combined_parts)
given_file.remove(i)
continue
elif len(i) > 0:
if i.find('0') == -1 and i.find('1') == -1 and i.find('2') == -1 and i.find('3') == -1 and i.find('4') == -1\
and i.find('5') == -1 and i.find('6') == -1 and i.find('7') == -1 and i.find('8') == -1 and i.find('9') == -1:
while not i[:1].isalpha():
i = i[1:]
while not i[-1:].isalpha():
i = i[:-1]
if i.lower() not in all_words:
all_words[i.lower()] = 1
elif i.lower() in all_words:
all_words[i.lower()] += 1
I think your problem is a consequence of an over complicated solution.
The error was pointed by #tobias_k. And anyway your code can be very inefficient.
Try to simplify, for example try: (I have not tested yet)
for i in given_file:
beg=0
end=len(i)-1
while beg<=end and not i[beg].isalpha():
beg=beg+1
while beg<=end and not i[end].isalpha():
end=end-1
res=""
if beg<=end:
res=i[beg:end]
There are a few problems with your code:
The immediate problem is that the second if can strip away the last character in a string of all non-alpha characters, and then the third if will produce an exception.
If the last character is non-alpha, you strip away the last two characters.
There is no need for those two nested loops, and you can use break instead of that boolean variable
if i.lower()[x] is non-alpha, so is i[x]; also, better use i[-1] for the last index
After fixing those issues, but keeping the general idea the same, your code becomes
while len(i) > 0:
if i[0].isalpha() and i[-1].isalpha():
break
if not i[-1].isalpha():
i = i[:-1]
elif not i[0].isalpha(): # actually, just 'else' would be enough, too
i = i[1:]
But that's still a bit hard to follow. I suggest using two loops for the two ends of the string:
while i and not i[:1].isalpha():
i = i[1:]
while i and not i[-1:].isalpha():
i = i[:-1]
Or you could just use a regular expression, somethink like this:
i = re.sub(r"^[^a-zA-Z]+|[^a-zA-Z]+$", "", i)
This reads: Replace all (+) characters that are not ([^...]) in the group a-zA-Z that are directly after the start of the string (^) or (|) before the string's end ($) with "".

Binary search code not working

Good afternoon everyone,
I'm trying to sort out names which are already sorted in alphabetical order. I can't figure out why my program isn't working. Any tips or pointers would be nice. Thanks.
def main():
names = ['Ava Fiscer', 'Bob White', 'Chris Rich', 'Danielle Porter', 'Gordon Pike', 'Hannah Beauregard', 'Matt Hoyle', 'Ross Harrison', 'Sasha Ricci', 'Xavier Adams']
input('Please enter the name to be searched: ', )
binarySearch
main()
def binarySearch(names):
first = 0
last = len(names) - 1
position = -1
found = False
while not found and first <= last:
middle = (first + last) / 2
if names[middle] == value:
found = True
position = middle
elif arr[middle] > value:
last = middle -1
else:
first = middle + 1
return position
What does it mean that the program isn't working? Is it a syntax error or is the problem in the wrong results?
With the code you pasted, there are several indentation problems, but besides that, lines:
input('Please enter the name to be searched: ', )
binarySearch
are also syntactically incorrect, the comma is redundant and only the function name appearing just like that is plain wrong. If you are interested in the correctness of your algorithm, it seems alright, but the boundaries can always be tricky. My code below is working and syntactically correct, if you find it helpful. (names are numbers, but that is irrelevant in this case)
names = [1,2,4,5,6,8,9]
def bs(n):
start = 0
end = len(names)
while end - start > 0:
m = (start+end)/2
if names[m] == n:
return m
elif n < names[m]:
end = m
else:
start = m + 1
return -1
print (bs(1))
print (bs(6))
print (bs(9))
print (bs(3))
print (bs(10))
print (bs(-8))
Another thing I would like to point out is that this kind of binary search is already in the python standard library, the bisect module. However, if you are writing your own for practice or for any other reason that is just fine.
if you are using python 3.* then you are going to want to change
m = (start+end)/2
to
m = (start+end)//2
When you do /2 it outputs a float in 3.*

Resources