2

Please bear with my novice question as I just started learning Python (2.x). I'm trying to run a script where user could enter any number (e.g. ints or float) and the expected output would be the total digit numbers of that input number.

However, I've encountered the following problems and wondered if you could kindly help guide me through solving them. Many thanks!! :)

(problems)

  1. In the printout message, the n value was always 0; whereas I wished to print out the original input number by the user.

  2. I wished it would also process the float number. For now, a 'ValueError' was returned and the script was halted whenever a float number was entered.

  3. If user enters any string or blank character, the script should ignore the input and repeat all over again asking for the user input until the number with correct format (i.e. either integer or float number) was entered.

 

def num_digits(n):
    count = 0
    while n:
        count = count + 1
        n = n/10
    print 'The total digits for this number, ', n, ', are: ', count
    return count

user_input = abs(int(raw_input('Enter a number:\n')))
num_digits(user_input)
Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
Marc Chen
  • 23
  • 1
  • 4

4 Answers4

1

Since you also want to be able to count the digits of floats, simply doing n/10 isn't enough. With float values, your loop will end up being infinite, since it will be doing float division instead of int division. (Ex. 16.3 / 10 = 1.63 --> 1.63 / 10 = .163 etc -- it will never reach 0)

To avoid this problem, I recommend treating the number as a string and counting the number of characters in the string which are digits.

def num_digits(n):
    count = 0
    curr = n # remaining string you're currently evaluating
    while (curr != ''):
        digit = curr[len(curr)-1] # get final char
        curr = curr[:len(curr)-1] # trim last char off the string
        if (not digit.isdigit()):
            # ignore things like decimal points or negative signs
            continue
        count += 1
    return count

while True:
    value = raw_input('Enter a number:\n') # keep it in string form
    try:
        convert = float(value) # if it's a valid float, then it's also a valid int
        break
    except:
        print "not a number. enter a valid number"

nd = num_digits(value)
print('{} has {} digits'.format(value, nd))

Sample output:

# float number, ignores negative sign and decimal point
$ python script.py 
Enter a number:
-16.3
-16.3 has 3 digits

# asks for input until it has a valid number
$ python script.py 
Enter a number:
foo
not a number. enter a valid number
Enter a number:
blah3
not a number. enter a valid number
Enter a number:
89
89 has 2 digits
xgord
  • 4,606
  • 6
  • 30
  • 51
1

Another answers have already explaine your bug. Anyway, here's a couple of other options for you to take a look & understand:

def num_digits1(n):
    return len(str(n).replace(".", "").replace("-", ""))


def num_digits2(n):
    return sum(c.isdigit() for c in str(n))

for v in [-1.0, 0, 00, 000, 1.0, 1e2, 1e-2]:
    print v, num_digits1(v), num_digits2(v)
BPL
  • 9,632
  • 9
  • 59
  • 117
  • Dear BPL: Many thanks for your insightful suggestions. I'm amazed to learn that my questions can be solved using such short and few lines of statements!! :) – Marc Chen Aug 17 '16 at 06:01
0

n is always going to be zero because you have this line:

while n:

It can never exit that loop without becoming a False-y value. If you want to keep the original value, either operate on a copy, or store the original value:

def num_digits(n):
    original = n
    ...  # the rest of your code

For floats, you need to convert your input to a float instead, i.e.

user_input = abs(float(raw_input('Enter a number:\n')))

And finally, if you want to require a number you could do something like this:

invalid_input = True
while invalid_input:
    user_input = raw_input('Enter a number:\n')
    try:
        number = abs(float(user_input))
    except ValueError:
        print('***ERROR*** Please enter a number.')
    else:
        num_digits(number)

Of course, you could make your life even easier, and change the else to this:

    else:
        print(len(user_input.split('.')[0]))

(The split('.')[0] is for handling floating point numbers)

Update:

It appears that you wanted the actual length of the floating point digit rather than to use the exact algorithm you're using. In which case, forget the .split part, print(len(user_input)) should do what you want.

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
0

This should do everything you asked. Feel free to comment any questions

def num_digits():
    while True:
        n = raw_input('Enter a number:\n')
        try:
            float(n)
            if '.' and '-' in n:
                print len(n) - 2
            elif '.' in n or '-' in n:
                print len(n) - 1
            else:
                print len(n)
            break
        except:
            print 'Invalid Input\n'
            continue
num_digits()
Kklj8
  • 137
  • 2
  • 11
  • Dear Jessie: Appreciated your kind reply. I'm wondering what I should add/modify if input with negative integer/float was to be correctly evaluated. As for my current Py knowledge, I can only think of using the Boolean logics to evaluate the presence of both (or either) '.' and '-'. Thanks. – Marc Chen Aug 17 '16 at 06:07
  • @MarcChen I just edited my answer to account for negative numbers, I overlooked that in my original answer – Kklj8 Aug 17 '16 at 06:31