Skip to content

Instantly share code, notes, and snippets.

@Pagliacii
Last active September 23, 2021 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pagliacii/8db2cd6c1a7527ce0363e32fbbb9bd57 to your computer and use it in GitHub Desktop.
Save Pagliacii/8db2cd6c1a7527ce0363e32fbbb9bd57 to your computer and use it in GitHub Desktop.
A Number class
#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
import re
def str_to_int(s: str) -> int:
if not s:
return 0
i = ord(s[0]) - ord("0")
if len(s) > 1:
for c in s[1:]:
i = i * 10 + (ord(c) - ord("0"))
return i
class Number:
REGEX = re.compile(
r"(?P<sign>[\+-])?"
r"(?P<integer>\d+)"
r"\.?"
r"(?P<decimal>\d+)?"
r"[eE]?"
r"(?P<expsign>[\+-])?"
r"(?P<exponent>\d+)?"
)
def __init__(self, s: str):
self._str_repr = s
matched = self.REGEX.match(s)
if not matched:
raise ValueError(f"expected a number string, got {s}")
self.sign = matched.group("sign") == "-" and -1 or 1
self.integer_part = matched.group("integer")
self.decimal_part = matched.group("decimal") or "0"
self.exp_sign = matched.group("expsign") == "-" and -1 or 1
self.exponent = str_to_int(matched.group("exponent") or "0")
def __str__(self) -> str:
return self._str_repr
def __repr__(self) -> str:
return self._str_repr
def as_int(self) -> int:
if self.exponent == 0:
i = str_to_int(self.integer_part) * self.sign
if str_to_int(self.decimal_part[0]) >= 5:
return i + 1
return i
if self.exp_sign == 1:
tail_zeroes = self.exponent - len(self.decimal_part)
if tail_zeroes < 0:
abs_val = str_to_int(
self.integer_part + self.decimal_part[: self.exponent]
)
else:
abs_val = str_to_int(
self.integer_part + self.decimal_part.ljust(self.exponent, "0")
)
return abs_val * self.sign
if self.exponent - len(self.integer_part) < 0:
i = str_to_int(self.integer_part[: self.exponent])
if str_to_int(self.integer_part[self.exponent]) >= 5:
i += 1
return i * self.sign
return 0
if __name__ == "__main__":
while True:
user_input = input(
"Please enter a number, supports these formats"
": 123|1.234|1.2e34\n"
)
if user_input.lower() in ["q", "quit", "exit"]:
break
print(Number(user_input).as_int())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment