Delete words made with print() - python-3.x

I want to make code so that a number goes from 1 to 2 to 3 and so on.
I am running this on Python 3. I have tried:
import time
from sys import stdout
for i in range(1,20):
stdout.write("\r%d" % i)
stdout.flush()
time.sleep(1)
stdout.write("\n") # move the cursor to the next line
But with that code, I get 12345678910111213141516171819.
Can someone help?
EDIT: I ran this code from the console, not from IDLE and it works. Can anyone explain?

For my setup it works (Arch Linux, Python3). Do you start from IDE? Or from console?
Maybe another way works for you:
import time
from sys import stdout
for i in range(1,20):
print(i)
time.sleep(0.1)
stdout.write("\033[F") #back to previous line
stdout.write("\033[K") #clear line
stdout.write("\n") # move the cursor to the next line
Idea found here. This example works in my console but not when I start from PyCharm directly.

Related

Python script does not print output as supposed

I have a very simple (test) code which I'm running either from a Linux shell, or in interactive mode, and I have two different behaviours I cannot figure out the reason of.
I have a file generated by a Popen call, previously, where each line is a file path. This is the code used to generate the file:
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
(Incidentally, I was trying to build a PIPE originally, namely inputting the output of this command to a grep command, and since I wasn't successful in any way, I decided to break the problem down and just read the file paths from a file, and process them one by one. So maybe there is a common issue that is blocking me somewhere in this procedure).
Since in this second step I wasn't even able to open and process the files by opening the addresses contained in each line of the find.txt file, I just tried to print the file lines out, because for sure they're available in there:
with open('find.txt','r') as g:
for l in g.readlines():
print(l)
Now, the interesting part:
if I paste the lines above into a python shell, everything works fine and I get my outputs as expected
if, on the other hand, I try to run python test.py, where test.py is the name of the file containing the lines above, no output appears in the shell's stdout.
I've tried sys.stdout.flush() to no avail. I've also inserted some dummy print() statements along the way: everything gets printed but what's after the g.readlines() statement.
Here's the full script I'm trying to make work (a pre-precursor of what I'm actually after, tbh).
#!/usr/bin/env python3
import subprocess
import sys
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
output being:
{ancis:>106> python test.py
hello
hello?
{ancis:>106>
EDIT
I've quickly tried the very same lines (but without the call to find, which isn't available) on my python installation in Windows: it works as expected)
Based on that, I've tried to run the simpler code below:
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
as a script, in Linux - This also works w/o problems.
This should mean that somehow I'm messing things up with the call to Popen... But what?
This is a race condition.
Your call to
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
is opening another process and running your find command which takes a bit of time to fully execute.
Python then continues on and reaches the reading of the file portion before the command is fully executed and the file is generated.
Want to test it out?
Add a time.sleep(1) just before the opening of the file.
Full test script:
#!/usr/bin/env python3
import subprocess
import time
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
time.sleep(1)
with open('find.txt','r') as g:
for l in g:
print(l)
To block until the process is complete you can use find.communicate().
With this you can also optionally set a timeout if that's something that you want.
#!/usr/bin/env python3
import subprocess
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
find.communicate()
with open('find.txt','r') as g:
for l in g:
print(l)
Source:
https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

using python to open many idle windows

i have this layout
1/mainy.py
2/main.py
3/main.py
........
i wish to run each "main" in its own idle window. not a cmd line because if it crashes i tend to lose the output.
so far i have
for i in range(150):
i+=1 # because theres no zero folder
exec(open(str(i)+"/"+'main.py').read()) # if i run this in idle it tries to run them in the same idle window
i want to have many different idle windows simultaneaously. right now i have to open each manually but i want a script to do it.
i very specfically want each one running in its own idle window so i should have 8 (9 including the one that opens the rest) windows open.
If you don't need to collect output from each idle, you can use subprocess.Popen
from subprocess import *
import os
#Loop over and change script name
for i in range(150):
script_name = os.path.join(str(i), "main.py")
print('script launching:', script_name)
subprocess.Popen("start python " + script_name, stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True)
You can open each Python script in separate window using this:
import subprocess
import time
import pyautogui
for i in range(150):
i+=1 # because theres no zero folder
subprocess.call([ 'C:/Users/tgmjack/AppData/Local/Programs/Python/Python37-32/Lib/idlelib/idle.bat', str(i)+"/"+'main.py'])
time.sleep(2)
pyautogui.press('f5')
time.sleep(2)
Change the first path to match where idle.bat is located and the second according to your Python script.
You can loop through the scripts but you have to use PyAutoGUI package to press F5 to run each script programmatically.
Refer to https://pypi.org/project/PyAutoGUI/

How to convert Balsamiq mockups to text strings txt with Python34 script on Windows XP

I've been trying to run these scripts https://github.com/balsamiq/mockups-strings-extractor within XP. I'm getting errors per this screenshot https://www.dropbox.com/s/rlbqp1iytkwvq3m/Screenshot%202014-05-30%2011.57.48.png
Also I tried CD into my test directory and although a text output file is generated it is empty and I still get these errors https://www.dropbox.com/s/odjfbr97e5i4gnn/Screenshot%202014-05-30%2012.09.31.png
Is anybody running Balsamiq on windows able to make this work ?
1) From the looks of the first error pic you included, you were trying to execute a Windows Shell command inside of a Python Interpreter. If you've still got the window open, type quit() before attempting your command again.
2) Your script was written for Python 2.x. If you're using Python 3.x, you'll need to add parentheses to the print lines in the script file and change urllib to urllib.parse. I made the changes below:
import os
import glob
import re
import urllib.parse
for infile in glob.glob( os.path.join(".", '*.bmml') ):
print("STRINGS FOUND IN " + infile)
print("===========================================================")
f = open (infile,"r")
data = f.read()
p = re.compile("<text>(.*?)</text>")
textStrings = p.findall(data)
print(urllib.parse.unquote('\n'.join(textStrings))+"\n")
f.close()
Hope this helps.

