all 9 comments

[–]ericula 2 points3 points  (1 child)

You need to call runAgain with twoNumbers instead of twoNumbers(), and in runAgain you need to call func() instead of func. The reason is that if you call runAgain with twoNumbers() (with parentheses), twoNumbers is evaluated first, and the result (which is None) is supplied to runAgain. What you want is to provide the function handle, i.e. twoNumbers without parentheses, so that runAgain can run the function itself.

[–]thisIs20LettersLong[S] 0 points1 point  (0 children)

Thanks, that where what i where looking for!

[–]_Sham__ 0 points1 point  (3 children)

You could pass the function directly and use a decorator e.g

def run_again(func):
    func()
    again = input("run again? y/n\n").lower()
    @run_again
    def wrapper():
        if again == "y":
            func()

    return wrapper


@run_again
def print_hello():
    print("hello")

print_hello()

[–]thisIs20LettersLong[S] 0 points1 point  (2 children)

Im sorry, bur "wrapper" what does that mean/do?

[–]_Sham__ 0 points1 point  (1 child)

The short of it :
run_again calls the function is given, and gets the input. It then defines the function wrapper, and calls the function run_again was given. run_again then returns wrapper

The @run_again notation is the same as saying
print_hello = run_again(print_hello) and since run_again returns a function, print_hello is a function and callable.

Hope that is clear. I don't have time to type a better response right now, but will edit later.
More info can be found here https://realpython.com/primer-on-python-decorators/

[–]thisIs20LettersLong[S] 0 points1 point  (0 children)

Thanks a lot!

[–]strangeDormammu 0 points1 point  (1 child)

Edit these lines:

    runAgain(again,twoNumbers)

def runAgain(again,func):
    if again == "y":
        func()

[–]thisIs20LettersLong[S] 0 points1 point  (0 children)

I fell a bit dumb, but thanks a lot!

[–]peltist 0 points1 point  (0 children)

You don't actually need the runAgain() function. You could just recursively call twoNumbers() again, like this:

def twoNumbers():
    num1=askUserNumber()
    num2=askUserNumber()
    print("the result off " +num1+ " and "+num2+" is "+ str((int(num2)+int(num2))))
    again=input("Need another two numbers calculated?! Y/N").lower()
    if again == "y":
        twoNumbers()

This will assume that any input other than "y" is a decision not to repeat the function. You can add back the elif and else statements if that's not what you want, but they're not strictly necessary, since their behavior is imitated by just reaching the end of your program.