How to use != sign correctly in if/else clause? - python

Problem: I'm trying to invoke ask_user() again if the user inputs words != 'encrypt' or 'decrypt', but the same error message appears when the input IS correct.
def ask_user():
while True:
mode = input("Would you like to encrypt or decrypt: ")
if mode != 'encrypt' or mode != 'decrypt':
print("Please retry; you must type lowercase. \n")
ask_user()
else:
message = input("Enter your message: ")
It seems that using more than one != statements on same line doesn't work as I'd imagined:
# test to support above observ.
for n in range(4):
if n != 2 or n != 3:
print('me')
else:
print(n)
How should I change the code to fix this problem?

Your problem is that you are using or instead of and.
If you think about how the code is interpreted:
Let's say that mode="encrypt". Step by step:
mode != 'encrypt' evaluates to false. All good so far.
mode != 'decrypt', however, evaluates to true. This is a problem.
The final expression sent to the if will be: false or true. This, finally, evaluates to true, causing the if block to be entered.
Changing it to and means that both of invalid modes will have to be checked true for the block to be entered.

n != 2 or n != 3 will always be true. If n is 2 then it's not 3. All other values are not 2.
You intended n != 2 and n != 3.

You need to use and, not or. Because n will never be equal to both 3 and 4, the if statement that incorporates or will always resolve to True

Related

Checking multiple conditions for a "password"

I'm trying to write code that can check if an input contains;
At least 8 letters, whereas at least 1 of those is a number (0-9)
Contains an upper and lower case character
I keep getting stuck in a "inputs password, returns true, and input password again, exit" single loop..
Fairly new at programming, doing my first semester atm so all help would be appreciated!
This is my program so far
def is_valid():
valid = 0
password = input("Password: ")
for ele in password:
if ele.isupper and ele.islower and ele.isdigit and len(password) > 7:
return "True"
else:
return "False"
print(is_valid())
is_valid()
I tried moving the print inside the function, as I think it is intended, by then It won't print..
for ele in password:
if ele.isupper and ele.islower and ele.isdigit and len(password) > 7:
return "True"
else:
return "False"
This code has several problems.
First, you're referring to the ele.isupper function, but because you don't have parentheses (), you're not calling the function. So the code is basically asking "Does ele.isupper exist"? Well yes, it is a function, and it exists, so the if condition is true.
Use ele.isupper() instead of ele.isupper.
Second, even if you fix that problem (and also the same problem for ele.islower and ele.isdigit), there's no way that one letter will be uppercase AND lowercase AND a digit.
Third, the return statement makes the function exit immediately, so your loop will only look at the first letter. Instead of doing that, you want to loop over all the letters, and move the return statement to after the loop.
I think you were actually looking for code like this:
uc = 0
lc = 0
digits = 0
for ele in password:
if ele.isupper():
uc += 1
elif ele.islower():
lc += 1
elif ele.isdigit():
digits += 1
if uc > 1 and lc > 1 and digits > 1 and len(password) > 7:
return "True"
else:
return "False"
There are many ways to do this. But first I will clarify some mistakes.
First, when you write ele.isupper you are not calling the function, for that you must put the parenthesis: ele.isupper().
Secondly, your loop is looping through each letter of the password and in the case of solving the previous bug you would find that the condition would never be fulfilled since a character cannot be all things at the same time.
I leave you an example of how you can solve these problems, as I said, there are many ways to do it but I present you one that is not complex and uses the basics. Also, if the password is incorrect, ask for it again on the screen.
def is_valid():
valid = [0, 0, 0]
password = input("Password: ")
for ele in password:
if len(password) < 8:
break
elif ele.isupper() and valid[0] == 0:
valid[0] = 1
elif ele.islower() and valid[1] == 0:
valid[1] = 1
elif ele.isdigit() and valid[2] == 0:
valid[2] = 1
if sum(valid) < 3:
print('False')
is_valid()
else:
print('True')
is_valid()
Output:
Password: hello
False
Password: Hello
False
Password: Hello World
False
Password: Hello World 1
True
The code first checks if the length is correct, if it is not, it does not make any further checks.
If this condition is met it continues and as conditions are met, one of the variables in the valid list is incremented. You can do this with a number instead of a list, but if you want to specify what has gone wrong you can access each value in the list to check it or say that n conditions have failed, for example:
if valid[1] == 0:
print('There must be at least one lower character').
There are a couple of problems in your code.
Reaching return statement exits the loop and the function itself, returning the value. So you are just checking first letter and the immediately finish the loop.
valid = 0 seems to be never used.
Last instruction if your function print(is_valid()) would also have no effect.
One possible straightforward solution to your problem would be to set a number of different flags for things you want to check, ant then once you find them, set te proper value for the flags. Like this:
def is_valid():
password = input("Password: ")
has_upper = False
has_digit = False
has_lower = False
has_good_length = False
for ele in password:
if ele.isupper():
has_upper = True
if ele.islower():
has_lower = True
if ele.isdigit():
has_digit = True
if len(password) > 7:
has_good_length = True
if has_upper and has_lower and has_digit and has_good_length:
return True
return False
print(is_valid())
You should also check for characters that are neither letters nor digits (according to the rules stated in the question) - e.g., punctuation.
How about using a bit mask?
def is_valid(pwd):
state = 0
if len(pwd) >= 8:
for c in pwd:
if c.isdigit():
state |= 1
elif c.islower():
state |= 2
elif c.isupper():
state |= 4
else:
state |= 8
return state == 7
password = input('Password: ')
print(is_valid(password))
You're going element-wise in a loop on your password, rather than considering the whole thing together. You want something like:
def is_valid():
password = input("Password: ")
if not any(el.isupper() for el in password):
return False
if not any(el.islower() for el in password):
return False
if not any(el.isdigit() for el in password):
return False
if len(password) < 8:
return False
return True
is_valid()
for ele in password will iterate through the characters in the user's input.
your if statement doesnt make sense. ele.isupper and ele.islower will never be true at the same time.
if statement needs work. make booleans for each condition you want to validate and set them to true individually is you see the required elements.

