-1

I'm working on an experimental project (creating a basic enigma machine mechanism), and I'm running into an issue when reassigning a variable. I have a "check" function that checks to ensure that the value entered by the user is a number between 1 and 26, if it isn't, it calls the input function again, asking for a new value. Everything works fine if I input a number between 1 and 26 (ex: 4), however, if I enter 29 or "qwerty", it begins to mess up. It calls the input function again (as expected), and if I were to then enter 4 as the value, the variable gets assigned as "None".

How can I fix this?

CLI output of it when working (ex: entered 4):

What is the message you would like to encrypt?as
For the next 3 questions, please input ONLY a number from 1 to 26
What is the first key value?4
4

CLI output of it when failing (ex: entered 28 then 4):

What is the message you would like to encrypt?asd
For the next 3 questions, please input ONLY a number from 1 to 26
What is the first key value?28
You must input a number between 1 and 26!
What is the first key value?4
None

Code:

class Input:

    def message():
        msg = input("What is the message you would like to encrypt?")
        msg = msg.upper()
        print("\n For the next 3 questions, please input ONLY a number from 1 to 26")

    def check(input):
        try:
            if int(input) < 1 or int(input) > 26:
                return False
            else:
                return True
        except:
            return False

    def getKey(keyNum):
        word = ""
        if keyNum == 1:
            word = "first"
        elif keyNum == 2:
            word = "second"
        else:
            word = "third"

        s = input("What is the {} key value?".format(word))
        chk = Input.check(s)
        if chk:
            return(s)
        else:
            print("You must input a number between 1 and 26!")
            Input.getKey(1)

inp = Input
inp.message()
s1 = inp.getKey(1)
print(s1)
David Z
  • 128,184
  • 27
  • 255
  • 279
  • After you fix the issue you're asking about here, you might want to head over to [codereview.SE] to get some general tips about structuring your code. – David Z Aug 02 '17 at 17:39

3 Answers3

1

The problem comes from your getKey() function:

def getKey(keyNum):
    ...
    chk = Input.check(s)
    if chk:
        return(s)
    else:
        print("You must input a number between 1 and 26!")
        Input.getKey(1)

If the first call to Input.check(s) returns True, then getKey() returns the value that was entered. But if that first call returns False, then getKey() does not return anything. It asks for input again, which you see, but it never conveys that input back to the code that needs it. What you need to do is add an appropriate return statement to the else block so that the value coming from the recursive call to getKey() is returned.

David Z
  • 128,184
  • 27
  • 255
  • 279
0

In your code here:

    if chk:
        return(s)
    else:
        print("You must input a number between 1 and 26!")
        Input.getKey(1)

When chk is "truthy" -- that is, when if chk: succeeds -- you do a return of s.

But when the else: is run, you don't return anything. Instead, you recurse into getKey(1) (which is wrong - you should use the parameter in case it's 2 or 3).

Now, the recursive call to getKey(1) will return a value. But you ignore that value and don't return.

Since you don't return in that branch, you "fall through" to the end of the function, where Python's default mechanism kicks in: if a function doesn't return any value, Python automatically supplies a None as the result.

That's what you're getting in the else: case.

aghast
  • 14,785
  • 3
  • 24
  • 56
-1

You have created class name Input so its class function should have first argument self in them also on calling the same function from inside function we will call it by self.name function so that it doesn't call other function for other variable but present.
A little mistake was calling Input.getKey(1) which should be correctly like self.getKey(keyNum) to supply current Key.

class Input:

    def message(self):
        msg = input("What is the message you would like to encrypt?")
        msg = msg.upper()
        print("\n For the next 3 questions, please input ONLY a number from 1 to 26")

    def check(self,input):
        try:
            if int(input) < 1 or int(input) > 26:
                return False
            else:
                return True
        except:
            return False

    def getKey(self,keyNum):
        word = ""
        if keyNum == 1:
            word = "first"
        elif keyNum == 2:
            word = "second"
        else:
            word = "third"

        s = input("What is the {} key value?".format(word))
        chk = self.check(s)
        if chk:
            return s
        else:
            print("You must input a number between 1 and 26!")
            return self.getKey(keyNum)

inp = Input()
inp.message()
s1 = inp.getKey(1)
print(s1)

The proper way of calling member function in a class variable here

See it working here

Rajan Chauhan
  • 1,378
  • 1
  • 13
  • 32
  • I attempted to use self in the way that you suggested, by adding it into the arguments, but now I get the error "TypeError: message() missing 1 required positional argument: 'self'" when I try to call the function. – Trilliante Aug 02 '17 at 17:52
  • @Trilliante Try it i have edited the answer. By the way this is the correct implementation while using class. See the last link on the answer to check. – Rajan Chauhan Aug 02 '17 at 17:53
  • Ah, it seems that it didn't work because I had "inp = Input" rather than "inp = Input()" – Trilliante Aug 02 '17 at 17:56
  • @Trilliante Please do change the accepted answer as it is misleading. – Rajan Chauhan Aug 02 '17 at 17:57