Skip to content

Instantly share code, notes, and snippets.

@HackerEarthBlog
Last active February 13, 2017 07:13
Show Gist options
  • Save HackerEarthBlog/ed8269f4f12c02c398910e3b54808fb3 to your computer and use it in GitHub Desktop.
Save HackerEarthBlog/ed8269f4f12c02c398910e3b54808fb3 to your computer and use it in GitHub Desktop.
revamped `BufferedInput` class
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