How to evaluate user's input in s loop?

I'm new in coding or programming so I hope for respect.
How can I create a program that continually accepts input from the user. The input shall be in this format operatornumber like -3
Like
num = 0
while((a := input("Enter operatornumber like -9;")) != "-0"):
if (len(a) >= 2) and (a[0] in "/*-+"):
num = eval(f"{num}{a}")
else:
print("Invalid input, try again.")
print(num)
But how can I make the first input of the user to only use the add (+) or subtract(-) operators but in the next input they can now use the other operators.
Like
Enter operatornumber like -9; +9
Enter operatornumber like -9; -8
Enter operatornumber like -9; -0
1
And how can I combine all the input like
+9-9 is 1?
In the input statement, you're closing the "Enter operator and number like" msg. This is creating more problems after that line, where all green parts are considered as string now. Also, in while statement, "w" should be small letter, python is case sensitive. Try doing this:
Number = input("Enter operator and number like '-9' ")
Operator = ("+","-","/")
while Number == (Operator + Number):
if Number == "-0":
Total = 0
Total += Number
print(f"the result of {num} is {total} ")
You can use double quotes for the text and single quotes for the number, so they don't close each other.
You can get input forever using following code:
while True:
Number = input("Enter operator and number like '-9'")
# Place your next code here.
Here is another answer. We have to take input from user with operator as well, so len(<user_input<) should be >=2. Now, we'll take another variable h in which we'll traverse the string from index 1 to end, which means the operator gets removed and we'll convert it into int. Then we'll put if condition in which we'll check the user_input[0] is +,-,*,/ and then acc to that, we'll update the result. We'll ask the user whether he wants more operations or no, if y, then keep asking, else, break the while loop. Here's my code:
result=0
while True:
a=input("Enter operator and number= ")
if len(a)>=2 and a[0] in ["+","-","*","/"]:
h=int(a[1::])
if a[0]=="+":
result+=h
elif a[0]=="-":
result-=h
elif a[0]=="*":
result*=h
elif a[0]=="/":
result/=h
else:
print("choose only from +-/*")
else:
print("invalid input")
ch=input("Enter more?")
if ch=='n':
break
print(f"The result is {result}")
Check for indentation errors because I've copied and pasted it so it may have indentation errors

"IndexError: string index out of range" while trying to verify an input

