I am writing a class called 'Message' which takes a string 'message' in its constructor function. It basically encodes and decodes the message with some algorithms. Very basic and beginner stuff. The class is as follows: (It is a very long one.)
class Message:
def __init__(self, message: str) -> None:
self.message: str = message.strip()
self.__displacement: int = 0
self.__info: dict[Any, Any] = {
"Encoded": False, "Algorithms": (), "Caesar_shift": "NONE"}
def __str__(self) -> str:
return self.message
def __repr__(self) -> str:
return self.message
_enc_types: list[str] = ["None", "CAESAR", "MORSE"]
_enc_funcs: dict[str, Any] = {
"CAESAR": lambda message, *args: Message(message)._caesar_encode(*args),
"MORSE": lambda message: Message(message)._morse_encode()
}
_dec_funcs: dict[str, Any] = {
"CAESAR": lambda message: Message(message)._caesar_decode(),
"MORSE": lambda message: Message(message)._morse_decode()
}
@staticmethod
def __modify_val(value: int, shift: str, mag: int) -> int:
if shift == "LEFT":
value -= mag
if value < 0:
value += 27
elif shift == "RIGHT":
value += mag
if value > 26:
value -= 27
else:
raise ValueError(
f"Argument '{shift}' for parameter 'shift' is not allowed.")
return value
def __displace(self, shift: str, mag: int) -> None:
if shift.upper() == "RIGHT":
self.__displacement += mag
else:
self.__displacement -= mag
eval_dict: dict[bool, str] = {
True: "LEFT",
False: "RIGHT"
}
if self.__displacement != 0:
self.__info["Caesar_shift"] = eval_dict.get(
(self.__displacement < 0), "NONE")
def _caesar_encode(self, shift: str, mag: int) -> str:
mag -= 1
with open("F:\Practice_Python\jsons\caesar.json", "r") as file:
dict_list = json.load(file)
letter_dict: dict[str, int] = dict_list[0]
num_dict: dict[str, str] = dict_list[1]
self.message = ''.join([num_dict.get(str(self.__modify_val(letter_dict.get(
letter, -1), shift, mag)), "?") for letter in self.message.lower()])
self.__displace(shift, mag)
return self.message
def _caesar_decode(self) -> None:
if (not self.__info["Encoded"]) and (self.__info["Algorithms"][-1] != "Caesar"):
raise EncodingError(
"Given message is not encoded by allowed algorithms.")
shift: str = self.__info["Caesar_shift"]
mag: int = self.__displacement + 1
if shift == "RIGHT":
shift = "LEFT"
self._caesar_encode(shift, mag)
self.__displace(shift, mag)
elif shift == "LEFT":
shift = "RIGHT"
self._caesar_encode(shift, mag)
self.__displace(shift, mag)
else:
raise EncodingError(
"Given message is not encoded by allowed algorithms.")
def _morse_encode(self) -> None:
with open("F:\Practice_Python\jsons\morse.json", "r") as file:
dict_morse: dict[str, str] = json.load(file)
self.message = "".join(
[dict_morse.get(char, char) + ' ' for char in self.message.lower()])
def _morse_decode(self) -> None:
with open('F:\Practice_Python\jsons\morse.json', 'r') as file:
dict_morse: dict[str, str] = json.load(file)
dict_decode: dict[str, str] = {
value: key for key, value in dict_morse.items()}
self.message = ''
for sub1 in self.message.lower().split(' '):
for sub2 in sub1.split(' '):
self.message += dict_decode.get(sub2, '?')
self.message += ' '
def __update_encoded(self, type: str) -> None:
self.__info["Encoded"] = True
self.__info["Algorithms"] = list(self.__info["Algorithms"])
self.__info["Algorithms"].append(type)
self.__info["Algorithms"] = tuple(self.__info["Algorithms"])
def __update_decoded(self) -> None:
self.__info["Algorithms"] = list(self.__info["Algorithms"])
del self.__info["Algorithms"][-1]
self.__info["Algorithms"] = tuple(self.__info["Algorithms"])
if len(self.__info["Algorithms"]) == 0:
self.__info["Encoded"] = False
def encode(self, type: str, *args):
type = type.upper().strip()
if type not in self._enc_types:
raise EncodingError(
"Given algorithm for encoding message is not present.")
self._enc_funcs.get(type, type)(self.message, *args)
self.__update_encoded(type)
def decode(self):
type: str = self.__info["Algorithms"][-1]
self._dec_funcs.get(type, type)()
self.__update_decoded(type)
Sorry if it is poorly written. But the encode function when called does not behave properly. Expected:
>>> message = Message('Hello')
>>> message.encode('CAESAR', 'RIGHT', 4)
>>> print(message)
khoor
Actual:
>>> message = Message('Hello')
>>> message.encode('CAESAR', 'RIGHT', 4)
>>> print(message)
Hello
So, it does not change the attribute to the desired value. But the function does it properly. It is probably the encode function's fault. I cannot find the problem. Please help and guide me. Thank you. And again sorry for the messy code.
_enc_funcs: dict[str, Any] = {
"CAESAR": lambda message, *args: Message(message)._caesar_encode(*args),
"MORSE": lambda message: Message(message)._morse_encode()
}
These lambda functions create a new Message object (which is then discarded); they do not encode the current Message object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.