Optimized recursive_bubble_sort (#2410)

* optimized recursive_bubble_sort

* Fixed doctest error due whitespace

* reduce loop times for optimization

* fixup! Format Python code with psf/black push

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
Du Yuanchao
2020-09-10 16:31:26 +08:00
committed by GitHub
parent 25946e4570
commit 4d0a8f2355
60 changed files with 900 additions and 859 deletions

View File

@ -17,26 +17,50 @@ Created by TrapinchO
# used alphabet --------------------------
# from string.ascii_uppercase
abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# -------------------------- default selection --------------------------
# rotors --------------------------
rotor1 = 'EGZWVONAHDCLFQMSIPJBYUKXTR'
rotor2 = 'FOBHMDKEXQNRAULPGSJVTYICZW'
rotor3 = 'ZJXESIUQLHAVRMDOYGTNFWPBKC'
rotor1 = "EGZWVONAHDCLFQMSIPJBYUKXTR"
rotor2 = "FOBHMDKEXQNRAULPGSJVTYICZW"
rotor3 = "ZJXESIUQLHAVRMDOYGTNFWPBKC"
# reflector --------------------------
reflector = {'A': 'N', 'N': 'A', 'B': 'O', 'O': 'B', 'C': 'P', 'P': 'C', 'D': 'Q',
'Q': 'D', 'E': 'R', 'R': 'E', 'F': 'S', 'S': 'F', 'G': 'T', 'T': 'G',
'H': 'U', 'U': 'H', 'I': 'V', 'V': 'I', 'J': 'W', 'W': 'J', 'K': 'X',
'X': 'K', 'L': 'Y', 'Y': 'L', 'M': 'Z', 'Z': 'M'}
reflector = {
"A": "N",
"N": "A",
"B": "O",
"O": "B",
"C": "P",
"P": "C",
"D": "Q",
"Q": "D",
"E": "R",
"R": "E",
"F": "S",
"S": "F",
"G": "T",
"T": "G",
"H": "U",
"U": "H",
"I": "V",
"V": "I",
"J": "W",
"W": "J",
"K": "X",
"X": "K",
"L": "Y",
"Y": "L",
"M": "Z",
"Z": "M",
}
# -------------------------- extra rotors --------------------------
rotor4 = 'RMDJXFUWGISLHVTCQNKYPBEZOA'
rotor5 = 'SGLCPQWZHKXAREONTFBVIYJUDM'
rotor6 = 'HVSICLTYKQUBXDWAJZOMFGPREN'
rotor7 = 'RZWQHFMVDBKICJLNTUXAGYPSOE'
rotor8 = 'LFKIJODBEGAMQPXVUHYSTCZRWN'
rotor9 = 'KOAEGVDHXPQZMLFTYWJNBRCIUS'
rotor4 = "RMDJXFUWGISLHVTCQNKYPBEZOA"
rotor5 = "SGLCPQWZHKXAREONTFBVIYJUDM"
rotor6 = "HVSICLTYKQUBXDWAJZOMFGPREN"
rotor7 = "RZWQHFMVDBKICJLNTUXAGYPSOE"
rotor8 = "LFKIJODBEGAMQPXVUHYSTCZRWN"
rotor9 = "KOAEGVDHXPQZMLFTYWJNBRCIUS"
def _validator(rotpos: tuple, rotsel: tuple, pb: str) -> tuple:
@ -57,19 +81,22 @@ def _validator(rotpos: tuple, rotsel: tuple, pb: str) -> tuple:
unique_rotsel = len(set(rotsel))
if unique_rotsel < 3:
raise Exception(f'Please use 3 unique rotors (not {unique_rotsel})')
raise Exception(f"Please use 3 unique rotors (not {unique_rotsel})")
# Checks if rotor positions are valid
rotorpos1, rotorpos2, rotorpos3 = rotpos
if not 0 < rotorpos1 <= len(abc):
raise ValueError(f'First rotor position is not within range of 1..26 ('
f'{rotorpos1}')
raise ValueError(
f"First rotor position is not within range of 1..26 (" f"{rotorpos1}"
)
if not 0 < rotorpos2 <= len(abc):
raise ValueError(f'Second rotor position is not within range of 1..26 ('
f'{rotorpos2})')
raise ValueError(
f"Second rotor position is not within range of 1..26 (" f"{rotorpos2})"
)
if not 0 < rotorpos3 <= len(abc):
raise ValueError(f'Third rotor position is not within range of 1..26 ('
f'{rotorpos3})')
raise ValueError(
f"Third rotor position is not within range of 1..26 (" f"{rotorpos3})"
)
# Validates string and returns dict
pb = _plugboard(pb)
@ -97,21 +124,21 @@ def _plugboard(pbstring: str) -> dict:
# a) is type string
# b) has even length (so pairs can be made)
if not isinstance(pbstring, str):
raise TypeError(f'Plugboard setting isn\'t type string ({type(pbstring)})')
raise TypeError(f"Plugboard setting isn't type string ({type(pbstring)})")
elif len(pbstring) % 2 != 0:
raise Exception(f'Odd number of symbols ({len(pbstring)})')
elif pbstring == '':
raise Exception(f"Odd number of symbols ({len(pbstring)})")
elif pbstring == "":
return {}
pbstring.replace(' ', '')
pbstring.replace(" ", "")
# Checks if all characters are unique
tmppbl = set()
for i in pbstring:
if i not in abc:
raise Exception(f'\'{i}\' not in list of symbols')
raise Exception(f"'{i}' not in list of symbols")
elif i in tmppbl:
raise Exception(f'Duplicate symbol ({i})')
raise Exception(f"Duplicate symbol ({i})")
else:
tmppbl.add(i)
del tmppbl
@ -125,8 +152,12 @@ def _plugboard(pbstring: str) -> dict:
return pb
def enigma(text: str, rotor_position: tuple,
rotor_selection: tuple = (rotor1, rotor2, rotor3), plugb: str = '') -> str:
def enigma(
text: str,
rotor_position: tuple,
rotor_selection: tuple = (rotor1, rotor2, rotor3),
plugb: str = "",
) -> str:
"""
The only difference with real-world enigma is that I allowed string input.
All characters are converted to uppercase. (non-letter symbol are ignored)
@ -179,7 +210,8 @@ def enigma(text: str, rotor_position: tuple,
text = text.upper()
rotor_position, rotor_selection, plugboard = _validator(
rotor_position, rotor_selection, plugb.upper())
rotor_position, rotor_selection, plugb.upper()
)
rotorpos1, rotorpos2, rotorpos3 = rotor_position
rotor1, rotor2, rotor3 = rotor_selection
@ -245,12 +277,12 @@ def enigma(text: str, rotor_position: tuple,
return "".join(result)
if __name__ == '__main__':
message = 'This is my Python script that emulates the Enigma machine from WWII.'
if __name__ == "__main__":
message = "This is my Python script that emulates the Enigma machine from WWII."
rotor_pos = (1, 1, 1)
pb = 'pictures'
pb = "pictures"
rotor_sel = (rotor2, rotor4, rotor8)
en = enigma(message, rotor_pos, rotor_sel, pb)
print('Encrypted message:', en)
print('Decrypted message:', enigma(en, rotor_pos, rotor_sel, pb))
print("Encrypted message:", en)
print("Decrypted message:", enigma(en, rotor_pos, rotor_sel, pb))

View File

@ -21,20 +21,20 @@
class XORCipher:
def __init__(self, key=0):
"""
simple constructor that receives a key or uses
default key = 0
"""
simple constructor that receives a key or uses
default key = 0
"""
# private field
self.__key = key
def encrypt(self, content, key):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(key, int) and isinstance(content, str)
@ -55,11 +55,11 @@ class XORCipher:
def decrypt(self, content, key):
"""
input: 'content' of type list and 'key' of type int
output: decrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: 'content' of type list and 'key' of type int
output: decrypted string 'content' as a list of chars
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(key, int) and isinstance(content, list)
@ -80,11 +80,11 @@ class XORCipher:
def encrypt_string(self, content, key=0):
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: 'content' of type string and 'key' of type int
output: encrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(key, int) and isinstance(content, str)
@ -105,11 +105,11 @@ class XORCipher:
def decrypt_string(self, content, key=0):
"""
input: 'content' of type string and 'key' of type int
output: decrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: 'content' of type string and 'key' of type int
output: decrypted string 'content'
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(key, int) and isinstance(content, str)
@ -130,12 +130,12 @@ class XORCipher:
def encrypt_file(self, file, key=0):
"""
input: filename (str) and a key (int)
output: returns true if encrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: filename (str) and a key (int)
output: returns true if encrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(file, str) and isinstance(key, int)
@ -155,12 +155,12 @@ class XORCipher:
def decrypt_file(self, file, key):
"""
input: filename (str) and a key (int)
output: returns true if decrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
input: filename (str) and a key (int)
output: returns true if decrypt process was
successful otherwise false
if key not passed the method uses the key by the constructor.
otherwise key = 1
"""
# precondition
assert isinstance(file, str) and isinstance(key, int)