How to change the sleep function of time module in python - python

from time import sleep
a = 30
text = ""
source = pd.read_csv("questions.csv")
questions = source["questions"]
for i in questions:
try:
print(i)
text = text.join(i)
except TypeError:
pass
print(len(text) / 60 / a)
def plan3():#env):
for i in range(len(text)):
b = text[(i * a):(i * a) + a]
print(b, end="")
sleep(1)
plan3()
I am trying to make ^ work, but the screen doesn't update until I manually cancel the program with KeyboardInterrupt.
I believe it is due to the way sleep() is coded that makes it perform the function for the required amount of time, so I am unable to change this property.
The csv file has a database of questions, it can be swapped for a large string value and still it will not update "dynamically", if I am using the word correctly.
I need the questions to print like a printer, line by line on the screen on the TERMINAL.
setting print("",flush = True) didn't solve for python 3.8

Related

Stuck in loop help - Python

The second 'if' statement midway through this code is using an 'or' between two conditions. This is causing the issue I just don't know how to get around it. The code is going through a data file and turning on the given relay number at a specific time, I need it to only do this once per given relay. If I use an 'and' between the conditions, it will only turn on the first relay that matches the current time and wait for the next hour and turn on the next given relay.
Could someone suggest something to fix this issue, thank you!
def schedule():
metadata, sched = dbx.files_download(path=RELAYSCHEDULE)
if not sched.content:
pass # If file is empty then exit routine
else:
relaySchedule = str(sched.content)
commaNum = relaySchedule.count(',')
data1 = relaySchedule.split(',')
for i in range(commaNum):
data2 = data1[i].split('-')
Time1 = data2[1]
currentRN = data2[0]
currentDT = datetime.datetime.now()
currentHR = currentDT.hour
global RN
global T
if str(currentHR) == str(Time1):
if T != currentHR or RN != currentRN:
relaynum = int(data2[0])
relaytime = int(data2[2])
T = currentHR
RN = currentRN
k = threading.Thread(target=SendToRelay(relaynum, relaytime)).start()
else:
print("Pass")
Desired Inputs:
sched.content = '1-19-10,3-9-20,4-9-10,'
T = ' '
RN = ' '
T and RN are global variables because the loop is running indefinitely, they're there to let the loop know whether the specific Time(T) and Relay Number(RN) have already been used.
Desired Outputs:
If the time is 9 AM then,
T = 9
RN should be whatever the given relay number is so RN = 3, but not sure this is the right thing to use.
Sorry if this is confusing. I basically need the program to read a set of scheduled times for specific relays to turn on, I need it to read the current time and if it matches the time in the schedule it will then check which relay is within that time and turn it on for however long. Once it has completed that, I need it to go over that same set of data in case there is another relay within the same time that also needs to turn on, the issue is that if I don't use T and RN variables to check whether a previous relay has been set, it will read the file and turn on the same relay over and over.
Try printing all used variables, check if everything is, what you think it is. On top of that, sometimes whietespaces characters causes problem with comparison.
I fixed it. For anyone wondering this is the new working code:
def schedule():
metadata, sched = dbx.files_download(path=RELAYSCHEDULE)
if not sched.content:
pass # If file is empty then exit routine
else:
relaySchedule = str(sched.content)
commaNum = relaySchedule.count(',')
data1 = relaySchedule.split(',')
for i in range(commaNum):
data2 = data1[i].split('-')
TimeSched = data2[1]
relaySched = data2[0]
currentDT = datetime.datetime.now()
currentHR = currentDT.hour
global RN
global T
if str(currentHR) == str(TimeSched):
if str(T) != str(currentHR):
RN = ''
T = currentHR
if str(relaySched) not in str(RN):
relaynum = int(data2[0])
relaytime = int(data2[2])
k = threading.Thread(target=SendToRelay(relaynum, relaytime)).start()
RN = str(RN) + str(relaySched)

