-4
import random
userask = float(input("enter number: "))
userask = userask + ((random.randrange(20)*userask)/random.randint(3, 100))
print("new value is " + str(userask))

Let's say my input is 123.0123
I want the program to force the new value after such operation to have the same number of digits as my initial input, rounding the result.
An example: my input is 102.31, the new value should have two digits and be rounded.
I have read round() docs but could not find something useful for this. how would you do it?

gonza
  • 3
  • 4
  • 3
    The number of decimal digits is not defined for a float. What you can do is to count the numbers after the dot in string form and convert the input to a float later. – Selcuk Dec 17 '19 at 06:42
  • Ughh new programming practicer over here. May you explain further? Thanks and sorry! – gonza Dec 17 '19 at 06:47
  • 1
    All good. The problem is, floats are stored in a binary format in memory, so the _computer_ does not have the idea of the number of decimal digits for a float. That's why you should capture the number of decimal digits _before_ you convert your input to a float. You can then pass this value as the [`ndigits` argument of `round` function](https://docs.python.org/3/library/functions.html#round). – Selcuk Dec 17 '19 at 06:50

2 Answers2

1

You can try this:

import random
userask = input("enter number: ")
lst = userask.split('.')
digits = 0 if len(lst)==1 else len(lst[1])
userask = float(userask)
userask = userask + ((random.randrange(20)*userask)/random.randint(3, 100))
print("new value is " + '{:.{}f}'.format(digits).format(userask))
Ank
  • 1,864
  • 4
  • 31
  • 51
0

You can do the following:

import random
import re
inp = input("enter number: ")
if '.' in inp:
    num_digits = len(inp.split('.')[1])
else:
    num_digits = 0

val = float(inp)
val = val + ((random.randrange(20)*val)/random.randint(3, 100))
if num_digits:
    res = round(val, num_digits)
else:
    res = int(val)
print("new value is " + str(res))

This code will work also for int's as well for float's, notice that the second if is not mandatory if you don't mind that your output will be printed as float, meaning that for an int it will have a 0 in the decimal place (13 -> 13.0)

Notice

You should always check the input entered to match the desired behaviour of your program, in this case you should probably check that the value entered has the proper "looks" of a number either float or int.

In this case you could do something like:

checker = re.compile('^[0-9]+.?[0-9]*$')
is_valid = bool(checker.match(inp))

and if is_valid isn't True then the value entered is problematic

David
  • 8,113
  • 2
  • 17
  • 36
  • Thanks sir. One last thing: what if I wanted the decimal to be rounded to .5 or .0 strictly depending on what is closer. For example, if the result is 444.200 it should be rounded to 444.0; if the result were 16.88, it should be rounded to 17.0 – gonza Dec 17 '19 at 08:11
  • @gonza as part of your question it will affect the logic, but there is probably a different approach to combine both, but what you are asking now is rounding to the **nearest int** so it will be `int(round(v))`; for example 444.200-> 444, 16.8->17 – David Dec 17 '19 at 08:15
  • Using a regex to find a dot feels _wrong_ and not very pythonic. You could have simply used `if "." in inp:`. – Selcuk Dec 17 '19 at 23:46
  • @Selcuk edited, you are right; it was just overkilling it but because I wanted to refer to the issue of checking the input properly and that was done using regex – David Dec 18 '19 at 05:57