开发者

Number Guesser: Please Review and Make it More Pythonic

I'm working on learning python, here is a simple program, I wrote:

def guesser(var, num1,possible):
    if var == 'n':
        cutoff = len(possible)/2
        possible = possible[0:cutoff]
        cutoff = possible[len(possible)/2]
        #print possible

        if (len(possible) == 1):
             print "Your开发者_开发技巧 Number is:", possible
        else:
            var = raw_input("Is Your Number Bigger Than %s? (y/n): " %cutoff)
            guesser(var, cutoff,possible)


    elif var == 'y':
        cutoff = len(possible)/2
        possible = possible[cutoff:len(possible)]
        cutoff = possible[len(possible)/2]
        #print possible
        #print cutoff

       if (len(possible) == 1):
           print "Your Number is:", possible
       else:
            var = raw_input("Is Your Number Bigger Than %s? (y/n): " %cutoff)
            guesser(var, cutoff,possible)


    else:
        var = raw_input("Is Your Number Bigger Than 50? (y/n): ")
        guesser(var, 50, possible)

possible = []
possible = range(1,101)

guesser('a', 50, possible)


Normally I would try to help with your code, but you have made it so way much too complicated that I think it would be easier for you to look at some code.

def guesser( bounds ):
    a, b = bounds
    mid = ( a + b ) // 2

    if a == b: return a

    if input( "over {0}? ".format( mid ) ) == "y":
        new_bounds = ( mid, b )
    else:
        new_bounds = ( a, mid )

    return guesser( new_bounds )

You should think about how your algorithm will work in abstract terms before diving in.

EDIT: Simplified the code at the expense of brevity.


Before doing it more pythonic I will probably make it more simple... the algorithm is much more complex than necessary. No need to use a list when two ints are enough.

def guesser(low = 0, up = 100):
    print("Choose a number between %d and %d" % (low, up-1))
    while low < up - 1:
        mid = (low+up)//2
        yn = raw_input("Is Your Number Smaller Than %s? (y/n): " % mid)
        if yn not in ['y', 'n']: continue
        low, up =  (low, mid) if yn == 'y' else (mid, up)
    print "Your Number is:", low


guesser()


More pythonic to use the bisect module - and a class of course :)

import bisect    
hival= 50

class Guesser(list):
    def __getitem__(self, idx):
        return 0 if raw_input("Is your number bigger than %s? (y/n)"%idx)=='y' else hival

g=Guesser()
print "Think of a number between 0 and %s"%hival
print "Your number is: %s"%bisect.bisect(g,0,hi=hival)

Here is the definition of bisect.bisect from the python library. As you can see, most of the algorithm is implemented here for you

def bisect_right(a, x, lo=0, hi=None):
    """Return the index where to insert item x in list a, assuming a is sorted.

    The return value i is such that all e in a[:i] have e <= x, and all e in
    a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
    insert just after the rightmost x already there.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if x < a[mid]: hi = mid
        else: lo = mid+1
    return lo

bisect = bisect_right   # backward compatibility


This is not as elegant as katrielalex's recursion, but it illustrates a basic class.

class guesser:
    def __init__(self, l_bound, u_bound):
        self.u_bound = u_bound
        self.l_bound = l_bound
        self.nextguess()

    def nextguess(self):
        self.guess = int((self.u_bound + self.l_bound)/2)
        print 'Higher or lower than %i?' % self.guess

    def mynumberishigher(self):
        self.l_bound = self.guess
        self.nextguess()

    def mynumberislower(self):
        self.u_bound = self.guess
        self.nextguess()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