Skip to content

Instantly share code, notes, and snippets.

@m4dc4p
Last active December 19, 2015 14:29
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 m4dc4p/5969538 to your computer and use it in GitHub Desktop.
Save m4dc4p/5969538 to your computer and use it in GitHub Desktop.
A simple programming problem - "Read lines of text, until a completely blank line is found. Eliminate redundant blanks between the words. Print the text, thirty characters to a line, without breaking words between lines." If a word is longer than 30 characters, print the word on its own line. All blanks (including tabs and newlines) are converte…
"""
This program reads lines of text from standard input, until a
completely blank line is seen. Lines are printed on standard
output,with redundant blanks between words removed. No more than 30
characters will be printed on each line, and lines are always broken
at whitespace. Only if a word is more than 30 characters long will a
line longer than 30 characters be printed.
"""
import sys
def read_chars(fd):
"""Yield individual characters until EOF."""
c = fd.read(1)
while c is not "":
yield c
c = fd.read(1)
def read_words(chars):
"""Yield words from chars with blanks in-between stripped. Terminates
on a blank line (or EOF).
"""
cs = ""
yielded = False
for cn in chars:
if cn.isspace():
if len(cs) > 0:
yield cs
cs = ""
yielded = True
for next in chars:
if next == "\n" and cn == "\n":
blankLine = True
break
elif next == "\n":
cn = next
elif not next.isspace():
cs += next
blankLine = False
break
else:
break
if blankLine:
break
else:
cs += cn
if len(cs) > 0:
yield cs
def print_lines(words, out):
"""Print words to given out stream. No more than 30 charactesr will be
printed on each line; lines are always broken in-between
words. Lines longer than 30 charactesr can be printed if any word
exceeds 30 characters.
"""
word = ""
first_on_line = 0
count = 0
for word in words:
if len(word) + first_on_line + count < 30:
if first_on_line == 1:
out.write(' ')
out.write(word)
count += len(word) + first_on_line
first_on_line = 1
elif first_on_line == 0:
out.write(word)
first_on_line = 1
count = len(word)
else:
out.write("\n" + word)
count = len(word) + 1
out.write("\n")
# Change to True for testing.
if True:
import StringIO
test_strs =[
# input
'''"""
This program reads lines of text from standard input, until a
completely blank line is seen. Linesareprintedonestandardoutput,with
redundant blanks between words removed. No more than 30
characters will be printed on each line, and lines are always broken
at whitespace. Only if a word is more than 30 characters long will a
line longer than 30 characters be printed.
"""''',
# result
'''""" This program reads lines
of text from standard input,
until a completely blank
line is seen.
Linesareprintedonestandardoutput,with
''',
# input
'''""" This program reads lines of text from standard input, until a
completely blank line is seen. Linesareprintedonestandardoutput,with
redundant blanks between words removed. No more than 30
characters will be printed on each line, and lines are always broken
at whitespace. Only if a word is more than 30 characters long will a
line longer than 30 characters be printed.
"""''',
# result
'''""" This program reads lines
of text from standard input,
until a completely blank
line is seen.
Linesareprintedonestandardoutput,with
redundant blanks between
words removed. No more than
30 characters will be
printed on each line, and
lines are always broken at
whitespace. Only if a word
is more than 30 characters
long will a line longer than
30 characters be printed.
"""
''',
# input
'''"""This program reads lines of text from standard input, until a
completely blank line is seen. Lines are printed on standard
output,with redundant blanks between words removed. No more than 30
characters will be printed on each line, and lines are always broken
at whitespace. Only if a word is more than 30 characters long will a
line longer than 30 characters be printed.
"""''',
# result
'''"""This program reads lines
of text from standard input,
until a completely blank
line is seen. Lines are
printed on standard
output,with redundant blanks
between words removed. No
more than 30 characters will
be printed on each line, and
lines are always broken at
whitespace. Only if a word
is more than 30 characters
long will a line longer than
30 characters be printed.
"""
''',
]
for i in xrange(0, len(test_strs), 2):
test = test_strs[i]
result = test_strs[i + 1]
out = StringIO.StringIO()
input = StringIO.StringIO(test)
print_lines(read_words(read_chars(input)), out)
if not result == out.getvalue():
sys.stdout.write(test + "\n")
sys.stdout.write("-" * 30 + "\n") # debugging
sys.stdout.write(result)
sys.stdout.write("-" * 30 + "\n") # debugging
sys.stdout.write(out.getvalue())
assert result == out.getvalue()
else:
print_lines(read_words(read_chars(open('lines.py'))), sys.stdout)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment