while loop in command prompt python - python

How do I create a while loop using python in the command prompt? I want to create an infinite loop that prints a string. I know how to do this normally but being limited to a one line execute makes this very confusing.

$ python -c "while True: print(\"test\")"
Something like this?

The command line won't execute your line if there is another line that's meant to be there. You can just write your loop as you would normally and Python won't start executing it until your loop is closed:
>>> while True:
... print("abc")
... #something else
...
You have to press Enter twice to signal Python that you are done with your loop.

The syntax is the same that you would use in an IDE like vs code.
This is a really easy example:
c = 0
while c <= 3:
print(c)
c+=1

If you're making an infinite loop that simply just prints a string over and over again, something like this should work:
while True: print("Hello!")
Fits on one line and the condition and print argument can be modified to anything you like

Related

Python Unusual error with multiline code in IDLE Shell

I was testing some code on IDLE for Python which I haven't used in a while and stumbled on an unusual error.
I was attempting to run this simple code:
for i in range(10):
print(i)
print('Done')
I recall that the shell works on a line by line basis, so here is what I did first:
>>> for i in range(10):
print(i)
print('Done')
This resulted in a indent error, shown by the picture below:
I tried another way, as it might be that the next statement needed to be at the start perhaps, like this:
>>> for i in range(10):
print(i)
print('Done')
But this gave a syntax error, oddly:
This is quite odd to me the way IDLE works.
Take Note:
I am actually testing a much more complex program and didn't want to create a small Python file for a short test. After all, isn't IDLE's shell used for short tests anyways?
Why is multi-line coding causing this issue? Thanks.
Just hit return once or twice after the print(i), until you get the >>> prompt again. Then you can type the print('Done'). What's going on is that python is waiting for you to tell it that you're done working inside that for. And you do that by hitting return.
(You'll see, though, that the for loop is executed right away.)

Automatically insert newline after for loop in pydev

Suppose I have a block of code like this:
for i in range(10):
print(i)
I select them and press F2 to send them to the python console, then it looks like this:
>>> for i in range(10):
... print(i)
and I need to change focus to the console and press return, otherwise the for loop will not run.
This is very annoying. Is there a way to make pydev automatically insert this return for me?
Well, by design it works as you're seeing: it needs some unidented code to run, so, what you can do as a workaround is putting in your code an unindented 'pass' in the end and execute it too with F2 (the other choice is really going to the console to hit enter):
for i in range(10):
print(i)
pass

Run statment only once if loop stops in Python

I've been doing something that needs to run an infinite while loop inside another infinite while loop (don't judge) and breaks if some sort of event happens. I need to run a statement once when the inside loop breaks, without having it modified in the external loop.
I need something like this:
while True:
while condition:
do stuff
<run some code when the inside while finishes>
continue running external loop without running the line inside <>
Basically, the reverse of a while-else construct.
Edit: I've changed the code to relate to the real problem. I'm really sorry for the mistake. Was bombarded by other stuff and wasn't thinking right.
If you only need the statement to run once when the internal while breaks, why not just put it in the if block?
while True:
while condition:
if other-condition:
<code to run when the inside loop breaks>
break
<continue external loop>
EDIT: In order to run only once after the inner loop is finished (without an if other_condition: ...; break) you should use the following:
while True:
has_run = False
while condition:
<loop code>
if not has_run:
<code to run when inner loop finishes>
has_run = True
<rest of outer loop code>
Add a boolean that you switch after the code has been executed once! This way you can always make things happen just once in a loop. Also, if you want to run the external loop again, the internal loop will start again, and it will break again, so are you sure you only want to run that line once?
broken = False
while True:
while condition:
if other-condition:
break
if not broken:
broken = True
<run some code when the inside while breaks>
continue running external loop without running the line inside <>
If you need continue code after while loop than use variable was_break
while True:
was_break = False
while condition:
if other-condition:
was_break = True
break
if was_break:
<run some code when the inside while breaks>
continue running external loop without running the line inside <>
Pythonic way for this is to use else with while loop. This is how it should be done.
If the else statement is used with a while loop, the else statement is executed when the condition becomes false.
x=1
while x:
print "in while"
x=0
#your code here
else:
print "in else"

taking multiline input with sys.stdin