Why does resizeColumnToContents work interactively at the python prompt, but not in a PyQt script?

I've been working on a filebrowser application, and I'd like the first column (file name) to be resized properly on startup. I can type the following code at the python prompt and the column resizes properly, but when I put it in a file and try to run it, the column is not resized. Any idea why?
#!/bin/env python
import sys
import os
from PyQt4.QtGui import *
app = QApplication(sys.argv)
treeView = QTreeView()
fileSystemModel = QFileSystemModel(treeView)
rootDir = fileSystemModel.setRootPath(os.path.expanduser('~'))
treeView.setModel(fileSystemModel)
treeView.setRootIndex(rootDir)
treeView.setGeometry(100,100,1024,768)
treeView.show()
treeView.resizeColumnToContents(0)
app.exec_()
Of course, when I copy it to the python prompt, I leave off the app.exec_(). Is that what is causing the column to not resize? (EDIT: I copied "app.exec_()" to the prompt and it did pretty much what you'd expect - the event loop started, and I was able to use the app, then close it, and then I was returned to the python prompt.)
It seems that replacing the call to treeView.resizeColumnToContents(0) with treeView.header().setResizeMode(0, QHeaderView.ResizeToContents) results in the column being expanded when run from the Python prompt and from a script. I have no clue why resizeColumnToContents is not working as intended.
Side note: should #!/bin/env python be #! /usr/bin/env python? At least on my distro, /bin/env doesn't exist.

Testing python programs without using python shell

I would like to easily test my python programs without constantly using the python shell since each time the program is modified you have to quit, re-enter the python shell and import the program again. I am using a 2012 Macbook pro with OSX. I have the following code:
import sys
def read_strings(filename):
with open(filename) as file:
return file.read().split('>')[1:0]
file1 = sys.argv[1]
filename = read_strings(file1)
Essentially I would like to read into and split a txt file containing:
id1>id2>id3>id4
I am entering this into my command line:
pal-nat184-102-127:python_stuff ceb$ python3 program.py string.txt
However when I try the sys.argv approach on the command line my program returns nothing. Is this a good approach to testing code, could anyone point me in the correct direction?
This is what I would like to happen:
pal-nat184-102-127:python_stuff ceb$ python3 program.py string.txt
['id1', 'id2', 'id3', 'id4']
Let's take this a piece at a time:
However when I try the sys.argv approach on the command line my
program returns nothing
The final result of your program is that it writes a string into the variable filename. It's a little strange to have a program "return" a value. Generally, you want a program to print it's something out or save something to a file. I'm guessing it would ease your debugging if you modified your program by adding,
print (filename)
at the end: you'd be able to see the result of your program.
could anyone point me in the correct direction?
One other debugging note: It can be useful to write your .py files so that they can be run both independently at the command line or in a python shell. How you've currently structured your code, this will work semi-poorly. (Starting a shell and then importing your file will cause an error because sys.argv[1] isn't defined.)
A solution to this is to change your the bottom section of your code as follows:
if __name__ == '__main__':
file1 = sys.argv[1]
filename = read_strings(file1)
The if guard at the top says, "If running as a standalone script, then run what's below me. If you imported me from some place else, then do not execute what's below me."
Feel free to follow up below if I misinterpreted your question.
You never do anything with the result of read_strings. Try:
print(read_strings(file1))

Resources