What does lambda do to stop switcher from executing all functions - python

I am learning python, I used the the switcher dictionary. I encountered the problem of all the functions of the dictionary getting executed.
'''
Created on Mar 10, 2019
#author: priti
Questions
1) Write a program that accepts a comma separated sequence of words as input and prints the words in a comma-separated sequence after sorting them alphabetically.
Suppose the following input is supplied to the program:
without,hello,bag,world
Then, the output should be:
bag,hello,without,world
2) Write a program that accepts a sentence and calculate the number of upper case letters and lower case letters.
Suppose the following input is supplied to the program:
Hello world!
Then, the output should be:
UPPER CASE 1
LOWER CASE 9
Hints:
In case of input data being supplied to the question, it should be assumed to be a console input.
3) (HINT use re i.e. import re (re is regular expression library/functions).
Question:
A website requires the users to input username and password to register. Write a program to check the validity of password input by users.
Following are the criteria for checking the password:
1. At least 1 letter between [a-z]
2. At least 1 number between [0-9]
1. At least 1 letter between [A-Z]
3. At least 1 character from [$##]
4. Minimum length of transaction password: 6
5. Maximum length of transaction password: 12
Your program should accept a sequence of comma separated passwords and will check them according to the above criteria. Passwords that match the criteria are to be printed, each separated by a comma.
Example
If the following passwords are given as input to the program:
ABd1234#1,a F1#,2w3E*,2We3345
Then, the output of the program should be:
ABd1234#1
'''
# method used to perform operation regarding the first question
from unittest.util import sorted_list_difference
import re
def comma_separated():
sorted_list=[]
rawData = input("Please enter comma separated words\n")
rawData = rawData.strip().split(",")
for item in rawData:
item.strip()
sorted_list.append(item)
sorted_list.sort()
for item in sorted_list:
print(item)
def cal_num_upper_lower():
upperCase = 0
lowerCase = 0
rawData = input("Please enter string\n")
rawData.strip().split(",")
for i in rawData:
#print(i)
if(i.islower()):
lowerCase +=1
if(i.isupper()):
upperCase +=1
print("UPPER CASE = " + str(upperCase))
print("LOWER CASE = " + str(lowerCase))
# method used to perform operation regarding the third question
def check_regular_expression():
sorted_list=[]
password = input("Enter string to test: ")
password = password.strip().split(",")
for item in password:
item.strip()
sorted_list.append(item)
#
# print("match")
for item in sorted_list:
if(re.match(r"^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[##$]){6,12}", item)):
print(item)
def choose_the_option(argument):
switcher = {
1: lambda: comma_separated(),
2: lambda: cal_num_upper_lower(),
3: lambda: check_regular_expression(),
}
return switcher.get(argument,lambda: "Please enter a valid number") ()
print("Select one of the options")
option = int(input("1:Sort sequence of words\n2:Calculate Number of upper and lower case\n3:Check Regular Expression\n Please enter:"))
choose_the_option(option)
So I followed this question
Executing functions within switch dictionary
Here is is mentioned that we need to use lambda to ensure only the correct method is called. While the solution worked perfectly,I could not get what exactly happens when we use lambda in switcher.
Thanks.

Related

Trying to create code that both verifies that a variable is numbers and has 4 or 5 characters long

I am trying to create code that takes a ZIP code and verifies that the input is numeric and that it's between 4 to 5 characters in length. This is the code I am trying to use. But if I put in letters, it doesn't print "Invalid Area Code", it just errors out.
zip_code = int(input("Please enter your area code: "))
if len(zip_code) == 4 or len(area_code) == 5 and zip_code.isnumeric():
print (zip_code)
else:
print("Invalid zip Code")
There are two issues with your code:
You're converting the input to an integer, then calling len() on it. You can call len() on strings, but not integers, so don't transform the input to an integer.
area_code isn't defined. You're probably looking to use zip_code instead.
Here is a code snippet that resolves both of these issues:
zip_code = input("Please enter your area code: ")
if len(zip_code) == 4 or len(zip_code) == 5 and zip_code.isnumeric():
print(zip_code)
else:
print("Invalid ZIP code")
If a string is parsable to be an integer, meaning that it is actually a number, your code will work fine. But most of the time, user inputs can not be predicted. if you just use isnumeric or isdigit in your code, you won't have any problem.
Personally speaking, I use regex to validate user input in most of the cases. In your case, I came up with code below:
import re
string = input("Please enter your area code: ")
pattern = "^\d{4,5}$"
if re.search(pattern, string):
print("Valid " + string)
else:
print("Invalid zip Code")
Example of correct input:
1234
Output
Valid 1234
Example of incorrect input:
123415
Output:
Invalid zip Code
Explanation
re.search function takes two arguments. The first argument is a pattern which will check if the second argument, which is a string, follows the pattern or not. ^\d{4,5}$ checks if the user input is a number that has 4 or 5 digits.

Conversion Program

