Member Avatar for sravan953

Hey guys...

I am working on a program where when a user enters a number, the program adds all the digits of the number and goes on till the sum is single digit.

Example:
9812737
= 9 + 8 + 1 + 2 + 7 + 3 +7
= 37
= 3 + 7
= 10
= 1 + 0
=1

So, here goes:

def reduce():
    s=raw_input("Enter a number: ")
    x=int(s)
    p=0
    for i in s:
        p+=x%10
        x=x/10
    return p and x

reduce()

if(p>9):
    reduce()

print(p)
def reduce():
    # global p
    s = raw_input("Enter a number: ")
    x = int(s)
    p = 0
    for i in s:
        p += x % 10
        x = x / 10
    return p, x   
    
reduce()
print p

Why are we getting a NameError now?
Take away # and use the not so popular global.

Read a little about local and global scope in python.

Member Avatar for sravan953

No, it doesn't show any error. Just that it takes eternity to process it and most of the time it's wrong!

No, it doesn't show any error.

yes it dos.
To make it simple.

def test():
    # global a
    a = 5

test()
print a

This gives a NameError.
Are you using any python ide editor?

Member Avatar for sravan953

Yeah...
What happens is whatever number I enter, is prints '0'! :_(
And, no, there is no error in my code

Hint, in while loop turn the number string into list of individual digits and sum the list until the sum is less than 10, then break.

Careful here, you are using strings(characters) and integers. So you have to use str() and int() to convert at the appropriate time.

For example:

s = '123'
print list(s)  # ['1', '2', '3']
# for sum() you want list of integers
print [int(x) for x in s]       # [1, 2, 3]
print sum([int(x) for x in s])  # 6

That`s a other problem,now u are returing x.
And x is in your code is alway returing 0.

Copy my code in post #2
Run it,and u get a NameError
Take away # before global.
And now is "p" calulatet correct outside the function.

Then u start to work on "x" and why it always return 0.

Bumsfeld is putting you on the right track. I'll say not to convert the raw_input to an integer like you're doing now, so that you can cycle through each character in it as a string. Then just make sure to convert to integers at the right times (i.e. when adding them).

Member Avatar for sravan953

Hint, in while loop turn the number string into list of individual digits and sum the list until the sum is less than 10, then break.

Careful here, you are using strings(characters) and integers. So you have to use str() and int() to convert at the appropriate time.

For example:

s = '123'
print list(s)  # ['1', '2', '3']
# for sum() you want list of integers
print [int(x) for x in s]       # [1, 2, 3]
print sum([int(x) for x in s])  # 6

But the problem in bumsfeld's method is that if the number I enter is huuge, then the simplified one itself be two or three characters length..so then how do I go about it?

Member Avatar for sravan953

For now, I am working on:

s=raw_input("Enter a number to simplify: ")
global p
p=0
def loop():
    for i in s:
        p+=int(i)
    if(p>9):
        loop()
    return p
print(p)

this might help .

def reduces(s):
    x=int(s)
    p= 10
    while p>9:
        p = 0
        for i in str(s):
            p+= int(i)
        s = p
    return (p,x)
    

s=raw_input("Enter a number: ")
p , x = reduces(s)

print(p)

Instead of using a global variable for p, you could just pass that to the function as an optional parameter for the recursion you're doing. And you may want to rename the function. I think that loop is not a great description of what it does; something like sumOfDigits is better.

Other than that, you can't actually modify p within the loop function until you define p as the global WITHIN the loop function, like:

p = 0
def loop():
    global p
    # now you can modify p in this function's scope

Also, your code will always print 0. You never actually make a call to the loop function at all! You just define it.

You are getting into recursion (can get screwy), a while loop will serve you better ...

def reduce_digits(s):
    while True:
        if int(s) < 10:
            break
        p = 0
        for i in s:
            p += int(i)
            #print i, p  # test
        s = str(p)
    return p

#s = raw_input("Enter a number to simplify: ")
s = '123456789'  # for testing

n = reduce_digits(s)
print(n)   # --> 9

The basics are there, can be simplified a bit more.

But the problem in bumsfeld's method is that if the number I enter is huuge, then the simplified one itself be two or three characters length..so then how do I go about it?

This will work for adding integer together.

while True:
    total = sum([int(x) for x in raw_input('Enter integer')])
    if total <= 9:
        print 'Less than 10'
        break
    else:
        print total

Python has a build in function "eval"
Eval evaluates a Python expression and returns the
resulting value.

>>> eval(raw_input("Enter an arithmetic expression: "))
>>> Enter an arithmetic expression: 8/2*25-258+5896
>>> 5738
while True:
    total = eval(raw_input("Enter an expression: "))
    if total <= 9:
        print 'Less than 10'
        break
    else:
        print total

For now, I am working on:

s=raw_input("Enter a number to simplify: ")
global p
p=0
def loop():
    for i in s:
        p+=int(i)
    if(p>9):
        loop()
    return p
print(p)

You got the right idea, but if you insist on recursion, you have to follow certain rules:

#s=raw_input("Enter a number to simplify: ")
s = '123456789'  # for test

def loop(s, p=0):
    for i in s:
        p += int(i)
    if p > 9:
        # recursively loop with adjusted string s
        return loop(str(p))
    return p

n = loop(s)
print(n)    # 9
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.