Why wav:source doesn't work in my script but it works when I enter it directly from the terminal?

I'm doing a school assignment and I need some help. I have to connect to hp 54600 oscilloscope and collect data from both channels and then do some measurements. But I tried every command I could think off, and it still does measurements from channel1, no matter what I do. It changes the source to channel2 when I do it directly from the terminal, but it doesn't do anything when i run my program. So, I will send you my basic code and I hope you can tell me what to add to solve this.
**
import serial, time, sys
from pylab import *
hp = serial.Serial('/dev/ttyUSB0',460800,timeout = 5)
kanal=int(sys.argv[1])
if kanal==1:
hp.write('wav:sour chan1\r')
else:
hp.write('wav:sour chan2\r')
hp.write('+eoi:0\r')
hp.write('+eos:13\r')
hp.write('+a:5\r')
time.sleep(1)
hp.write('wav:form asc\r')
time.sleep(1)
hp.write('wav:poin 5000\r')
time.sleep(1)
hp.write('wav:data?\r')
x = hp.readline()
x = x.replace('\x00','')
x = x[10:-1]
x = x.split(',')
xx = []
for entry in x:
xx.append(float(entry))
np.save(str(kanal),xx)
plot(xx,'m-',linewidth=2)
show()
hp.close()
**

Python: how to interrupt, then return to while loop, without goto?