I have a program where I need to prompt the user for an input of a word and a key. Next, the program should remove all the spaces, punctuation and all numbers from the word and convert all the letters into uppercase. Once that is done I need the program to replace all the characters of the word with the key. So if the word is a library, and the key is moose, the program should print out moosemo. I know that this part includes something like append.key(len plaintext) something of this fashion, but I'm not exactly sure how. I don't have a lot of the code done because I am pretty lost. Here is what I have so far:
phrase = input("Please enter the phrase to be encrypted: ") #prompt user for phrase
encryptionkey = input("Please enter the key: ") #prompt user for encryption key
print(phrase.upper()) #converts all characters from phrase to uppercase
If anyone knows what to do or what to change, please let me know. Please show the change in code with your response. Thanks in advance
I used answers from here and here to make compose this.
Here is one way you might do it, using the string class to get rid of punctuation and numbers.
import string
phrase = input("Please enter the phrase to be encrypted: ") #prompt user for phrase
encryptionkey = input("Please enter the key: ") #prompt user for encryption key
#replace - gets rid of spaces
#first translate - gets rid of punctuation
#second translate - gets rid of digits
#upper - capitalizes.
phrase = phrase.replace(" ", "")\
.translate(str.maketrans('', '', string.punctuation))\
.translate(str.maketrans('','',string.digits))\
.upper()
times_to_repeat = len(phrase)//len(encryptionkey)
leftover_length = len(phrase)%len(encryptionkey)
#multiply string by how many times longer it is than the encryption, then add remaining length.
#in python you can do 'string'*2 to get 'stringstring'
final_phrase = encryptionkey*times_to_repeat+encryptionkey[:leftover_length]
print(final_phrase)
Output:
# Only keep the alphabet characters
phrase = ''.join(c for c in phrase if c.isalpha())
# Add the encryption key at least 1 more times than divisible (to count for remainder)
# and slice the output to the length needed
phrase = (encryptionkey * (1 + len(phrase) // len(encryptionkey)) [:len(phrase)]

How can I single out certain elements in a list and get an output with user input?

So I'm trying to a code using python where the user inputs a certain input and in return it gives a list with just the words with a (#) in front of it.
def labeled():
message_input = input("Enter a message or type q to end:").split()
result = list(message_input)
lstA =[]
for i in result:
if '#' in i :
lstA.append(i[1:])
continue
print(lstA)
else:
import sys
sys.exit()
break
So far I am able to get the message the user typed and give a list as an output but I want for the user to input a message (ex: "Nice day today #running #marathon") and for python to return [running,marathon]. With this in mind too how would I take out the punctuation at the end of a word if it has it too (ex: #marathon.) output should be [marathon].
I also am trying to get the program to quit if user inputs a q specifically but until the user presses q the system should keep asking the user to input messages and once they quit it returns a list of what the user inputted.
You can use translate to find a specific character in following way:
def test():
while(True):
result = input("Enter a message or type q to end:")
lstA =[]
if result =='q':
break
else:
for i in result.split():
if i.startswith('#'):
lstA.append(i.translate({ord('#'): None}))
print(lstA)
## calling test function
test()
I hope, it solves your problem.
Can use a regex to search for any alphanumeric string prefixed by a # for example
import re
def labeled(s):
return re.findall(r'#([\w\d]+)', s)
>>> labeled("Nice day today #running #marathon")
['running', 'marathon']
Similarly you could str.split the string on whitespace and keep all the substrings that str.startwith a '#' character
def labeled(s):
return [i[1:] for i in s.split() if i.startswith('#')]
>>> labeled("Nice day today #running #marathon")
['running', 'marathon']

String Format Checking in Python

While preparing for my AS-Level Computer Science exam I came across a question in the pre-release material:
Prompt the user to input a User ID and check if the format of the ID corresponds with pre-defined formatting rules and output accordingly.
The Format (In order):
One upper case letter
Two Lower case letters
Three numeric characters (digits)
Example: "Abc123"
I came up with a solution using my language of choice(Python), however, I was wondering if there is a more elegant or better way to solve this. Especially the third check.
Here is my code:
#Task 2.2
u_id = input("Input User ID: ") #DECLARE u_id : string
numbers = [str(num) for num in range(10)]
#Checking if final 3 characters of User ID (u_id) are digits
for i in list(u_id[3::]):
if i not in numbers:
digit_check = False #DECLARE digit_check : bool
break
else:
digit_check = True
#User ID format check
if (u_id[0:1].isupper() == True) and (u_id[1:3] == u_id[1:3].lower()) and (digit_check == True):
print ("Correct Format")
else:
print ("Wrong Format")
Ignore the DECLARATION comments. They are an exam requirement.
Thanks
If you are allowed to import re:
import re
u_id = input("Input User ID: ") #DECLARE u_id : string
rex = re.compile("^[A-Z][a-z]{2}[0-9]{3}$")
if rex.match(u_id):
print("Correct format")
else:
print("Incorrect")
Explanation of expression:
^ represents the beginning of a string.
[A-Z] is a range, containing all uppercase letters (in the English alphabet).
[a-z] is a range, containing all lowercase letters.
[0-9] is a range, containing all numbers.
{n} specifies that n items (items are whatever is before the curly brackets) will be matched.
$ represents the end of the string.
Also, you can see more detailed explanations and test arbitrary strings against this regular expression here.
If you want to solve it without regular expressions (mind you, in this case they are the right tool!), you could do something like this:
id_format = [
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", # or string.ascii_uppercase etc.
"abcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyz",
"0123456789",
"0123456789",
"0123456789",
]
def check(input):
# check for same length
if len(input) != len(id_format):
return False
for test, valid in zip(input, id_format): # itertools.zip_longest can make
if test not in valid: # the length check unnecessary
return False
return True
check("Abc123") # True
check("abc123") # False

Python - Trying to use a list value in an IF statment

I need to ask a user to input a question that will be compared to a list. The matched word will be displayed and then linked to an option menu. I have added the code below. I have managed to get the the program to search the input and return the word in the find list if a match appears. However I can not figure out how to use the result in an if statement as it is not a string value. I know there is a long way of doing this but is there a simple way of changing 'result' to a string value?
import re
question = input("Please enter your problem:")
find=["display","screen","battery"]
words=re.findall("\w+",question)
result=[x for x in find if x in words]
print (result)
if result in find:
print("Is your display not working?")
else:
print("Hard Luck")
Sorry I forgot to say that the outcome of the match will result in a different if statement being selected/printed. For example - If the 'question' used the word 'display' then an IF statement suggesting a solution will be printed, elif the 'question' used the word 'screen' then I elif for a solution to a broken screen will be printed and elif 'question' used 'battery' elif solution to charge the battery will be printed. The problem is I can not change 'result' to a str value to use in an IF statement. I can not check - if result=="display".. or if result=="screen".. or if result=="battery"...
If what you are trying to achieve is given the user input, whether any of the words in the user given by the user is also present in find list. Then you should just check whether the result list is empty or not. If the result list is empty, that means that none of the words in find were present in the list words . Example -
if result:
print("Is your display not working?")
else:
print("Hard Luck")
Please note, empty lists are considered False-like in boolean context, so you can simply do if result: , as given above.
An easier way for you to do this would be to create sets from start and use set.intersection(). Example -
import re
question = input("Please enter your problem:")
find=set(["display","screen","battery"])
words=re.findall("\w+",question)
result = find.intersection(words)
if result:
print("Is your display not working?")
else:
print("Hard Luck")
You may use set type for your task:
import re
question = input("Please enter your problem:")
find={"display","screen","battery"}
words=re.findall("\w+",question)
result=set([x for x in find if x in words])
print (result)
if result & find:
print("Is your display not working?")
else:
print("Hard Luck")
Considering you are already using a regex to extract the words from question and you considering the matched word will be displayed and then linked to an option menu you should compile the regex using the words you want to search for and do a findall with that, you also need to consider the case, if you want Screen and screen to be considered the same word you need to lower the input string:
import re
question = input("Please enter your problem:").lower()
find = ["display","screen","battery"]
r = re.compile(r"\b|\b".join(find))
words = r.findall(question)
if words:
print(words)
print("Is your display not working?")
That like your own code and all the answers here will not return a string, it potentially returns multiple strings including the same word repeated multiple times. If you want to use each word you
If you want the first match or only care if any word matches use search which will also cover is there a simple way of changing 'result' to a string value:
r = re.compile(r"|".join(find))
words = r.search(question)
if words:
print(words.group())
That will give you the first match in sentence for any word in the input sentence.
You also need to use word boundaries if you don't want to match screens etc..
find = ["display","screen","battery"]
r = re.compile(r"|".join([r"\b{}\b".format(s) for s in find]),re.I)
To do it using sets and get the actual word without a regex you can lower, split and rstrip the punctuation from each word in the sentence, then check if each word is in a set of words using next to get the first match:
from string import punctuation
question = input("Please enter your problem:").lower()
find = {"display","screen","battery"}
words = (word.rstrip(punctuation) for word in question.split())
result = next((x for x in words if word in find), None)
if result:
print(result)
print("Is your display not working?")
else:
print("Hard Luck")
Lastly if you did not actually want the words, you should not use intersection, just check if the set find is disjoint of words which will be True if any word in words appears in find:
find = {"display","screen","battery"}
words = re.findall("\w+",question)
if not find.isdisjoint(words):
print("Is your display not working?")
else:
print("Hard Luck")
If you want to output a particular message for each word, use a dict with the appropriate string for each word as the value:
import re
question = input("Please enter your problem:").lower()
find = ["display", "screen", "battery"]
r = re.compile(r"\b|\b".join(find))
output = {"screen":"screen message","display":"display message","battery":"battery message"}
word = r.search(question)
if word:
print(output[word.group()])
Or for multiple words:
output = {"screen":"screen message","display":"display message","battery":"battery message"}
words = r.findall(question)
print("\n".join([output[word] for word in words]))
import re
def questioner():
question = raw_input("Please enter your problem:")
find = ["display", "screen", "battery"]
words = re.findall("\w+", question)
result = [x for x in find if x in words]
if len(result) > 0:
print("Is your display not working?")
else:
print("Hard Luck")
if __name__ == "__main__":
questioner()
You just have to check if result list is subset of existing find list!

Categories

Resources