Last active
February 13, 2017 07:13
-
-
Save HackerEarthBlog/ed8269f4f12c02c398910e3b54808fb3 to your computer and use it in GitHub Desktop.
revamped `BufferedInput` class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BufferedInput: | |
def __init__(self): | |
# the buffer holds the content that has be entered by the user but has not been read by into a variable yet | |
self.buffer = '' | |
def getc(self): | |
self.fill_buffer() | |
byte = self.buffer[0] | |
self.buffer = self.buffer[1:] | |
return byte | |
def ungetc(self, s): | |
# add the character at the beginning of the present buffer so that it can be read later | |
self.buffer = s + self.buffer | |
def getword(self): | |
# the word will be read in this variable | |
w = '' | |
while True: | |
# keep appending characters to w as long as no whitespace is encountered | |
c = self.getc() | |
if c not in {' ', '\t', '\n'} and w: | |
w += c | |
else: | |
break | |
if w: | |
return w | |
else: | |
# In case, no word is entered and EOF is encountered, we raise this exception | |
raise EOFError(“Input source exhausted.”) | |
def getint(self): | |
# skip whitespace | |
c = ' ' | |
while c in {' ', '\t', '\n'}: | |
c = self.getc() | |
# get the sign for the number if any | |
sign = c | |
if sign not in {'-', '+'}: | |
# if no sign is available, put the read character back into the buffer and use an empty character for the sign | |
self.ungetc(sign) | |
sign = '' | |
# get the first digit of the number | |
# if it is not a digit, raise an exception | |
digit = self.getc() | |
if ord(digit) not in range(ord('0'), ord('9') + 1): | |
raise ValueError(“A number was expected.”) | |
num = '' | |
# keep getting a digit as long as no non-digit characters are encountered and append to num | |
while digit.isdigit() and digit not in {' ', '\t', '\n'}: | |
num += digit | |
digit = self.getc() | |
self.ungetc(digit) # the last char read is a non-digit | |
return int(num) | |
def getfloat(self): | |
# the value before the decimal point | |
pre_dot_num = str(self.getint()) | |
# the value after the decimal point | |
post_dot_num = '' | |
# the decimal point itself | |
# if the decimal point is not available, unread it | |
dot = self.getc() | |
if dot == '.': | |
digit = self.getc() | |
if ord(digit) not in range(ord('0'), ord('9') + 1): | |
self.ungetc(digit) | |
return float(pre_dot_num) | |
while digit.isdigit() and digit not in {' ', '\t', '\n'}: | |
post_dot_num += digit | |
digit = self.getc() | |
self.ungetc(digit) | |
return float(pre_dot_num + dot + post_dot_num) | |
def fill_buffer(self): | |
if not self.buffer: | |
self.buffer = input() + '\n' # input strips the trailing new line, so we add it explicitly | |
def empty_buffer(self): | |
copy = self.buffer | |
self.buffer = '' | |
return copy |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment