Search code examples
pythonfloating-pointrangegenerator

How can I make this program more efficient, short, and less complex?


I have made a Python program that takes any number (be it float) from the user and Python prints all the numbers between 1 and that number. For example, If I enter 12.5, then Python will show 1,2,3,4,5,6,7,8,9,10,11,12,12.1,12.2,12.3,12.4 The code for the same is the following:

import math
from decimal import *


user_input = float(input("Enter a number(upto one decimal place): "))

frac, whole = math.modf(user_input)           # frac doesn't give the exact decimal value. For ex. 0.3 = 0.299999999999999999998
frac_actual = Decimal(str(user_input)) % 1 
# Decimal also doesn't give the exact value if we give the parameter as a float, but we can give string float as a parameter(because it gives exact value), with which we can perform the desired operations

if user_input > 0:
    if user_input % 1 == 0:
        print(f"All the numbers between 0 and {int(user_input)} are: ", end='')
        print(*range(1, int(whole) + 1), sep=',', end='')
        frac_str = str(frac_actual)          # will convert Decimal('0.something') to ('0.something')
        decimal = int(frac_str[2])
    else:
        print(f"All the numbers between 0 and {user_input} are: ", end='')
        print(*range(1, int(whole) + 1), sep=',', end='')
        frac_str = str(frac_actual)          # will convert Decimal('0.something') to ('0.something')
        decimal = int(frac_str[2])
        generator_object = (whole + i / 10 for i in range(1, decimal))
        unpacked_generator_object = [*generator_object]
        string_generator_object = ','.join(map(str, unpacked_generator_object))
        print("," + string_generator_object)


elif user_input == 0:
    print("Sorry, numbers between 0 and 0 can't be displayed.")


else:
    while user_input < 0:
        print("Please enter a positive number or 0.")
        user_input = float(input("Enter a number(upto one decimal place): "))

    # frac doesn't give the exact decimal value. For ex. 0.3 = 0.299999999999999999998
    frac, whole = math.modf(user_input)
    frac_actual = Decimal(str(user_input)) % 1
    # Decimal also doesn't give the exact value if we give the parameter as a float, but we can give string float as a parameter(because it gives exact value), with which we can perform the desired operations

    if user_input % 1 == 0:
        print(f"All the numbers between 0 and {int(user_input)} are: ", end='')
        print(*range(1, int(whole) + 1), sep=',', end='')
        # will convert Decimal('0.something') to ('0.something')
        frac_str = str(frac_actual)
        decimal = int(frac_str[2])
    else:
        print(f"All the numbers between 0 and {user_input} are: ", end='')
        print(*range(1, int(whole) + 1), sep=',', end='')
        # will convert Decimal('0.something') to ('0.something')
        frac_str = str(frac_actual)
        decimal = int(frac_str[2])
        generator_object = (whole + i / 10 for i in range(1, decimal))
        unpacked_generator_object = [*generator_object]
        string_generator_object = ','.join(map(str, unpacked_generator_object))
        print("," + string_generator_object)

Its output is the following:

Enter a number(upto one decimal place): 15.7
All the numbers between 0 and 15.7 are: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15.1,15.2,15.3,15.4,15.5,15.6

Its second output:

Enter a number(upto one decimal place): 15
All the numbers between 0 and 15 are: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

But the program's code is too complex. So, is there any better way to do the same operation in fewer lines of code and more efficiently?

UPDATE #1 @Abhishek has given an answer which is almost perfect. After slight modifications, it will look like this:

from decimal import *

def between_nums(n):
    frac = float(str(Decimal(str(n)) % 1))
    l = []
    for x in range(1, int(n) + 1):
        l.append(x)

    for i in [l[-1] + x / 10 for x in range(1, int(frac * 10))]:
        l.append(i)

    str_list = ", ".join(map(str, l))

    if user_input % 1 == 0:
        print(f"All the numbers between 0 and {int(user_input)} are: ", str_list)
    else:
        print(f"All the numbers between 0 and {user_input} are: ", str_list)

    return l

user_input = float(input("Enter a number: "))
between_nums(user_input)

Solution

  • you can try this. if you don't mind data inside list you

    def between_nums(n):
        exp = n % 1
        l = []
        for x in range(int(n)+1):
            l.append(x)
    
        for i in [l[-1]+x / 10 for x in range(0,int(exp*10))]:
            l.append(i)
        return l
    
    
    print(between_nums(12.5))
    

    output i get is : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12.0, 12.1, 12.2, 12.3, 12.4]