Python: Preserve last line in console for specific output - python

I have a program that does lots of printing. For UX, I want to have the line at the bottom of the console screen always display the same piece of information - a summary of how many jobs are done, and how many remain X done, Y remaining (X and Y are constantly changing throughout the program's runtime).
I tried using curses, however, I only need to control one line and I could not find a way to limit curses's screen scope.
I also tried using blessings:
with t.location(0, t.height - 1):
print 'This is at the bottom.'
but it only worked when there wasn't enough stdout to reach the last line in the console.
I am using python 2.7

Try this:
def print_with_fixed_bottom(message):
fixed = 'This is at the bottom.'
print '\r{: <{width}}\n{}'.format(message, fixed, width=len(fixed)), # comma is important

Related

Python function not working with seemingly correct string path

I have the following code (it changes the string/filepath, replacing the numbers at the end of the filename + the file extension, and replaces that with "#.exr")
I was doing it this way because the name can be typed in all kinds of ways, for example:
r_frame.003.exr (but also)
r_12_frame.03.exr
etc.
import pyseq
import re
#create render sequence list
selected_file = 'H:/test/r_frame1.exr'
without_extention = selected_file.replace(".exr", "")
my_regex_pattern = r"\d+\b"
sequence_name_with_replaced_number = re.sub(my_regex_pattern, "#.exr" ,without_extention)
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
If I print the "sequence_name_with_replaced_number" value, this results in the console in:
'H:/test/r_frame#.exr'
When I use that variable inside that function like this:
mijn_sequences = fileseq.findSequencesOnDisk(sequence_name_with_replaced_number)
Then it does not work.
But when I manually replace that last line into:
mijn_sequences = fileseq.findSequencesOnDisk('H:/test/r_frame#.exr')
Then it works fine. (it's the seems like same value/string)
But this is not an viable option, the whole point of the code if to have the computer do this for thousands of frames.
Anybody any idea what might be the cause of this?
After this I will do simple for loop going trough al the files in that sequence. The reason I'm doing this workflow is to delete the numbers before the .exr file extensions and replace them with # signs. (but ognoring all the bumbers that are not at the end of the filename, hence that regex above. Again, the "sequence_name_with_replaced_number" variable seems ok in the console. It spits out: 'H:/test/r_frame#.exr' (that's what I need it to be)
I fixed it. the problem as stated was correct, every time I did a cut and past from the variable value in the console and treated it as manual input it worked.
Then I did a len() of both values, and there was a difference by 2! What happend? The console added the ''
But in the generated variable it had those baked in as extra letters. i fixed it by adding cleaned_sequence = sequence_name_with_replaced_number[1:-1] so 'H:/test/r_frame1.exr' (as the console showed me) was not the same as 'H:/test/r_frame1.exr' (what I inserted manually, because I added these marks, in the console there are showed automatically)

How to change Pycharm auto-format?

I am using pycharm as my editor in python. One problem I have with it is that whenever I press autoformat (command+option+l), it causes some of my code lines to be broken into several lines. For example, this code:
percentage_optimal_arm = self.main_program.compute_percentage_optimal_arm(algorithm_instance.chosen_arm_history,self.k_value_of_arms_list)
breaks to this:
percentage_optimal_arm = self.main_program.compute_percentage_optimal_arm(
algorithm_instance.chosen_arm_history, self.k_value_of_arms_list)
This is really annoying as my screen is big enough to include the whole line and it makes my whole code looks ugly. Is there a way to increase the limit for breaking lines in pycharm?
Change Hard Wrap value at Settings > Editor > Code Style > Python
Default is 120 line spaces. Change it your desired value ex: 180

Why is a part of my Python code interpreted diffently when I add a seemingly unrelated part?

Some background: I'm implementing a GUI to interact with equipment via GPIB. The issue arises in this method:
from tkinter import *
from tkinter import ttk
import visa #PyVisa Package. pyvisa.readthedocs.io
from time import sleep
import numpy as np #NumPy Package. Scipy.org
def oneDSweep():
Voltage =[]
Current =[]
Source = []
try:
#Gate = parseGate(Gate1Input.get()) #Not implemented yet.
Min = float(Gate1MinInput.get()) #Add a check for valid input
#if Min < .001:
#Throw exception
Max = float(Gate1MaxInput.get()) #Add a check for valid input
VoltageInterval = .02 #Prompt user for interval?
rm = visa.ResourceManager()
SIM900 = rm.open_resource("GPIB0::1::INSTR") #Add a check that session is open.
x = 0
Volt = Min
while Volt <= Max:
SIM900.write("SNDT 1, 'VOLT " + str(Volt) + "'") #Set voltage.
SIM900.write("SNDT 7, 'VOLT? 1'") #Ask a port for voltage.
Vnow = SIM900.query("GETN? 7, 50") #Retrieve data from previous port.
Vnow = Vnow[6:15]
Vnow = float(Vnow) ############Error location
Voltage = np.append(Voltage, Vnow)
SIM900.write("SNDT 1, 'VOLT?'") #Ask a different port for voltage.
Snow = SIM900.query("GETN? 1, 50") #Retrieve data.
print(Snow) #Debugging method. Probably not problematic.
Snow = Snow[4:]
Snow = float(Snow)
sleep(1) #Add a delay for science reasons.
#The code below helps the while loop act like a for loop.
x = x+1
Volt = Min + VoltageInterval*x
Volt = float(truncate(Volt, 7))
finally:
print(Voltage)
print(Source)
Voltage.tofile("output.txt.",sep=",")
SIM900.write("FLSH")#Flush the ports' memories to ensure no bad data stays there.
I get a simple ValueError at the marked location during the first pass of the while loop; Python says it cannot convert the string to a float(more on this later). However, simply remove these five lines of code:
SIM900.write("SNDT 1, 'VOLT?'")
Snow = SIM900.query("GETN? 1, 50")
print(Snow)
Snow = Snow[4:]
Snow = float(Snow)
and the program runs perfectly. I understand the source of the error. With those lines added, when I send these two lines to my instrument:
SIM900.write("SNDT 7, 'VOLT? 1'")
Vnow = SIM900.query("GETN? 7, 50")
I get essentially a null error. #3000 is returned, which is a blank message the machine sends when it is asked to output data and it has none to output. However, these same two lines produce something like #3006 00.003 when the four lines I mentioned are excluded from the program. In other words, simply adding those four lines to my program has changed the message sent to the instrument at the beginning of the while loop, despite adding them near the end.
I am convinced that Python's interpreter is at fault here. Earlier, I was cleaning up my code and discovered that one particular set of quotes, when changed from ' to ", produced this same error, despite no other quote pair exhibiting this behavior, even within the same line. My question is, why does the execution of my code change dependent upon unrelated alterations to the code(would also appreciate a fix)? I understand this problem is difficult to replicate given my somewhat specific application, so if there is more information that would be helpful that I can provide, please let me know.
EDIT: Functionality has improved after moving from the command prompt to IDLE. I'm still baffled by what happened, but due to my meager command prompt skills, I can't provide any proof. Please close this question.
Python is telling you exactly what is wrong with your code -- a ValueError. It even gives you the exact line number and the value that is causing the problem.
'#3006 00.003'
That is the value of SNOW that is being printed out. Then you do this
SNOW = SNOW[4:]
Now SNOW is
'6 00.003'
You then try to call float() on this string. 6 00.003 can't be converted to a float because it's a nonsensical number.
I am convinced that Python's interpreter is at fault here. Earlier, I was cleaning up my code and discovered that one particular set of quotes, when changed from ' to ", produced this same error, despite no other quote pair exhibiting this behavior, even within the same line.
Python generates exactly the same bytecode for single and double quoted strings (unless embedded quotes are involved, of course). So either the environment you're running your script in is seriously broken (I'm counting the python interpreter as part of the "environment"), or your diagnosis is incorrect. I'd put my money on the second.
Here's an alternative explanation. For whatever reason, the hardware you hooked up is returning inconsistent results. So one time you get what you expect, the next time you get an error-- you think your changes to the code account for the differences, but there's no relationship between cause and effect and you end up pulling your hair out. When you run the same code several times in a row, do you get consistent results? I.e. do you consistently get the odd behavior? Even if you do, the problem must be with the hardware or the hookup, not with Python.

How to save a changed item to an external file? (Python 3)

I'm fairly new to python, but I'm making a script and I want one of the functions to update a variable from another file. It works, but when I exit the script and reload it, the changes aren't there anymore. For example (this isn't my script):
#File: changeFile.txt
number = 0
#File: changerFile.py
def changeNumber():
number += 1
If I retrieve number during that session, it will return 1, but if I exit out and go back in again and retrieve number without calling changeNumber, it returns 0.
How can I get the script to actually save the number edited in changeNumber to changeFile.txt? As I said, I'm fairly new to python, but I've looked just about everywhere on the Internet and couldn't really find an answer that worked.
EDIT: Sorry, I forgot to include that in the actual script, there are other values.
So I want to change number and have it save without deleting the other 10 values stored in that file.
Assuming, as you show, that changeFile.txt has no other content whatever, then just change the function to:
def changeNumber():
global number # will not possibly work w/o this, the way you posted!
number += 1
with open('changeFile.txt', 'w') as f:
f.write('number = {}\n'.format(number))
ADDED: the OP edited the Q to mention (originally omitted!-) the crucial fact that changefile.txt has other lines that need to be preserved as well as the one that needs to be changed.
That, of course, changes everything -- but, Python can cope!-)
Just add import fileinput at the start of this module, and change the last two lines of the above snippet (starting with with) to:
for line in fileinput.input(['changefile.txt'], inplace=True):
if line.startswith('number ');
line = 'number = {}\n'.format(number)'
print line,
This is the Python 2 solution (the OP didn't bother to tell us if using Py2 or Py3, a crucial bit of info -- hey, who cares about making it easy rather than very hard for willing volunteers to help you, right?!-). If Python 3, change the last statement from print line, to
print(line, end='')
to get exactly the same desired effect.

Separate functions in python?

I'm not sure if function is the word I am looking for. In fact I don't really know what I'm saying but I have some code and it's not quite doing it what I want to. Basically I want to copy and paste this code I've got and email it to someone. I want them to be able to simply copy and paste it into their Terminal and perform calculations.:
## SCSAC.py
def round(x, base=5):
return int(base * round(float(x)/base))
option = 'yes'
while (option == 'yes'):
x=float(raw_input('How many accumulated orders do you have from retailers: '));
y=float(raw_input('How many units are in the inventory: '));
z=float(raw_input('How many accumulated orders have you placed: '));
print 'Place an order of %s units' % round(((x / 25 + y / 10 + z / 25) + 115));
print ;
option=raw_input("Do you wish to calculate another order? (Enter 'yes' to continue or any other key to quit):: ");
print
Whenever I type this code in line for line, it works perfectly. That's because there are basically 3 seperate things happening here.
I define "round" which rounds a value to the nearest 5.
I define an option to loop the program upon completion
I define the actual program, and in that I round the answer and conclude with the option to loop. You may notice 2 print's that don't print anything, but they are only there to have blank lines.
When I copy and paste it, I get a syntax error.
I am not a programmer and I have just been playing with this all day. I just want to know how I can edit this code so it is copy/paste-able and will run the way it is supposed to.
Try using IPython instead of the regular Python interpret at the shell. With IPython, you can type %cpaste, and then paste a whole chunk of code, which it will execute for you step by step, saving the intermediate variables into working memory.
If you insist on pasting it in the regular interpreter, then do it line by line, and take special care for the indentations. The indentations are usually where paste syntax errors come from.
Even better, use Emacs. Then you can just save the pasted code into a file, like test.py, type M-x shell, and then python test.py to quickly run it. Or, if you saved it to a file like test.py then in IPython you can also type %run "test.py" and it will run the code and again store intermediate variables into working memory.
If you're copy/pasting this after making changes more than once or twice, just save it to a file and run it like a script.
You can save the code in a file, and run it using Python.
You can add #!/usr/bin/env python to the beginning of the file, so it can run on *nix systems (if you have execute permission).
Or, you can do python SCSAC.py and run your code. This works on all systems (AFAIK). You can email the file to your person, and she can run it using Python. This seems to be the easiest way to do it.

Categories