LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Why this simplest code is fine with python2 but is wrong with python3? (https://www.linuxquestions.org/questions/programming-9/why-this-simplest-code-is-fine-with-python2-but-is-wrong-with-python3-4175667768/)

dedec0 01-15-2020 10:38 AM

Why this simplest code is fine with python2 but is wrong with python3?
 
I do not know python.

I am doing a basic course that uses python, but it does not requires programming knowledge in it, or any other language - although they will help a lot. Basically, this means i skip a few things the course teaches. Anyway, it is giving me very basic examples of python code.

Right now, i am in this situation. First, i have a CSV data file:

Code:

Cidade, Estado
Mariana, MG
Betim, MG
Salvador, BA

Second, i have the source code:

Code:

#!/usr/bin/python
 
# Assign a variable name to a data file.
varReadFile = open('/dev/shm/data.csv')

# For each line in the file, read it
for varLine in varReadFile:
    if 'Betim' in varLine:
        # Each time a line is read,
        # print it to the screen
        print ( varLine )

The course is made for possible programming newbies, so they mostly do things to work in python 3.6 in a Win10 enrironment, but giving quick directions to the other options (like mine, in Debian). But i have even installed the IDLE Python thing, just to try it, since the course mentioned its friendlyness. First, i really hated its white bg theme... but that was fixable with something i searched around the web (just in its settings was not enough in easy or quick steps). But it still more awkward then my usual workplace of a terminal with a few tabs, source on one, compiler called in command line in other, and sometimes another tab with something else.

Anyway, i ended up finding that my usual "programming habits" are also possible with python, although the course did not mention it.

I did not have to install python 2 or 3 in my Debian 9. Both were already installed. 2.7 and 3.5 - and i did not feel a need to update that, since i have done it in very few weeks (maybe days) ago. I installed just the IDLE Python (for both python versions).

So, using the terminal with vim to edit the source (with my usual settings for indentation and everything else), and compiling with simple commands, i have this output, after saving the two files above in the same dir:

Code:

$ python2 code.py
Betim, MG

$ python3 code.py
  File "ex.03.py", line 11
    print ( varLine )
                    ^
TabError: inconsistent use of tabs and spaces in indentation

$ python3 code.py # After changing spaces in line 11 (...)
  File "ex.03.py", line 11
    print ( varLine )
                    ^
TabError: inconsistent use of tabs and spaces in indentation

$

I tried changing the spaces in lines 11 in a good number of ways, and none worked.

Please notice that the indentation i use with Vim is 4 spaces sized, but tabs are used to transform 8 consec. spaces into 1 tab.

Directly, the vim settings i edited *and copied* the source code given above, are:

Code:

set noexpandtab # this line is not even in my rc, and not anywhere else
set tabstop=8 # this line is not even in my rc, and not anywhere else
set softtabstop=4
set shiftwidth=4

all in my ~/.vimrc

What is wrong with me (probably) or python3?

dugan 01-15-2020 11:17 AM

In vim, you can use "set list" to see which parts are indented with tabs and which are indented with spaces.

Pick one of the two. Python stops you if you're inconsistent.

boughtonp 01-15-2020 11:19 AM

It's not the size of tabs, it's the mixing.

Your code has:
Code:

for varLine in varReadFile:
<sp><sp><sp><sp>if 'Betim' in varLine:
<tab># Each time a line is read,
<tab># print it to the screen
<tab>print ( varLine )

You can't do 4 spaces then 1 tab regardless of how wide your tabs are.

Pick either tabs or spaces and indent with your choice consistently.

i.e either:
Code:

for varLine in varReadFile:
<tab>if 'Betim' in varLine:
<tab><tab>print ( varLine )

or:
Code:

for varLine in varReadFile:
<sp><sp><sp><sp>if 'Betim' in varLine:
<sp><sp><sp><sp><sp><sp><sp><sp>print ( varLine )


smallpond 01-15-2020 11:31 AM

python3 is not intended to be perfectly compatible with python2. If you want to use python3 style printing, add:

Code:

from __future__ import print_function

dugan 01-15-2020 12:15 PM

The way he's calling print is compatible with both.

dedec0 01-15-2020 12:28 PM

Quote:

Originally Posted by boughtonp (Post 6078668)
It's not the size of tabs, it's the mixing.

Your code has:
Code:

for varLine in varReadFile:
<sp><sp><sp><sp>if 'Betim' in varLine:
<tab># Each time a line is read,
<tab># print it to the screen
<tab>print ( varLine )

You can't do 4 spaces then 1 tab regardless of how wide your tabs are.

So this is the problem, as i suspected. But python2 understands it, and accepts the config i set - which uses basically everything in default sizes, but sometimes using spaces to do a <half tab char> indent, to build shift widths of 4 spaces, as vim does. Id est:

Code:

# I may have
<tab>for varLine in varReadFile:
<tab><sp><sp><sp><sp>if 'Betim' in varLine:
<tab><tab># Each time a line is read,
<tab><tab># print it to the screen
<tab><tab>print ( varLine )

# But it will never happen indentation with 8 spaces, if a
# tab was used anywhere if 1+1 > 1:
<tab>for varLine in varReadFile:
<tab><sp><sp><sp><sp>if 'Betim' in varLine:
<tab><sp><sp><sp><sp><sp><sp><sp><sp># Each time a line is read,
<tab><sp><sp><sp><sp><sp><sp><sp><sp># print it to the screen
<tab><sp><sp><sp><sp><sp><sp><sp><sp>print ( varLine )

# Also, it will not happen to happen inconsistent uses of
# tabs and spaces, like
b was used anywhere
if 1+1 > 1:
<tab>for varLine in varReadFile:
<sp><sp><sp><sp><sp><sp><sp><sp><sp><sp><sp><sp>if 'Betim' in varLine:
<tab><sp><sp><sp><sp><sp><sp><sp><sp># Each time a line is read,
<tab><sp><sp><sp><sp><sp><sp><sp><sp># print it to the screen
<tab><sp><sp><sp><sp><sp><sp><sp><sp>print ( varLine )

But python 2.7, with the "special flavor of hex dump hint" file below, made with a copy of the code in #1 post, works as expected. Should not this be something to be taken to python 3 too, since it is something good (IMHO) python 2 has?

Code:

#!/usr/bin/python

#<sp>Assign<sp>a<sp>variable<sp>name<sp>to<sp>a<sp>data<sp>file.
varReadFile<sp>=<sp>open('/dev/shm/t/lixo/dados.csv')

#<sp>For<sp>each<sp>line<sp>in<sp>the<sp>file,<sp>read<sp>it
for<sp>varLine<sp>in<sp>varReadFile:
<sp><sp><sp><sp>
<sp><sp><sp><sp>if<sp>'Betim'<sp>in<sp>varLine:
<tab>#<sp>Each<sp>time<sp>a<sp>line<sp>is<sp>read,
<tab>#<sp>print<sp>it<sp>to<sp>the<sp>screen
<tab>print<sp>(varLine)


dugan 01-15-2020 12:38 PM

Quote:

Originally Posted by dedec0 (Post 6078692)
Should not this be something to be taken to python 3 too, since it is something good (IMHO) python 2 has?

No. Stop doing that.

Most Python 2 linters (like flake8) would have flagged it as something to be fixed.

dedec0 01-15-2020 12:43 PM

Quote:

Originally Posted by dugan (Post 6078665)
In vim, you can use "set list" to see which parts are indented with tabs and which are indented with spaces.

Pick one of the two. Python stops you if you're inconsistent.

Interesting command. I never heard about if before. Thank you (:

SoftSprocket 01-15-2020 12:50 PM

The problem with mixing tabs and space is that tabs are open to interpretation by an editor.

I always disliked the use of indentation for block demarcation.

dedec0 01-15-2020 02:21 PM

Quote:

Originally Posted by dugan (Post 6078695)
No. Stop doing that.

Most Python 2 linters (like flake8) would have flagged it as something to be fixed.

I am not sure i got all you thoughts about it, from the few pages with general searches for linters or for flake8. But seems fairly well.

Anyway, vim has enough features for that. I will use it in python files, starting today,

ts=4
sts=4
sw=4
et=no

Anything missing? (any common issue, even not related with indentation, which is the heart of this thread?)

dedec0 01-15-2020 02:32 PM

Quote:

Originally Posted by SoftSprocket (Post 6078698)
The problem with mixing tabs and space is that tabs are open to interpretation by an editor.

I always disliked the use of indentation for block demarcation.

All programming languages have comments. To avoid wrong interpretation of "colorful indentation settings" by other editors, vim has created a flexible comment to be added to the end of files, where such settings may be defined every time the file is opened by vim. The settings i described in #1 are much much compatible with practically all other editors, since they do not use non standard things (like a tab size that is not 8, which is something i learned to use in Vim help pages).

Now, with what i said in #10 with my tabs sized 4 instead of 8, my python sources *will* look different if opened in Windows' notepad.exe or in simpler linux editors like nano, pico, pluma or several others. But they will keep the indentation correct, for their programming block point of view.

I like the idea of blocks by indentation. I find it a graceful solution. (:

We may discuss the subject i bit more, if anyone wants. I will mark the thread as solved, though, since the problem is already found: python 3 does not accept indentation done with any kind of mix of tabs and spaces. It must be done with one of them, and only one in each whole file.

Thank all people who have helped me here, either with help comments or with other words on the subject.

dugan 01-15-2020 04:31 PM

Code:

et=no
No that's wrong. That would have you indenting with tabs. You're supposed to indent not with tabs, but with 4 spaces.

Save the following as ~/.vim/after/ftplugin/python.vim

Code:

setlocal tabstop=4 shiftwidth=4 expandtab

dugan 01-15-2020 04:37 PM

The official word, btw:

Quote:

Spaces are the preferred indentation method.
Quote:

Python 3 disallows mixing the use of tabs and spaces for indentation.

Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.

When invoking the Python 2 command line interpreter with the -t option, it issues warnings about code that illegally mixes tabs and spaces. When using -tt these warnings become errors. These options are highly recommended!
https://www.python.org/dev/peps/pep-0008/

Geist 01-15-2020 05:06 PM

:retab

Will convert all tabs/spaces to the flavor you are using, it unmixes the mixup.

scasey 01-15-2020 05:24 PM

Quote:

Originally Posted by SoftSprocket (Post 6078698)
I always disliked the use of indentation for block demarcation.

Quote:

Originally Posted by dedec0 (Post 6078740)
I like the idea of blocks by indentation. I find it a graceful solution. (:

I have always run screaming from the room when faced with a language where column positioning/indentation was part of the syntax. I changed jobs once when my employer was planning to migrate to IBM AS400 -- I don't recall the name of the language involved -- but commands had to start in specific columns to work.

Indentation for clarity in a free-form language, yes. Definitely. Indentation that done incorrectly causes syntax errors. Not!


All times are GMT -5. The time now is 12:19 PM.