So I just learned about "List Comprehensions" in python. some of these are getting too long for a single line (PEP8) and I'm trying to figure out the best (most readable) way to break these out.
I've come up with this
questions = [
(
q,
q.vote_set.filter(choice__exact='Y'),
q.vote_set.filter(choice__exact='N'),
request.session.get(str(q.id))
)
for q in questions
]
but it still complains about whitespace before the ], the specific pep8 error is E202
this is in an indented block.
I would probably do it like this:
questions = [(q,
q.vote_set.filter(choice__exact='Y'),
q.vote_set.filter(choice__exact='N'),
request.session.get(str(q.id)))
for q in questions]
Keep in mind that PEP8 is intended to be used along with your best judgement; they aren't intended to be followed absolutely in all circumstances. They also aren't structured to always make sense when multiple rules conflict.
It's OK to intentionally break the rules once in a while; checkers like that are just intended to make sure you don't break them accidentally.
Edit: Moving my comment into my answer.
Your code looks a little bit too much like a Lisp-like parenthesis language or a C-like curly-braces language because of you putting brackets and parenthesis on separate lines.
In Python, you just use indentation to show what you would normally show with a bracket / parenthesis / brace on a separate line in another language. If you take your code and make that change, it's identical to my version.
Really though, don't worry too much about the PEP checker. If you really like the extra whitespace you get from putting the parenthesis and brackets on separate lines, then do it. It doesn't make it "bad code" nor does it decrease the readability.
Depends upon to the tool, I guess. Which tool is giving you E202? I copy pasted and tried with this pep8 tool and it did not give any error. But I specifically but a whitespace after questions and got the error.
The E202 on the ] says that it is finding a whitespace before that. Make sure that you don't have that in the code. Try closing ] soon after questions.
Consider writing your statement using a generator expression.
questions = ((q,
q.vote_set.filter(choice__exact='Y'),
q.vote_set.filter(choice__exact='N'),
request.session.get(str(q.id)),)
for q in questions)
Additionally, not that its "wrong", but in general I don't recommend redefining declared variables cause it may cause confusion in the code. In this case you are changing the questions instance to another type.
I was also unable to reproduce your PEP8 warning with the code you showed above. Perhaps you could put your exact code in a pastebin?
The example test cases for PEP8 (if you use the --show-pep8 option) are as follows:
Avoid extraneous whitespace in the following situations:
- Immediately inside parentheses, brackets or braces.
- Immediately before a comma, semicolon, or colon.
Okay: spam(ham[1], {eggs: 2})
E201: spam( ham[1], {eggs: 2})
E201: spam(ham[ 1], {eggs: 2})
E201: spam(ham[1], { eggs: 2})
E202: spam(ham[1], {eggs: 2} )
E202: spam(ham[1 ], {eggs: 2})
E202: spam(ham[1], {eggs: 2 })
E203: if x == 4: print x, y; x, y = y , x
E203: if x == 4: print x, y ; x, y = y, x
E203: if x == 4 : print x, y; x, y = y, x
Also, I haven't actually used Textmate, but if you're doing on the fly checking similar to emacs' flymake mode, then it could also be that pep8 is getting called on an old version of the file, and the issue may go away when you save the file. We may need more information to debug further.
As for the formatting of the list comprehension itself, you may want to take a look at this other SO question as well as the take from the Google style guide. I personally have no problem with the way you did it. I suppose you could also do something like
def _question_tuple(q):
return (
q,
q.vote_set.filter(choice__exact='Y'),
q.vote_set.filter(choice__exact='N'),
request.session.get(str(q.id))
)
question_tups = [_question_tuple(q) for q in questions]
but it's really about what will be the most readable/maintainable, and that's up to your own judgment.
Related
I am using Python
but the space gap is making my life very hard with it
example
when I use the if statement
if Parm2 == 1:
Ch = "A"
elif Parm2 == 2:
Ch = "B"
elif Parm2 == 3:
Ch = "C"
else:
continue
mdl = CallFunc(Parm2)
print("XX Always Print XX")
now the "XX Always Print XX" should be printed regardless
but due to my mistake it is inside the if statement which cause me long time to find
the actual if statement is nested and longer
I wonder if there is a method I can use begin/end or {} in such statements in Python
something like
UPDATE
for the people who focus on the IF statement
if Parm2 == 1:
{
Ch = "A"
}
elif Parm2 == 2:
{
Ch = "B"
}
elif Parm2 == 3:
{
Ch = "C"
}
else:
{
mdl = CallFunc(Parm2)
}
print("XX Always Print XX")
Happy now??
ok now how to get the brackets work in Python?
Python is indentation based. Yeah, its harder to read and easier to make mistakes like you indicated, but that's what it is.
Think about downloading an IDE for python, like Pycharm, they are helpful for identifying errors like this one, they also have an "auto-indent" feature. But no, Python is indentation based.
What the Python designers realized is that braces or begin/end keywords are mostly noise to human programmers. They generally recognize the structure of code by its layout. For instance, if you were to write the C code:
if (condition)
x = y;
w = z;
a human would often not notice that the braces are missing, and assume that both assignments are controlled by the condition. Writing code like this is a common error, especially when you start with a block that has just one statement (so the braces are optional and were omitted), and forget to add braces when a second statement is added. (See Why is it considered a bad practice to omit curly braces?).
Conversely, if you write
if (condition) {
x = y;
w = z;
}
it looks like w = z; is not part of the conditional.
Braces mainly exist for the benefit of software that processes code (compilers, editors, IDEs), they make it easier for them to detect groups of code. The Python designers decided to mirror the way humans read code in their parser, rather than forcing humans to adapt to the computer's needs.
Braces allow for more flexible code layout, but in practice it's usually condiered wrong to take advantage of this. Writing code like
while (something) { statement1; statement2;
statement3; }
is less readable than
while something:
statement1
statement2
statement3
Python does allow some flexibility: You can separate statements on the same line with ;, and put the contents of a conditional on the same line after the :. But writing like this is not considered Pythonic, and should be used only in very special circumstances (this blog post describes those cases).
There's always some adjustment necessary when you're learning a new programming language and you're accustomed to the patterns of the languages you previously used (many programmers have refused to learn Lisp, because of its Lots of Irritating, Stupid Parentheses). But give it a little time and you'll get used to it.
This shows how you can hack it:
if True: {
print("hello")
}
If you do a google search for "python what if you don't want to use indentation for blocks" you might get:
peach pit python indentation
Programmers familiar with other languages often bristle at the thought that indentation matters: Many programmers like the freedom to format their code how they please. However, Python indentation rules are quite simple, and most programmers already use indentation to make their code readable. Python simply takes this idea one step further and gives meaning to the indentation.
i.e. they force you not to use indentation.
My problem with this is that I love to use emacs auto-indentation to reindent the whole code file but this totally screws up the indentation in python; in C or C++ this finds the indentation problems and makes them evident; in python it loses all your information and changes the meaning of the program;
Don't get me wrong I want to use BOTH rigorous indentation AND curly braces;
You can use the hack above to "circumvent" python indentation but when writing code for anyone other than yourself it won't be popular.
Sorry in advance if this is something really easy, I'm very new to Python. This seems like it should be something very simple, but I am having a frustratingly hard time finding an answer online.
I'm writing a Python script in a preliminary, pseudo sort of fashion at the moment, and don't have all variable defined yet. I want to be able to have comments in the middle of a line to symbolize where the variable will go, but without commenting out the entire rest of the line to the right.
To visualize what I mean, this is how what I want is done in C/C++:
int some_variable = /*some_variable_that_doesnt_exist_yet*/ + an_existing_variable;
Basically I need to be able to comment the middle of a line without commenting the left or right sides of said comment. Is there any way to do this?
I know there's a way to do it like this (or something similar to this):
some_variable = #some_variable_that_doesnt_exist_yet
\+ an_existing_variable
...but I'd rather not do it that way if possible, just for ease of reading.
Unfortunately no. But you can always break things into multiple lines and comment in between. Parentheses come in handy for that.
my_var = (#some_variable +
some_other_var)
As with any language switch you will need to learn new habits that fit the features of the language. Python does not have the feature you desire, you could use some horrendous hack to force something that looks a bit similar in but I rather suggest you don't.
Some options are: document the TODO on a neighbouring line, perhaps using docstrings; don't sweat it and figure you'll add it later when your tests start requiring it; or use the fact that variables are lightweight and just create them with dummy values that leave the final calculation unchanged.
Inline comments do not exist in python.
The closest that I know of is the use of strings:
int some_variable = "some_variable_that_doesnt_exist_yet +" and an_existing_variable;
But that is terrible, and you should never do that.
You can't: According to the documentation, comments in Python start with the hash character (#) and extend to the end of the physical line. See An Informal Introduction to Python.
Why not use something like:
name = "Use this for something later"
:
:
name = 27
Python does not have inline or block comments like this. You can add a string (or any other expression), as suggested by others, but you will have to make sure to (consistently) replace all of those placeholders, which is extremely error prone
If it's only the value of the variable that is missing or unclear, and not the variable itself, how about this:
variable_to_be_defined = None # TODO define me!
some_other_variable = variable_to_be_defined + an_existing_variable
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
What is better to do?
self.call(1, True, "hi")
or
self.call(1, True, "hi",)
And what in the following cases:
self.call(
1,
True,
"hi"
)
or
self.call(
1,
True,
"hi",
)
?
Reasons for adding a trailing comma in data structures are familiar to me, but what about function calls?
There's no technical reason to avoid trailing commas in function calls, but some people might find them distracting. Some may wonder: Hmmm, is that comma supposed to be there?
One effect of using trailing commas in conjunction with an indented style is to make version control diffs look a little bit cleaner when adding an argument.
For example, a function like this:
def my_fun(a, b, c=None):
...
...called like this:
my_fun(
a='abc',
b=123
)
...then changed to this:
my_fun(
a='abc',
b=123,
c='def'
)
produces this diff in git:
$ git diff
...
my_fun(
a='abc',
- b=123
+ b=123,
+ c='def'
)
Whereas,
my_fun(
a='abc',
b=123,
)
changed to...
my_fun(
a='abc',
b=123,
c='def',
)
produces this diff in git:
$ git diff
...
my_fun(
a='abc',
b=123,
+ c='def',
)
I'll also leave my 2 cents here, even if this thread has been here for quite some time, it might benefit somebody :)
PEP8 actually does say when to use trailing commas and if you follow their recommendations (not mandatory, but definitely recommended) then the second one-liner example of yours can be ruled out, i.e:
No:
self.call(1, True, "hi",)
Yes:
self.call(
1,
True,
"hi",
)
Usages in function calls (use sparingly to never) and here's why:
One of the coding principles is that a function should do one thing, and one thing only. So, seeing a trailing comma there, a lot of questions may arise, when they really shouldn't. Normally when you see a trailing comma somewhere, you expect that thing to change over time. So if it's a list, tuple, dict, etc. it usually indicates that whoever designed it, did it with the intention of physically adding or removing or switching lines in that data structure, and well... you don't see that with functions very often, or at least you shouldn't, and if you do, a better design should be considered.
As aforementioned, a function should also be very predictable, you don't design a function that sends mail and rockets to the moon at the same time, and leave a trailing comma when calling it to send mail because who knows when you might send rockets and you want less cluttered diff (it will only cause more confusion and its a poor design).
An arbitrary number of parameters (or even a fixed, but large number of parameters) usually indicates that either you are either instantiating an object there, or you are doing multiple things, when really what you should be doing is split your design into creating multiple smaller functions, that each do one thing, hence, no trailing comma needed.
Also consider, even if you did have a function, which you would be able to call with multiple number of parameters, think about how often would you do that and what it implies? Well that would imply something like:
Refactoring the code at the call place (which may be in another function, or in a module or somewhere) because usually the result from functions is stored in variables, and you need to use that new result, so that would imply refactoring.
If it doesn't imply refactoring then it means the function doesn't return anything, or it returns the same thing, in which case it means that it does multiple things with the extra arguments passed in the call, which, as previously said, is not very ideal.
Actual usages
Trailing commas make sense, like you said in data structures, data structures that are expected to change physically over time, because if you change it at run-time, well it wouldn't make any sense for anything that's in the editor, except for the definition which might as well be an empty structure [] xD
Where data structures (lists, dicts, sets, tuples, etc) are expected to change (physically, the source code) then trailing commas are actually recommended and actually useful (see the full PEP link, it has use cases and recommendations)
Conclusion:
Recommended in multi-line data structures that are expected to physically change
Rarely to never in function calls
Never in function definitions
In data structures, the trailing comma is "useful" for making it easier to add items:
a = [
1,
2,
3,
]
is easier to change into
a = [
1,
2,
3,
4,
5,
]
because you don't have to edit the line that says 3,.
But there is no such benefit in function calls which usually don't change in length. So I would discourage the use of a trailing comma.
I think, in this matter the same reasons apply as for lists and tuples, because the function argument list is exactly that.
Here's a quote from the FAQ on design decisions that were made for the language (c.f.):
Why does Python allow commas at the end of lists and tuples?
Python lets you add a trailing comma at the end of lists, tuples, and dictionaries:
[1, 2, 3,]
('a', 'b', 'c',)
d = {
"A": [1, 5],
"B": [6, 7], # last trailing comma is optional but good style
}
There are several reasons to allow this.
When you have a literal value for a list, tuple, or dictionary spread across multiple lines, it’s easier to add more elements because you don’t have to remember to add a comma to the previous line. The lines can also be reordered without creating a syntax error.
Accidentally omitting the comma can lead to errors that are hard to diagnose. For example:
x = [
"fee",
"fie"
"foo",
"fum"
]
This list looks like it has four elements, but it actually contains three: “fee”, “fiefoo” and “fum”. Always adding the comma avoids this source of error.
Allowing the trailing comma may also make programmatic code generation easier.
This is tool specific, but it actually makes code refactoring much easier in vim/Gvim even on single line function parameter lists.
def foo( a, b, c, e, d, ):
changed to
def foo( a, b, c, d, e, ):
When using vim, you can just delete the "e," or "d," with two keystrokes (dW) move to where you want to paste it in and press (p).
If you didn't have the ending comma, you end up having to remove it from your new last item and adding it to your old last item. Alternately, you'd have to be more careful deleting only up until the comma and pasting more precisely. With comma's everywhere, you can treat everything as uniform chunks that can be swapped around with ease.
Vim's apparently quite popular with python writers so this actually appears to have some merit: https://www.sitepoint.com/which-code-editors-do-pythonists-use/
Which is preferred ("." indicating whitespace)?
A)
def foo():
x = 1
y = 2
....
if True:
bar()
B)
def foo():
x = 1
y = 2
if True:
bar()
My intuition would be B (that's also what vim does for me), but I see people using A) all the time. Is it just because most of the editors out there are broken?
If you use A, you could copy paste your block in python shell, B will get unexpected indentation error.
The PEP 8 does not seem to be clear on this issue, although the statements about "blank lines" could be interpreted in favor of B. The PEP 8 style-checker (pep8.py) prefers B and warns if you use A; however, both variations are legal. My own view is that since Python will successfully interpret the code in either case that this doesn't really matter, and trying to enforce it would be a lot of work for very little gain. I suppose if you are very adamantly in favor of one or the other you could automatically convert the one to the other. Trying to fix all such lines manually, though, would be a huge undertaking and really not worth the effort, IMHO.
Adding proper indentation to blank lines (style A in the question) vastly improves code readability with display whitespace enabled because it makes it easier to see whether code after a blank line is part of the same indentation block or not.
For a language like Python, where there is no end statement or close bracket, I'm surprised this is not part of PEP. Editing Python with display whitespace on is strongly recommended, to avoid both trailing whitespace and mixed indentation.
Compare reading the following:
A)
def foo():
....x = 1
....y = 2
....
....if True:
........bar()
B)
def foo():
....x = 1
....y = 2
....if True:
........bar()
In A, it is far clearer that the last two lines are part of foo. This is even more useful at higher indentation levels.
That empty line belongs to foo(), so I would consider A to be the most natural. But I guess it's just a matter of opinion.
TextMate breaks block collapsing if you use B, and I prefer A anyway since it's more "logical".
My experience in open-source development is that one should never leave whitespace inside blank lines. Also one should never leave trailing white-space.
It's a matter of coding etiquette.
I wouldn't necessarily call the first example "broken", because I know some people hate it when the cursor "jumps back" when moving the cursor up or down in code. E.g. Visual Studio (at least 2008) automatically prevents this from happening without using any whitespace characters on those lines.
B is preferred - i.e. no indentation. PEP 8 says:
Avoid trailing whitespace anywhere. Because it's usually invisible, it can be confusing: e.g. a backslash followed by a space and a newline does not count as a line continuation marker. Some editors don't preserve it and many projects (like CPython itself) have pre-commit hooks that reject it.
Emacs does B) for me, but I really don't think it matters. A) means that you can add in a line at the correct indentation without any tabbing.
vi implicitly discourages the behaviour in A because the {/} navigations no longer work as expected. git explicitly discourages it by highlighting it in red when you run git diff. I would also argue that if a line contains spaces it is not a blank line.
For that reason I strongly prefer B. There is nothing worse than expecting to skip six or so lines up with the { motion and ending up at the top of a class def.
I was reading that Python does all it's "code blocks" by indentation, rather than with curly braces. Is that right? So functions, if's and stuff like that all appear without surrounding their block with curly braces?
You can try to add support for braces using a future import statement, but it's not yet supported, so you'll get a syntax error:
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Correct for code blocks. However, you do define dictionaries in Python using curly braces:
a_dict = {
'key': 'value',
}
Ahhhhhh.
Yes. Curly braces are not used. Instead, you use the : symbol to introduce new blocks, like so:
if True:
do_something()
something_else()
else:
something()
Python with Braces is a variant of python that lets you do exactly that.
It's a project that I've been working on lately together with my friend.
Use Whyton:
http://writeonly.wordpress.com/2010/04/01/whython-python-for-people-who-hate-whitespace/
Yup :)
And there's (usually) a difference between 4 spaces and a tab, so make sure you standardize the usage ..
Yes.
if True:
#dosomething
else:
#dosomething else
#continue on with whatever you were doing
Basically, wherever you would've had an opening curly brace, use a colon instead. Unindent to close the region. It doesn't take long for it to feel completely natural.
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Well that explains a lot.
Note however, that Python does natively support curly brace-d code blocks! Take a look at below:
if x: #{
x += 1
#}
For Ada or Pascal programmers, I take delight in revealing to you:
if x: #BEGIN
...
#END
Taken from the docs:
Python's parser is also sophisticated enough to recognize mixed
notations, and it will even catch missing beginning or end
delimiters and correct the program for the user. This allows the
following to be recognized as legal Python:
if x: #BEGIN
x = x + 1
#}
And this, for Bash users:
if x:
x=99
#fi
Even better, for programmers familiar with C, C++, etc. you can omit the curly braces completely for only one statement:
if x:
do_stuff()
Beautiful. As mentioned before, Python can also automatically correct code with incorrect delimiters, so this code is also legal:
if x:
do_a_hundred_or_more_statements()
x = x + 1
print(x)
As this must make you love Python even more, I send you off with one last quote from the docs.
Now as you can see from this series of examples, Python has
advanced the state of the art of parser technology and code
recognition capabilities well beyond that of the legacy languages.
It has done this in a manner which carefully balances good coding
style with the need for older programmers to feel comfortable with
look of the language syntax.
The only limitation is that these special delimiters be preceded by a hashtag symbol.
Python does not use curly braces for code blocks:
>>> while True {
File "<stdin>", line 1
while True {
^
SyntaxError: invalid syntax
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
(Notice the "not a chance" message – this is an Easter egg reflecting this design decision.)
As a language designed to be easy to use and read, Python uses colons and indentation to designate code blocks. Defining code blocks by indentation is unusual and can come as a surprise to programmers who are used to languages like C++ and C# because these (and many other languages) don't care about extra whitespace or indentation. This rule is intended to increase readability of Python code, at the cost of some of the programmer's freedom to use varying amounts of whitespace.
An increase in the indentation level indicates the start of a code block, while a decrease indicates the end of the code block. By convention, each indentation is four spaces wide.
Here's a simple example which sums all the integers from 0 to 9. Note that ranges in Python include the first value, up to but not including the last value:
j = 0
for i in range(0, 10):
j += i
print(j)
Yes you can use this library/package { Py }
Use curly braces instead of indenting, plus much more sugar added to Python's syntax.
https://pypi.org/project/brackets/
// Use braces in Python!
def fib(n) {
a, b = 0, 1
while (a < n) {
print(a, end=' ')
a, b = b, a+b
}
print()
}
/*
Powerful anonymous functions
*/
print([def(x) {
if(x in [0, 1]) {
return x
};
while (x < 100) {
x = x ** 2
};
return x
}(x) for x in range(0, 10)])
As others have mentioned, you are correct, no curly braces in Python. Also, you do not have no end or endif or endfor or anything like that (as in pascal or ruby). All code blocks are indentation based.
Yes, code blocks in Python are defined by their indentation. The creators of Python were very interested in self-documenting code. They included indentation in the syntax as a way of innately enforcing good formatting practice.
I programmed in Python for a few years and became quite fond of its code structure because it really is easier. Have you ever left out a closing curly brace in a large program and spent hours trying to find it? Not a problem in Python. When I left that job and had to start using PHP, I really missed the Python syntax.
I will give some thoughts about this question.
Admittedly at first I also thought it is strange to write code without curly braces. But after using Python for many years, I think it is a good design.
First, do we really need curly braces? I mean, as a human. If you are allowed to use curly braces in Python, won't you use indentation anymore? Of course, you will still use indentation! Because you want to write readable code, and indentation is one of the key points.
Second, when do we really need curly braces? As far as I think, we only strictly need curly braces when we need to minify our source code files. Like minified js files. But will you use Python in a situation that even the size of source code is sensitive? Also as far as I think, you won't.
So finally, I think curly braces are somehow like ;. It is just a historical issue, with or without it, we will always use indentation in Python.
In Python, four spaces() are used for indentation in place of curly braces ({). Though, curly braces are used at few places in Python which serve different purpose:
Initialize a non-empty set (unordered collection of unique elements):
fuitBasket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
Citation
Initialize an empty dictionary (key-value pairs):
telephoneNumbers = {}
Initialize a non-empty dictionary (key-value pairs):
telephoneNumbers = {'jack': 4098, 'sape': 4139}
Citation
In relation to format string, curly braces take on a different meaning. See https://docs.python.org/3/library/string.html?highlight=curly :
Format strings contain “replacement fields” surrounded by curly braces
{}. Anything that is not contained in braces is considered literal
text, which is copied unchanged to the output. If you need to include
a brace character in the literal text, it can be escaped by doubling:
{{ and }}.