[Tutor] How inefficient is this code?

Joe Cortes escozzia at gmail.com
Thu May 8 04:03:28 CEST 2014


> I see. Thanks that is exactly what I was looking for. Would your
> example be an instance of an object-oriented approach,
> compartmentalizing things into functions?

That's an interesting question.

It's an example of abstraction, which is one of the pillars of object
oriented design. You're abstracting the principle of calculating the
fibonacci numbers, into the function fib, and separating it from the
concrete use cases for the numbers themselves.

This is probably the pattern you're detecting here and associating
with OOP: you take a self-contained piece of functionality and throw
it somewhere where its logic can be used in an abstract manner.

Now, there are more pillars to object oriented design: encapsulation,
inheritance, and polymorphism, and this example demonstrates neither.
For example, it doesn't really feature polymorphism: the fib function
is very concrete, and has really only one "form", namely the one
you're seeing.

So, while these generator functions introduce a pretty neat
possibility for abstraction, namely abstracting out the concept of
iteration and separating from what happens during iteration, I'm not
really sure you can call it OOP.

Perhaps it depends on the way you look at it. A more complex generator
(maybe implemented as an object) might, for example, be polymorphic in
nature. These design questions can often blur, so I'm not sure how
better to answer your question, maybe someone can chime in.

On Wed, May 7, 2014 at 8:39 PM, C Smith <illusiontechniques at gmail.com> wrote:

> On Wed, May 7, 2014 at 7:55 PM, Joe Cortes <escozzia at gmail.com> wrote:
>> Welcome to the wonderful world of generators!
>>
>> Looking at your code, you'll notice two things. First, you're
>> iterating over all the numbers twice: once to calculate them, and then
>> another time to actually do the sum. What's worse, at any given point
>> in time, you're only really using fibs[-1] and fibs[-2], and yet
>> you're still building this huge list with all the numbers. This is bad
>> in terms of memory efficiency. Luckily, it's such a common problem
>> that Python offers a really nice, really Pythonic solution. You can
>> define the following function:
>>
>> def fib(top):
>>     first = 1 # As an aside, consider starting the sequence from 0, 1.
>>     next = 2
>>     yield first
>>     while next < top:
>>          yield next
>>          # For kicks, try rewriting the following three lines as a
>> tuple assignment.
>>          new_next = next + first
>>          first = next
>>          next = new_next
>>
>> Now, how do you use this? This being Python, there is a super simple
>> way to do this:
>>
>> sum = 0
>> for num in fib(4000000):
>>      if num % 2 == 0:
>>             sum += num
>> print sum
>>
>>
>> So, what's going on here? fib is mostly straightforward, but that
>> yield keyword might look new.
>> Here's the deal: when you have a function that uses the yield keyword,
>> that function becomes usable in the context of a for loop. Every time
>> it hits a yield it will, well, yield that value out to the for loop.
>> At the end of an iteration, control will be handed back to the
>> function, which will do its magic, and yield another value. Again, the
>> value will be sent out to the for loop, in this case as the "num"
>> variable, for use in that iteration.
>> When the function hits a return (or reaches the end of its body), the
>> for loop ends.
>>
>> This is called a generator function, and is a really nice way to
>> simplify and optimize your loops.
>>
>> You can read more about generators here: https://wiki.python.org/moin/Generators
>>
>>
>> On Wed, May 7, 2014 at 7:27 PM, C Smith <illusiontechniques at gmail.com> wrote:
>>> A topic came up on slashdot concerning "intermediate" programming,
>>> where the poster expressed the feeling that the easy stuff is too easy
>>> and the hard stuff is too hard.
>>>
>>> Someone did point out that 'intermediate' programming would still
>>> involve actually selling code or at least some professional
>>> experience, so this would probably fall into the category of 'novice'.
>>>
>>> I feel similarly right now and the cs 101 classes from udacity or
>>> coursera or the opencourseware stuff are very easy and boring. I tried
>>> the class "design of computer programs" on udacity and made it about
>>> halfway before being overwhelmed. The class involved making an api for
>>> a regex-like function to parse text (if I am communicating that
>>> correctly, it was sort of rewriting regex functionality in Python
>>> terms), and it seemed to go over a very definite cliff in terms of
>>> difficulty. Could someone provide a concise example of decorator use?
>>>
>>> Someone suggested projecteuler.net and I started blazing through
>>> things I had done before, when I realized this would be a good time to
>>> start more efficient practices instead of code that just happens to
>>> work and may be very inefficient.
>>>
>>> #sum all even fib seq integers under 4 million
>>> fibs = [1,2]
>>> sum = 0
>>> while fibs[-1] < 4000000:
>>>     nexty = fibs[-1] + fibs[-2]
>>>     fibs.append(nexty)
>>>
>>> for xer in fibs:
>>>     if xer%2 == 0:
>>>         sum += xer
>>> print sum
>>>
>>> This gets the correct solution, but what would be ways to improve
>>> speed or use more complicated parts of Python to do the same thing.
>>> Thanks in advance
>>> _______________________________________________
>>> Tutor maillist  -  Tutor at python.org
>>> To unsubscribe or change subscription options:
>>> https://mail.python.org/mailman/listinfo/tutor


More information about the Tutor mailing list