RecursionError at a place where I have defined no recursive function

  • #1
1,327
1,135

Main Question or Discussion Point

Here is the code that I wrote:
Python:
import numpy as np

global m, n, p, q, arr1, arr2


def input():
    # Input for first matrix:
    print("Enter the number of rows of the first matrix: ", end="")
    globals()['m'] = int(input())
    print("Enter the number of columns of the first matrix: ", end="")
    globals()['n'] = int(input())
    print("\nEnter the first matrix: ")
    globals()['arr1'] = np.empty((m, n))
    for i in range(0, m):
        for j in range(0, n):
            print("Enter the element in cell [", i, " ][", j, "]: ", end="")
            arr1[i][j] = eval(input())

    print("\nThe first matrix is: ")
    printMatrix(arr1)

    # Input for second matrix:
    print("Enter the number of rows of the second matrix: ", end="")
    globals()['p'] = int(input())
    print("Enter the number of columns of the second matrix: ", end="")
    globals()['q'] = int(input())
    print("\nEnter the first matrix: ")
    globals()['arr2'] = np.empty((p, q))
    for i in range(0, p):
        for j in range(0, q):
            print("Enter the element in cell [", i, " ][", j, "]: ", end="")
            arr2[i][j] = eval(input())

    print("\nThe second matrix is: ")
    printMatrix(arr2)

    multiply_check()


def printMatrix(arr: np.ndarray):
    pass


def multiply_check():
    pass

input()
For simplicity, I have removed the code for functions multiply_check() and printMatrix().

As you can see, I am calling the static function input(). My program has been built such that input() will call the other functions.

I get a RecursionError when I run this file:

1573716743845.png


There is no recursion anywhere in the program. I don't understand how line 8 is calling itself recursively.

If I enclose everything inside a class, including the declaration for global variables, the program executes properly. Also, if I remove the functions and write the program without functions, it works properly. (I do not prefer doing the latter, this was just for debugging).

I tried removing the global variables and then passing the local variables as parameters in function calls, but no luck. Same problem at the same point.

I faced the same problem a few days back with a different program in a different computer. I executed each line in the command line, and everything executed properly.

Any idea why this problem is occuring?

Python version: 3.7.4, Numpy version: 1.17.3
 

Answers and Replies

  • #2
Ibix
Science Advisor
Insights Author
5,849
4,386
You've defined a function called input() which uses a function called input(). You intend the latter to be the builtin input() function, but your definition of input() overrides that - so python calls your input() from within your input() and you have recursion.

I strongly recommend that you never, in any language, name a function the same as a builtin function or key word.

Edit: if you must do so for some reason, __builtins__ contains all the builtin functions, so __builtins__.input() will tell python you wanted to use its function. As I say, don't do this (it's asking for trouble) unless you absolutely must for some reason.
 
Last edited:
  • #3
11,361
4,831
This is why programmers are often bad spellers or they use camel case or hyphenated names because its really bad to use a variable or function name matching a reserved word or builtin word. Dire consequences can result.

If you had renamed your function to in_put then it may work better.
 
  • #4
Ibix
Science Advisor
Insights Author
5,849
4,386
This is why programmers are often bad spellers
Wat ar yoo torking abowt? therz nuthing rong weeth mi speling orr capitalisashun.

More seriously, doing anything with wavelengths or affine parameters for orbits in GR is annoying in python, because they're both usually denoted ##\lambda## and lambda is a python keyword.
 
  • #5
1,327
1,135
You've defined a function called input() which uses a function called input(). You intend the latter to be the builtin input() function, but your definition of input() overrides that - so python calls your input() from within your input() and you have recursion.
This is why programmers are often bad spellers or they use camel case or hyphenated names because its really bad to use a variable or function name matching a reserved word or builtin word. Dire consequences can result.

If you had renamed your function to in_put then it may work better.
My bad, transition from Java to Python is taking a toll on me. In Java, I used to define functions with the name input(); I didn't have in mind that there is already a predefined function with that name in Python. :headbang:
 
  • #6
11,361
4,831
We all go through this turmoil so theres nothing ro be ashamed of. I once ported code from to python and after some difficulties got it working only to find it needed to be v3.x python not v2.7.

The math broke with the change of the / to / and // in v3
 
  • #7
Ibix
Science Advisor
Insights Author
5,849
4,386
I spent a week bug-hunting in a MATLAB to C translation, only to find I'd fallen over an integer-divide bug. Every other thing I'd written was fine...
 
  • #8
984
489
From: IBM documentation
There are no reserved words in PL/I. However, using some keywords, for example, IF or THEN, as variable names might make a program needlessly hard to understand.
Maybe the second sentence would qualify as an understatement. :rolleyes:
 
  • #9
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
23,863
6,311
as variable names might make a program needlessly hard to understand
Hard to understand, I get. But needlessly hard to understand? Heck, there are even obfuscated source code contests out there.

I am told that one of the early Lisp machines allowed "zero" to be redefined. This did not always lead to a desirable outcome.
 
  • #10
