class CipherTest:
def __init__(self):
self.shift = 0
self.direction = 'r'
self.text = "Testing"
# Shift to right function
def shift_to_right(self, text, shift):
encrypted_text = ""
for i in range(len(self.text)):
c = self.text[i]
# Encrypt upper case
if (c == ' '):
encrypted_text = ' '
elif (c.isupper()):
encrypted_text = chr((ord(c) self.shift - 65) % 26 65)
# Encrypt lower case
else:
encrypted_text = chr((ord(c) self.shift - 97) % 26 97)
return encrypted_text
# Shift to left function
def shift_to_left(self, text, shift):
encrypted_text = ""
for i in range(len(self.text)):
c = self.text[i]
# Encrypt upper case
if (c == ' '):
encrypted_text = ' '
elif (c.isupper()):
encrypted_text = chr((ord(c) - self.shift - 65) % 26 65)
# Encrypt lower case
else:
encrypted_text = chr((ord(c) - self.shift - 97) % 26 97)
return encrypted_text
if __name__ == "__main__":
user_text = str(input())
user_shift = int(input())
user_direction = str(input().lower()) # user inputs
Cipher_Message = CipherTest() # create an instance of the class
if user_direction == 'l': # picking left or right
print(CipherTest.shift_to_left(Cipher_Message, user_text, user_shift))
if user_direction == 'r':
print(CipherTest.shift_to_right(Cipher_Message, user_text, user_shift))
Am I calling the functions within my class incorrectly? Currently no matter the input, it prints "Testing". I'm new to classes but I believe that in the last couple lines, I am calling the new instance, telling it which method to perform, then feeding it the variables it needs to successfully run. From there it should be printing the 'encrypted_text' that is returned using my methods.
CodePudding user response:
The issue is that CipherTest
have attributes direction, shift and text but you also have local variables that you pass as parameter which you don't use
So your method keep using Testing
and 0
, that returns Testing
so
The easiest, is to remove the attributs, so the class instance can do both direction, and in fact the method can be static (meaning no instance needed, only the class)
class CipherTest:
@staticmethod
def shift_to_right(text, shift):
encrypted_text = ""
for c in text:
if c == ' ':
encrypted_text = ' '
elif c.isupper():
encrypted_text = chr((ord(c) shift - 65) % 26 65)
else:
encrypted_text = chr((ord(c) shift - 97) % 26 97)
return encrypted_text
if __name__ == "__main__":
user_text = "hey how are you"
user_shift = 2
user_direction = "l"
if user_direction == 'l':
enc = CipherTest.shift_to_left(user_text, user_shift)
print(enc) # encrypted
print(CipherTest.shift_to_right(enc, user_shift)) # back to plain
elif user_direction == 'r':
enc = CipherTest.shift_to_right(user_text, user_shift)
print(enc) # encrypted
print(CipherTest.shift_to_left(enc, user_shift)) # back to plain
Another example, so you understand better, is to put the shift
as class attribut, in order to use ise, we need to save in the class with self.shift = shift
then we can use one cipher instance, with it's shift, to do both operation (also see how we really call a instance method)
class CipherTest:
def __init__(self, shift: int):
self.shift = shift
def shift_to_right(self, text):
encrypted_text = ""
for c in text:
if c == ' ':
encrypted_text = ' '
elif c.isupper():
encrypted_text = chr((ord(c) self.shift - 65) % 26 65)
else:
encrypted_text = chr((ord(c) self.shift - 97) % 26 97)
return encrypted_text
if __name__ == "__main__":
user_text = "hey how are you"
user_shift = 2
user_direction = "l"
cipher = CipherTest(user_shift)
if user_direction == 'l':
enc = cipher.shift_to_left(user_text)
print(enc) # encrypted
print(cipher.shift_to_right(enc)) # back to plain
elif user_direction == 'r':
enc = cipher.shift_to_right(user_text)
print(enc) # encrypted
print(cipher.shift_to_left(enc)) # back to plain
CodePudding user response:
You're passing the class in as a parameter to your function.
CipherTest.shift_to_left(Cipher_Message, user_text, user_shift)
When you define a class method in python, you include self as a parameter but don't actually pass it when calling the function. It's interpreting Cipher_Message (the instance) as what you intended to put in as user_text.
Fix this by simply removing Cipher_Message from your parameters:
CipherTest.shift_to_left(user_text, user_shift)
You're not done yet. You're attempting to call a non-static method on the Class, instead of the instance. This means you're telling the 'blueprint' to shift your encryption as opposed to your actual test class. Fix this by changing the class to the instance:
Cipher_Message.shift_to_left(user_text, user_shift)
A nonbreaking bug you also have is that your functions seem to be taking parameters that you aren't using.
def shift_to_right(self, text, shift):
takes two parameters - text & shift, yet you use the class's fields instead of those.
Simply removing them from the definitions and calls will remedy this.
def shift_to_right(self):
.shift_to_right()
CodePudding user response:
Within your class methods, you are accepting parameters of text and shift, but the code of the methods never references those parameters.
The methods only reference the instance variables self.text and self.shift, which are attributes of the instance Cipher_Message
, assigned during the execution of __init__ when the new instance was created
Two options:
- Update the methods to use the parameters instead of the instance attributes.
- Update __init__ to take text and shift as parameters, and assign the instance attributes based on the parameters that were passed in.
CodePudding user response:
Ignoring how the user input is handled, this can be greatly simplified.
class CipherTest:
@staticmethod
def shift_to_left(text, shift):
return CipherTest.shift(text, -shift)
@staticmethod
def shift_to_right(text, shift):
return CipherTest.shift(text, shift)
@staticmethod
def shift(text, shift):
result = ''
for c in text:
if c.isupper():
c = chr((ord(c) shift - 65) % 26 65)
elif c.islower():
c = chr((ord(c) shift - 97) % 26 97)
# note that whitespace is neither upper nor lower so just append unchanged
result = c
return result
print(CipherTest.shift_to_left(CipherTest.shift_to_right('Hello world', 3), 3))
...which keeps the interface similar. Alternatively:
print(CipherTest.shift(CipherTest.shift('Hello world', 3), -3))
Output:
Hello world