Python boolean check in other functions - python

this is my code for a password and I actually have 4 conditions. Then, I am cheking at the end with def final_password that if all of the 4 previous fuctions are TRUE then the password in TRUE otherwise it's FALSE. However, the last one did not work, during my testing it was always FALSE even when the 4 conditions where TRUE. Thank you!
NON_ALPHABETIC_CARACTERS = ("!", "?", "ยง")
def password_len (password) :
lenght_caracters_check = False
for i in password :
if len(password) > 4 and len(password) < 10 :
lenght_caracters_check = True
break
else :
return lenght_caracters_check
def password_numeric_caracters (password) :
numeric_caracters_check = False
for i in password :
if i.isnumeric () :
numeric_caracters_check = True
break
else :
return numeric_caracters_check
def password_alphabetic_caracters (password) :
alphabetic_caracters_check = False
for i in password :
if i.isalpha () :
alphabetic_caracters_check = True
break
else :
return alphabetic_caracters_check
def special_caracters (password) :
special_caracters_check = False
for i in password :
if i in NON_ALPHABETIC_CARACTERS :
special_caracters_check = True
break
else :
return special_caracters_check
def final_password (password) :
final_password_check = False
if password_len(password) and password_numeric_caracters(password) and password_alphabetic_caracters(password) and password_special_caracters(password) :
final_password_check = True
return final_password_check

You need to add "return" to all functions for True cases.
For True cases you are just setting a variable true. However you are not returning it.
In addition there is no overall check for all characters since you are breaking the loop for the first success case. You need to modify break with continue:
for i in password :
if i.isalpha () :
continue
else :
return False
return True

There are some other issues with your code, but answering your question, your function special_caracters(password) does not return any value when the condition is True. Try refactoring it a bit:
def special_caracters (password):
for i in password:
if i in NON_ALPHABETIC_CARACTERS:
return True
return False

Related

How can check number in string?

I want to know that 'password' is containd number using 'string.digits'
import string
def validate_password(password):
is_long = len(password)
if is_long < 8:
return False
includes_digit = password
for digit in string.digits:
if digit in includes_digit:
break
return False
for u in string.ascii_uppercase:
if u in includes_digit:
break
return False
for char in string.ascii_lowercase:
if char in password:
break
return False
return True
is_password_valid = validate_password("12345678ff")
print(is_password_valid)
I guess that is ok but didn't work
help me plz
In all of your validators, you don't return False because that return statement is underneath the if statement. You always break before reaching the return.
Put an else under your for loops like this. This part executes if the for loop finishes without encountering a break.
includes_digit = password
for digit in string.digits:
if digit in includes_digit:
break
else:
return False
You should use regex in this case.
import re
password = 'Azerty123'
contains_digit = bool(re.search('\d', password))
print(contains_digit) # True

How do I make a user input change a Boolean value?

