I'm studying software development and we've started using python, and for an exercise I wanted to make a "fancy" printing style. With some help from the internet I managed to get this to work in the terminal of VS Code, which I've been using- but when running the .py file on its own or through CMD, the loop is ran as many times as it should, and only then prints the output all at once.
from time import *
from random import *
from numbers import *
# Slow printing function- prints 1 character at a time
def slowPrint(line):
for char in line: # For every character (char) in the string (line)
t = uniform(0.03, 0.3)
print(char,end="") # Print the character, end on nothing to ensure no spaces between characters
sleep(t) # Sleep for t amount of seconds
# Conversation
slowPrint("Message 1."), sleep(0.5), slowPrint(" Message 2.\n")
input("Press enter;")
What I believe it should do, and what it does in the VS Code Terminal, is that it prints every character on its own, with a random delay between each character. I can't figure out what is making this different between VS Code and CMD.
I hope someone here knows this :> thanks in advance!
Add flush=True to the print function:
print(char, end="", flush=True)
Basically flush well... flushes the data immediately instead of buffering it (w3schools reference to print function)
Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
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
I have a problem with python programming, when I'm trying to write a game (introduced by the book: Coding Games Python DK 3), it says:
name 'Actor' is not defined.
here's my code:
import pgzrun
from random import randint
WIDTH = 400
HEIGHT = 400
dots = []
lines = []
next_dot = 0
for dot in range(0, 10):
actor = Actor("dot")
actor.pos = randint(20, WIDTH -20), randint (20, HEIGHT - 20)
dots.append(actor)
def draw():
screen.fill("black")
number = 1
for dot in dots:
screen.draw.text(str(number), (dot.pos[0], dot.pos[1] + 12))
dot.draw()
number = number + 1
for line in lines:
screen.draw.line(line[0], line[1], (100, 0, 0))
pgzrun.go()
You are using the Python library pgzero (indirectly via importing pgzrun).
I had refactored my game code into multiple files (imported into the main file) and did also observe the same strange
NameError: name 'Actor' is not defined
error message.
The Actor class seems to be "private", but can be imported with this simple code line:
from pgzero.builtins import Actor, animate, keyboard
For background see:
https://github.com/lordmauve/pgzero/issues/61
Update Aug 18, 2019: The screen object cannot be imported since it is created as global variable during runtime (object = instance of the Screen class) and IDE-supported code completion is not possible then. See the source code: https://github.com/lordmauve/pgzero/blob/master/pgzero/game.py (esp. the def reinit_screen part)
This page on the Pygame site will help you run it from your IDE: https://pygame-zero.readthedocs.io/en/stable/ide-mode.html
Essentially, you have to have these two lines of code:
import pgzrun
...
...
pgzrun.go()
But during coding, the IDE will still complain that objects and functions like screen and Actor are undefined. Pretty annoying. As far as I know, there's no way to fix it, you just have to ignore the complaints and hit Debug > Run. Provided you have no mistakes, the program will compile and run.
With regards to
import pgzrun
actor = pgzrun.Actor("dot")
Or
from pgzrun import *
dot=Actor("dot")
Neither of these help integrated development environments like Spyder or Visual Studio recognise objects and functions like screen and Actor
pgzrun doesn't seem to behave like a normal python library.
Pygame relies on using pgzrun to run your python script from the command line:
pgzrun mygame.py
In chapter 5, page 73 of Coding Games in Python, step 2 is to save the file as numbers.py. This creates a conflict with the built in module numbers. This is the cause of the error "name 'Actor' is not defined". The solution is to save the file with a different name (i.e. follow.py).
Please define the class Actor or import it from package if you have it in your pip packages or in same dir
From what I could find on the Pygame Documentation website, Actor is defined in the pgzrun package. With your current import statements, you would have to call the Actor constructor by
actor = pgzrun.Actor("dot")
which would show the compiler that Actor belongs to pgzrun.
Alternatively, if you wanted to just use Actor("dot"), you could change your import statement to
from pgzrun import *
which means "import everything from pgzrun". This also keeps track of what comes from pgzrun and tells the compiler, but it could lead to issues (eg. if you define your own Actor constructor in your code, the compiler wouldn't know which one you're trying to use).
well I just found out It has no problem running with cmd, it has problem with running from the software itself.
So, code is correct but I might suspect something. I think you didnt upload a picture called "dot" in pgzero.
I was getting the same error message, until finally I found this topic here. The book version is missing those pgzrun first and last lines.
If you're still getting the error after putting those lines in, I bet your 'python' points to python2. Try this at the command-line:
python -V
If it shows a version of 2, you'll need to fix that. Check
which python
If it's in /usr/bin, you can do:
sudo su
cd /usr/bin
rm python
ln -s python3 python
If it's in an update-alternatives directory, you can run that program to fix it.
I had the exact same problem at the exact same code. After weeks of deleting and rewriting everything that has to do with python on my computer, I realised that it runs if you make the screen. ... lines comments by writing # in the start of each of them. I haven't found how to fix it yet, but I will inform when I will.
I found the issue. Everything on my computer was uploaded automatically to OneDrive. As a result I had a file with the same name on my computer and on OneDrive and when I tried to run it, it always ran from OneDrive where pygame and pgzero are not installed. I solved it by disconnecting auto upload and by changing the name of the file that was on my computer. Hope this works!
the solution is very simple. do not give the file a name.py name because it conflicts with python numbers.py
So I'm pretty new to both coding and this website, so please bear with me if this is stupid:
I'm working on a personal project and would like to find a way to clear "print()" statements in python 3.6. For example:
print("The user would see this text.")
but if I continue
print("The user would see this text.")
print("They would also see this text.")
Is there a way to make it so a user would only see the second print statement?
I have seen "os.system('cls')" and "os.system('clear')" recommended, but I get these errors for each:
os.system('cls')
resulting in
sh: 1: cls: not found
and
os.system('clear')
resulting in
TERM environment variable not set.
Obviously I'm missing something, but if you know what it'd be much appreciated. If you know of another way to do what I'm thinking, that would also be awesome. Thank you for taking the time to read this, and thanks for any help.
Edit: I'm using Repl.it as my IDE. Could this be an issue with that site specifically?
Edit: Downloaded a new IDE to check, and the reply worked. If you are new and using Repl.it, be aware that some code does not function properly.
The method that I've used in the past to 'reprint' something on an existing line is to make use of the standard output directly, coupled with a carriage return to bring the printed statement's cursor back to the start of the line (\r = carriage return), instead of relying on the print function.
In pseudocode:
# Send what you want to print initially to standard output, with a carriage return appended to the front of it.
# Flush the contents of standard output.
# Send the second thing you want to print to standard output.
A working example in Python:
import sys
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sys.stdout.write('\rThe user would also see this text')
Edit
Figured I'd add an example where you can actually see the code working, since the working example above is going to execute so quickly that you'll never see the original line. The below code incorporates a sleep so that you can see it print the first line, wait, then reprint the line using the second string:
import sys
from time import sleep
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sleep(2)
sys.stdout.write('\rThe user would also see this text')
Files:
File 1: metrobot.py
File 2: irc.py
File 3: cmd.py
MetroBot.py starts irc.py, irc.py makes a while loop which then uses cmd.py.
I try reloading the cmd module from irc.py. After i've reloaded it, the changes in cmd.py still won't take effect.
Reload code snippet:
if ":!reload" in self.buf:
reload(sys.modules['cmd'])
I've also tried
reload(cmd)
None of the two works.
Anyone know what cause the reload to not work, or another simple way? This script is meant to be running at all times.
I created the following three mini-scripts to test this and it works:
bot.py:
import irc
def start():
irc.run()
irc.py:
import cmd, time
def run():
while 1:
print cmd.dothis()
reload(cmd)
time.sleep(1)
cmd.py:
def dothis():
return 1
Now if you run bot.start() it will print "1" once a second and if I then edit cmd.py at some point to say return 2 it prints "2".. Obviously I'm imagining this is a whole way simpler than whatever code you're having, but you'll need to post some samples to help us answer you better. Or try breaking your code down and testing the reload with a stripped down version of your code.