Python question
-
I wrote my first python application. I know Wordpress, SQL and other stuff I have used has limitations on special characters. Does python use any special characters? This application stops if you fail a section of the tests. I was taught to code this way. Why continue wasting computer cycles, if failure was reached.
It checks your password for the following criteria.
# This program will verify your password is the following criteria # 2 or more lowercase consonants # 2 or more lowercase vowels # 2 or more upper case consonants # 2 or more upper case vowels # 2 or more numbers # minimum of 12 characters from typing import List
The code is:
# !/usr/bin/python # This program will verify your password is the following criteria # 2 or more lowercase consonants # 2 or more lowercase vowels # 2 or more upper case consonants # 2 or more upper case vowels # 2 or more numbers # minimum of 12 characters from typing import List def main(): # creates arrays of lowercase consonants and uppercase consonants lower_con = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z']; lower_con upper_con = [element.upper() for element in lower_con]; upper_con # creates arrays of lowercase vowels and uppercase vowels lower_vowel = ['a', 'e', 'i', 'o', 'u']; lower_vowel upper_vowel = [element.upper() for element in lower_vowel]; upper_vowel # array of integers numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] # array of special characters special_char = ['`', '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '+', ':', ';', '?', '@', '<', '>', '_', '/', '|'] pass_test: List[str] = [ 'ShortTest77', 'CorrectSize12', 'ThreeeRepeating', 'UPPERCASETESt12', 'UppercaseTest12', 'UppErcaseTest12', 'UppErcaseTest12', 'UppErcASeTests2', 'UpPercAsETest34', 'Up%PercAsETest34', 'Up%PercAsE#Test34'] print(upper_con) print(lower_vowel) print(upper_vowel) print(numbers) print(special_char) print(pass_test) print(' ') print('now comes the fun stuff') # first thing check the password is longer than 12 characters # if shorter, you don't need to keep testing for a in pass_test: # is the password 12 characters or longer print(" ") if len(a) < 12: pass_testTF = "false" print(a, " ", "FAILED: Password is too short") else: print(a, " ", "PASSED: password is 12 characters or longer") pass_testTF = "true" # Next test is 3 duplicate characters import time if pass_testTF == "true": lengthofpw = len(a) loopcount = lengthofpw - 2 c = 0 while c < loopcount: if a[c] == a[c + 1] == a[c + 2]: pass_testTF = "false" c += 1 if pass_testTF == "true": print(a, " ", "PASSED: Does not have 3 repeating character") else: print(a, " ", "FAILED: has 3 repeating characters") # does it contain 2 or more lower case letters # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 lower_con_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 20: if a[c] == lower_con[cc]: lower_con_count += 1 cc += 1 c += 1 if lower_con_count >= 2: print(a, " ", "PASSED: It has at least 2 lower case consonants") else: print(a, " ", "FAILED: It has less than 2 lower case consonants") pass_testTF = "false" # does it contain 2 or more upper case consonants # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 upper_con_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 20: if a[c] == upper_con[cc]: upper_con_count += 1 cc += 1 c += 1 if upper_con_count >= 2: print(a, " ", "PASSED: It has at least 2 upper case consonants") else: print(a, " ", "FAILED: It has less than 2 upper case consonants") pass_testTF = "false" # does it contain 2 or more uppercase vowels # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 upper_vowel_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 4: if a[c] == upper_vowel[cc]: upper_vowel_count += 1 cc += 1 c += 1 if upper_vowel_count >= 2: print(a, " ", "PASSED: It has at least 2 uppercase vowels") else: print(a, " ", "FAILED: It has less than 2 uppercase vowels") pass_testTF = "false" # does it contain 2 or more lowercase vowels # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 lower_vowel_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 4: if a[c] == lower_vowel[cc]: lower_vowel_count += 1 cc += 1 c += 1 if lower_vowel_count >= 2: print(a, " ", "PASSED: It has at least 2 lowercase vowels") else: print(a, " ", "FAILED: It has less than 2 lowercase vowels") pass_testTF = "false" # does it contain 2 or more numbers # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 number_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 9: if a[c] == numbers[cc]: number_count += 1 cc += 1 c += 1 if number_count >= 2: print(a, " ", "PASSED: It has at least than 2 numbers") else: print(a, " ", "FAILED: It has less than 2 numbers") pass_testTF = "false" # does it contain 2 or more special characters # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 spec_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 9: if a[c] == special_char[cc]: spec_count += 1 cc += 1 c += 1 if spec_count >= 2: print(a, " ", "PASSED: It has at least than 2 special characters") else: print(a, " ", "FAILED: It has less thn 2 special characters") pass_testTF = "false" if __name__ == "__main__": main() # !/usr/bin/python # This program will verify your password is the following criteria # 2 or more lowercase consonants # 2 or more lowercase vowels # 2 or more upper case consonants # 2 or more upper case vowels # 2 or more numbers # minimum of 12 characters from typing import List def main(): # creates arrays of lowercase consonants and uppercase consonants lower_con = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z']; lower_con upper_con = [element.upper() for element in lower_con]; upper_con # creates arrays of lowercase vowels and uppercase vowels lower_vowel = ['a', 'e', 'i', 'o', 'u']; lower_vowel upper_vowel = [element.upper() for element in lower_vowel]; upper_vowel # array of integers numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] # array of special characters special_char = ['`', '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '+', ':', ';', '?', '@', '<', '>', '_', '/', '|'] pass_test: List[str] = [ 'ShortTest77', 'CorrectSize12', 'ThreeeRepeating', 'UPPERCASETESt12', 'UppercaseTest12', 'UppErcaseTest12', 'UppErcaseTest12', 'UppErcASeTests2', 'UpPercAsETest34', 'Up%PercAsETest34', 'Up%PercAsE#Test34'] print(upper_con) print(lower_vowel) print(upper_vowel) print(numbers) print(special_char) print(pass_test) print(' ') print('now comes the fun stuff') # first thing check the password is longer than 12 characters # if shorter, you don't need to keep testing for a in pass_test: # is the password 12 characters or longer print(" ") if len(a) < 12: pass_testTF = "false" print(a, " ", "FAILED: Password is too short") else: print(a, " ", "PASSED: password is 12 characters or longer") pass_testTF = "true" # Next test is 3 duplicate characters import time if pass_testTF == "true": lengthofpw = len(a) loopcount = lengthofpw - 2 c = 0 while c < loopcount: if a[c] == a[c + 1] == a[c + 2]: pass_testTF = "false" c += 1 if pass_testTF == "true": print(a, " ", "PASSED: Does not have 3 repeating character") else: print(a, " ", "FAILED: has 3 repeating characters") # does it contain 2 or more lower case letters # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 lower_con_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 20: if a[c] == lower_con[cc]: lower_con_count += 1 cc += 1 c += 1 if lower_con_count >= 2: print(a, " ", "PASSED: It has at least 2 lower case consonants") else: print(a, " ", "FAILED: It has less than 2 lower case consonants") pass_testTF = "false" # does it contain 2 or more upper case consonants # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 upper_con_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 20: if a[c] == upper_con[cc]: upper_con_count += 1 cc += 1 c += 1 if upper_con_count >= 2: print(a, " ", "PASSED: It has at least 2 upper case consonants") else: print(a, " ", "FAILED: It has less than 2 upper case consonants") pass_testTF = "false" # does it contain 2 or more uppercase vowels # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 upper_vowel_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 4: if a[c] == upper_vowel[cc]: upper_vowel_count += 1 cc += 1 c += 1 if upper_vowel_count >= 2: print(a, " ", "PASSED: It has at least 2 uppercase vowels") else: print(a, " ", "FAILED: It has less than 2 uppercase vowels") pass_testTF = "false" # does it contain 2 or more lowercase vowels # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 lower_vowel_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 4: if a[c] == lower_vowel[cc]: lower_vowel_count += 1 cc += 1 c += 1 if lower_vowel_count >= 2: print(a, " ", "PASSED: It has at least 2 lowercase vowels") else: print(a, " ", "FAILED: It has less than 2 lowercase vowels") pass_testTF = "false" # does it contain 2 or more numbers # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 number_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 9: if a[c] == numbers[cc]: number_count += 1 cc += 1 c += 1 if number_count >= 2: print(a, " ", "PASSED: It has at least than 2 numbers") else: print(a, " ", "FAILED: It has less than 2 numbers") pass_testTF = "false" # does it contain 2 or more special characters # Outside loop is the letters of test-Pass if pass_testTF == "true": c = 0 spec_count = 0 while c < lengthofpw: # inside loop is the lower_con array cc = 0 while cc < 9: if a[c] == special_char[cc]: spec_count += 1 cc += 1 c += 1 if spec_count >= 2: print(a, " ", "PASSED: It has at least than 2 special characters") else: print(a, " ", "FAILED: It has less thn 2 special characters") pass_testTF = "false" if __name__ == "__main__": main()
Output:
/home/michael/PycharmProjects/firstproj/venv/bin/python /home/michael/PycharmProjects/firstproj/arrays.py ['B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z'] ['a', 'e', 'i', 'o', 'u'] ['A', 'E', 'I', 'O', 'U'] ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] ['`', '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '+', ':', ';', '?', '@', '<', '>', '_', '/', '|'] ['ShortTest77', 'CorrectSize12', 'ThreeeRepeating', 'UPPERCASETESt12', 'UppercaseTest12', 'UppErcaseTest12', 'UppErcaseTest12', 'UppErcASeTests2', 'UpPercAsETest34', 'Up%PercAsETest34', 'Up%PercAsE#Test34'] now comes the fun stuff ShortTest77 FAILED: Password is too short CorrectSize12 PASSED: password is 12 characters or longer CorrectSize12 PASSED: Does not have 3 repeating character CorrectSize12 PASSED: It has at least 2 lower case consonants CorrectSize12 PASSED: It has at least 2 upper case consonants CorrectSize12 FAILED: It has less than 2 uppercase vowels ThreeeRepeating PASSED: password is 12 characters or longer ThreeeRepeating FAILED: has 3 repeating characters UPPERCASETESt12 PASSED: password is 12 characters or longer UPPERCASETESt12 PASSED: Does not have 3 repeating character UPPERCASETESt12 FAILED: It has less than 2 lower case consonants UppercaseTest12 PASSED: password is 12 characters or longer UppercaseTest12 PASSED: Does not have 3 repeating character UppercaseTest12 PASSED: It has at least 2 lower case consonants UppercaseTest12 FAILED: It has less than 2 upper case consonants UppErcaseTest12 PASSED: password is 12 characters or longer UppErcaseTest12 PASSED: Does not have 3 repeating character UppErcaseTest12 PASSED: It has at least 2 lower case consonants UppErcaseTest12 FAILED: It has less than 2 upper case consonants UppErcaseTest12 PASSED: password is 12 characters or longer UppErcaseTest12 PASSED: Does not have 3 repeating character UppErcaseTest12 PASSED: It has at least 2 lower case consonants UppErcaseTest12 FAILED: It has less than 2 upper case consonants UppErcASeTests2 PASSED: password is 12 characters or longer UppErcASeTests2 PASSED: Does not have 3 repeating character UppErcASeTests2 PASSED: It has at least 2 lower case consonants UppErcASeTests2 PASSED: It has at least 2 upper case consonants UppErcASeTests2 PASSED: It has at least 2 uppercase vowels UppErcASeTests2 PASSED: It has at least 2 lowercase vowels UppErcASeTests2 FAILED: It has less than 2 numbers UpPercAsETest34 PASSED: password is 12 characters or longer UpPercAsETest34 PASSED: Does not have 3 repeating character UpPercAsETest34 PASSED: It has at least 2 lower case consonants UpPercAsETest34 PASSED: It has at least 2 upper case consonants UpPercAsETest34 PASSED: It has at least 2 uppercase vowels UpPercAsETest34 PASSED: It has at least 2 lowercase vowels UpPercAsETest34 PASSED: It has at least than 2 numbers UpPercAsETest34 FAILED: It has less thn 2 special characters Up%PercAsETest34 PASSED: password is 12 characters or longer Up%PercAsETest34 PASSED: Does not have 3 repeating character Up%PercAsETest34 PASSED: It has at least 2 lower case consonants Up%PercAsETest34 PASSED: It has at least 2 upper case consonants Up%PercAsETest34 PASSED: It has at least 2 uppercase vowels Up%PercAsETest34 PASSED: It has at least 2 lowercase vowels Up%PercAsETest34 PASSED: It has at least than 2 numbers Up%PercAsETest34 FAILED: It has less thn 2 special characters Up%PercAsE#Test34 PASSED: password is 12 characters or longer Up%PercAsE#Test34 PASSED: Does not have 3 repeating character Up%PercAsE#Test34 PASSED: It has at least 2 lower case consonants Up%PercAsE#Test34 PASSED: It has at least 2 upper case consonants Up%PercAsE#Test34 PASSED: It has at least 2 uppercase vowels Up%PercAsE#Test34 PASSED: It has at least 2 lowercase vowels Up%PercAsE#Test34 PASSED: It has at least than 2 numbers Up%PercAsE#Test34 PASSED: It has at least than 2 special characters Process finished with exit code 0
-
Michael,
If you are using Python3, then the string type supports unicode encoding so there shouldn't be any limitation on what can be used in a string. -
Virtualization: vmware Operating System: Ubuntu 18.04.3 LTS Kernel: Linux 5.0.0-36-generic Architecture: x86-64
python --version Python 2.7.15+
Python 3 is not installed by default. Not sure why. I was considering looking into the repository install for it.
michael@programmer:~$ python3 --version Python 3.7.5
-
I changed the top part to
# !/usr/bin/python3 # This program will verify your password is the following criteria # 2 or more lowercase consonants # 2 or more lowercase vowels # 2 or more upper case consonants # 2 or more upper case vowels # 2 or more numbers # minimum of 12 characters from typing import List def main(): import sys print(sys.version)
/home/michael/PycharmProjects/firstproj/venv/bin/python /home/michael/PycharmProjects/firstproj/arrays.py 3.6.8 (default, Oct 7 2019, 12:59:55) [GCC 8.3.0]
-
Word of warning. Don't upgrade Python!
It broke netplan. On reboot Ubuntu desktop gui stopped working. 17 update available but all are updated. Server is trashed.
-
Michael,
Unfortunately, come January 2020, Python 2 will be dead. If security is a concern, then you will have to upgrade. Any tools that do not, I would be concerned about. -
I did a clean reinstall. Didn't try to put netplan in. Python 3 is installed now as 3.6.8. I think once 3.7.5 is stable it will be installed. I check several times a week for updates. I checked to see if python --version is installed. 2.7..5 is gone. It said use python3. SSH and RDP are working. I put the code back in and ran it.
Learned a new wordpress <pre><code> to display my code on my web site.
Thanks for the help. I appreciated it.
-
Hey Michael,
You piqued my interest on this problem. I decided to give it shot implementing in my style. I am not sure that all of the checks are exactly that same (I didn't distinguish between consonant and vowels). However, I figured I would post it as I find it a great learning experience to see how individuals solve the same problem. (I am not saying that mine is the best either :D)#!/usr/bin/python #!/bin/bash # this is wrong, but left for documentation... see above. import re import textwrap def window(seq, window_size=3): size = len(seq) - window_size + 1 for i in range(size): yield seq[i:i + window_size] def no_repeating_three_characters(s): return not any( all(x == chunk[0] for x in chunk) for chunk in window(s) ) conditions = ( ("2+ lowercase", re.compile(r"[a-z].*[a-z]").search), ("2+ uppercase", re.compile(r"[A-Z].*[A-Z]").search), ("2+ numbers", re.compile(r"[0-9].*[0-9]").search), ("2+ special characters", re.compile(r"[!@#$%^&*()<>?].*[!@#$%^&*()<>?]").search), ("no 3+ repeating letters", no_repeating_three_characters), ("12+ characters long", lambda x: len(x) >= 12) ) tests = ( 'ShortTest77', 'CorrectSize12', 'ThreeeRepeating', 'UPPERCASETESt12', 'UppercaseTest12', 'UppErcaseTest12', 'UppErcaseTest12', 'UppErcASeTests2', 'UpPercAsETest34', 'Up%PercAsETest34', 'Up%PercAsE#Test34' ) def main(): for test in tests: print(f"Testing: {test}") messages = [] for label, fn in conditions: check = fn(test) message = textwrap.indent( f"{label}: {'Passed' if bool(check) else 'Failed'}", prefix=" + " ) messages.append(message) if not check: break print("\n".join(messages)) if __name__ == '__main__': main()
P.S. I have used some Python 3.5+ features such as f-strings.
-
I usually start out coding in several phases.
1.) Get it done so it works.
2.) find better methods to cut the code by 20% in lines and run time.
3.) Tweak on it for stuff I thought of afterI want my code short fast and in elevator mode. Start at the top and fall through without going back up. I am going to load your code and try it. Python indents are annoying me. My servers today upgraded to 3.6.9 from 3.6.8.
You really shorted the code down to a fewer lines. I loaded it into Python3. You used bash instead of python3.
-
@Michael-McKenney skipping separating vowels made is easier to code. Adding in vowels as a test, made it more difficult to do. Do they have a way to doing just vowels by your method?
-
You could add this to the tuple of conditions:
("2+ vowels", re.compile(r"[aeiouAEIOU].*[aeiouAEIOU]").search)
I would probably refactor that
re.compile(r"...").search
repetitive function into an independent function eventually, but this works for now.Also, I just put the wrong shebang at the top of my file. It is Python3.
-
#!/usr/bin/env python3 import re import textwrap def window(seq, window_size=3): size = len(seq) - window_size + 1 for i in range(size): yield seq[i:i + window_size] def no_repeating_three_characters(s): return not any( all(x == chunk[0] for x in chunk) for chunk in window(s) ) conditions = ( ("2+ vowels", re.compile(r"[aeiouAEIOU].*[aeiouAEIOU ]").search), ("2+ consonants", re.compile(r"[bcdfghjklmnpqrstvwxyzBCDFGHIJKLMNPQRSTVWXYZ].*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ ]").search), ("2+ numbers", re.compile(r"[0-9].*[0-9]").search), ("2+ special characters", re.compile(r"[!@#$%^&*()<>?].*[!@#$%^&*()<>?]").search), ("no 3+ repeating letters", no_repeating_three_characters), ("12+ characters long", lambda x: len(x) >= 12) ) tests = ( 'ShortTest77', 'CorrectSize12', 'ThreeeRepeating', 'UPPERCASETESt12', 'UppercaseTest12', 'UppErcaseTest12', 'UppErcaseTest12', 'UppErcASeTests2', 'UpPercAsETest34', 'Up%PercAsETest34', 'Up%PercAsE#Test34' ) def main(): for test in tests: print(f"Testing: {test}") messages = [] for label, fn in conditions: check = fn(test) message = textwrap.indent( f"{label}: {'Passed' if bool(check) else 'Failed'}", prefix=" + " ) messages.append(message) if not check: break print("\n".join(messages)) if __name__ == '__main__': main()
So something like this? I think I would move the 12+ character test to first item. If it is too short why do the rest of it.
-
That will work. I tend not to work on performance so much if the problem space is small or until I run into performance issues. Reordering is ultimately your preference.
-
I have been on very old networks that performance on applications I write is a must. It also makes debugging easier having the right order. I would probably put 3 characters second. It is one time check that eliminates loop count faster.
-
I would always profile before making a determination on performance.