Run a function between two inputs in the console - python

I have a Script that works well, but I would like to add an implementation to it.
In first place, I am using the Script to communicate with a couple of devices (Frequency generator and Oscilloscope) via PyVISA and get some measurements. At a certain step during the process, I have to adjust manually a Photodetector (physical device that cannot be used with PyVISA, but attached to the oscilloscope) with a knob which is very sensitive and can be damaged. I am using my own function to control the damage measuring the voltage through the oscilloscope, named PreventAPD. Mainly the function reads the voltage of the oscilloscope and if it is larger than a certain level it stops the system.
When running the script, there is a moment when a message is shown in the console to proceed to the adjustment, I want at this moment to start running the PreventAPD function and that it stops running when the adjustment is done and I push Enter in the console again. The adjustment time can take uncertian times, sometimes 1 min or maybe 3 mins.
The code below shows an example of my question.
print('Adjust manually the Gain from the APD')
input('Press Enter to continue') <---- From here
PreventAPD() <---- Function to run
PreventLD() <---- Function to run
M = int(input("Insert the value of M: "))
print(f"The value of M is {M}")
input('Press Enter to continue') <---- Until here
Does anyone have any idea?

… the script runs the functions between the two inputs in the console, but just once. … I would like it to be running in a loop that starts with an input console and stops with another input console.
You could use a KeyboardInterrupt exception to break a loop:
print('Adjust manually the Gain from the APD')
input('Press Enter to continue')
print('Press Interrupt (Ctrl-C) to enter M')
try:
while True:
PreventAPD()
PreventLD()
except KeyboardInterrupt:
pass
M = int(input("Insert the value of M: "))

Related

windows Command prompt vanishes after running a python script converted to .exe using pyinstaller

