LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-15-2020, 10:38 AM   #1
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Rep: Reputation: 51
Question 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?
 
Old 01-15-2020, 11:17 AM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
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.

Last edited by dugan; 01-15-2020 at 11:23 AM.
 
1 members found this post helpful.
Old 01-15-2020, 11:19 AM   #3
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,596

Rep: Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545
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 )
 
1 members found this post helpful.
Old 01-15-2020, 11:31 AM   #4
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 4,138

Rep: Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263Reputation: 1263
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
 
Old 01-15-2020, 12:15 PM   #5
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
The way he's calling print is compatible with both.
 
Old 01-15-2020, 12:28 PM   #6
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by boughtonp View Post
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)

Last edited by dedec0; 01-15-2020 at 12:30 PM.
 
Old 01-15-2020, 12:38 PM   #7
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
Quote:
Originally Posted by dedec0 View Post
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.
 
Old 01-15-2020, 12:43 PM   #8
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by dugan View Post
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 (:
 
Old 01-15-2020, 12:50 PM   #9
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
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.
 
Old 01-15-2020, 02:21 PM   #10
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by dugan View Post
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?)
 
Old 01-15-2020, 02:32 PM   #11
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Talking

Quote:
Originally Posted by SoftSprocket View Post
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.

Last edited by dedec0; 01-15-2020 at 02:37 PM.
 
Old 01-15-2020, 04:31 PM   #12
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
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

Last edited by dugan; 01-15-2020 at 04:36 PM.
 
Old 01-15-2020, 04:37 PM   #13
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
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/

Last edited by dugan; 01-15-2020 at 04:38 PM.
 
2 members found this post helpful.
Old 01-15-2020, 05:06 PM   #14
Geist
Member
 
Registered: Jul 2013
Distribution: Slackware 14 / current
Posts: 442

Rep: Reputation: 196Reputation: 196
:retab

Will convert all tabs/spaces to the flavor you are using, it unmixes the mixup.
 
2 members found this post helpful.
Old 01-15-2020, 05:24 PM   #15
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,723

Rep: Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211
Quote:
Originally Posted by SoftSprocket View Post
I always disliked the use of indentation for block demarcation.
Quote:
Originally Posted by dedec0 View Post
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!
 
1 members found this post helpful.
  


Reply

Tags
python, python2, python3, vim


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] standard output changes in python3 versus python2 sharky Programming 5 10-16-2018 04:30 PM
[SOLVED] Python2 to Python3 - Print function has changed - How to make it work? rrrssssss Programming 5 02-05-2015 02:11 PM
[SOLVED] How can I make Python2.7 my default Python without deleting/removing python2.6. steves504 Linux - Server 2 03-21-2014 11:57 AM
[SOLVED] Trying to install 'Gmail Backup' but it requires python2.5 - I have python2.8... Robert.Thompson Slackware 6 05-10-2011 08:23 AM
Python2.5-devel is unable to find installed Python2.5 Setya SUSE / openSUSE 1 06-08-2007 01:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration