Как найти сумму цифр суммы цифр каждого из T чисел неоднократно в Python, пока он не станет однозначным числом? - PullRequest
0 голосов
/ 26 августа 2018

Вот код, который я написал, чтобы получить сумму цифр из числа, повторяемого число раз, пока сумма не станет ниже 10:

T = int(input())
for i in range(T):
    N = int(input())
    def P():
            M = [int(d) for d in str(N)]
            N = sum(M)
            if N<10:
                    print(N)
            else :
                    return P()
    P()

При запуске этого кода мне выдается ошибка вроде:

 Traceback (most recent call last): 
 File"C:/Users/AdityaShrivastava/AppData/Roaming/Python/Python36/Scripts/tes 
 ting.py", line 11, in <module>
 P()
 File "C:/Users/Aditya 
 Shrivastava/AppData/Roaming/Python/Python36/Scripts/testing.py", line 5, in 
 P
 M = [int(d) for d in str(N)]
 UnboundLocalError: local variable 'N' referenced before assignment

Ответы [ 4 ]

0 голосов
/ 26 августа 2018

Вы используете рекурсию для решения этой проблемы. Более эффективно просто использовать цикл:

def gimmeNumber(text):
    """"Helper: Asks for input until valid integer number is inputted. Retuns the number"""
    while True:
        T = input(text).strip()
        if T and T.isdigit():
            T = int(T)
            break
        print("Thats not a number ...")
    return T

def sumDigits(number):
    return sum(int(x) for x in str(number))

T = gimmeNumber("How many numbers? ")
for _ in range(T):
    s = 0
    N = gimmeNumber("Give me a number: ")
    # calculate the cross-sum
    s = sumDigits(N)
    while s > 9: # repeat while greater then 9  
        s = sumDigits(s)

    print(s)

Ввод: 4, затем 999,888,333,111

Выход:

9
6
9
3

Как @Arne предложил изменить gimmeNumber(text), чтобы использовать try/except вместо этого лучше вписывается в питонов Просить прощения, а не разрешения мышление, и я согласен.

Тем не менее, приведенный выше вариант также работает и его легче понять новичкам. Вот try/except один:

def gimmeNumber(text):
    """"Helper: Asks for input until valid integer number is inputted. Retuns the number"""
    while True:
        try:
            T = int(input(text).strip())
            break
        except ValueError as e:
            print("Thats not a number ...")
    return T

Для получения дополнительной информации о проверке ввода я бы предложил прочитать его в ответах Запрашивать у пользователя ввод, пока он не даст действительный ответ .

0 голосов
/ 26 августа 2018

UnboundLocalError: local variable 'N' referenced before assignment, который вы получаете, является результатом использования N внутри функции P() без ее объявления и инициализации.

N = int(input()) находится внутри цикла, но выходит за рамки P(),Последняя строка P() в цикле вызовет функцию P() и не вернется к N = int(input()), где было бы назначено N.

Я изменил код на

T = int(input())
for i in range(T):
    N = int(input())
    def P(N):
        M = [int(d) for d in str(N)]
        N = sum(M)
        if N<10:
            print(N)
        else :
            return P(N)
    P(N)
0 голосов
/ 26 августа 2018

Это можно исправить, передав N в качестве параметра функции P.

T = int(input())
for i in range(T):
N = int(input())
def P(n):
        M = [int(d) for d in str(n)]
        n = sum(M)
        if n<10:
                print(n)
        else :
                P(n)
P(N)

Если вы установите значение N внутри функции P, python понимает его как создание локальной переменной с этим именем.Эта локальная переменная маскирует глобальную переменную N, используемую вне функции.Итак, вам лучше передать N в качестве параметра функции P.

Спасибо.

0 голосов
/ 26 августа 2018

Функции в python объявляют новую область видимости, поэтому N не отображается в вашей функции. Вы можете обойти это, передав N во внутреннюю область видимости, вот так:

T = int(input())
for i in range(T):
    N = int(input())
    def P(N):
            M = [int(d) for d in str(N)]
            N = sum(M)  # this line was the actual culprit
            if N<10:
                    print(N)
            else :
                    return P(N)
    P(N)

>>> 1      # test one time
>>> 12345  # cross total of 121212
6

Python консервативен в операциях записи. Хорошо только чтение из внешней области видимости, но повторное присвоение имени N (что происходит, если вы пишете N = sum(M)) заставляет его строго проверять переменную local с таким именем.

Как следствие, предполагается, что эта еще не объявленная переменная находится там, где вы хотите прочитать в строке над ней, что, честно говоря, немного вводит в заблуждение.


Для получения дополнительной информации о областях и пространствах имен в Python, проверьте здесь .

...