I am making a login page in which I have to cover all the login test scenarios. I am am validating all type of input the user is putting, but the problem is when a while condition handles one test condition, that same while condition is not repeated after the another while condition runs. if the same test condition occurs again after user puts the same input value after another type of input value. Here is my code:
import re
userDetails=[]
accountDetails= {"FirstName": "Ajay", "LastName": "Kumar","DateOfBirth":"24-07-1992","Account Number":"4242342345234","Balance Currency":"Rs","Balance Amount":"5000"}
specialCharacters = re.compile('[#_!#$%^&*()<>?/\|}{~:]')
firstName=str(input("Enter First Name"))
while True:
if firstName=="":
print("Name cannot be blank")
firstName=str(input("Enter First Name"))
while True:
if firstName.isdigit():
print("Name cannot be in digits")
firstName=str(input("Enter First Name"))
while True:
if specialCharacters.search(firstName) != None:
print("Please don't enter special characters")
firstName=str(input("Enter First Name"))
while True:
if firstName!=accountDetails.get("FirstName"):
print("The account does not exist with the given details, please try again")
print("Enter valid first name")
firstName=str(input("Enter First Name"))
else:
userDetails.append(firstName)
Use exceptions and functions and do all your validation at once:
class ValidationError(Exception):
pass
def validate_name(name):
name = name.strip()
if not name:
raise ValidationError("Name cannot be blank")
if name.isdigit():
raise ValidationErrir("Name cannot be in digits")
if specialCharacters.search(name) is not None:
raise ValidationError("Please don't enter special characters")
if name != accountDetails.get("FirstName"):
raise ValidationError("The account does not exist with the given details, please try again")
def get_first_name():
while True:
first_name = input("Enter First Name")
try:
validate_name(firstName)
except ValidationError as e:
print(str(e))
else:
# ok we're good
return first_name
first_name = get_first_name()
do_something_with(first_name)
One way to write it:
import re
specialCharacters = re.compile('[#_!#$%^&*()<>?/\|}{~:]')
accountDetails= {"FirstName": "Ajay", "LastName": "Kumar","DateOfBirth":"24-07-1992","Account Number":"4242342345234","Balance Currency":"Rs","Balance Amount":"5000"}
not_valid = True
while not_valid:
firstName=str(input("Enter First Name: "))
if firstName == "" or specialCharacters.search(firstName) != None or firstName.isdigit() or firstName!=accountDetails.get("FirstName"):
not_valid = True
continue
else:
not_valid = False
It could also be done with a break.
I suggest refactoring the validation to a separate function, something like this.
import re
userDetails = []
accountDetails = {
"FirstName": "Ajay",
"LastName": "Kumar",
"DateOfBirth": "24-07-1992",
"Account Number": "4242342345234",
"Balance Currency":"Rs",
"Balance Amount":"5000",
}
specialCharacters = re.compile('[#_!#$%^&*()<>?/\|}{~:]')
def validate(accountDetails, firstName):
if not firstName:
return "Name cannot be blank"
if firstName.isdigit():
return "Name cannot be in digits"
if specialCharacters.search(firstName):
return "Please don't enter special characters"
if firstName != accountDetails.get("FirstName"):
return "The account does not exist with the given details, please try again"
return None # No error
while True:
firstName = str(input("Enter First Name"))
error = validate(accountDetails, firstName)
if error:
print(error)
else:
break
userDetails.append(firstName)
You need to understand how while works, or loops in general. Let's go through your code -
firstName=str(input("Enter First Name"))
# We got an input
while True: # (Oh, I have to run indefinitely)
....
The first while True will get you stuck in an infinite loop and the code won't be executed ever after. Rather than doing this, do something like -
while not len(firstName): # (Okay, I will run till I get a non empty firstname)
# your code
# and subsequent conditions
while not firstName.isdigit():
# your code
#.... and so on
Or better rather, put these conditions in a function
Related
This is the concept of what I'm trying to acheive with the code. I want the user to be able to leave the login section whenever they press '0', the codes below works, but is there anyway that I can shorten these codes, cause I felt like there's too much if else being use.
def signup():
print("Press '0' to return mainpage")
firstname = input("Please enter your first name : ")
if firstname == "0":
print("Mainpage returned")
mainpage()
else:
lastname = input("Please enter your last name : ")
if lastname == "0":
print("Mainpage returned")
mainpage()
else:
username = firstname+lastname
print("Welcome", username)
def mainpage():
option = input("Press '1' to signup: ")
if option == '1':
print("Sign up page accessed")
signup()
mainpage()
You could use early returns to remove some of the nesting.
def signup():
print("Press '0' to return mainpage")
firstname = input("Please enter your first name : ")
if firstname == "0":
print("Mainpage returned")
mainpage()
return
lastname = input("Please enter your last name : ")
if lastname == "0":
print("Mainpage returned")
mainpage()
return
username = firstname+lastname
print("Welcome", username)
First of all, write code that matches your true logic. This potentially infinite recursion is inappropriate. This is a nested process, not something innately recursive.
You say that you want to leave the signup area when the user inputs 0. If so, then leave -- don't go down yet another "rabbit hole": delete those calls to mainpage and return normally. After all, mainpage is where you came from.
As for using fewer if statements, you can't reduce this much without very much generalizing the interactions in your program. You want to check for 0 in two places and for 1 in another. This requires either 3 if checks or a process general enough to make all of the transitions given a list of legal "moves". If you want that, please look up how to implement a finites state machine.
However, there is one straightforward economy: your user interface is unduly wordy. Just ask for the entire name at once:
def signup():
print("Press '0' to return mainpage")
username = input("Please enter your name : ")
if name == "0":
print("Mainpage returned")
else:
username.replace(' ', '') # remove space(s)
print("Welcome", username)
Either way, this routine naturally returns to mainpage.
I need help with the below code please, I am trying to create a piece of code that displays true or false at the beginning with a given course code using a function. four letters, 3 digits, and a 'space' in between them if that condition is true then the program will ask the user to choose the menu with 6 options using a dictionary. please explain to me where did I go wrong.
Thank you
What I have tried:
def CourseCode(input_word):
COURSES = ['SCIN', 'ENGG', 'MATC', 'BCSE', 'BCMS', 'ENGS', 'MGMT', 'COMM']
VALID_DIGITS = (1, 2, 3, 4, 6)
if user_code == 'SCIN 123':
return True
else:
return False
def user_menu():
add_course = {}
add_course['1'] ="Add new Course:"
add_course[True] = "Course added"
add_course[False]= "Invalid course code: The format is XXXX 111"
list_course = {}
list_course['2'] = "List Course:"
print("SCIN 123", "ENGG 101", "MATC 354", "MATC 355", "BCSE 202", "CCMS 100", "ENGS 202" )
stu_enrol = {}
stu_enrol['3'] = "Enrol Student"
stu_enrol = input("Please enter student family name: ")
stu_enrol[new_student]=[]
print(stu_enrol)
stu_enrol = input(f"Please enter student first initial {new_student}: ")
stu_enrol = input(f"Please enter course to enrol or X to finish {new_student}: ")
if key_data in stu_enrol:
print("Successfully enrolled.")
elif(key_data != add_course ):
print("Sorry you need to enrol in at least two courses")
elif(key_data != stu_enrol):
print("Sorry, already enrolled in that course")
elif(key_data != CourseCode):
print("Sorry, that course does not exist.")
else:
print("Sorry, a maximum of four courses are allowed")
lis_enr_stu = {}
lis_enr_stu['4']={"List Enrolments for a Student"}
lis_all_enr = {}
lis_all_enr['5']={"List all Enrolments"}
user_exit['6'] = "Quit"
if action() is False:
break
input_word = input("Please select menu choice: ")
CourseCode = CourseCode(input_word)
i am trying to validate every input value but stuck here where if user put wrong value then my function stop taking other input & ask him to correct the error.
import re
import os.path
from csv import DictWriter
service ={}
class App:
def __init__(self):
pass
def services(self):
Problem is here
name=input("Enter Name: ")
name_r = re.match('^[a-zA-Z]{3,20}$',name)
if name_r:
print("true")
else:
print("Wrong Value Entered. Please Enter Correct Name")
i wanna use try & except block but exactly don't know how to use in this case.
if i put validated value in except block then rest of the input will also have have their own except block (am confused guide me) also the main problem, is there any short way to do this because if i validate each line like this so it will take so much time.
phone=input("Enter PTCL: ")
email=input("Enter Email: ")
mobile=input("Enter Mobile: ")
address=input("Enter Address: ")
service_type=input("Enter Problem Type: ")
date_time=input("Enter Date & Time: ")
msg=input("Enter Message: ")
Below Code is fine
#getting input values
service['name'] = name_r
service['ptcl'] = phone
service['mobile'] = mobile
service['date_time'] = date_time
service['service_type'] = service_type
service['address'] = address
service['msg'] = msg
service['email'] = email
file_exists = os.path.isfile(r"sevices.csv")
with open(r"sevices.csv",'a',newline='') as for_write:
writing_data = DictWriter(for_write,delimiter=',',fieldnames=["Name","Email","PTCL","Mobile","Service Type","Date & Time","Address","Message"])
if not file_exists:
writing_data.writeheader()
writing_data.writerow({
'Name': service['name'],
'Email':service['email'],
'PTCL':service['ptcl'],
'Mobile':service['mobile'],
'Service Type':service['service_type'],
'Date & Time':service['date_time'],
'Address':service['address'],
'Message':service['msg']
})
o1= App()
o1.services()
The easiest way to accomplish what you want is to create a while loop that exits on an accepted input.
while True:
name=input("Enter Name: ")
name_r = re.match('^[a-zA-Z]{3,20}$',name)
if name_r:
break
else:
print("Wrong Value Entered. Please Enter Correct Name")
If I run this program
emails=[]
a=(0)
while a==(0):
user_email= input("Please write email")
if "#" in user_email:
if ".edu"in user_email:
print("Adding email to list")
emails.append(user_email)
print(emails)
else:
a=(0)
a=(0)
else:
print("Error:Email does not meet requirements")
a=(0)
And I type an input that meets only one of the requirements, it only displays the error message in one scenario. How could I make the error message show up in both cases where the requirements are not met since I cant write two conditions in the "if" statement.
Use and keywords, print error message for all other scenarios.
if '#' in user_email and '.edu' in user_email:
pass
else:
print('error')
Or
if all(keyword in user_email for keyword in ['#', '.edu']):
pass
else:
print('error')
emails=[]
while True:
user_email= input("Please write email: ")
if user_email.count("#") == 1 and user_email.count(".edu") == 1:
print("Adding email to list")
emails.append(user_email)
print(emails)
else:
print("Error:Email does not meet requirements")
Or using regular expression:
import re
emails=[]
while True:
user_email= input("Please write email: ")
email_pt = re.compile("^[\w.]+#[\w.]+\.edu$")
if email_pt.search(user_email):
print("Adding email to list")
emails.append(user_email)
print(emails)
else:
print("Error:Email does not meet requirements")
Here is a simple function for you to use that can replace your nested if statements:
#A nice function that returns true if # and .edu are in the mail
def matches(user_email):
boolean = True
if '#' not in user_email:
boolean = False
if '.edu' not in user_email:
boolean = False
return boolean
#Your new code
emails=[]
a=(0)
while a==(0):
user_email= str(input("Please write email: "))
#New function in use
if matches(user_email):
print("Adding email to list")
emails.append(user_email)
print(emails)
else:
print("Error:Email does not meet requirements")
Hope this helps! :D
Alright so here's the code
def user_password():
input('Please Enter Password: ')
#profiles
def intercept():
user_password()
if user_password == "intercept":
print("this is working so far")
else:
print("Incorect Password")
def Jimmy():
user_password()
if user_password == "Jimmy":
print("this is working so far")
else:
print("Incorect Password")
def Tommy():
user_password()
if user_password == "Tommy":
print("this is working so far")
else:
print("Incorect Password")
#login
user_functions = dict(
intercept=intercept,
Jimmy=Jimmy,
Tommy=Tommy,
# ...
)
user_input = input("Input function name: ")
if user_input in user_functions:
user_functions[user_input]()
else:
print("Error: Unknown function.")
PROBLEMS:
My code always starts with asking for the password even though I don't want it
to.
When I change the first variable to a function it fixes this
Why does it execute when I'm just setting the variable. I'm pretty sure I shouldn't have to use a function instead of a variable
No matter what it always ends up as Incorrect Password even if I give the correct password
I think you are trying to write something like that:
def get_user_password():
return input('Please Enter Password: ')
def Jimmy():
user_password = get_user_password()
if user_password == "Jimmy":
print("this is working so far")