Last active
December 19, 2015 14:29
-
-
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 file contains 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
""" | |
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