[Tutor] Use functions re avoid Re: Can the following algorithm be improved?

Nathan Pinno falcon3166 at hotmail.com
Mon Aug 8 04:10:19 CEST 2005


My message is in the attachment.
---------------------------------------------------------------
I wanted help, and you criticized me,
I wanted aid, and you refused,
So I will do it myself!
--Author unknown
-------------------------------------------------------------------
----- Original Message ----- 
From: "Danny Yoo" <dyoo at hkn.eecs.berkeley.edu>
To: "Nathan Pinno" <falcon3166 at hotmail.com>
Cc: "Tutor mailing list" <tutor at python.org>
Sent: Sunday, August 07, 2005 7:30 PM
Subject: Use functions re avoid Re: [Tutor] Can the following algorithm be 
improved?


>
> Answer: yes, very much so.  *grin*
>
>
> Ok, let's take a look at some snippets.
>
> ######
>    cd = int(raw_input("How many cards to deal (1-6) or 9 to exit:"))
>    if cd == 1:
>        a = random.choice(range(52))
>        if a == 0:
>            a = "Ace of Hearts"
>        elif a == 1:
>            a = "Two of Hearts"
> [... code cut]
>    elif cd == 2:
>        b = random.choice(range(52))
>        c = random.choice(range(52))
>        for item in [b,c]:
>            if item == 0:
>                item = "Ace of Hearts"
>            elif item == 1:
>                item = "Two of Hearts"
> [... code cut]
>    elif cd == 3:
>        d = random.choice(range(52))
>        e = random.choice(range(52))
>        f = random.choice(range(52))
>        for item in (d,e,f):
>            if item == 0:
>                item = "Ace of Hearts"
>            elif item == 1:
>                item = "Two of Hearts"
> ######
>
> Ok, let's stop there.
>
> The block of code above is taking a number (0-52) and trying to transform
> it into a readable definition.  But there is repetition here that can be
> improved if you take advantage of the problem's structure.
>
>
> If you can write a function that takes a number from 0 to 52, and turns it
> into a card name, then instead of having to repeat the same if/elif code
> the number of times that you're dealing a card, you can save a lot of
> typing.  You'll only need maybe eighty lines of code, instead of six
> hundred.
>
> (Actually, if you take advantage of the essence of the program, the
> program can be reduced to about ten lines total.  That's the general
> direction that we'll try to lead you towards.  Short programs are much
> nicer than long ones.)
>
>
>
> To make it clear what we mean, here's a similar situation: let's say that
> we wanted to flip two coins and get back a nice description of what we
> got.  We could write code like this:
>
> ######
> first_flip = random.choice(range(2))
> second_flip = random.choice(range(2))
>
> if first_flip == 0 and second_flip == 0:
>    print "heads", "heads"
> elif first_flip == 0 and second_flip == 1:
>    print "heads", "tails"
> elif first_flip == 1 and second_flip == 0:
>    print "tails", "heads"
> elif first_flip == 1 and second_flip == 1:
>    print "tails", "tails"
> #######
>
>
> But there is a much nicer way of writing this:
>
> ######
> def number_to_coin(n):
>    if n == 0:
>        return "heads"
>    else:
>        return "tails"
>
> first_flip = random.choice(range(2))
> second_flip = random.choice(range(2))
> print number_to_coin(first_flip), number_to_coin(second_flip)
> ######
>
>
> There is a concrete reason why the second version is better: it scales if
> we want to use more coins.  Once we have number_to_coin(), we can easily
> handle three coins:
>
> ######
> first_flip = random.choice(range(2))
> second_flip = random.choice(range(2))
> third_flip = random.choice(range(2))
> print number_to_coin(first_flip), number_to_coin(second_flip),
> print number_to_coin(third_flip)
> ######
>
> The original approach, on the other hand, simply won't scale at all, and
> we'll end up with huge source code for very little gain.
>
>
> Avoiding code duplication is one major reason that we use functions.  As
> soon as you start cutting and pasting code, that's a honking red warning
> light that you should be writing functions.  But it takes practice, which
> is what we're pointing out to you now.  *grin*
>
>
> Try rewriting your program so you don't copy-and-paste those huge if/elif
> blocks on each card flip.
>
> That is, write a function number_to_card() that takes a number from 0 to
> 52 and returns the string description of that card.  Your program will be
> much more managable, and will probably fit on a single screen.
>
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: message2.zip
Type: application/x-zip-compressed
Size: 817 bytes
Desc: not available
Url : http://mail.python.org/pipermail/tutor/attachments/20050807/054f2b05/message2.bin


More information about the Tutor mailing list