I am trying to make a simple little program using Python 3.7.4. I was wondering if it is possible (If so, how?) to change the Boolean value of a variable from a user input.
As you can see in the attached code, I have tried putting the append in quotations. I also tried no quotations.
is_male = []
is_female = []
is_tall = []
is_short = []
ans_male = bool(input("Are you a male? (True or False): "))
if ans_male == "True":
is_male.append("True")
if ans_male == "False":
is_male.append("False")
ans_female = bool(input("Are you a female? (True or False): "))
if ans_female == "True":
is_female.append("True")
if ans_female == "False":
is_female.append("False")
ans_tall = bool(input("Are you tall? (True or False): "))
if ans_tall == "True":
is_tall.append("True")
if ans_tall == "False":
is_tall.append("False")
ans_short = bool(input("Are you short? (True or False): "))
if ans_short == "True":
is_short.append("True")
if ans_short == "False":
is_short.append("False")
I expect the is_male, is_tall, etc. variable's value to change to True or False according to the input.
You are getting a few things wrong.
1) When transforming a string into a boolean, python always returns True unless the string is empty (""). So it doesn't matter if the string is "True" or "False", it will always become True when you do bool(str).
2) In your if statements, you're comparing a boolean (the ans_male variable) with a string ("True"). If you want to work with booleans, you should write only True or False, without the quotation marks.
In your case, as you're reading a value from the input(), it is much easier to just leave it as a string and compare it with "True" and "False" instead. So you could do as follow:
ans_male = input("Are you a male? (True or False): ")
if ans_male == "True": # Check if string is equal to "True"
is_male.append(True) # Appends the boolean value True to the list.
Here ans_male will have true value even if your input is false. You can't convert string to bool value like this. Better create a function to convert string into bool values as following.
def stringToBool(ans_male):
if ans_male == 'True':
return True
else if ans_male == 'False'
return False
else:
raise ValueError
Booleans don't have quotation marks, those are only for strings. The following is 1/4 of your code with this change applied:
is_male = []
ans_male = bool(input("Are you a male? (True or False): "))
if ans_male == "True":
is_male.append(True)
if ans_male == "False":
is_male.append(False)
Note: ans_male == "True" has the boolean in string format because values assigned using input() are always strings.
Because of this, you may want to use the following instead (because follow):
is_male = []
is_female = []
is_tall = []
is_short = []
ans_male = bool(input("Are you a male? (Yes or No): "))
if ans_male == "Yes":
is_male.append(True)
if ans_male == "No":
is_male.append(False)
ans_female = bool(input("Are you a male? (Yes or No): "))
if ans_female == "Yes":
is_female.append(True)
if ans_female == "No":
is_female.append(False)
ans_tall = bool(input("Are you a male? (Yes or No): "))
if ans_tall == "Yes":
is_tall.append(True)
if ans_tall == "No":
is_tall.append(False)
ans_short = bool(input("Are you a male? (Yes or No): "))
if ans_short == "Yes":
is_short.append(True)
if ans_short == "No":
is_short.append(False)
is_male.append(True) should work. I tested it and it works for me on v3.7.4.
Consider this code. You have a list of questions you want to ask, paired with the associated property (is_male, etc.). You have a dictionary that maps user input to a boolean. For each question, you print the current question and wait for the user to enter something. If they enter something invalid (something other than "True" or "False"), the while-loop will keep asking the same question until the user answers satisfactorily. When the user has answered all questions we print the results.
questions = [
("Are you male?", "is_male"),
("Are you tall?", "is_tall")
]
input_to_bool = {
"True": True,
"False": False
}
user = {}
for question, key in questions:
while True:
user_input = input(f"{question}: ")
if user_input in input_to_bool:
user.update({key: input_to_bool[user_input]})
break
for key, value in user.items():
print(f"{key}: {value}")
Output:
Are you male?: True
Are you tall?: False
is_male: True
is_tall: False
Your code transform the user input to bool.
ans_male = bool(input("Are you a male? (True or False): "))
So any input will be True and no input will be False.
How about doing something like:
is_male = []
ans_male = input('Are you a male? (Y or N): ')
if ans_male.upper() == 'Y':
is_male.append(True)
elif ans_male.upper() == 'N':
is_male.append(False)
else:
print('Please choose Y or N')
pass
Put your less affords and time with this code :
is_male = []
is_female = []
is_tall = []
is_short = []
que = "Are you {} (Yes/No) : "
ans_male = True if input(que.format("a male?")).lower()=='yes' else False
is_male.append(str(ans_male))
#if you want to append list with 'True'/'False' (type->str)
ans_female = True if input(que.format("a female?")).lower()=='yes' else False
is_female.append(ans_female)
#if you want to append list with True/False (type -> bool)
ans_tall = True if input(que.format("tall?")).lower()=='yes' else False
is_tall.append(ans_tall)
ans_short = True if input(que.format("short?")).lower()=='yes' else False
is_short.append(ans_short)
It is the same code that you post in the question with efficient solution.
And yes an answer should be Yes/No because True/False sometime looks weird for this type of questions.

Get TypeError when call the function from second time

