The problem is best explained by just showing the code:
a = True
b = True
while True:
"""
A
"""
if a == True:
pass
"""
B
"""
elif b == True:
pass
The issue being that there is a syntax error at "elif b", though when removing the comments, the issue disappears. I tried removing the indents on the comments which resulted in an expected indent on the closing comment line after "A". I know I could switch to using "#" to comment sections, though """ makes things much clearer and is more convenient for large chunks. Perhaps I'm missing something obvious, I would appreciate any help.
String literals aren't comments. You can sometimes sort of pretend they're comments, but they're not, and the fact that they're not is finally biting you.
An elif has to appear immediately after the end of the block associated with the preceding if or elif. There can be comments and whitespace in between, but no statements, and strings count. Use real comments, with #.
If you really want to keep pretending strings are comments, you can indent the B string into the body of the if, but it won't line up cleanly with the block it's intended to be a comment on, and you'll just keep having to mess with your formatting to patch up the differences between comments and string literals.
You're creating a new string when you use """triple quotes""". So, you essentially have an un-indented block of code before your elif, which requires a preceding if statement. The improper tabbing on the quotes ends your if block. Once your parser reaches the elif block, it doesn't have a matching if block, hence the error.
Triplequotes are used as docstrings in places, and can act like comments, but they're not actually comments.
Reference (search for """)
Related
So here is an example of a multiline string in vscode/python:
Cursor is after the p , and then you press enter, and end up like this:
i.e. the string ends up indented, which seems what you almost never want - why have an arbitratly amount of whitespace on the next line of this string ?
Is there any way change this in vscode, i.e. for multiline strings, it should end up with this:
I think this problem is related to different coding styles of different people.
For example,
def example(x):
if x:
a = '''
This is help
'''
def example(x):
if x:
a = '''This is help
'''
The automatic indenting of vscode line breaks is based on code blocks. If you want Vscode can identify multiline string, I think it would be better to submit future request in github. I've submitted this issue for you.
I am not 100% sure if what OP meant is just to refer to the indentation in the editor (namely, VSC) or if, by this:
i.e. the string ends up indented, which seems what you almost never want - why have an arbitrary amount of white space on the next line of this string?
...they also meant to refer to the actual output of the multi-line string,
(or also, just in case anybody else finds this post looking for a way to avoid this affecting the actual output of the multi-line string), I'd like to add as a complementary answer (cannot comment yet) that this was already beautifully answered here.
If that's the case and you're reading this for that reason, in short, all you want is to import the standard lib 'inspect' and post-process your string with it, using the cleandoc method.
Without breaking the indentation in your IDE, this method makes sure to give you the string output you actually expected:
All leading whitespace is removed from the first line. Any leading whitespace that can be uniformly removed from the second line onwards is removed. Empty lines at the beginning and end are subsequently removed. Also, all tabs are expanded to spaces.
(From the docs link above)
Hope that helps anyone.
My CS teacher told me that """ triple quotations are used as comments, yet I learned it as strings with line-breaks and indentations. This got me thinking about - does python completely triple quote lines outside of relevant statements?
"""is this completely ignored like a comment"""
-or, is the computer actually considering this?
Triple quoted strings are used as comment by many developers but it is actually not a comment, it is similar to regular strings in python but it allows the string to be in multi-line. You will find no official reference for triple quoted strings to be a comment.
In python, there is only one type of comment that starts with hash # and can contain only a single line of text.
According to PEP 257, it can however be used as a docstring, which is again not really a comment.
def foo():
"""
Developer friendly text for describing the purpose of function
Some test cases used by different unit testing libraries
"""
<body of the function>
You can just assign them to a variable as you do with single quoted strings:
x = """a multi-line text
enclosed by
triple quotes
"""
Furthermore, if you try in repl, triple quoted strings get printed, had it really been a comment, should it have been printed?:
>>> #comment
>>> """triple quoted"""
'triple quoted'
As someone else already pointed out, they are indeed strings and not comments in Python. I just wanted to add a little more context about your question of "is the computer actually considering it?"
The answer is yes, since it isn't a comment. Take the below code for example:
def my_func():
"""
Some string
"""
print("Hello World!")
my_func()
Trying to run this will actually produce a syntax error because of the indentation.
So as far as I know, triple quotes can be used for both purposes but # is the standard for commenting.
According to this website, what I can understand is that ''' This '''
can be used as a comment and because they are handled as docstrings technically (not tested) ' This ' can also act as a comment depending on where put it. However, even though single and triple quotes can be used as comments, it does not mean that they are comments. For example, # comments are compeletely ignored by the interpreter whereas ''' comments might be loaded into memory (just a probable guess, not confirmed). But from what I can tell, they aren't handled as comments as shown below:
So they are not but they can be used as comments. Generally speaking, use #.
EDIT:
As #BTables pointed out, you will get an indentation error if you don't indent them correctly. So they are indeed handled as strings.
I am writing a lexer + parser in JFlex + CUP, and I wanted to have Python-like syntax regarding blocks; that is, indentation marks the block level.
I am unsure of how to tackle this, and whether it should be done at the lexical or sintax level.
My current approach is to solve the issue at the lexical level - newlines are parsed as instruction separators, and when one is processed I move the lexer to a special state which checks how many characters are in front of the new line and remembers in which column the last line started, and accordingly introduces and open block or close block character.
However, I am running into all sort of trouble. For example:
JFlex cannot match empty strings, so my instructions need to have at least one blanck after every newline.
I cannot close two blocks at the same time with this approach.
Is my approach correct? Should I be doing things different?
Your approach of handling indents in the lexer rather than the parser is correct. Well, it’s doable either way, but this is usually the easier way, and it’s the way Python itself (or at least CPython and PyPy) does it.
I don’t know much about JFlex, and you haven’t given us any code to work with, but I can explain in general terms.
For your first problem, you're already putting the lexer into a special state after the newline, so that "grab 0 or more spaces" should be doable by escaping from the normal flow of things and just running a regex against the line.
For your second problem, the simplest solution (and the one Python uses) is to keep a stack of indents. I'll demonstrate something a bit simpler than what Python does.
First:
indents = [0]
After each newline, grab a run of 0 or more spaces as spaces. Then:
if len(spaces) == indents[-1]:
pass
elif len(spaces) > indents[-1]:
indents.append(len(spaces))
emit(INDENT_TOKEN)
else:
while len(spaces) != indents[-1]:
indents.pop()
emit(DEDENT_TOKEN)
Now your parser just sees INDENT_TOKEN and DEDENT_TOKEN, which are no different from, say, OPEN_BRACE_TOKEN and CLOSE_BRACE_TOKEN in a C-like language.
Of you’d want better error handling—raise some kind of tokenizer error rather than an implicit IndexError, maybe use < instead of != so you can detect that you’ve gone too far instead of exhausting the stack (for better error recovery if you want to continue to emit further errors instead of bailing at the first one), etc.
For real-life example code (with error handling, and tabs as well as spaces, and backslash newline escaping, and handling non-syntactic indentation inside of parenthesized expressions, etc.), see the tokenize docs and source in the stdlib.
What is the purpose of the colon before a block in Python?
Example:
if n == 0:
print "The end"
The colon is there to declare the start of an indented block.
Technically, it's not necessary; you could just indent and de-indent when the block is done. However, based on the Python koan “explicit is better than implicit” (EIBTI), I believe that Guido deliberately made the colon obligatory, so any statement that should be followed by indented code ends in a colon. (It also allows one-liners if you continue after the colon, but this style is not in wide use.)
It also makes the work of syntax-aware auto-indenting editors easier, which also counted in the decision.
This question turns out to be a Python FAQ, and I found one of its answers by Guido here:
Why are colons required for the if/while/def/class statements?
The colon is required primarily to enhance readability (one of the results of the experimental ABC language). Consider this:
if a == b
print a
versus
if a == b:
print a
Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in this FAQ answer; it’s a standard usage in English.
Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased instead of having to do a more elaborate parsing of the program text.
Consider the following list of things to buy from the grocery store, written in Pewprikanese.
pewkah
lalala
chunkykachoo
pewpewpew
skunkybacon
When I read that, I'm confused, Are chunkykachoo and pewpewpew a kind of lalala? Or what if chunkykachoo and pewpewpew are indented just because they are special items?
Now see what happens when my Pewprikanese friend add a colon to help me parse the list better: (<-- like this)
pewkah
lalala: (<-- see this colon)
chunkykachoo
pewpewpew
skunkybacon
Now it's clear that chunkykachoo and pewpewpew are a kind of lalala.
Let's say there is a person who's starting to learn Python, which happens to be her first programming language to learn. Without colons, there's a considerable probability that she's going to keep thinking "this lines are indented because this lines are like special items.", and it could take a while to realize that that's not the best way to think about indentation.
Three reasons:
To increase readability. The colon helps the code flow into the following indented block.
To help text editors/IDEs, they can automatically indent the next line if the previous line ended with a colon.
To make parsing by python slightly easier.
As far as I know, it's an intentional design to make it more obvious, that the reader should expect an indentation after the colon.
It also makes constructs like this possible:
if expression: action()
code_continues()
since having the code for the if immediately following the colon makes it possible for the compiler to understand that the next line should not be indented.
According to Guido Van Rossum, the Python inventor, the idea of using a colon to make the structure more apparent is inspired by earlier experiments with a Python predecessor, ABC language, which also targeted the beginners. Apparently, on their early tests, beginner learners progressed faster with colon than without it. Read the whole story at Guido's post python history blog.
http://python-history.blogspot.com/2009/02/early-language-design-and-development.html
And yes, the colon is useful in one-liners and is less annoying than the semicolon. Also style guide for long time recommended break on several lines only when it ends with a binary operator
x = (23 +
24 +
33)
Addition of colon made compound statement look the same way for greater style uniformity.
There is a 'colonless' encoding for CPython as well as colon-less dialect, called cobra. Those did not pick up.
I am Python newbie and I am working on NLP using Python. I am having an error in writing an if-else block in Python. When I am writing only an if block at that time it is working fine:
if xyzzy.endswith('l'):
print xyzzy
After entering a colon (:) I am pressing Enter and it is automatically taking me to the correct indentation.
But when I am trying to add an else block to it after pressing the Enter key after the print statement, it is considering it to be statement of an IF block only, so it is giving me incorrect indentation as I want an else block after, while when I am trying to write else block my self it is giving me this error.
else:
^
IndentationError: unexpected indent
What should I do after writing print statement? Enter is clearly not working, because it is taking the cursor forward, while when I use space to come to the correct pointer it is giving me an error.
It's hard to see from your post what the problem is, but an if-else is formatted like so
if someCondition:
do_something # could be a single statement, or a series of statements
else:
do_something_else # could be a single statement, or a series of statements
I.e., the else needs to be at the same level as the corresponding if.
See this Python doc/tutorial on if, and this other tutorial too.
Sometimes when your editor does autoindent for you and you edit manually too things might get messed up, so you'll have to figure out how your editor handles indentations (e.g., is it always using tabs or spaces?, what happens if you hit return etc).
Also, be wary of mixing tabs and spaces, that will cause problems too (hard to spot since both are "invisible")
With your updated post:
if xyzzy.endswith('l'):
print xyzzy
else:
something_else
The else should be at the same level of indentation as the if with which it is coupled:
if x:
# Do something
else:
# Do something else
In your case,
if xyzzy.endswith('l'):
print xyzzy
else:
# Something else
Even if your editor is auto-indenting for you, you should still un-indent to make the code syntactically correct.
Getting the indentation correct isn't really a Python issue but rather an issue with the editor that you're using for your source code.
Most editors that understand Python will correctly add one level of indentation after a colon (as you're seeing). Because you can have as many statements as you want in that block of code, the editor has no way to know when to "outdent" the next line for the else.
You have to tell the editor to outdent that line by hitting backspace or Shift + Tab on the line before starting to type.
If you are inserting the else part after the rest of the code is written, make absolutely certain that the characters you use to indent are the same as for the if statement. If the if statement is indented with spaces, use the same number of spaces for else. If the if statement is indented with one or more tabs, use the same number of tabs for the else statement. Don't mix spaces and tabs for indentation.
Don't assume that just because the lines "look" as if they're indented the same that they are indented the same. One may use spaces and one may use tabs (or some combination).
when I use space to come to the correct pointer it is giving me a error
Of course. Using space never makes a "line break", typically this is \n in Unix systems. If you'd open your .py file in a different editor (say Notepad in Windows) you'd see that your else statement is in the same line as print.
Enter is clearly not working because it is taking the cursor forward
Press backspace the correct amount of times to reach the same level of indentation as your IF statement.
I don't agree entirely with the accepted answer. Yes, indention is very important in Python, but to state that the if-else has to always look like that with this formatting is a little bit overboard.
Python allows you a one-liners (even multiple) as long as you don't do anything fancy in there that requires indention in the body of the if, elif or else.
Here are some examples:
choice = 1
# if with one-liner
if choice == 1: print('This is choice 1')
# if-else with one-liners
if choice == 1: print('This is choice 1')
else: print('This is a choice other than 1')
# if-else if with one-liners
if choice == 1: print('This is choice 1')
elif choice == 2: print('This is choice 2')
# if-else if-else with one-liners
if choice == 1: print('This is choice 1')
elif choice == 2: print('This is choice 2')
else: print('This is a choice other than 1 and 2')
# Multiple simple statements on a single line have to be separated by a semicolumn (;) except for the last one on the line
if choice == 1: print('First statement'); print('Second statement'); print('Third statement')
Usually it is not recommended to pack too many statements on a single line because then you lose one of the big features of Python - readability of the code.
Notice also that the above examples can also easily be applied to for and while. You can go even further as to do some crazy nesting of one-liner if blocks if you use the ternary conditional operator.
Here is how the operator usually looks:
flag = True
print('Flag is set to %s' % ('AWESOME' if True else 'BORING'))
Basically, it creates a simple if-else statement. You can embed it with one of your one-liners if you need more branching (but not complex one).
I hope this clarifies the situation a bit and what is allowed and not allowed. ;)
I've been getting this error even when the indentation looked correct.
Viewing in Notepad++ there is an option to see white spaces and Tabs. The error was caused by mixing spaces and tabs to create indentation.
Replacing Tabs with spaces in every line helped to get rid of an error.
Actually, this is a Python IDLE UI issue: Once you hit Enter after the if block finishes, next the else statement is already in intent with the if statement. There isn't any need to provide any tabs or spaces to make indentation. Below is the image for reference.