Ibix
Science Advisor
Insights Author
5,849
4,386
I am told that one of the early Lisp machines allowed "zero" to be redefined.
:oldeek:
This did not always lead to a desirable outcome.
Are you saying "did not always" because you accidentally redefined "never" to mean something else?
 
  • #11
984
489
Vanadium 50 said:
But needlessly hard to understand?
Well, Prim's algorithm (for finding minimum-weight spanning trees) might be hard to understand, but here's a brief example of code that might render other parts of the code needlessly hard to understand:
Code:
PROC OPTIONS(MAIN);
DCL REAL EXTERNAL ENTRY OPTIONS(ASM,INTER,NOMAP);
DECLARE DECLARE FIXED BIN(31),
FIXED FIXED DEC(8),
DEC FIXED BIN(16);
I imagine that you get the gist. :oldwink:
 
  • #12
FactChecker
Science Advisor
Gold Member
5,317
1,904
Another "knit-pick" unrelated to the solution to the recursion problem:
Please do not edit your code. That makes the line numbers in the error message wrong for the code that you post.
 
  • #13
1,327
1,135
Another "knit-pick" unrelated to the solution to the recursion problem:
Please do not edit your code. That makes the line numbers in the error message wrong for the code that you post.
Only one line number (47) didn't match with the error message (52), and clearly the problem was not occuring there but further inside the stack. So I didn't edit that one.
 
  • #14
984
489
We all go through this turmoil so theres nothing ro be ashamed of. I once ported code from to python and after some difficulties got it working only to find it needed to be v3.x python not v2.7.

The math broke with the change of the / to / and // in v3
I like that IBM kept backward compatibility -- system code that I wrote in the '80s still runs on today's machines -- and some other (older) persons can say the same about their code from the '60s and '70s.
 
  • #15
FactChecker
Science Advisor
Gold Member
5,317
1,904
Only one line number (47) didn't match with the error message (52), and clearly the problem was not occuring there but further inside the stack. So I didn't edit that one.
Suite yourself. Some could say that that is exactly where the error was -- calling your own function that should have had a different name.
 
  • #16
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
23,863
6,311
exactly where the error was
Something about computers that people ask for help, get help, and then disregard the advice they just got. Don't understand this.

Many moons ago - around ten years - I was running some FORTRAN code. I needed some function that wasn't an intrinsic: maybe an inverse hyperbolic function or something similarly mathy. So I wrote a function and that was that. I moved on to other things.

Time passes.

The FORTRAN compiler is updated.

It now includes the function I wrote as an intrinsic. The code now compiles fine, but crashes when it runs, with an error message that makes no sense. (Maybe it was "string too long" on code that didn't use strings.) The root problem was having two identically named functions in the link table.
 
Last edited:
  • #17
11,361
4,831
How did you find it? Did the compiler flag it as being an intrinsic function? or was it much trickier?

One trick, I've done there is no error is to first review my changes. Sometimes commenting them out fixes the problem. Sometimes not.

Next I've used a debugger to isolate where the error might occur and backtrack from there.

Without a debugger, then you have to split the program using a sort of binary search approach. Does it fail on the first half or the second half? Second okay does it fail in first quarter of the second half or the second? ...

Sometimes, the problem may be an internal compiler error. In one fortran program I wrote, I noticed an nice pattern where i could index through the filecodes of the write statement ie have an array of filecodes and then index through the array as in write(fc(i),9) but the program mysteriously failed at the write with no explanation.

Later I found the compiler designers never considered that the filecode being passed to a write could ever be anything more than an integer constant. My hack was to create a set of if statements and write actions for each file I wanted to write to. Not as elegant but it got the job done.

Lastly, one example of an error occurring due to a coding mistake elsewhere. I wrote a C program that defined a local char array for a string and passed it to a subroutine who passed to another and another. One of the low level function overwrote the string size changing the stack at that spot since the local array was allocated on the stack. As the stack unraveled the program crashed at a crazy address. Adding print statements to track down the error masked the problem because they changed the stack. Once I changed to using malloc for the array then it went away ie the program didn't crash but the array still got overwritten by string data ruining another string but thats another story.

These stories stay with you as things to watch out for in the future. So many errors, so many stories its a wonder that anything works at all. Future AGI or ASI will save us, right?
 
  • #18
Vanadium 50
Staff Emeritus
Science Advisor
Education Advisor
2019 Award
23,863
6,311
How did you find it? Did the compiler flag it as being an intrinsic function? or was it much trickier?
It did not, and I just started commenting out chunks of code until the problem was obvious.

Even though the code was doing something stupid, it was reported as a bug. The senior technical guy, a Russian with an accent like Boris Badanov's, put it well: "Compiler should produce one of two things: working code, or error message."
 

Related Threads for: RecursionError at a place where I have defined no recursive function

  • Last Post
Replies
5
Views
750
Replies
19
Views
1K
  • Last Post
Replies
6
Views
6K
  • Last Post
Replies
8
Views
784
Replies
4
Views
2K
Replies
1
Views
10K
  • Last Post
Replies
12
Views
80K
Top