Random indentation errors? [duplicate] - python

This question already has answers here:
I'm getting an IndentationError. How do I fix it?
(6 answers)
Closed 4 years ago.
Here's my code:
def options():
selection=int(input("#>"))
if selection == 1:
#Connect
elif selection == 2:
#Modules
print("Modules")
elif selection == 3:
#Checking Internet
checkInternetConnection()
elif selection == 99:
#Exit
shutdown()
else:
print "Unknown Option Selected!"
sleep(100)
sys.clear()
start()
Every time I run i get this error:
File "main.py", line 41
elif selection == 2:
^
IndentationError: expected an indented block
I am probably being a noob here but please may someone help?! Thanks

There has to be a statement after your if block
Note: Comments don't count.
You can use pass statement instead.
eg.
if statement:
pass

While that indebted # Connect looks like a perfectly good if body to you, and to other human readers, to Python it‘s as if you had nothing there at all. And an empty if body is illegal.
There are two common ways to handle this, and you’ll want to get into the habit of doing one or the other without thinking, whenever you need to stick in a placeholder for code to be written later, or temporarily disable some code for debugging.
The first is to write this:
pass # TODO: Connect
The second is to write this:
"Connect"
The latter may look kind of weird (even if you’re used to docstrings), but it is a perfectly valid expression, and therefore a perfectly valid statement.
While you could just write pass # Connect, the problem with that is that pass and a comment is something you could reasonably have in your final code, so you have no way to tell whether this was a placeholder you meant to come back to before deploying anything.
By contrast, your linter/IDE/commit-hooks/CI/whatever can easily be configured to recognize either TODO comments, or expression statements that have no effect, and therefore warn you to double-check that this code really is ready to deploy.

Comments are not placeholders for if statements so use pass.
...
if selection == 1:
#Connect
pass
...

Where you have #connect, put some functional code under that if instead or with it. Its reading that the elif is ' under ' the if.

Related

Clearing Print in Python

So I'm pretty new to both coding and this website, so please bear with me if this is stupid:
I'm working on a personal project and would like to find a way to clear "print()" statements in python 3.6. For example:
print("The user would see this text.")
but if I continue
print("The user would see this text.")
print("They would also see this text.")
Is there a way to make it so a user would only see the second print statement?
I have seen "os.system('cls')" and "os.system('clear')" recommended, but I get these errors for each:
os.system('cls')
resulting in
sh: 1: cls: not found
and
os.system('clear')
resulting in
TERM environment variable not set.
Obviously I'm missing something, but if you know what it'd be much appreciated. If you know of another way to do what I'm thinking, that would also be awesome. Thank you for taking the time to read this, and thanks for any help.
Edit: I'm using Repl.it as my IDE. Could this be an issue with that site specifically?
Edit: Downloaded a new IDE to check, and the reply worked. If you are new and using Repl.it, be aware that some code does not function properly.
The method that I've used in the past to 'reprint' something on an existing line is to make use of the standard output directly, coupled with a carriage return to bring the printed statement's cursor back to the start of the line (\r = carriage return), instead of relying on the print function.
In pseudocode:
# Send what you want to print initially to standard output, with a carriage return appended to the front of it.
# Flush the contents of standard output.
# Send the second thing you want to print to standard output.
A working example in Python:
import sys
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sys.stdout.write('\rThe user would also see this text')
Edit
Figured I'd add an example where you can actually see the code working, since the working example above is going to execute so quickly that you'll never see the original line. The below code incorporates a sleep so that you can see it print the first line, wait, then reprint the line using the second string:
import sys
from time import sleep
sys.stdout.write('\rThe user would see this text')
sys.stdout.flush()
sleep(2)
sys.stdout.write('\rThe user would also see this text')

Python 3.x multi line comment throws syntax error

