Python question
-
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.