J.F. Ramirez
J.F. Ramirez

Reputation: 13

ModuleNotFoundError after python script runs

I've been trying to look for the solution to my specific error, but have had no success.

So, in the Python3 environment in my terminal, I type the following for 'problems1.py:

>>> import problems1.py

problems1.py:

import math

print("Please enter a number 'x' ")
x = input()
x = float(x)

print("Please enter a number 'y' ")
y = input()
y = float(y)

exp = x ** y
lgrm = math.log2(x)

print(f"The number 'x' raised to the power of 'y' is {exp}, and ...")
print(f"The log(base 2) of x is {lgrm}")

I am able to input the requested numbers and output the print statements only once, however, at the end of the outputs, the following error is shown:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'problems1.py'; 'problems1' is not a package

Any subsequent attempts to import problems1.py only returns the error.

Upvotes: 1

Views: 75

Answers (1)

Hampus Larsson
Hampus Larsson

Reputation: 3100

I think I have an answer for your question.

I'll simplify your file problems1.py to make this explanation easier to write down.

Let's assume that your file problems.py has the following piece of code inside of it:

#contents of the file: problems.py
firstname = input("First name: ")
lastname = input("Last name: ")
print(f"Your full name is: {firstname} {lastname}")

If we launch that file, then we get the following output:

First name: Kevin
Last name: Durant
Your full name is: Kevin Durant

Basically what happens when you issue an import is that the Python interpreter opens up the file that you import, and goes through it line-by-line, and tries to create the namespace for the file, and make some optimizations of the code.

As such, when the interpreter reaches the line firstname = input("First name: ") it will have to execute the code to the right of the equals-sign, to map the value to the namespace firstname.

The interpreter will read through the whole file, to be sure that it didn't miss any changes to the whole namespace before it will return to execute any other command after the import call.

So let's start an interpreter and issue import problems:

>>> import problems
First name: Kevin
Last name: Durant
Your full name is: Kevin Durant
>>>
>>> problems.firstname
'Kevin'
>>> problems.lastname 
'Durant'

See that when we issued the import, it executed the code inside of it. You can also see that we can access firstname and lastname from problems by accessing its attributes using problems.firstname and problems.lastname.

So, let's look at what happens when you issue import problems.firstname:

>>> import problems.firstname
First name: Kevin
Last name: Durant
Your full name is: Kevin Durant
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'problems.firstname'; 'problems' is not a package

What is happening here, is that when you issue a relative (dot separated) import, the Python interpreter assumes that what you're importing is a sub-file of the problems package.

Because it cannot find a package there, it throws an error, and crashes the code.

Upvotes: 2

Related Questions