Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WANT: bad code in python (for refactoring example)

298 views
Skip to first unread message

Makoto Kuwata

unread,
Feb 14, 2017, 5:44:24 PM2/14/17
to
Hi,

Is there any *just right* python code to refactor?
In other words, I'm finding bad code example in python.

(background)
I'm teaching Python to some novice programmer, and
want to show refactoring example to them.

(required)
* not good code
* not too large (for novice programmer)
* not too complex (for novice programmer)
* released under open source license

If you know good material in github or bitbucket to refactor,
let me know it.

--
regards,
kwatch

Irmen de Jong

unread,
Feb 14, 2017, 6:13:03 PM2/14/17
to
No code in text form, but I find the following video by Raymond Hettinger very clear
about the values of refactoring otherwise seemingly fine code

https://youtu.be/wf-BqAjZb8M?t=12m39s

code starts at 12 min. 40 sec.

It does require a bit of background knowledge about Python and the PEP8 code style and
API design.

Irmen

Steven D'Aprano

unread,
Feb 15, 2017, 1:28:59 AM2/15/17
to
On Wed, 15 Feb 2017 07:44:03 +0900, Makoto Kuwata wrote:

> Hi,
>
> Is there any *just right* python code to refactor?
> In other words, I'm finding bad code example in python.


Try looking at the ActiveState website for recipes in Python. Especially
look at the ones with negative ratings, but even positively rated recipes
are often nonsense.

E.g. http://code.activestate.com/recipes/580750

does nothing more that define

echo = sys.stdout.write

Why not use sys.stdout.write directly? Or print? If I saw somebody using
this recipe in production code, in the way shown, I'd refactor it to just
use print. There's no advantage to re-inventing the wheel this way.



--
Steve

Makoto Kuwata

unread,
Feb 15, 2017, 4:36:30 AM2/15/17
to
Thanks Irmen and Steven,

I'm sorry that my explanation is not enough.
I'm looking for bad python code, not refactoring examples.
I can do (and want to do) refactor bad code by myself.

Is there any bad python code (or project) with proper size?

# I found a lot of bad PHP code in github, but didn't find bad Python code.

--
regards,
makoto kuwata


On Wed, Feb 15, 2017 at 3:28 PM, Steven D'Aprano <st...@pearwood.info>
wrote:
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Antoon Pardon

unread,
Feb 15, 2017, 5:52:55 AM2/15/17
to
Op 15-02-17 om 07:28 schreef Steven D'Aprano:
On reason to use this is for some easy "logging", you use echo to help
in debugging and afterwards you can either define echo as an empty
function or something easy to find to comment out.

--
Antoon Pardon.

David Palao

unread,
Feb 15, 2017, 5:53:54 AM2/15/17
to
2017-02-15 10:36 GMT+01:00 Makoto Kuwata <k...@kuwata-lab.com>:
> Thanks Irmen and Steven,
>
> I'm sorry that my explanation is not enough.
> I'm looking for bad python code, not refactoring examples.
> I can do (and want to do) refactor bad code by myself.
>
> Is there any bad python code (or project) with proper size?
>
> # I found a lot of bad PHP code in github, but didn't find bad Python code.
>
> --
> regards,
> makoto kuwata
>
>
> On Wed, Feb 15, 2017 at 3:28 PM, Steven D'Aprano <st...@pearwood.info>
> wrote:
>
>> --
>> https://mail.python.org/mailman/listinfo/python-list
>>
> --
> https://mail.python.org/mailman/listinfo/python-list

Hello,
IMHO most code can be refactored.
Forme the point is how you want to teach it and what you want to teach
exactly. For instance, if you are following a tdd approach, then the
project you choose, should better come with that in mind.
If you are not considering tests, for whatever reason, I guess any
simple enough project would be good. Of course, it depends on the
details of what you want to teach.

BTW, at work I have been told to organize a course about testing and
good programming practices with Python. I was thinking in developing
an example by myself...
Best

David

Steve D'Aprano

unread,
Feb 15, 2017, 7:25:23 AM2/15/17
to
On Wed, 15 Feb 2017 09:49 pm, Antoon Pardon wrote:

> Op 15-02-17 om 07:28 schreef Steven D'Aprano:
[...]
>> Why not use sys.stdout.write directly? Or print? If I saw somebody using
>> this recipe in production code, in the way shown, I'd refactor it to just
>> use print. There's no advantage to re-inventing the wheel this way.
>
> On reason to use this is for some easy "logging", you use echo to help
> in debugging and afterwards you can either define echo as an empty
> function or something easy to find to comment out.