My problem is the error message only happen after I call the function second time
numLen, phoneMask = numberLen(3)
TypeError: 'NoneType' object is not iterable
Here is my code.
If I type in correct extension, for example 71023 at first time I run the script, there is no problem.
If I typed wrong extension at first time and typed in correct one the second time, it return the typeerror message and I can see numberlen(i) returned none.
Thank you in advance.
import sys
def numAssign(t):
maskList = ['02694406XX', '02693710XX']
extList = ['706XX', '710XX']
i = 0
while i < len(extList) :
if t != extList[i] :
i = i + 1
else :
return True, maskList[i]
print('''The extension you entered is not in the indial range.''')
return False, ' '
def numberLen(i):
t = input('Please enter the extnsion : ')
T = len(t)
isNum = t.isdecimal()
patternConvert = t[0:3] + 'XX'
if T == 5 and isNum == True :
valid, mask = numAssign(patternConvert)
print(mask)
print(i)
if valid == True:
print(numAssign(patternConvert))
return True, mask
else :
if i == 0 :
print('''The number you entered was not valid.
It has to be 5 digits.''')
else :
print('Please try again')
print(i)
numberLen(i-1)
else :
if i == 0 :
print('Your entering is invalid, we will terminiate the programe')
exit()
else :
numberLen(i-1)
if __name__ == '__main__':
numLen, phoneMask = numberLen(3)
print(phoneMask)enter code here
Your numberLen() function only returns the tuple the caller is expecting when the user makes a valid input the first time; otherwise it calls itself recursively and does not return its returning value, which makes the function to return None by default, causing the exception when the caller tries to unpack it as a sequence.
You should change both occurrences of:
numberLen(i-1)
to:
return numberLen(i-1)

Checking variables with isupper, islower and isdigit [duplicate]

This question already has an answer here:
Variable checking, something not right
(1 answer)
Closed 6 years ago.
I have tried to make a 'password checker' program that checks if an entered variable contains specific characters. I will need it to check thee things: uppercase, lowercase and number.
There are 3 things that the program will hopefully output, and these are:
Weak, for passwords with only upper OR only lower OR only number
Medium, for passwords that have upper and lower, OR upper and number, OR lower and number
Strong, for passwords that contain upper, lower and number at the same time.
This is my code:
if EnteredPassword.isupper() or EnteredPassword.islower() or EnteredPassword.isdigit():
print ("Your password is weak")
elif EnteredPassword.isupper()and EnteredPassword.islower():
print ("Your password is medium")
elif EnteredPassword.isupper() and EnteredPassword.isdigit():
print ("Your password is medium")
elif EnteredPassword.islower() and EnteredPassword.isdigit():
print ("Your password is medium")
elif EnteredPassword.isupper() and EnteredPassword.islower() and EnteredPassword.isdigit():
print ("Your password is strong")
else:
print ("That password should not have been accepted")
quit()
However, when the program is run, and for example I have put in UPPERLOWER6 the program skips to the else statement. If I put something that just contains UPPER etc., that is the only one that works and comes up with your password is weak
If there is anything wrong with the code I cannot see, please point it out. I have been re-directed to other questions but they are too complicated for me and people would know I have copied is, which is not allowed.
Many thanks!
you should do something like this:
Password Tester in Python
the functions you are using test the whole string and to make what you want to do is not the right option.
Use regex. Its easier.
Your code isn't working the way you want it to because isupper, islower and isdigit all check all the values of the string you feed it. i.e. 'a'.islower() returns True, while 'aA'.is lower() returns False.
So,
if str.isupper() and str.islower():
#statement
is never executed because one of the conditions is always bound to be False.
Note: isupper and islower ignore any digits if any character is present in the string. i.e. 'a6'.islower() return True, while '6'.islower() and 'a6'.isdigit() return False.
isupper / islower is not working same as like isdigit.
upper and lower ignores any digits and whitespaces (eg "UPPER6 ".isupper() is True)
on the other way digit check if string contains only digits
Anyway 'UPPERLOWER6' matches first condition, so it shouldn't skip to else. You string probably contains something else.
You can still iterate over chars, eg:
flags = [False] * 3
for ch in EnteredPassword:
flags[0] = flags[0] or ch.islower()
flags[1] = flags[1] or ch.isupper()
flags[2] = flags[2] or ch.isdigit()
strength = sum(flags)
print("Your password is {}".format(
["not accepted", "weak", "medium", "strong"][strength])
)
You r doing it wrong way as you can use isupper or islower functions only on characters and not on whole string. I would do something like this:
def containsOnlyUpper(s):
for c in s:
if(not c.isupper()):
return False
return True
def containsOnlyLower(s):
for c in s:
if(not c.islower()):
return False
return True
def containsOnlyNumber(s):
for c in s:
if(not c.isdigit()):
return False
return True
def containsUpperAndLower(s):
hasUpper = False
hasLower = False
for c in s:
if (c.islower()):
hasLower = True
if (c.isupper()):
hasUpper = True
if(hasUpper and hasLower):
return True
else:
return False
def containsUpperAndNumber(s):
hasUpper = False
hasNumber = False
for c in s:
if (c.isupper()):
hasUpper = True
if (c.isdigit()):
hasNumber = True
if(hasUpper and hasNumber):
return True
else:
return False
def containsLowerAndNumber(s):
hasLower = False
hasNumber = False
for c in s:
if (c.islower()):
hasLower = True
if (c.isdigit()):
hasNumber = True
if(hasLower and hasNumber):
return True
else:
return False
def isWeakPassword(s):
if(containsOnlyUpper(s) or containsOnlyLower(s) or containsOnlyNumber(s)):
return True
return False
def isMediumPassword(s):
if(containsUpperAndLower(s) or containsUpperAndNumber(s) or containsLowerAndNumber(s)):
return True
return False
def isStrongPassword(s):
hasUpper = False
hasLower = False
hasNumber = False
for c in s:
if (c.isupper()):
hasUpper = True
if (c.islower()):
hasLower = True
if (c.isdigit()):
hasNumber = True
if (hasLower and hasUpper and hasNumber):
return True
else:
return False
password = "UPPERLOWER6"
if(isWeakPassword(password)):
print "weak"
elif(isMediumPassword(password)):
print "medium"
elif(isStrongPassword(password)):
print "strong"
else:
print "none"
I think you could set variables as flags, then check the letter and recording the number of occurrences in input one by one.

