2

I am writing a program to calculate the sum of the first n natural numbers but I am having a hard time coding the first part of the program in which I ask for the input from the user (about how many successive natural numbers to add).

It's a very long code for such a simple task because I want the program to be able to:

  1. ask to "try again" in case the input isn't a natural number;

  2. accept mathematical expressions that are equal to a natural number (e.g. 6 / 3).

     # Program to calculate sum of first n natural numbers
    
     try:
         n = eval(input('How many successive natural numbers, starting from 1, would you like to add up? '))
         if type(n) != int and not n.is_integer() or n < 0:
             raise Exception
     except:
         while True:
             try:
                 n = eval(input('How many successive natural numbers, starting from 1, would you like to add up? '))
                 if type(n) != int and not n.is_integer() or n < 0:
                     raise Exception
             except:
                 continue
             else:
                 break
    
     print(n)
    

To get back to the point: why does my IDE keep telling me that n can be undefined?

And if you'd be willing to take the time to tell me how to shorten my code (that seems a little repetitive), I'd really appreciate it.

Thank you for your time!

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Tony Stark
  • 37
  • 3
  • 5
    How exactly is Python telling you "n can be undefined"? That doesn't sound like a Python error. – Samwise Dec 13 '21 at 19:50
  • 6
    **Don't** use `eval`. If you want to ask a "number" call `float` to only accept numbers – Bakuriu Dec 13 '21 at 19:50
  • 1
    Show the full traceback of the error as properly formatted text in the question. – Michael Butscher Dec 13 '21 at 19:50
  • 3
    Where does it say that? My guess is that it is not python telling you this, but your IDE. On the final line. Because if the `try` fails, and the other `try` also fails, `n` will not have been assigned anything. – lucidbrot Dec 13 '21 at 19:50
  • 1
    @lucidbrot Initially I thought that too, but the second `n =` is inside a `while True` and the `except` clause contains `continue` so it shouldn't exit the loop if that fails. Obviously the IDE wont realize this. – Bakuriu Dec 13 '21 at 19:52

2 Answers2

0

Don't use eval and don't try to detect the type with is_integer; just try to make the number an int and catch the ValueError that will raise if that doesn't work:

while True:
    try:
        n = int(input('How many successive natural numbers, starting from 1, would you like to add up? '))
        if n < 1:
            continue
        break
    except ValueError:
        pass

print(n)

This should fix the "can be undefined" warning (depending how smart your IDE's static analysis is -- mypy at least is able to figure it out) because the only way to get out of the while True: loop is to break after having assigned n to an int.

If you're still getting a warning, you can make it a little more obvious by putting it in a function:

def input_int(msg: str) -> int:
    while True:
        try:
            n = int(input(msg))
            if n > 0:
                return n
        except ValueError:
            pass

n = input_int('How many successive natural numbers, starting from 1, would you like to add up? ')
print(n)
How many successive natural numbers, starting from 1, would you like to add up? asdf
How many successive natural numbers, starting from 1, would you like to add up? blep
How many successive natural numbers, starting from 1, would you like to add up?
How many successive natural numbers, starting from 1, would you like to add up? 10
10
Samwise
  • 68,105
  • 3
  • 30
  • 44
  • Does this answer mean that the `eval` and type detection attempts are related to the "can be undefined" warning in the IDE, or are those just additional remarks? Didn't OP already have a while true loop that should ensure this, in their question? – lucidbrot Dec 13 '21 at 19:57
  • All good questions. Pretty hard to say without more information from OP exactly to what extent the convoluted control flow triggered the error they saw, but in any event this oughtta fix their problem. – Samwise Dec 13 '21 at 20:00
  • I can't use the int() function because at that point the program wouldn't accept mathematical expressions that are equal to natural numbers like 6/3 as input. – Tony Stark Dec 13 '21 at 20:22
  • also -7 is returned as good entry in first code (didnt check 2nd but looks similar) – pippo1980 Dec 13 '21 at 22:35
  • with `eval`, the program will accept input like `6/3`, but it will also accept input like `os.system("rm -rf *")`. Are you sure that's a good tradeoff? – Samwise Dec 14 '21 at 01:07
0

my attempt :

while True:
         try:
             n = input('How many successive natural numbers, starting from 1, would you like to add up? ')
             
             print('N : ', n , type(n))
             

             if (not float(n).is_integer() or not float(n) > 0): 
                 raise Exception
         except:
             continue
         else:
             n = int(float(n))
             print('input n :', )
             break

print(n)

tested here:

How many successive natural numbers, starting from 1, would you like to add up? -1
N :  -1 <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? +++
N :  +++ <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? -0.5
N :  -0.5 <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? 0.5
N :  0.5 <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? 1.3
N :  1.3 <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? 15.5
N :  15.5 <class 'str'>

How many successive natural numbers, starting from 1, would you like to add up? 2
N :  2 <class 'str'>
input n :
2

How many successive natural numbers, starting from 1, would you like to add up? 2.0
N :  2.0 <class 'str'>
input n :
2

sorry for the prints statements (are for me to understand) , still got the 6/3 problem

pippo1980
  • 2,181
  • 3
  • 14
  • 30
  • opps noticed now the no int() request from OP – pippo1980 Dec 13 '21 at 22:37
  • 1
    By the way, `type() != ` calls should probably use `not isinstance()` – OneCricketeer Dec 13 '21 at 22:50
  • I am sure its like you said, have you got a one liner explaining me why ? (its late I am sleepy and only 1220 brownie points) Promise I 'll read https://stackoverflow.com/questions/1549801/what-are-the-differences-between-type-and-isinstance/1549854 tomorrow early morning – pippo1980 Dec 13 '21 at 22:55
  • Well, the line I refer to itself will throw an exception on `int(n)` where `n` cannot be parsed. Then `int()` already returns an int, so there is no need to check the type – OneCricketeer Dec 13 '21 at 23:01
  • uach ..... I'll have to sleep on this... thanks for your time – pippo1980 Dec 13 '21 at 23:07