# Re: Under what kind of situation, time.sleep(n) would sleep much longer than n seconds?

```On Fri, Jun 20, 2014 at 3:17 AM, Christian Gollwitzer <aurio...@gmx.de> wrote:
> While I don't understand the purpose of the program (is it a game?), it
> shows exactly why this is a bad idea.```
```
It's a tool for calculating stuff about railway tracks. Never mind
about the details of what it does with the info, but the input phase
you're talking about is basically building up a speed map of the track
- straight-line track has an effective speed limit of 400km/h, curves
have lower limits.

> Here is my try (OSX):
>
> Apfelkiste:Tests chris\$ python runningtime.py
> Enter track length in m: 20
> Enter speed limit [400km/h]: 300
> Enter track length in m: 10
> Enter speed limit [400km/h]: 100
> Enter track length in m: 0
> ()
> [  0.00] Power
> [  7.85] Enter next section (10m speed 100)
> [  8.00] Cruise
> [  9.49] Enter next section (0m speed 0)
> Traceback (most recent call last):
>   File "runningtime.py", line 205, in <module>
>     nextsection, nextspeed = next(section)
> StopIteration

Well, you didn't put in enough track for the train to even get
started. Basically, you built thirty meters of railway line, then put
a suburban train on it (264 meters long - the figure's at the top of
the program, although I wouldn't expect anyone to know it; however, it
should make perfect sense that a train is more than 30m long!). So the
program crashed, because this is an early alpha that's designed to be
used by someone who knows what he's doing. If you crank those figures
up a bit and, say, put a few km of track down, then it won't bomb.

> Suppose I want to run it again, but have length 30 in the first step.

That would still be extremely odd, but suppose you want length 3000 in
the first step.

> 1.)How am I going to do this? I have to restart it and key in 4 numbers,
> whereas I only wanted to change 1. Now let that be 10 segments.
>
> 2.) There is no way to save the input or the result. Or it may not be
> obvious. I could prepare a file with the numbers, then do
>
>         python runningtime.py <input > output
> But then I don't see the prompts and have to be careful not to enter a speed
> for a length.

The program is designed to be used with either copy/paste or
redirection (you'll note a line comment in the code about redirection)
for that sort of scenario, and there's a TODO in the code to have it
read sys.argv. Thing is, you're looking at an extremely early alpha
that I developed alongside the one person who actually intends to use
it; any time spent on a GUI would be wasted at this stage, and even
parsing sys.argv to figure out which are file names and which are
other things would probably be a waste. Making something more
resilient would require design effort (first thought: read two numbers
per line, the length and the curve speed, and if it's a single number,
it's straight track at maximum speed) and thus would require
explanation ("so you need to put the two numbers on the same line").
It can be left for later.

Main point being that the existing UI works, and took almost no
effort. It gives us 99% of what we need for 1% of the work. The rest
of what we want can be obtained with small refinements, rather than a
full rewrite into a GUI.

> 3.) The program doesn't tell me how to break out of the entering process and
> start the computation. Is it a 0? Is it an empty string? I'm getting
> Tracebacks in either case (could be wrong python version, I'm using the OSX
> default 2.7.2)

The traceback when you enter a 0 is because you didn't give it enough
track to work with. The traceback on the empty string is because
that's a Python 3 program - it uses input() not raw_input() - and
you're asking it to eval an empty string. To be honest, I'm impressed
that it works as well as it does on 2.7; I never tested it. Definitely
some of the multi-arg print calls will produce messy output on 2.7
(they'll be printing tuples), but apparently the rest of the code is
so simple that a single __future__ directive and "try: input=raw_input
except NameError: pass" would make it work on 2.7. But we don't need
2.7 support.

> All these problems arise because the program forces me to enter the data in
> a predefined sequence. So no, this is not a good user experience. In a GUI
> it would be trivial to have an editable listbox for track length and speed,
> and a set of buttons to save, load, run the computation.

You're thinking in terms of the wrong sort of user and the wrong
scenario. Is it "a good user experience" to drop you into a completely
promptless input space, wait for you to hit Ctrl-D, and then echo back
every line you typed, in order? Because that's what the standard Unix
sort command does if you give it no args and no redirection. Is that
horrible design? Nope.

What runningtime.py has may not be 100% perfect, but it's better than
the editable listbox for several reasons:

1) Editing is actually not a common operation. Normal is to go through
a piece of track (as defined by some external resource), figure out
how long it'll take to go through it, and finish. Maybe compare two
tracks, which might start with the same few sections and then diverge
(do we go left or right around this obstacle?); in that case, copy and
paste of the early elements would be all you need for this UI, but
with an editable listbox, you'd have to go in and delete the half that
are wrong in order to retain the half that are right. Worse if it's
more than half different.

2) Time spent on the UI is time not spent on the guts of the program.
ESPECIALLY when I have severely limited time working with the client,
I don't want to waste it faffing around with incidentals. I want to
spend that time getting the crucial mathematics right. (Yeah. Like
River Tam and Queen Elsa, we did the math.)

3) This method makes it trivially easy to save to a file (eg
redirection). If you do it with a GUI, you then need a separate (and
separately-coded) facility to save and load. Glass teletype gives you

If Python had an sscanf-like function [1], I'd probably have made the
UI something like length,speed=sscanf("%d %d"), and that would be a
bit of an improvement (I think). The sequential nature of it isn't a
problem, though, so this would be a very minor thing. (And of course,
I could just read a string and manually parse. But that flies against
the principle of "waste no time on the UI when you're already short of
time for the maths".) What we have there is pretty good as it is, at
no effort.

ChrisA

[1] Something safer than C's one, of course. Pike does this:
http://pike.lysator.liu.se/generated/manual/modref/ex/predef_3A_3A/sscanf.html
--
https://mail.python.org/mailman/listinfo/python-list
```