Home > Blockchain >  Function that receives an integer n>0 and tells whether its digits (in base 10) form a nondecreas
Function that receives an integer n>0 and tells whether its digits (in base 10) form a nondecreas

Time:11-01

Write a function nondec(n) that receives an integer n>0 and reports whether its digits (in base 10) form a nondecreasing sequence (that is, each digit is greater or equal to the previous one).

I am having trouble with this exercise. My code so far is:

def nondec(n):
    '''
    >>> nondec(113355779)
    True
    >>> nondec(44569)
    True
    >>> nondec(346234)
    False
    >>> nondec(222)
    True
    >>> nondec(789)
    True
    >>> nondec(55555)
    True
    >>> nondec(1234123)
    False
    >>> nondec(98765)
    False
    '''
    prev = 9
    while n>0 :
        lastdigit = n
        if lastdigit > prev:
            return False
        prev = lastdigit
        n = n/10
    return True

if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=True)

It works for all cases but for those with repeated digits: 222, 55555. I tried many things but it makes my code worse. Thanks.

CodePudding user response:

Maybe this is the code you are looking for:

def nondec(n):
    '''
    >>> nondec(113355779)
    True
    >>> nondec(44569)
    True
    >>> nondec(346234)
    False
    >>> nondec(222)
    True
    >>> nondec(789)
    True
    >>> nondec(55555)
    True
    >>> nondec(1234123)
    False
    >>> nondec(98765)
    False
    '''
    prev = 9
    while n>0 :
        lastdigit = n % 10
        if lastdigit > prev:
            return False
        prev = lastdigit
        n = n // 10
    return True

The only change I did to your code is to the part that you do the division with 10: n = n / 10.

The problem was that this division returned a float but you wanted an int

For example if you take 222 when it divides by 10 then the new value of n was 22.2 when you wanted it to be 22. (You can check for such problems by printing the results of every line of code you write!)

You can accomplish this by using the // instead of /.

You can check this answer Python division by 10 to see what I am talking about

CodePudding user response:

You can do this:

def nondec(n):
    return all(int(x)<=int(y) for x,y in zip(str(n), str(n)[1:]))

Test it:

for n in (113355779,44569,346234,222,789,55555,1234123,98765):
    print(n, nondec(n))

Prints:

113355779 True
44569 True
346234 False
222 True
789 True
55555 True
1234123 False
98765 False

Since '0'<'1' ... '8'<'9' you actually can work with strings all the way through:

def nondec(n):
    s=str(n)
    return all(x<=y for x,y in zip(s, s[1:]))

    # same result...

CodePudding user response:

another more linguistic way to do it:

def nondec(n):
    '''
    >>> nondec(113355779)
    True
    >>> nondec(44569)
    True
    >>> nondec(346234)
    False
    >>> nondec(222)
    True
    >>> nondec(789)
    True
    >>> nondec(55555)
    True
    >>> nondec(1234123)
    False
    >>> nondec(98765)
    False
    '''
    n = str(n)
    for e,_ in enumerate(n):
        if e:
            if int(n[e]) < int(n[e-1]):
                return False 
    return True

if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=True)

CodePudding user response:

The variable n should be an integer. You should cast n to int inside your loop.

def nondec(n):
    '''
    >>> nondec(113355779)
    True
    >>> nondec(44569)
    True
    >>> nondec(346234)
    False
    >>> nondec(222)
    True
    >>> nondec(789)
    True
    >>> nondec(55555)
    True
    >>> nondec(1234123)
    False
    >>> nondec(98765)
    False
    '''
    prev = 9
    while n > 0:
        lastdigit = n % 10
        if lastdigit > prev:
            return False
        prev = lastdigit
        n = int(n / 10)
    return True


if __name__ == "__main__":
    import doctest

    doctest.testmod(verbose=True)
  • Related