I'm working on a Python project and as of now, my code has over 400+ lines. At one point, I had to write a multi-line comment about a small bug which needs a work around, and the interpreter decided to throw a syntax error.
According to the interpreter, the syntax error is occuring at elif.
I re-checked my indentation, converted tabs to spaces etc. Nothing seems to work.
if some_condition_1 == True:
do_something()
"""
Sub stage (b):
Refer documentation [1.7A] for ...
....
....
....
"""
elif condition_1 == True:
if condition_2 == False:
list.append(item)
However, if I remove the multi-line comment, the code executes fine.
Any idea what's going wrong? Please note that the code sample I've show above, is at very top of the file, and there's no chance for anything to go wrong elsewhere.
This is an indentation error. Your "multi-line comment" (really multi-line string) must be indented under the if block just like anything else.
""" These kinds of things """ are not really comments in Python. You're just creating a string and then throwing the value away (not storing it anywhere). Since Python doesn't have true multi-line comments, many people use them this way. However, since they are not true comments (they aren't ignored by the interpreter), they must obey all normal syntax rules, including indentation rules.
(Do note that when I say "creating a string" I'm speaking loosely. CPython, at least, has an optimization not to create an object here.)

Error in default programming of Google's Python exercise 'Copyspecial'

I get an IndexError: list index out of range error when using the --todir option in Google's Python Exercise copyspecial.py. How can I resolve this issue? What confuses me the most is that the part of code causing it is what was written by the instructor (from Google/Standford). I can only assume some syntactic error has spilled into other lines of code or that built in function syntax has changed since Python 2.7. This exercise code was written in 2.7.
The file works when no option is used, as so:
Printing list of special files
C:.\gpe\copyspecial\xyz__hello__.txt
C:.\gpe\copyspecial\zz__something__.jpg
done
This is the error:
The code:
def main():
# This basic command line argument parsing code is provided.
# Add code to call your functions below.
# Make a list of command line arguments, omitting the [0] element
# which is the script itself.
args = sys.argv[1:]
if not args:
print "usage: [--todir dir][--tozip zipfile] dir [dir ...]";
sys.exit(1)
# todir and tozip are either set from command line
# or left as the empty string.
# The args array is left just containing the dirs.
todir = ''
if args[0] == '--todir':
todir = args[1]
del args[0:2]
tozip = ''
if args[0] == '--tozip':
tozip = args[1]
del args[0:2]
if len(args) == 0:
print "error: must specify one or more dirs"
sys.exit(1)
# +++your code here+++
# Call your functions
All the aforementioned code is straight from google.com. My code comes before main() is defined and after where it says # +++your code here+++
I have spent hours trying to resolve this. I've learned a lot, but not the solution.
I've tried changing indentations.
I've tried doing sys.exit(1) nest under the '--todir' 'if', but the program keeps running down into the 'if tozip' part, which leads me to believe it's syntactical. But I can't find a misplaced () or :. I also checked indentations.
I've tried adding an 'if args[0]:' check, but it doesn't work, because as I later learned, although an empty list ('args[0]' = []), Python does not interpret it as an actual 'False' value.
The list goes on
I really appreciate the opportunity to have my question heard by the community at stackoverflow, and even more so as a first time poster.
As far as I can see your third try should work if you do it right:
tozip = ''
if args and args[0] == '--tozip':
tozip = args[1]
del args[0:2]
This actually checks the list args. If it is empty ([]), it is considered False and the second test args[0] == '--tozip' does not get evaluated.
Your problem is that args itself is an empty list which does evaluate to False (see https://docs.python.org/2/library/stdtypes.html#truth-value-testing), hence you cannot access args[0] and checking for it results in the same Indexerror.
However, you would still get an IndexError if you only pass one of the parameters without the argument because you access args[1] without testing.
EDIT (Why doesn't the code run as is?): I don't think any python versions >=2.4 would interpret this differently but I have no proof. This argument passing is very basic. Checking for malformed user input is always quite "annoying" because you have to handle every possible input which results in a lot of code. If you want to go into more detail of argument passing I recommend the argparse module (2.7, 3.5). My feeling is that to avoid having a large part of the exercise file that has nothing to do with the exercise they just left it that simple. If you don't supply at least one file path as a parameter you will get an error message in the next step anyway:
if len(args) == 0:
print "error: must specify one or more dirs"
sys.exit(1)
So the code does run as is. You just have to supply the right parameters.

How to quit Python function, throwing error statement without quitting Python interpreter [duplicate]

This question already has answers here:
Manually raising (throwing) an exception in Python
(11 answers)
Closed 4 months ago.
I'm new to Python and struggling with handling self-defined errors. When my code spots the error, I want it to throw an error in red font and take me back to the Python terminal without killing Python.
I came across sys.exit() looking for an answer, but it quits Python completely. Do you know of an alternative that throws back an error in red font and takes me back to the terminal?
This is what I have so far.
import sys
def do_something(parameter):
if parameter > 100:
# quit the function and any function(s) that may have called it
sys.exit('Your parameter should not be greater than 100!')
else:
# otherwise, carry on with the rest of the code
Please let me know if I'm not clear and I'll be happy to provide more details. Thank you all in advance!
You have two options (at least).
Using a return statement:
def do_something(parameter):
if parameter > 100:
# display error message if necessary
return # 'exit' function and return to caller
# rest of the code
You can also return soemthing passing the something value back to the caller. This can be used to provide a status code for instance (e.g. 0: success, 1: error).
Or a better approach is to raise an exception:
def do_something(parameter):
if parameter > 100:
raise ValueError('Parameter should...')
# rest of the code
try:
do_something(101)
except ValueError, e:
# display error message if necessary e.g. print str(e)
See exceptions in the Python manual.
There are built-in exception classes (like ValueError above). You can also define your own as follows:
class ParameterError(Exception):
pass
You can also add additional code to your custom exception classes to process parameters, display custom error messages, etc...
The built-in exceptions are listed here.
Define a custom exception, and raise it.
class MyError(Exception):
pass
...
if parameter > 100:
# quit the function and any function(s) that may have called it
raise MyError('Your parameter should not be greater than 100!')
(although actually, now I think about it, you could just use a built-in exception: ValueError would seem appropriate).

Understanding Global Names and Python2 and 3

As a newbie to Python, I'm kind of learning some of the differences between Python2 and 3. In working through the Python course, it seems that there are some things that need to be changed in the code to make it work in 3. Here's the code;
def clinic():
print "In this space goes the greeting"
print "Choose left or right"
answer = raw_input("Type left or right and hit 'Enter'.")
if answer == "LEFT" or answer == "Left" or answer == "left":
print "Here is test answer if you chose Left."
elif answer == "RIGHT" or answer == "Right" or answer == "right":
print "Here is the test answer if you chose Right!"
else:
print "You didn't make a valid choice, please try again."
clinic()
clinic()
To make this work in Python 3, the print syntax needs to be changed (add parens), but another issue that comes up is the error "NameError: global name 'raw_input' is not defined". I've seen this issue come up often in my learning. It doesn't seem to come up when I run it in Python2, but in 3 it seems to need it declared as a global. However, when I add "global raw_input" to the function, it doesn't seem to work (in other cases, it worked everytime I did it.) Can someone tell me what I'm doing wrong? Also, I've heard that declaring globals is a bad habit to get into when not necessary, so what's the best way to handle them?
raw_input() has been renamed in Python 3, use input() instead (and the old Python 2 input() was removed). See PEP 3111.
See What's new in Python 3.0 for an exhaustive overview. There is also the Dive into Python 3 overview.
Amending Martijn's answer, here's a general trick you can do for these kind of small incompatibilities:
try:
input_func = raw_input
except NameError:
raw_input = input
Afterwards you can just use raw_input in your script with both Py2 and Py3. Similar things might be required for the unicode, and byte types.
Since you indicated you're interested in migration from >=Py2.7 to a Py3, you should know that Python 2.7 was mostly a Python 2.6 with lots of Py3 stuff backported.
So, while the print function technically still is a statement in Py2.7, and a function in Py3, the Py2.7 print does accept tuples. And that makes some of the Py3 syntax work in Py2.7. In short, you can just use parantheses:
print("Here is the test answer if you chose Right!")
To print an empty line, the best method working in both versions would be
print("")
To print without adding a newline by default I'm resorting back to write(), e.g.:
import sys
sys.stdout.write("no newline here")
sys.stdout.write(" -- line continued here, and ends now.\n")
On the other hand, for lots of Py3 stuff, you can actually enable the full Py3 syntax in Py2.7 by importing things from the future:
from __future__ import print_function
Then you don't need to switch between write() and print().
In real applications it all depends on if and how you have to interact with other people's code (packages, other developers in your team, code publishing requirements) and what's your roadmap for Python version changes.

Categories

Resources