I'm running a simple PID control program in python. Basically an infinite while loop, which reads from sensors then calculates the appropriate control signal, as well as outputs diagnostic info to the terminal.
However, sometimes while watching the diagnostic info, I'd like to change the PID coefficients - which are essentially some constants used by the loop - by breaking from the loop, accepting user input, then returning to the very same loop. I'd like to do this an arbitrary number of times.
With 'goto' this would be simple and easy and just what I want. Can someone give me some python pseudo-code to do this? I can't really think of how to do it. I can interrupt the loop with a CTRL+C exception handler, but then I can't get back to the main loop.
There must be some very simple way to do this but I can't think of it. Thoughts?
Snippets from my code:
while True:
t0 = get_temp_deg_c(thermocouple1)
print "Hose Temperature = " + str(t0) + " deg C"
t1 = get_temp_deg_c(thermocouple2)
print "Valve Temperature = " + str(t1) + " deg C"
# write temps to file
fi.write(str(t0))
fi.write(" " + str(t1) + "\n")
error = setpoint - t0
print "Setpoint = " + str(setpoint) + " deg C"
print "Error = " + str(error) + " deg C"
percent_error = error/setpoint*100
print "Percent error = " + str(percent_error) + " %"
duty_out = p.GenOut(percent_error)
print "PID controller duty output: " + str(duty_out) + " %"
# clamp the output
if(duty_out) > 100:
duty_out = 100
if(duty_out < 0):
duty_out = 0
PWM.set_duty_cycle(PWM_pin, duty_out)
# do we need to increment the setpoint?
if( (setpoint - setpoint_precision) ... # omitted logic here
# Here we return to the top
As long as you're okay with restarting "from the top" after each interrupt (as opposed to returning to the exact point in the loop when the signal was raised, which is a much harder problem):
while True:
try:
controller.main_loop()
except KeyboardInterrupt:
controller.set_coefficients()
In case you don't want a separate thread for IO, generators may be used to preserve the state of your loop across KeyboardInterrupts.
some_parameter = 1
def do_pid_stuff():
while True:
sensor_data1 = 'data'
sensor_data2 = 'data'
sensor_data3 = 'data'
yield 'based on sensor_data1 ' * some_parameter
yield 'based on sensor_data2 ' * some_parameter
yield 'based on sensor_data3 ' * some_parameter
stuff = do_pid_stuff()
while True:
try:
for control_signal in stuff:
print(control_signal)
except KeyboardInterrupt:
some_parameter = int(input())
So the main loop will continue with new parameters from the last executed yield. This however would require to rewrite your loop. Probably, it should be splitted into a generator that will give you sensor data and into a function that will actually do stuff based on the sensor values.
You already have a few ways to interact with your loop, I'd like to point out another one: select(). Using select(), you can wait for either user input. If you add a timeout, you can then break into the normal loop if no user input is available and interact with your hardware there.
Notes:
Here's the documentation for select , but consider the warning on top and look at the selectors module instead.
This solution, like the one using a keyboard interrupt, will stop interacting with the hardware while parameters are being changed. If that isn't acceptable, using a background thread is necessary.
Using select() is more generally applicable, you could also wait for network traffic.
Your hardware will not be serviced as often as possible but with a fixed pause in between. On the upside, you also don't use a full CPU then.

How do I prevent python from freezing to work on a large number equation?

Because it takes too much time to calculate for A, I'll want the calculation to stop and have the program continue on to calculate for B. It would also be helpful to know what error this is called.
A = 999999999999999999**999999999999999999
B = 9**9
The program still freezes when using threading.Timer()
import threading
import time
a = 1
def zzz():
global a
print('restarting')
a = 0
threading.Timer(1.0,zzz).start()
a = 1
threading.Timer(1.0, zzz).start()
while 1:
while a == 1:
h = 999999999999999**999999999999999
I believe the problem has been solved: adding ".0" at the end of one number will allow python to recognize that 99999999999999.0**99999999999999 is too large of a result and will output an error that can be ignored with try/except

Python (Pywin32) Referencing Own Cell/Horizontal Movement

So please don't tell me to google or research or read anything, I've been doing that for the past couple of days and will get annoyed if I see someone say that again.
My problem: I am using pywin32 and python 2.7.8 to communicate with (an already existing) excel sheet. I use it to log my hours worked and money earned, etc. I have it functioning to the point that I can open the workbook, find the next empty cell under my existing entries and write the date in that cell. My problem lies in the fact that I need to navigate horizontally. I want the program to run automatically so I will not always know the number of the cell. For example, my current cell is 18,1. I need to move to 18,2 18,3 18,4 and 18,5. But next time I run the script I may need 19,2... etc.
How can I do this? Is there a way to return the current cell or something?
code:
import win32com.client as win32
import os, time
xl = win32.Dispatch('Excel.Application')
xl.visible = True
xl.Workbooks.Open(os.path.join('C:\\Users\\[REDACTED]\\Desktop', '[REDACTED].xls'))
xlSheet = xl.Sheets(1)
activecell = xlSheet.Cells(1,1)
def GetEmptyCell():
global activecell
activecell = xlSheet.Cells(1,1)
for c in range(1,99,1):
if activecell.Value == None:
print 'Empty cell'
activecell = xlSheet.Cells(c,1)
print '(' + str(c) + ',1)'
return activecell
elif activecell.Value != None:
c += 1
activecell = xlSheet.Cells(c,1)
print 'Full cell, next'
GetEmptyCell()
def WriteToEmpty():
global activecell
global HoursWorked
global GrossIncome
global NetIncome
HoursWorked = raw_input('Input amount of hours worked: ')
GrossIncome = float(HoursWorked) * 9.15
NetIncome = float(GrossIncome) * 0.86233
print 'Money Made: ' + str(GrossIncome) + ' Take Home: ' + str(NetIncome)
activecell.Value = time.strftime('%a') + ' ' + time.strftime('%m') + '/' + time.strftime('%d')
#HELP FROM HERE
WriteToEmpty()``
There are dozens of ways to acheive what you want. If you have contiguous data in column A you could use something like xl.range("A1").end(xldown).offset(1,0).address to get the address of the first cell in the next empty row. Or you could use xl.range("A1").currentregion and offset from there.
Personally i'd probably just put the current region into an array and work from there, then dump the array back to the sheet, but thats always my preference, most people seem to prefer to work on the sheet.

Categories