When I am importing a function from a module into a script of another file and then run it, the function starts all over after it has finished although it is supposed to run only once.
If I, however, only run the cell with the imported function then the function sometimes only runs once which is confusing because I have deactivated everything else in the script so it should not make a difference, should it? But sometimes it also runs twice which is even more confusing because I have not changed anything in the meantime (at least not that I would know).
One difference is that when I run the entire script the console says
Reloaded modules: mytestmodule
after the script has been executed while when I only run the cell this does not show up. I do not know if this matters though.
Either way, here is the function (from the file mytestmodule.py):
def equation():
print("Hi! Please enter your name.")
name=input()
print("Hello "+name+"! Please enter an integer that is bigger than 1 but smaller than 10.")
answertrue="That is correct!"
answerfalse="That integer is not correct. Please try again."
answernointeger="That is not an integer. Please try again."
biggersmaller=True
while biggersmaller:
task=input()
try:
if int(task)>1 and int(task)<10:
return(print(answertrue))
break
else:
print(answerfalse)
except ValueError:
print(answernointeger)
equation()
And here is the script of the import in the other file:
import mytestmodule
mytestmodule.equation()
This is because inside your mytestmodule.py you are calling the equation function already.
Either:
Remove the call of equation from mytestmodule.py
or
Don't call the function after importing it
Related
I have this code:
import sys
def random(size=16):
return open(r"C:\Users\ravishankarv\Documents\Python\key.txt").read(size)
def main():
key = random(13)
print(key)
When I try running the script, there are no errors, but nothing appears to happen. I expected it to print some content from the key file, but nothing is printed.
What is wrong? How do I make the code run?
You've not called your main function at all, so the Python interpreter won't call it for you.
Add this as the last line to just have it called at all times:
main()
Or, if you use the commonly seen:
if __name__ == "__main__":
main()
It will make sure your main method is called only if that module is executed as the starting code by the Python interpreter. More about that here: What does if __name__ == "__main__": do?
If you want to know how to write the best possible 'main' function, Guido van Rossum (the creator of Python) wrote about it here.
Python isn't like other languages where it automatically calls the main() function. All you have done is defined your function.
You have to manually call your main function:
main()
Also, you may commonly see this in some code:
if __name__ == '__main__':
main()
There's no such main method in python, what you have to do is:
if __name__ == '__main__':
main()
Something does happen, it just isn't noticeable
Python runs scripts from top to bottom. def is a statement, and it executes when it is encountered, just like any other statement. However, the effect of this is to create the function (and assign it a name), not to call it. Similarly, import is a statement that loads the other module (and makes its code run top to bottom, with its own global-variable context), and assigns it a name.
When the example code runs, therefore, three things happen:
The code for the sys standard library module runs, and then the name sys in our own module's global variables is bound to that module
A function is created from the code for random, and then the name random is bound to that function
A function is created from the code for main, and then the name main is bound to that function
There is nothing to call the functions, so they aren't called. Since they aren't called, the code inside them isn't run - it's only used to create the functions. Since that code doesn't run, the file isn't read and nothing is printed.
There are no "special" function names
Unlike in some other languages, Python does not care that a function is named main, or anything else. It will not be run automatically.
As the Zen of Python says, "Explicit is better than implicit". If we want a function to be called, we have to call it. The only things that run automatically are the things at top level, because those are the instructions we explicitly gave.
The script starts at the top
In many real-world scripts, you may see a line that says if __name__ == '__main__':. This is not "where the script starts". The script runs top to bottom.
Please read What does if __name__ == "__main__": do? to understand the purpose of such an if statement (short version: it makes sure that part of your top-level code is skipped if someone else imports this file as a module). It is not mandatory, and it does not have any kind of special "signalling" purpose to say where the code starts running. It is just a perfectly normal if statement, that is checking a slightly unusual condition. Nothing requires you to use it in a script (aside from wanting to check what it checks), and nothing prevents you from using it more than once. Nothing prevents you from checking whether __name__ is equal to other values, either (it's just... almost certainly useless).
You're not calling the function. Put main() at the bottom of your code.
Okay, so let me just say beforehand: I am new to Python. I was just experimenting with IDLE and then I had this weird "crash". I put "crash" inside speech marks because I'm not sure if it qualifies as a crash, as rather than the program just crashing the way a normal program would in Windows, it still runs, but whenever I press enter and try and get it to accept new text it doesn't do anything. E.g. if you try and type "print('a')" and then hit enter it just goes to the next line (and doesn't print 'a'). I tried to make a simple function which converted an integer to a string where each character in the string was either a '1' or a '0', forming the binary number representing said (unsigned) integer.
>>> def int_to_str(int_in):
str_out=''
bit_val=1<<int_in.bit_length()
while(int_in>0):
if(int_in>bit_val):
str_out+='1'
int_in-=bit_val
else:
str_out+='0'
bit_val>>=1
return str_out
>>> print('a')
print('c')
Basically, it becomes completely unresponsive to my input, and allows me to edit/change "print('a')" even though I shouldn't be able to if it had actually "accepted" my input. Why is this? What have I done wrong/messed up?
Also, I made sure it isn't something else I was previously messing around with by closing the shell and opening it again and only putting in said code for the "int_to_string" function, and I haven't changed any settings or imported any modules before hand or anything like that (in case it matters).
EDIT: I tried reinstalling, and that helped a bit in that I can now do other stuff fine, but the moment I try to use the "str_to_int()" function, it has this same weird behaviour of not accepting/interpreting any more user input.
Your while loop never terminates, you need to re-arrange your logic. Printing variables can be an effective debugging tool - like this:
>>> def int_to_str(int_in):
str_out=''
bit_val=1<<int_in.bit_length()
while(int_in>0):
print(int_in, bit_val)
if(int_in>bit_val):
str_out+='1'
int_in-=bit_val
else:
str_out+='0'
bit_val>>=1
return str_out
If your program seems to be going on too long you can stop it with ctrl-c.
I am currently writing a program that is supposed to return certain values when it completes, but the system that tests it is a black box (don't know how it tests the program), and even though I think it would work if I ran the program by itself, the automated tester always raises an end of file error when it encounters the first input prompt. This the part that is in the main portion of the python code (kind of the first thing that runs).
y=list(input("Enter numbers separated by commas and spaces"))
x=list(input("Do the same as above but for other list"))
The tester raises the end of file error on the first prompt. Any idea what may cause that?
It is quite possible that the tester is not supplying any input at all. In which case, you (I) have to supply the values in the program itself, not as input but as defined values.
So, I have been looking at other threads on this topic but they do not use the Module version of passing the argument to the other file, if so wasn't explained clearly enough for me to understand.
I have tried just to show I'm not just asking:
#MoneyCounter.py
import Password
enter = False
Password.system(enter)
def start(check):
if check == True:
main()
elif check == False:
print("Critical Error occured")
exit()
And my other file
#Password.py
import MoneyCounter
def system(check):
if check == False:
password() #This goes to password def not mentioned in this code
elif check == True:
MoneyCounter.start(check)
The error I am getting is the Module Password has no attribute system
The error I am getting is the Module Password has no attribute system
Of course it doesn't. The definition doesn't exist by the time the line of code is executed, since execution of the first file got interrupted by the import.
Either refactor or reorder your code so that the name isn't accessed until it exists, or remove the requirement that each module has for the other.
Your problem here is circular dependency/imports.
An import statement really executes the code in the imported file; that is, all the statements are executed, everything that is defed in the imported file gets defined etc. imports get imported, too.
So what's happening is this:
you run
$ python MoneyCounter.py
Python reads MoneyCounter.py, executes its first statement: import Password
Python reads Password.py, and executes its first statement: import MoneyCounter.py
Python reads MoneyCounter.py, this time it encounters import Password, but already has password in its list of known names; so it continues to
enter=False; Password.system(enter).
Now, Python already has a Password in its name lookup dictionary: the half-imported Password. In that, def system… hasn't happened yet, so Password.system is still unknown.
Generally, your architecture is questionable. Why would the Password "utility" module call into your "master" business logic? Better not do that, but write code that actually checks the return value of Password.system and acts based on that in your MoneyCounter.py.
On the assumption that MoneyCounter.py is the entry point (the name you run from the command-line), then I suggest you replace this:
enter = False
Password.system(enter)
with this:
if __name__ == "__main__":
enter = False
Password.system(enter)
That will only be executed from the entry-point (which is called __main__) and not when it is imported. However, you should reconsider your design.
Edit:
name is a reference to the text name of the current module. With modules that are explicitly imported the name is taken from the filename, but the entry-point (where the program starts) is always called __main__. So we can always test if we are running as an imported module or as an entry-point.
This test is extremely common in python. This way we can provide additional functionality depending on whether we run a module as a program or import it.
I saw the code in an answer here, and I'm trying to pick it apart to see how it works. I think I understand it (using the or operator as a sort of ersatz "if" statement.), but that's not the issue here. It is supposed to return a value, and after visualizing the code(done here) it apparently IS returning a value. However, when I run it in the terminal, no values are ACTUALLY displayed. What is happening?
def ispalin(word):
return(not word) or (word[0]==word[-1] and ispalin(word[1:-1]))
ispalin(input("Enter a word."))
When this runs, it asks for a value, but nothing is displayed.
Unless you run code in the interpreter, Python will not just print return values in module-level code.
You need to explicitly print your result:
print(ispalin(input("Enter a word.")))
The interactive interpreter session is a REPL, or Read-Eval-Print loop, where it'll print the results of whatever you try, but when you run code from the command line or when doubleclicking on your script, no printing takes place.
That is because you are just returning the value and not printing it
print (ispalin(input("Enter a word.")))
Will print out your values
O/P after changing the sentence
Enter a word.malayalam
True
Try,
print ispalin(input("Enter a word."))