Improve readability of ciphers/mixed_keyword_cypher.py (#8626)

* refactored the code

* the code will now pass the test

* looked more into it and fixed the logic

* made the code easier to read, added comments and fixed the logic

* got rid of redundant code + plaintext can contain chars that are not in the alphabet

* fixed the reduntant conversion of ascii_uppercase to a list

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* keyword and plaintext won't have default values

* ran the ruff command

* Update linear_discriminant_analysis.py and rsa_cipher.py (#8680)

* Update rsa_cipher.py by replacing %s with {}

* Update rsa_cipher.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update linear_discriminant_analysis.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update linear_discriminant_analysis.py

* Update linear_discriminant_analysis.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update linear_discriminant_analysis.py

* Update linear_discriminant_analysis.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update linear_discriminant_analysis.py

* Update machine_learning/linear_discriminant_analysis.py

Co-authored-by: Christian Clauss <cclauss@me.com>

* Update linear_discriminant_analysis.py

* updated

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>

* fixed some difficulties

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* added comments, made printing mapping optional, added 1 test

* shortened the line that was too long

* Update ciphers/mixed_keyword_cypher.py

Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Rohan Anand <96521078+rohan472000@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
This commit is contained in:
Jan Wojciechowski 2023-06-09 11:06:37 +02:00 committed by GitHub
parent 7775de0ef7
commit 9c9da8ebf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,7 +1,11 @@
def mixed_keyword(key: str = "college", pt: str = "UNIVERSITY") -> str: from string import ascii_uppercase
"""
For key:hello
def mixed_keyword(
keyword: str, plaintext: str, verbose: bool = False, alphabet: str = ascii_uppercase
) -> str:
"""
For keyword: hello
H E L O H E L O
A B C D A B C D
@ -12,58 +16,60 @@ def mixed_keyword(key: str = "college", pt: str = "UNIVERSITY") -> str:
Y Z Y Z
and map vertically and map vertically
>>> mixed_keyword("college", "UNIVERSITY") # doctest: +NORMALIZE_WHITESPACE >>> mixed_keyword("college", "UNIVERSITY", True) # doctest: +NORMALIZE_WHITESPACE
{'A': 'C', 'B': 'A', 'C': 'I', 'D': 'P', 'E': 'U', 'F': 'Z', 'G': 'O', 'H': 'B', {'A': 'C', 'B': 'A', 'C': 'I', 'D': 'P', 'E': 'U', 'F': 'Z', 'G': 'O', 'H': 'B',
'I': 'J', 'J': 'Q', 'K': 'V', 'L': 'L', 'M': 'D', 'N': 'K', 'O': 'R', 'P': 'W', 'I': 'J', 'J': 'Q', 'K': 'V', 'L': 'L', 'M': 'D', 'N': 'K', 'O': 'R', 'P': 'W',
'Q': 'E', 'R': 'F', 'S': 'M', 'T': 'S', 'U': 'X', 'V': 'G', 'W': 'H', 'X': 'N', 'Q': 'E', 'R': 'F', 'S': 'M', 'T': 'S', 'U': 'X', 'V': 'G', 'W': 'H', 'X': 'N',
'Y': 'T', 'Z': 'Y'} 'Y': 'T', 'Z': 'Y'}
'XKJGUFMJST' 'XKJGUFMJST'
>>> mixed_keyword("college", "UNIVERSITY", False) # doctest: +NORMALIZE_WHITESPACE
'XKJGUFMJST'
""" """
key = key.upper() keyword = keyword.upper()
pt = pt.upper() plaintext = plaintext.upper()
temp = [] alphabet_set = set(alphabet)
for i in key:
if i not in temp: # create a list of unique characters in the keyword - their order matters
temp.append(i) # it determines how we will map plaintext characters to the ciphertext
len_temp = len(temp) unique_chars = []
# print(temp) for char in keyword:
alpha = [] if char in alphabet_set and char not in unique_chars:
modalpha = [] unique_chars.append(char)
for j in range(65, 91): # the number of those unique characters will determine the number of rows
t = chr(j) num_unique_chars_in_keyword = len(unique_chars)
alpha.append(t)
if t not in temp: # create a shifted version of the alphabet
temp.append(t) shifted_alphabet = unique_chars + [
# print(temp) char for char in alphabet if char not in unique_chars
r = int(26 / 4) ]
# print(r)
k = 0 # create a modified alphabet by splitting the shifted alphabet into rows
for _ in range(r): modified_alphabet = [
s = [] shifted_alphabet[k : k + num_unique_chars_in_keyword]
for _ in range(len_temp): for k in range(0, 26, num_unique_chars_in_keyword)
s.append(temp[k]) ]
if k >= 25:
# map the alphabet characters to the modified alphabet characters
# going 'vertically' through the modified alphabet - consider columns first
mapping = {}
letter_index = 0
for column in range(num_unique_chars_in_keyword):
for row in modified_alphabet:
# if current row (the last one) is too short, break out of loop
if len(row) <= column:
break break
k += 1
modalpha.append(s) # map current letter to letter in modified alphabet
# print(modalpha) mapping[alphabet[letter_index]] = row[column]
d = {} letter_index += 1
j = 0
k = 0 if verbose:
for j in range(len_temp): print(mapping)
for m in modalpha: # create the encrypted text by mapping the plaintext to the modified alphabet
if not len(m) - 1 >= j: return "".join(mapping[char] if char in mapping else char for char in plaintext)
break
d[alpha[k]] = m[j]
if not k < 25:
break
k += 1
print(d)
cypher = ""
for i in pt:
cypher += d[i]
return cypher
if __name__ == "__main__": if __name__ == "__main__":
# example use
print(mixed_keyword("college", "UNIVERSITY")) print(mixed_keyword("college", "UNIVERSITY"))