In Python 3 you can always add

def print(*args, **kw):
pass

in your module to disable printing. But a better way, in my opinion, is to
use your editor to search for:

print(

and replace with:

#print(



But even better, once you get to the point of putting print calls in more
than two or three places in your code, you should probably invest the time
to learn how to use the logging module.




--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

Antoon Pardon

unread,
Feb 15, 2017, 8:39:05 AM2/15/17
to
Op 15-02-17 om 13:24 schreef Steve D'Aprano:
> On Wed, 15 Feb 2017 09:49 pm, Antoon Pardon wrote:
>
>> Op 15-02-17 om 07:28 schreef Steven D'Aprano:
> [...]
>>> Why not use sys.stdout.write directly? Or print? If I saw somebody using
>>> this recipe in production code, in the way shown, I'd refactor it to just
>>> use print. There's no advantage to re-inventing the wheel this way.
>> On reason to use this is for some easy "logging", you use echo to help
>> in debugging and afterwards you can either define echo as an empty
>> function or something easy to find to comment out.
> In Python 3 you can always add
>
> def print(*args, **kw):
> pass
>
> in your module to disable printing. But a better way, in my opinion, is to
> use your editor to search for:
>
> print(
>
> and replace with:
>
> #print(

You don't seem to understand, I don't want to disable all printing, only the
diagnostics. That is easier to do if I use a different name for printing
diagnostics than for regular I/O. Whether I disable it by defining an empty
function or by commenting them out, doesn't really matter with this regard.

> But even better, once you get to the point of putting print calls in more
> than two or three places in your code, you should probably invest the time
> to learn how to use the logging module.

I know how to use the logging module. It is my experience that for a lot
of rather small projects, the hassle of setting it up, is not worth it.
YMMV.

--
Antoon Pardon

Chris Angelico

unread,
Feb 15, 2017, 1:51:28 PM2/15/17
to
On Thu, Feb 16, 2017 at 12:37 AM, Antoon Pardon
<antoon...@rece.vub.ac.be> wrote:
>> But a better way, in my opinion, is to
>> use your editor to search for:
>>
>> print(
>>
>> and replace with:
>>
>> #print(
>
> You don't seem to understand, I don't want to disable all printing, only the
> diagnostics. That is easier to do if I use a different name for printing
> diagnostics than for regular I/O. Whether I disable it by defining an empty
> function or by commenting them out, doesn't really matter with this regard.
>
>> But even better, once you get to the point of putting print calls in more
>> than two or three places in your code, you should probably invest the time
>> to learn how to use the logging module.
>
> I know how to use the logging module. It is my experience that for a lot
> of rather small projects, the hassle of setting it up, is not worth it.
> YMMV.

Once you get to the point of saying either "but #print( might comment
out only the first line, so I can't wrap it" or "but #print( would
comment out too much, I only want to toggle some of the statements",
it's time to set up logging. Also, if you're building a daemon that
should play nicely with a larger system (eg a system process on
Unix/Linux), the logging module makes that work a lot easier, since
you can easily redirect it to a file or whatever you want.

ChrisA

jlad...@itu.edu

unread,
Feb 15, 2017, 2:18:13 PM2/15/17
to
On Wednesday, February 15, 2017 at 2:52:55 AM UTC-8, Antoon Pardon wrote:
> Op 15-02-17 om 07:28 schreef Steven D'Aprano:

> > E.g. http://code.activestate.com/recipes/580750
> >
> > does nothing more that define
> >
> > echo = sys.stdout.write
> >
> > Why not use sys.stdout.write directly? Or print? If I saw somebody using
> > this recipe in production code, in the way shown, I'd refactor it to just
> > use print. There's no advantage to re-inventing the wheel this way.
>
> On reason to use this is for some easy "logging", you use echo to help
> in debugging and afterwards you can either define echo as an empty
> function or something easy to find to comment out.
>
> --
> Antoon Pardon.

Agreed, I have done things like this myself, but within functions, not at the global level. The "echo" name could be assigned to some other function elsewhere in the code. I use the name reassignment to direct the function's logging information -- to a console, to a GUI, or to "/dev/null" by creating an empty function.

Dotan Cohen

unread,
Feb 15, 2017, 4:35:28 PM2/15/17
to
I think that we can help each other! This is my own code, back when I
was writing Python like PHP:
https://github.com/dotancohen/burton

It is badly in need of a Pythonic refactor! Have at it, and I'll be
happy to accept any pull requests.

On Wed, Feb 15, 2017 at 12:44 AM, Makoto Kuwata <k...@kuwata-lab.com> wrote:
> Hi,
>
> Is there any *just right* python code to refactor?
> In other words, I'm finding bad code example in python.
>
> (background)
> I'm teaching Python to some novice programmer, and
> want to show refactoring example to them.
>
> (required)
> * not good code
> * not too large (for novice programmer)
> * not too complex (for novice programmer)
> * released under open source license
>
> If you know good material in github or bitbucket to refactor,
> let me know it.
>
> --
> regards,
> kwatch
> --
> https://mail.python.org/mailman/listinfo/python-list



--
Dotan Cohen

http://gibberish.co.il
http://what-is-what.com

Erik

unread,
Feb 15, 2017, 4:53:54 PM2/15/17
to
Hi,

On 15/02/17 09:36, Makoto Kuwata wrote:
> I'm sorry that my explanation is not enough.
> I'm looking for bad python code, not refactoring examples.

I think you need to explain what you mean by "bad". Do you mean
something like:

i = 0
data = ["bad", "example", "of", "python", "code"]
while i < len(data):
process(data[i])
i = i + 1

... which could be better expressed as:

data = ["good", "example", "of", "python", "code"]
for d in data:
process(data)

?

If so, then you're asking for "unpythonic" code examples (code that is
written in the style of a different language that doesn't have some of
Python's syntactic sugar and underlying mechanisms).

I suspect that you can find many short examples like the above on sites
like StackOverflow, but finding a substantial code-base example (which
is what I think you mean by "proper size") is unlikely, as anyone
writing a large project in Python is almost certainly going to have
learned and adopted the "pythonic" idioms long before their project
became as large as you appear to be asking for.

If you _don't_ mean what I suggested above, please explain further
(Python code examples of what you think is "bad" vs "good" would be useful).

E.

Erik

unread,
Feb 15, 2017, 5:05:34 PM2/15/17
to
On 15/02/17 21:53, Erik wrote:
> process(data)

Before I get jumped on by a pack of rabid wolves, I of course meant:

process(d)

E.

Paul Rubin

unread,
Feb 15, 2017, 10:09:09 PM2/15/17
to
Antoon Pardon <antoon...@rece.vub.ac.be> writes:
> On reason to use this is for some easy "logging"

I think it's better to use the actual logging module. I generally start
a new program with print statements but convert them to logging after
there's enough code to want to be more organized about it.

alister

unread,
Feb 16, 2017, 4:43:40 AM2/16/17
to
my default python template file includes basic logging setup from the
start
(all 3 lines of it )



--
"...if the church put in half the time on covetousness that it does on
lust,
this would be a better world." - Garrison Keillor, "Lake Wobegon Days"

Cecil Westerhof

unread,
Feb 16, 2017, 6:14:12 AM2/16/17
to
On Thursday 16 Feb 2017 10:43 CET, alister wrote:

> On Wed, 15 Feb 2017 19:08:59 -0800, Paul Rubin wrote:
>
>> Antoon Pardon <antoon...@rece.vub.ac.be> writes:
>>> On reason to use this is for some easy "logging"
>>
>> I think it's better to use the actual logging module. I generally
>> start a new program with print statements but convert them to
>> logging after there's enough code to want to be more organized
>> about it.
>
> my default python template file includes basic logging setup from
> the start (all 3 lines of it )

You should have shared your template, or at least those three lines.
:-P

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

alister

unread,
Feb 16, 2017, 9:18:28 AM2/16/17
to
On Thu, 16 Feb 2017 12:00:36 +0100, Cecil Westerhof wrote:

> On Thursday 16 Feb 2017 10:43 CET, alister wrote:
>
>> On Wed, 15 Feb 2017 19:08:59 -0800, Paul Rubin wrote:
>>
>>> Antoon Pardon <antoon...@rece.vub.ac.be> writes:
>>>> On reason to use this is for some easy "logging"
>>>
>>> I think it's better to use the actual logging module. I generally
>>> start a new program with print statements but convert them to logging
>>> after there's enough code to want to be more organized about it.
>>
>> my default python template file includes basic logging setup from the
>> start (all 3 lines of it )
>
> You should have shared your template, or at least those three lines.
> :-P

import logging
logger=logging.getLogger()
logging.basicConfig(level=logging.DEBUG)

now simply add logger.debug('debug message')
wherever needed instead of print statements

alternatively
import logging
logger=logging.getLogger()
logging.basicConfig(filename='logfile',level=logging.DEBUG)

if you would prefer to log to a file instead.

simples :-)



--
A New Way of Taking Pills
A physician one night in Wisconsin being disturbed by a burglar,
and
having no ball or shot for his pistol, noiselessly loaded the weapon with
small, hard pills, and gave the intruder a "prescription" which he thinks
will go far towards curing the rascal of a very bad ailment.
-- Nevada Morning Transcript, January 30, 1861

Makoto Kuwata

unread,
Feb 16, 2017, 9:03:47 PM2/16/17
to
Thanks Erik,


On Thu, Feb 16, 2017 at 6:53 AM, Erik <pyt...@lucidity.plus.com> wrote:

> (which is what I think you mean by "proper size")
>

As I explained at my first post, I'm teaching Python to novice programmers.
Therefore refactoring example code should be in the size what they can
understand.
It is hard for them to read and understand over than thousand lines of code.

Almost of all projects have code over than thousand lines of code,
but it is possible to quote a part of them for refactoring example, I think.



>
> (Python code examples of what you think is "bad" vs "good" would be
> useful).
>

You are right.

Bad code Example:

#
https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming

from random import random

def move_cars(car_positions):
return map(lambda x: x + 1 if random() > 0.3 else x,
car_positions)

def output_car(car_position):
return '-' * car_position

def run_step_of_race(state):
return {'time': state['time'] - 1,
'car_positions': move_cars(state['car_positions'])}

def draw(state):
print ''
print '\n'.join(map(output_car, state['car_positions']))

def race(state):
draw(state)
if state['time']:
race(run_step_of_race(state))

race({'time': 5,
'car_positions': [1, 1, 1]})


Refactoring example:

from random import random

class Car(object):

def __init__(self):
self.position = 1

def move(self):
if random() > 0.3:
self.position += 1
return self.position

class Race(object):

def __init__(self, n_cars=3):
self._cars = [ Car() for _ in range(n_cars) ]

def round(self):
for car in self._cars:
car.move()

def report(self):
print("")
for car in self._cars:
print('-' * car.position)

def run(self, n_rounds=5):
self.report()
for _ in range(n_rounds):
self.round()
self.report()

if __name__ == '__main__':
Race(3).run(5)


--
regards,
makoto kuwata

Jussi Piitulainen

unread,
Feb 17, 2017, 4:07:30 AM2/17/17
to
Here's a rewrite in functional style, which I consider somewhat better
than the original:

from random import random

def move(positions):
return [ pos + bool(random() > 0.3) for pos in positions ]

def race(positions, steps):
for step in range(steps):
positions = move(positions)
yield positions

def draw(positions):
print(*('-' * pos for pos in positions), sep = '\n')

if __name__ == '__main__':
for step, positions in enumerate(race([1,1,1], 5)):
step and print()
draw(positions)

I did a number of things, but mainly I reconceptualized the race itself
explicitly as a sequence of positions. While a Python generator is an
extremely stateful object, with some care it works well in functional
style.
If you want to refactor bad code into better code, it would be more
honest to start with code that is already in your preferred style. That
would be a good lesson.

Now you've taken questionable code in a somewhat functional style and
refactored it into object-oriented style. But you don't call them that.
You call them bad code and good code. That's a bad lesson. It conflates
issues.

Take good functional code, refactor it into your preferred style. Also
do the reverse. That would be a good lesson, assuming your students are
ready for such discussion.

Makoto Kuwata

unread,
Feb 17, 2017, 8:48:30 AM2/17/17
to
On Thu, Feb 16, 2017 at 6:34 AM, Dotan Cohen <dotan...@gmail.com> wrote:

> I think that we can help each other! This is my own code, back when I
> was writing Python like PHP:
> https://github.com/dotancohen/burton


Year, this is a good example code for me to do refactoring.

I created a pull request. This will be shown to my students.

https://github.com/dotancohen/burton/pull/20/files

I hope you favor this PR.

--
regards,
makoto kuwata

Dotan Cohen

unread,
Feb 19, 2017, 2:44:14 PM2/19/17
to
There are some nice changes in here. You can mention to the students
that I really appreciated the work done on the menu loop. You took an
example of code that had grown piecemeal and become reasonably
unmaintainable, and refactored it to be very maintainable in the
future.

Good luck to all class participants!
0 new messages