TDT4109/Exercise 1/11 - James Bond and Operation Round/task11b.py

58 lines
2.0 KiB
Python

import math
from common import inputTypeCheck
def removeEmptyDecimals(number):
hasEmptyDecimals = (number == int(number))
return int(number) if hasEmptyDecimals else number
def myRoundFunction(integerPart,decimalPart,amountOfDecimals):
decimalOffset = len(str(integerPart))
roundOffset = decimalOffset + amountOfDecimals
numberString = f'{integerPart}{decimalPart}'
lastDigit = int(numberString[roundOffset-1])
firstEvalDigit = int(numberString[roundOffset])
addPointAtOffset = lambda num,off: float(str(num)[:off] + '.' + str(num)[off:])
if (firstEvalDigit < 5):
return addPointAtOffset(numberString[:roundOffset], decimalOffset)
elif (firstEvalDigit == 5):
try:
hasDigitsBehind5 = (int(numberString[roundOffset+1:]) > 0)
except ValueError:
hasDigitsBehind5 = False
# This is the special case where round() rounds 2.5 down to 2.
# It is only valid when there's no digits behind the eval digit
# and when the base digit is even.
specialCase = ((not hasDigitsBehind5) and (lastDigit % 2 == 0))
roundedNumber = int(numberString[:roundOffset]) + 1 - specialCase
return addPointAtOffset(roundedNumber, decimalOffset)
else:
return addPointAtOffset(int(numberString[:roundOffset]) + 1, decimalOffset)
integerPart = inputTypeCheck(
message='Oppgi heltallsdelen av tallet (det foran punktum): ',
type=int,
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
)
decimalPart = inputTypeCheck(
message='Oppgi desimaldelen av tallet (det bak punktum): ',
type=int,
errorMessage='Beklager, dette er ikke et tall, eller inneholder et desimalpunkt. Prøv igjen\n'
)
amountOfDecimals = inputTypeCheck(
message='Oppgi ønsket antall desimaler i avrunding: ',
type=int,
errorMessage='Beklager, det du skrev inn er ikke et heltall. Prøv igjen\n'
)
roundedNumber = removeEmptyDecimals(myRoundFunction(integerPart, decimalPart, amountOfDecimals))
print(f'{integerPart}.{decimalPart} avrundet til {amountOfDecimals} desimaler blir {roundedNumber}')