I have the following function:
def getInput():
# define buffer (list of lines)
buffer = []
run = True
while run:
# loop through each line of user input, adding it to buffer
for line in sys.stdin.readlines():
if line == 'quit\n':
run = False
else:
buffer.append(line.replace('\n',''))
# return list of lines
return buffer
which is called in my function takeCommands(), which is called to actually run my program.
However, this doesn't do anything. I'm hoping to add each line to an array, and once a line == 'quit' it stops taking user input. I've tried both for line in sys.stdin.readlines() and for line sys.stdin, but neither of them register any of my input (I'm running it in Windows Command Prompt). Any ideas? Thanks
So, took your code out of the function and ran some tests.
import sys
buffer = []
while run:
line = sys.stdin.readline().rstrip('\n')
if line == 'quit':
run = False
else:
buffer.append(line)
print buffer
Changes:
Removed the 'for' loop
Using 'readline' instead of 'readlines'
strip'd out the '\n' after input, so all processing afterwards is much easier.
Another way:
import sys
buffer = []
while True:
line = sys.stdin.readline().rstrip('\n')
if line == 'quit':
break
else:
buffer.append(line)
print buffer
Takes out the 'run' variable, as it is not really needed.
I'd use itertools.takewhile for this:
import sys
import itertools
print list(itertools.takewhile(lambda x: x.strip() != 'quit', sys.stdin))
Another way to do this would be to use the 2-argument iter form:
print list(iter(raw_input,'quit'))
This has the advantage that raw_input takes care of all of the line-buffering issues and it will strip the newlines for you already -- But it will loop until you run out of memory if the user forgets to add a quit to the script.
Both of these pass the test:
python test.py <<EOF
foo
bar
baz
quit
cat
dog
cow
EOF
There are multiple separate problems with this code:
while run:
# loop through each line of user input, adding it to buffer
for line in sys.stdin.readlines():
if line == 'quit':
run = False
First, you have an inner loop that won't finish until all lines have been processed, even if you type "quit" at some point. Setting run = False doesn't break out of that loop. Instead of quitting as soon as you type "quit", it will keep going until it's looked at all of the lines, and then quit if you typed "quit" at any point.
You can fix this one pretty easily by adding a break after the run = False.
But, with or without that fix, if you didn't type "quit" during that first time through the outer loop, since you've already read all input, there's nothing else to read, so you'll just keep running an empty inner loop over and over forever that you can never exit.
You have a loop that means "read and process all the input". You want to do that exactly once. So, what should the outer loop be? It should not be anyway; the way to do something once is to not use a loop. So, to fix this one, get rid of run and the while run: loop; just use the inner loop.
Then, if you type "quit", line will actually be "quit\n", because readlines does not strip newlines.
You fix this one by either testing for "quit\n", or stripping the lines.
Finally, even if you fix all of these problems, you're still waiting forever before doing anything. readlines returns a list of lines. The only way it can possibly do that is by reading all of the lines that will ever be on stdin. You can't even start looping until you've read all those lines.
When standard input is a file, that happens when the file ends, so it's not too terrible. But when standard input is the Windows command prompt, the command prompt never ends.* So, this takes forever. You don't get to start processing the list of lines, because it takes forever to wait for the list of lines.
The solution is to not use readlines(). Really, there is never a good reason to call readlines() on anything, stdin or not. Anything that readlines works on is already an iterable full of lines, just like the list that readlines would give you, except that it's "lazy": it can give you the lines one at a time, instead of waiting and giving you all of them at once. (And even if you really need the list, just do list(f) instead of f.readlines().)
So, instead of for line in sys.stdin.readlines():, just do for line in sys.stdin: (Or, better, replace the explicit loop completely and use a sequence of iterator transformations, as in mgilson's answer.)
The fixes JBernardo, Wing Tang Wong, etc. proposed are all correct, and necessary. The reason none of them fixed your problems is that if you have 4 bugs and fix 1, your code still doesn't work. That's exactly why "doesn't work" isn't a useful measure of anything in programming, and you have to debug what's actually going wrong to know whether you're making progress.
* I lied a bit about stdin never being finished. If you type a control-Z (you may or may not need to follow it with a return), then stdin is finished. But if your assignment is to make it quit as soon as the user types "quit"< turning in something that only quits when the user types "quit" and then return, control-Z, return again probably won't be considered successful.

How do I skip a loop with pdb?

How can I skip over a loop using pdb.set_trace()?
For example,
pdb.set_trace()
for i in range(5):
print(i)
print('Done!')
pdb prompts before the loop. I input a command. All 1-5 values are returned and then I'd like to be prompted with pdb again before the print('Done!') executes.
Try the until statement.
Go to the last line of the loop (with next or n) and then use until or unt. This will take you to the next line, right after the loop.
http://www.doughellmann.com/PyMOTW/pdb/ has a good explanation
You should set a breakpoint after the loop ("break main.py:4" presuming the above lines are in a file called main.py) and then continue ("c").
In the link mentioned by the accepted answer (https://pymotw.com/3/pdb/), I found this section somewhat more helpful:
To let execution run until a specific line, pass the line number to
the until command.
Here's an example of how that can work re: loops:
It spares you from two things: having to create extra breakpoints, and having to navigate to the end of a loop (especially when you might have already iterated such that you wouldn't be able to without re-running the debugger).
Here's the Python docs on until. Btw I'm using pdb++ as a drop-in for the standard debugger (hence the formatting) but until works the same in both.
You can set another breakpoint after the loop and jump to it (when debugging) with c:
pdb.set_trace()
for i in range(5):
print(i)
pdb.set_trace()
print('Done!')
If I understood this correctly.
One possible way of doing this would be:
Once you get you pdb prompt . Just hit n (next) 10 times to exit the loop.
However, I am not aware of a way to exit a loop in pdb.
You could use r to exit a function though.

Categories

Resources