Python: How to display errors in "Making a Valid Password" and indicate if first character is a letter?

I'm trying to make a password with typical requirements like it has at least 1 uppercase/lowercase, etc. If the password is not valid according to the requirements, we have to display the errors in order for the user to try to get it correct again.
I started out with a while loop so that in the end the user will have an option to continue with another test or not. These are general steps I did.
At the end, if the user's text input is determined to not be valid, I have to display what his/her errors were. That's my main problem now. The code is better after a suggestion. Now I just have to display the errors somehow.
Here's how my code went
while True:
pw = input('Enter password to be tested if valid or not: ')
correct_length = False
uc_letter = False
lc_letter = False
digit = False
no_blanks = True
first_letter = False
if len(pw) >= 8:
correct_length = True
for ch in pw:
if ch.isupper():
uc_letter = True
if ch.islower():
lc_letter = True
if pw.isalnum():
digit = True
if pw[:1].isalpha():
first_letter = True
if not pw.find(' '):
no_blanks = True
if correct_length and uc_letter and lc_letter and digit and first_letter and no_blanks:
valid_pw = True
else:
valid_pw = False
#This is the part where I'm suppose to display the errors if the user gets it wrong.
#Initially, in the test for ch. above, I put in an else: with a print statement but because of the for- statement, it prints it out for every single character.
answer = input('Try another password input? y/n ')
if answer == 'y'
answer = True
else:
break
isdigit only returns True or False.
if ch.isdigit():
If you want to check if the first two characters are digits, do it outside the loop:
if pw[:2].isdigit():
digit = True
for ch in pw:
...
And to check if there are spaces in the string:
if not pw.find(' '):
no_blanks = True
Or if you want to escape all kinds of white spaces and blanks, including newline characters:
import string
...
if not any(c in string.whitespace for c in pw):
no_blanks = True
for ch in pw:
...
For the white space I would use (don't forget to import string):
import string
for ws in string.whitespace:
if ws in pw:
no_blanks = False
break
This checks for all kinds of white space, including for example Space and Tab
For the digits I would define dig_count = 0 before your for-loop.
Inside the for-loop:
if ch.isdigit():
dig_count += 1
After the for-loop:
if dig_count >= 2:
digit = True

Categories

Resources