I'm currently attempting to create a Bulls and Cows game for a school mock assessment and am having problems with this line of code
def BullsAndCows():
Guess= input("Please enter a 4 digit number, remember no duplicates!")
Guess = str(Guess)
while len(Guess) != 4:
Guess = input("IT has to be FOUR digits!")
Guess = str(Guess)
while Guess[0] == Guess[1] or Guess[0] == Guess[2] or Guess[0] == Guess[3] or Guess[1] == Guess[2] or Guess[1] == Guess[3] or Guess[2] == Guess[3]:
Guess = input("You can't use duplicates silly! Try another number!")
Guess = str(Guess)`
The problem is if i input a 4 digit number with a duplicate i can no longer input a non 4 digit number without it outputting this error
Traceback (most recent call last):
File "python", line 64, in
File "python", line 57, in BullsAndCows
IndexError: string index out of range
Line 57 is the while Guess[0] ==...
Line 64 is just BullsandCows() which is used to call the function.
Anyone know the problem?
Your error is generated when a user enters a string with a length lesser than 4. In which case, guess[3] will be out of bounds.
If you want to check whether your input adheres to come condition, I would recommend a single while terminated by a condition:
import re
guess = ''
while not (guess.isdigit() \
and len(guess) == 4 \
and not re.search(r'(\d).*\1', guess)):
guess = input(...)
As long as the while condition remains False, the loop continues to run.
guess.isdigit() is a string function to check whether a string is numeric or not. For example:
In [889]: '1234'.isdigit()
Out[889]: True
In [890]: '1234abc'.isdigit()
Out[890]: False
len(guess) == 4 will check whether the string is of length 4, if the first condition is True.
Additionally, to prevent duplicates, I would highly recommend using regular expressions. If the first and second condition are True, the re.search function will apply a regex pattern (explained below) to search for duplicates in the string. If there is a duplicate, a match is returned which is evaluated to True. Otherwise, None is returned which is False.
As long as any one of these 3 conditions are False, the entire expression is False (due to how or boolean logic works) and the loop continues to execute.
Regex Details
(\d) # digit (capture group)
.* # match 0 or more chars
\1 # reference 1st capture group
The reason for your error is that once you've passed the 4-digit test once, you never do it anymore even if the input changes. So if you input 1111 first, it passes the first test (while len(Guess) != 4) but not the second test. If you then input 123, you get an error because the input only has 3 digits, and Guess[3] raises an IndexError
You should refactor your code to include all tests on the input in the same place, and only have one while loop. Somehting like this :
def BullsAndCows():
Guess= input("Please enter a 4 digit number, remember no duplicates!")
Guess = str(Guess)
(correct, message) = check_input(Guess)
while not correct:
Guess = input(message)
(correst, message) = check_input(Guess)
def check_input(guess):
if not guess.isdigit():
return (False, "Input a number")
if len(guess) != 4:
return (False, "The number should have 4 digits")
if guess[0] == guess[1] or ...
return (False, "No duplicates")
#other tests if necessary
return (True, "ok")
Edit : as others have pointed out, guess[0] == guess[1] or ... is cumbersome and error-prone. Better to replace it with something more generic and that works equally well if you have 4, 5, ... n digits in the input. AK47's solution (len(set(guess)) != len(guess)) works well for this. Since the syntax is a bit obscure for first-time users, here's how it works:
set(guess) turns the input into a set of its characters. A set can only have distinct elements, so set('123') = set('1233212') = {'1', '2', '3'}.
if len(set(guess)) == len(guess), this means that all the characters in guess are also in the set; therefore all characters are distinct.
You can simplify your method alot by removing the while loops and just using 1 which will keep the program running until the method breaks
You can use the len() function to check to see if the value entered matches 4 digits
You can use the set() constructor to build a set out of your input which will remove duplicates, and then compare the len() of the set to the len() of the original input
def BullsAndCows():
while True:
guess = str(input("Please enter a 4 digit number, remember no duplicates:"))
if len(guess) != 4:
print("It has to be FOUR digits")
continue
if len(set(guess)) != len(guess):
print("You cant enter duplicates silly! Try another number")
continue
print("No duplicates in number: {}".format(guess))
break
BullsAndCows()
>> Please enter a 4 digit number, remember no duplicates:
> 123
>> It has to be FOUR digits
>> Please enter a 4 digit number, remember no duplicates:
> 1111
>> You cant enter duplicates silly! Try another number
>> Please enter a 4 digit number, remember no duplicates:
> 1234
>> No duplicates in number: 1234

What is wrong with this syntax for my elif statement?

I am the most beginner of the beginners and I'm getting a syntax error message for the semicolon after 'elif' why is that? Also, should the code work otherwise?
#a - this program uses function valid(x) to determine if the user's input is a positive, non-zero number while imposing a limit of 3 attempts
def valid(x):
return (x > 0)
n = int(input('Please input a positive non-zero number: '))
if(valid(n)== True):
print(n,'is valid')
elif:
print(u = int(input('error please input a positive non-zero number: ')))
if(valid(u)== True):
print(u,'is valid')
elif:
print(m = int(input('error please input a positive non-zero number: ')))
if(valid(m)== True):
print(m,'is valid')
The following is a proper syntax for if..else condition in python. Are you following this?
if expression1:
statement(s)
elif expression2:
statement(s)
elif expression3:
statement(s)
else:
statement(s)
The elif statement allows you to check multiple expressions for TRUE and execute a block of code as soon as one of the conditions evaluates to TRUE. In your code snippet, there is no expression to be executed in the elif statement!
I believe you need something like as follows.
# This program uses function valid(x) to determine if the user's input is positive, non-zero number while imposing a limit of 3 attempts
def valid(x):
return (x > 0)
n = int(input('Please input a positive non-zero number: '))
if(valid(n)== True):
print(n,'is valid')
else:
n = int(input('error please input a positive non-zero number: '))
if(valid(n)== True):
print(n,'is valid')
else:
n = int(input('error please input a positive non-zero number: '))
if(valid(n)== True):
print(n,'is valid')
Your syntax is invalid because elif is short for else if and you don't have a condition to test. Try just using else: for that.
Also, don't compare against True. Just let the expression stand alone. And this isn't C or Java, so no parens around conditionals:
if(valid(n)== True):
print(n,'is valid')
Becomes:
if valid(n):
print(n, 'is valid')
Just offering a more concise solution (and pythonic). elifs need a condition. You can use a for loop to check the password three times. And if the password is correct, the loop ends.
def valid(x):
return x > 0
for i in range(3):
n = input('Please input a positive non-zero number: ')
if valid(n):
print(n, 'is valid')
break

Syntax error on the "N" on line 18

I've been working on this simple program in Python just so I can start experimenting with Python and become more knowledgeable of Python and other programming languages in general by designing them in a way in which others can use them in an efficient manner without getting caught on the parts which make this code work. I've been doing this by having a simple program calculate "Angles in a triangle" as it's a simple subject. Recently, I replaced def(): commands with if statements as it cuts down typing to a minimum and making it generally easier for others however, when I try to run this code I get a syntax error message with N becoming highlighted on line 17.
def triangle():
N = int(input("Please enter the number of angles you currently have between 1 and 3: "))
if N == 1:
a = int(input("What's one of the angles?"))
b = int(input("What's the other angle in the triangle?"))
c = a + b
f = 180 - c
print(f)
print("If you'd like to continue, please type in triangle()")
elif N == 2:
a = int(input("What's the value of angle 1?"))
b = 180 - a
c = b /2
print(c)
print("If you'd like to continue, please type in triangle()")
else N == 3:
a = 180
b = 180 / 3
print(b)
print("If you'd like to continue, please type in triangle()")
But I'm getting a syntax error returned on elif N == 3:
Any tips would be great.
else does not have a condition.. remove it to just say
else:
or make it says
elif N == 3:
You have else N == 3:. That is not how the if..elif..else structure works - the else is a catch-all branch that is entered if none of the preceding if or elif conditions are satisfied. If you want to check specifically for N == 3 and no other values, use elif N == 3. If you want a catch-all condition, simply use else:.
elif N == 3:
Either you meant elif (which is Python for else..if), or else
If you meant plain else, it doesn't take a condition.
If you want to annotate that an else implies a certain condition is met, then I use a comment:
else: # N == 3
But that's considered bad style: only do that if you're sure N cannot have any other value than 1,2,3. In your case the user could also input any number 4,5,..,9 (or indeed 10 or larger, or indeed 0 or any negative number), and that will wrongly get handled by the N==3 branch.
Whereas if your last branch if elif N == 3, with no else-clause, invalid numbers will silently fail every branch in your tree.
So for completeness and sanity-checking, you might prefer to do:
...
elif N ==3:
# Handle N == 3 case
else:
print "Invalid number!"

Categories