I am using python3.7
I wrote a script which takes some inputs (e.g. a=input("enter a value")
it runs smoothly if i go to its path and run it on command prompt.
I can give input also and run .
If i give wrong input it shows an error or exception(traceback)
So i converted it to .exe using pyinstaller
when i run .exe , it asks for input as expected ,it runs and vanishes , i can't see any output.
if i give a wrong input it suddenly vanishes without showing any traceback
I read many questions regarding this on stackoverflow and google , so i added an input statement at end to make program wait before exiting,
but it doesn't works in case of wrong input or if i use sys.exit("test failed") in some cases it just vanishes ,how to resolve and keep cmd window open?
Adding script for e.g.:
import sys
x = int(input(" enter a number :"))
y = int(input(" enter a number :"))
if x>100 or y > 100 :
sys.exit("ERROR :value out of range")
z=x+y;
print(z)
input('press enter to exit')
if inputs are less than 100 and integer then script(.exe file) runs smoothly and i get message "press enter to exit"
but if input number greater than 100 or if i put a "string or float" in input , cmd window vanishes without display any traceback
whereas if i run py file from cmd then i get proper traceback for wrong input.
You could use try-except and input() function, so that when there is any error, it will wait for the user to interact.
Look at this example -
a = input('Please enter a number: ')
try:
int(a) # Converts into a integer type
except ValueError as v:
# This will run when it cannot be converted or if there is any error
print(v) # Shows the error
input() # Waits for user input before closing
For your e.g code, try this -
import sys
try:
x = int(input(" enter a number :"))
y = int(input(" enter a number :"))
except ValueError as v:
print(v)
input('Press any key to exit ')
sys.exit()
if x>100 or y > 100 :
try:
sys.exit("ERROR :value out of range")
except SystemExit as s:
print(s)
input('Press any key to exit ')
sys.exit()
z=x+y
print(z)
You will see that the command prompt does not close immediately
You're not waiting for input.
When you run a .exe that's set up to run in the Windows console, unless you've already opened the console and if your program through that using console commands, and it was set up to just run all the way through to the end, you'll just see the window pop up and then close itself unless your program is doing something that requires user input or a lot of computational time.
This is fairly common sight when programming with languages like C# that natively run as .exes; presumably, this behaviour would also be fairly common in Python. The way to fix this is to add in a line at the end of your program to ask the user for input, so that the console will wait for the user before closing.
In your case, you mention that you have added to the end of your program; the problem is that the program isn't getting to that stage because it's hitting an exception and then exiting. You'll need to handle your exceptions and add a prompt for user input to prevent this behaviour.
Use while loop so if you gave wrong input then it will return to input again so you can give any input. and for example if you want to use only integer value then input must be convert as integer or string depend on you. example below now I think you can
ask = "" #ask variable empty here because I want to use in while condition
print("YOU LOVE ME")
while ask != 'Ok Son':
ask = input("Why? : ")
print("OK THANKS DAD")

Is it possible to control OMXplayer based on time in Python?

I am trying to control OMXplayer during playback of a video using a Python script. I am new to Dbus on Python, and am hopefully just missing something simple.
Eventually I want to do this with a motion sensor using the GPIO pins, but first I am just trying to get control over the player. What I need to do is loop a section of the video once a certain time passes, and then jump forward to the 'second' section when the passage is interrupted. I am testing this using a key entry.
My problem is that the 'if' statement within the code does not loop unless there is an interruption from a key being inputted, or any other signal. Any key will cause an interruption, but I want the time-specific 'if' statement in the loop to trigger without any input being entered. I hope what I am saying is clear in the below code, but if not please ask any question and I'll be happy to try to clarify.
I am using Will Price's OMXplayer wrapper: https://github.com/willprice/python-omxplayer-wrapper/
My hardware is a Raspberry Pi 3B+
I have looked at similar questions including those below, but have not found the answer:
How to open and close omxplayer (Python/Raspberry Pi) while playing video?
https://www.raspberrypi.org/forums/viewtopic.php?p=533160
I have cleaned out unnecessary parts of the code so this is a basic functioning version.
from omxplayer.player import OMXPlayer #runs from the popcornmix omxplayer wrapper at https://github.com/popcornmix/omxplayerhttps://github.com/popcornmix/omxplayer and https://python-omxplayer-wrapper.readthedocs.io/en/latest/)
from pathlib import Path
import time
import RPi.GPIO as GPIO #for taking signal from GPIO
import subprocess
import logging
logging.basicConfig(level=logging.INFO)
VIDEO_PATH = Path("VIDEO.m4v")
player_log = logging.getLogger("Player 1")
player = OMXPlayer(VIDEO_PATH, dbus_name='org.mpris.MediaPlayer2.omxplayer1')
player.playEvent += lambda _: player_log.info("Play")
player.pauseEvent += lambda _: player_log.info("Pause")
player.stopEvent += lambda _: player_log.info("Stop")
positionEvent = 12
flyin = 3
flyaway = 15
'''
THE ERROR OCCURS IN THE BELOW FUNCTION!!!
the following function does not run each time
the 'while' loop below is playing, but does run
when there is a key pressed as an 'input'
I want to add a chck so that each time a certain
amount of time passes, the video jumps back
'''
def checktime():
currtime = player.position()
print("current time is " + str(currtime))
if(currtime > 3):
print("currtime is greater than 3")
try:
player.play()
print (" Ready")
while True:
'''
Below is the call for the function 'checktime'
This runs once when the video starts, and only
runs again when a key is entered.
I want this to run on a continuous loop
and call each time the video loops
'''
checktime()
key = input()
if key == 'd': #works perfectly
currtime = player.position()
player.seek(flyin-currtime)
print("player position is" + str(player.position()))
if key == 'a': #works perfectly
currtime = player.position()
player.seek(flyaway-currtime)
if key == 's': #works perfectly
player.play()
'''
in addition to the key inputs above, entering any key
and pressing return will run the checktime()
function. I understand that this is receiving an
input, therefore 'waking' the program up,
but I don't understand why the loop is not working
continuously
'''
# Wait for 10 milliseconds
time.sleep(.01)
except KeyboardInterrupt:
print (" Quit")
# Reset GPIO settings
GPIO.cleanup()
The video is controlled using the 's', 'a' and 'd' keys as inputs, and this works perfectly. However, the 'checktime()' function does not call each time the while loop goes around. My guess is that this is because once the video is playing, it is not looking for anything from the Python program until it receives another input.
I am not sure if I am using DBus correctly. Ideally, I wanted to use the seek_absolute function of omxplayer-wrapper, but I haven't been able to understand this. I have been ploughing ahead on this project and have gotten a better understanding since posting an earlier question (see here: OMXplayer-wrapper and Python - jump to a specific point in video) but I am a bit stumped here.
If anyone can help I would appreciate any suggestions!

Parallel Processing in Python with Robot

I have coded a robot that runs modules containing the commands necessary to carry out a specific process. As of now, the user inputs the desired command, my code uses an if statement to determine what command they entered, and it runs the appropriate command. However, the command must be finished before the user can input another command.
Now I would like to do the following: have the user input a command, start the command, and, while the command is running, rerun the command to get the users input.
For example, the user inputs move forward, the robot starts moving, then the user changes the command to move backward midway through the robot moving forward, and the robot resets and starts moving backward in response.
Below is the code of the while loop that runs the modules and askes for user input. Let me know if you have any ideas on how I can achieve this or if you need any clarification. I am a high schooler who is still learning how to code, so any help would be greatly appreciated.
Thanks in advance.
Best,
Christopher
#runs all the modules and gets user input
while True:
defultPosition()
command = raw_input("Enter move forward, move backward, turn or cancel: ")
defultPosition()
if command == "cancel":
break
if command == ("move forward") or (command == "move backward"):
speedInput = input("Enter the desired speed: ")
distanceInput = input("Enter the number of inches you wish the robot to move (must be a factor of 5): ")
if command == "turn":
speedInput = input("Enter the desired speed: ")
degrees = input("Enter the number of degrees for the robot to move: ")
print ("\nINPUTED COMMAND: %s \n" % command)
if command == "move forward":
#run the moveForward module
print "Initiating command\n"
moveForward(speedInput, distanceInput)
print "Finished command; restarting and waiting for another input \n"
if command == "move backward":
#run the moveBackward module
print "Initiating command\n"
moveBackward(speedInput, distanceInput)
print "Finished command; restarting and waiting for another input \n"
if command == "turn":
#runs the turn module
print "Initiating command\n"
turnCounterClockwise(speedInput, degrees)
print "Finished command; restarting and waiting for another input \n"
I have determined that using threading is the best solution to my problem. It is able to send termination signals at any point in the program and it will restart the thread with new parameters.
Let me know if anyone would like to view the code I used.

Custom user input prompt (to object constructor) does not appear / appears sporadically when called from a separate thread

Have a function of the form:
def setup_my_object():
my_object = My_Object()
my_object_daemon = Pyro4.core.Daemon(port=55666)
Pyro4.Daemon.serveSimple({my_object: "my.object"},ns = False,daemon = my_object_daemon)
Pyro4 library allows to access the object over the network. Because the main process creates several different objects, a separate thread is created using:
def main():
threaded_object = threading.Thread(target = setup_my_object)
threaded_object.start()
The object is of the form (in reality constructor is more complicated).
class My_Object(object):
def __init__(self):
name_option = input('\nDo you want to enter a name? [y/n]:\n')
if (name_option == 'y')
self.m_name = add_name()
def add_name(self):
name = input('\nPlease enter the name: \n')
return(name)
The main() runs on a linux server, launched from a python console. The problem is when I launch main() the console never promts me "Do you want to enter a name?". I migh hit enter - wait for 30 seconds - nothing. Hit enter two times - wait for 30 seconds nothing. Only when I click enter like five times (and inadvertently the sixth) it will display "Do you want to enter a name?". What is going on and how do I avoid this, i.e. get an instant printout of "Do you want to enter a name?"?
Additional info: I am not seeing this problem when launching on a Windows machine; the problem is only on a Linux machine.
The problem may be that you're doing input and output to stdin/stdout from different threads. Threads and stdin/stdout don't work nicely together. Imagine 4 threads that all sit waiting in their input... and you press enter... what thread will see your keystroke? That's basically random. Same with their output; multiple threads writing to stdout can produce very weird results.
It doesn't explain the large delay though. You haven't shown all your code. What does main() do more? If you replace the Pyro calls that start the daemon by some print statements, does the issue go away? Basically: figure out exactly where the cause of your issue is (what line of code) and continue from there

How to pause and wait for command input in a Python script

Is it possible to have a script like the following in Python?
...
Pause
->
Wait for the user to execute some commands in the terminal (e.g.
to print the value of a variable, to import a library, or whatever).
The script will keep waiting if the user does not input anything.
->
Continue execution of the remaining part of the script
Essentially the script gives the control to the Python command line interpreter temporarily, and resume after the user somehow finishes that part.
What I come up with (inspired by the answer) is something like the following:
x = 1
i_cmd = 1
while True:
s = raw_input('Input [{0:d}] '.format(i_cmd))
i_cmd += 1
n = len(s)
if n > 0 and s.lower() == 'break'[0:n]:
break
exec(s)
print 'x = ', x
print 'I am out of the loop.'
if you are using Python 2.x: raw_input()
Python 3.x: input()
Example:
# Do some stuff in script
variable = raw_input('input something!: ')
# Do stuff with variable
The best way I know to do this is to use the pdb debugger. So put
import pdb
at the top of your program, and then use
pdb.set_trace()
for your "pause".
At the (Pdb) prompt you can enter commands such as
(Pdb) print 'x = ', x
and you can also step through code, though that's not your goal here. When you are done simply type
(Pdb) c
or any subset of the word 'continue', and the code will resume execution.
A nice easy introduction to the debugger as of Nov 2015 is at Debugging in Python, but there are of course many such sources if you google 'python debugger' or 'python pdb'.
Waiting for user input to 'proceed':
The input function will indeed stop execution of the script until a user does something. Here's an example showing how execution may be manually continued after reviewing pre-determined variables of interest:
var1 = "Interesting value to see"
print("My variable of interest is {}".format(var1))
key_pressed = input('Press ENTER to continue: ')
Proceed after waiting pre-defined time:
Another case I find to be helpful is to put in a delay, so that I can read previous outputs and decide to Ctrl + C if I want the script to terminate at a nice point, but continue if I do nothing.
import time.sleep
var2 = "Some value I want to see"
print("My variable of interest is {}".format(var2))
print("Sleeping for 5 seconds")
time.sleep(5) # Delay for 5 seconds
Actual Debugger for executable Command Line:
Please see answers above on using pdb for stepping through code
Reference: Python’s time.sleep() – Pause, Stop, Wait or Sleep your Python Code
I think you are looking for something like this:
import re
# Get user's name
name = raw_input("Please enter name: ")
# While name has incorrect characters
while re.search('[^a-zA-Z\n]',name):
# Print out an error
print("illegal name - Please use only letters")
# Ask for the name again (if it's incorrect, while loop starts again)
name = raw_input("Please enter name: ")
Simply use the input() function as follows:
# Code to be run before pause
input() # Waits for user to type any character and
# press Enter or just press Enter twice
# Code to be run after pause

Categories

Resources