[SOLVED] Why this simplest code is fine with python2 but is wrong with python3?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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 )
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?
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.
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!
I always disliked the use of indentation for block demarcation.
Quote:
Originally Posted by dedec0
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!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.