I am trying to learn python by contributing to some projects.
Currently there is a --sleep_interval that takes int x which does as you would expect.
I would like to expand the functionality of sleep_interval to accept something like this:
--sleep_interval=100-200
If the input is in the format of "int-int", we should use a random interval within that range.
Current state -
sleep_interval = self.params.get('sleep_interval')
if sleep_interval:
self.to_screen('[download] Sleeping %s seconds...' % sleep_interval)
time.sleep(sleep_interval)
I was guessing at perhaps doing something like this:
sleep_interval = random.randrange(int(self.params.get('sleep_interval').split('-')[0]), int(self.params.get('sleep_interval').split('-')[1]))
So, I guess this could be done with if/else logic.
However, the input "100-200" would be a string, right?
What is the best way to approach this?
I'd just do this:
if '-' in sleep_interval:
start,stop = sleep_interval.split('-')
sleep_interval = random.randrange(int(start),int(stop))
Canaryyellow's answer is correct but - as far as user input is provided - be sure to provide a useful error message when input is invalid. Hence, my code would end up with something like:
sleep_interval = self.params.get('sleep_interval')
if '-' in sleep_interval:
try:
start, stop = sleep_interval.split('-')
sleep_interval = random.randrange(int(start), int(stop))
except ValueError:
raise ValueError("Invalid range 'a-b' provided: expected 'a' to be integer smaller integer 'b'")
Related
I am having the problem where i need some code to be error captioned, so if the user does not enter a number it should tell them that they have done something wrong. Below is the code that i would like to error capture, and i am not sure how to do about doing this.
if cmd in ('L', 'LEFT'):
Left_position = (int(input("How many places would you like to move left")))
if args:
step = int(args[0])
else:
step = Left_position
y -= step
This line:
Left_position = (int(input("How many places would you like to move left")))
Will throw an error if the input is not a string that can be turned into an integer. To capture this, surround this with a try block:
try:
Left_position = (int(input("How many places would you like to move left")))
except ValueError:
print('Error is handled here')
if args:
....
You might want to rearrange your code slightly. As far as I can see, you only actually want to ask the user for input if args haven't been provided. If this is the case, the following should work:
if args:
step = int(args[0])
else:
while True:
try:
Left_position = (int(input("How many places would you like to move left")))
break
except ValueError:
print 'This is not an integer! Please try again'
step = Left_position
y -= step
First, if there are args we use the first element and carry on. If there aren't, we enter a (potentially infinite) loop where the user is asked to provide an input. If this is not wrappable as an integer, an error message is printed and then the user is asked again for an input value. This terminates once an integer is provided - the break line can only be reached if an error isn't thrown by the input.
This is what I have so far, it probably is completely junk. What I want to do is validate caminput1, so that the format is HH:MM:SS.
The hashes are from when I was testing.
def cameraspeedcheck():
timeformat = ("%H:%M:%S")
caminput1 = input("At what time did sensor 1 actuate? ")
# is caminput1 = time(HH:MM:SS)
# time.strptime(caminput1[%H:%M:%S])
caminput1.strptime(timeformat)
# else cameraspeedcheck()
I am not very experienced with the syntax of all this stuff, or coding in general, but before you tell me to go and look it up.
I have been looking around for ages, and I cannot find anything that explains the whole process.
strptime is a class-method of datetime.datetime which accepts the string to parse as first argument and the format as the second argument. So you should do -
def cameraspeedcheck():
timeformat = "%H:%M:%S"
caminput1 = input("At what time did sensor 1 actuate? ")
try:
validtime = datetime.datetime.strptime(caminput1, timeformat)
#Do your logic with validtime, which is a valid format
except ValueError:
#Do your logic for invalid format (maybe print some message?).
I'm new here and to programming so please take it easy. I understand that almost anybody reading this knows more than I do and that I'm probably doing it wrong.
That being said, this is what I'm trying to do:
while True:
arrival = raw_input('Arrival time? Example 8:30 \n')
if arrival != "%s%s:%s%s" % (range(0, 1), range(0, 10), range(0, 7), range(0, 10):
arrival = raw_input('Follow the example: 8:30 \n)
break
elif arrival == "q":
print "escape velocity reached!!!"
return 0
The "if" statement doesn't have proper syntax and I don't even know if this is how one should/would go about writing this code in the first place. Basically, I would like the user input to be in the format 1:11 or 11:11, or my code breaks. Please ignore elif, its just there to break the loop while I'm testing.
Main question:
How can I fix this code or the implement the idea behind this code?
Related questions:
How can I get python to accept many different possible combinations of "properly" formatted strings (XX:XX or X:XX)?
What is a better way to coerce somebody into inputting data within a range of tolerance in a specific format or increase raw_input tolerance?
What is a better way to do all of the above or is there a better way to approach this problem?
Thank you in advance!
p.s.
I know that the only way to get a good answer is to ask a good question... Any tips on better question formatting appreciated as well.
Here's how I would do this:
Use time.strptime to parse the time. A format string of '%H:%M' works OK for
your example, you could get more specific or try to support multiple formats
if you need to.
Use try/except to deal with input that can't be parsed properly. strptime will raise
a ValueError if the format doesn't match, so you use except to deal with that
Set the time_ok flag to True (and therefore exit the while loop) once we've got a time that can be parsed.
Code:
import time
time_ok = False
while not time_ok:
arrival = raw_input('Arrival time? Example 8:30 \n')
if arrival == 'q':
print("Exiting.")
break
# Try to parse the entered time
try:
time_data = time.strptime(arrival, '%H:%M')
time_ok = True
# If the format doesn't match, print a warning
# and go back through the while loop
except ValueError:
print('Follow the example: 8:30 \n')
hours, minutes = time_data.tm_hour, time_data.tm_min
print(hours, minutes)
If I'm understanding you right you want people to enter a time from 0:00 to 11:59. All you have to do is something like the following
while True:
arrival = raw_input("Please enter a time in the format hr:min (such as 8:30)")
if ":" not in arrival:
print("Please enter a time in the format hour:minute")
continue
else:
arrival_list = arrival.split(":")
if (int(arrival_list[0]) not in range(12)) or
(int(arrival_list[1]) not in range(60)):
print("Please enter a valid hour from 0-12 and a valid minute from 0-59")
else:
break
This will keep your loop going until you have a properly formatted time given as an input.
From an overall, general programming point of view I think using the time module is probably better, but I tried to keep this to what I estimated was your skill level.
You will want to use regular expressions to match the input:
import re
format_ok = False
while format_ok:
arrival = raw_input('Arrival time? Example 8:30 \n')
if re.match("\d{1,2}:\d{2}", arrival):
#string format is OK - break the loop
format_ok = True
I defined a method, like so:
class MyDatastructure(object):
# init method here
def appending(self, elem):
self.data.append(elem)
if self.count >= self.size:
print "popping " + str(self.data[0])
print "inserting " + str(elem)
self.data.pop(0)
elif self.count < self.size:
self.count += 1
print "count after end of method " + str(self.count)
I tested it out, and it worked as supposed to.
Underneath this definition, I wanted to process some user input and use this method. However, it doesn't enter the if case anymore! Any idea why?
# in the same file
def process_input():
while True:
# getting user input
x = raw_input()
ds = MyDatastructure(x) # creating data structure of size, which was taken from user input, count initially 0
ds.appending(1)
ds.appending(2)
ds.appending(3)
# Still appending and NOT popping, even though the if in appending doesn't allow it!
# This functionality works if I test it without user input!
The problem is with this line:
x = raw_input()
Calling raw_input will return a string. If I type in the number 3, that means that the data structure will assign the string "3" to the size.
Attempting to compare a string to a number is considered undefined behavior, and will do weird things -- see this StackOverflow answer. Note that Python 3 fixes this piece of weirdness -- attempting to compare a string to an int will cause a TypeError exception to occur.
Instead, you want to convert it into an int so you can do your size comparison properly.
x = int(raw_input())
No clue why this is happening. I must be missing something obvious.
I'm trying to make a counter print out something like SMPTE code (hours:minutes:seconds:frames (assuming 24fps)).
Code thus far:
import time
s_time = time.time()
def format_time():
t = time.time() - s_time
if t < 1:
print '00:00:00:%02d' % int(t/0.041666666666666664)
elif t < 60:
t = str(t).split('.')
print '00:00:%02d:%02d' % (int(t[0]), int(int(t[1][:4])/0.041666666666666664) )
while True:
format_time()
All seems well initially, until the duration surpasses 1 second and the elif branch is entered. Seconds print out fine, but the frames print out the full multi-digit result of the calculation. Given that the formatting operator is specifying %02d, just like it does in the first if branch (which behaves as expected), why is it not obeying in the second branch? I'm at a loss trying to figure out why it is still printing the full result rather than the truncated version.
You are trying to get the integer part and the fractional part of the float to print your result. It is a good practice to use operators and functions on numeric data directly instead of adding a heavy overhead by converting the float into str and back to number.
Use the math module modf function for that. It will also simplify your algorithm.
import time
import math
s_time = time.time()
def format_time():
t = time.time() - s_time
if t < 60:
f,i = math.modf(t)
print '00:00:%02d:%02d' % (i, f/0.041666666666666664)
while True:
format_time()
PS: for your code error, in your elif block, you are passing t as an integer with a huge value instead of passing the 0.xxxxx value of it. This error wouldn't occur if you keep using the math functions of floats.
I expect you want something like this:
hours = int(t)/3600
minutes = (int(t)/60)%60
seconds = int(t)%60
frames = (t-int(t))*24
print '%02d:%02d:%02d:%02d' % (hours, minutes, seconds, frames)
%02d means: print the integer and if it's shorter than 2 digits, prefix it with zeroes.
it doesn't limit the formatted string to two digits.
edit: one way of getting the first 2 (rounded) digits of a number n would be:
n = 13900
print round(n/10**math.floor(math.log10(n)-1))
or if you don't care about rounding, just cut the string...