Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
Using rpartition solution in Clear category for What Does the Cow Say? by suic
def cowsay(text):
return draw_balloon(text) + draw_cow()
def draw_cow():
return r'''
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
'''
def draw_balloon(text):
text = replace_multiple_spaces(text)
if len(text) < 40:
return draw_border(len(text), draw_line(text, len(text), "<", ">"))
else:
lines = list(get_balloon_lines(text))
width = max([len(line) for line in lines])
balloon_text = ""
for ind, line in enumerate(lines):
if not ind: b, e = "/", "\\"
elif ind == len(lines) - 1: b, e = "\\", "/"
else: b = e = "|"
balloon_text += draw_line(line, width, b, e)
return draw_border(width, balloon_text)
def replace_multiple_spaces(text):
return (" " * (len(text) > len(text.lstrip()))
+ ' '.join(text.split())
+ " " * (len(text) > len(text.rstrip())))
def draw_border(width, text):
"""Draw top and bottom border for a given text."""
top_border = "\n" + border(width, "_") + "\n"
bottom_border = border(width, "-")
return "".join((top_border, text, bottom_border))
def border(width, character):
"""Returns a border line."""
return(" %s" % (character * (width + 2)))
def draw_line(text, width, open_border, close_border):
"""Return a line of text with borders."""
return "%s %s %s\n" % (open_border, text.ljust(width), close_border)
def get_balloon_lines(text):
"""Split the text to lines, which will appear in the balloon."""
while text:
line = get_next_line(text)
text = text[len(line):]
# Don't remove lines, which contain only one space.
text = text.lstrip() if text != " " else text
yield line
def get_next_line(text):
"""Get the next file from the text using rpartition."""
# One-line text => no additional action required
if len(text) < 40: return text
# Edge case:
# When the text begins with space, the space has to be ignored.
# in rpartition(" ") as it depends on on spaces. Otherwise it removes
# the leading space.
if text[0] == " ":
before_last_space, _, after_last_space = text[1:40].rpartition(" ")
if before_last_space:
if len(before_last_space) == 38: return " "
else: return " " + before_last_space
else:
if len(after_last_space) == 39: return " "
else: return " " + after_last_space
# Normal case:
# Split the string by the rightmost space using rpartition.
# *rpartition* returns a tuple *(text_before_space, space, text_after_space)*
before_last_space, _, after_last_space = text[:40].rpartition(" ")
# *before_last_space* is empty, there's no space
# so all the text is in *after_last_space*
result = before_last_space if before_last_space else after_last_space
# Fit the line in 39 characters.
return result if len(result) != 40 else result[:-1]
if __name__ == '__main__':
#These "asserts" using only for self-checking and not necessary for auto-testing
expected_cowsay_one_line = r'''
________________
< Checkio rulezz >
----------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
'''
expected_cowsay_two_lines = r'''
________________________________________
/ A \
\ longtextwithonlyonespacetofittwolines. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
'''
expected_cowsay_many_lines = r'''
_________________________________________
/ Lorem ipsum dolor sit amet, consectetur \
| adipisicing elit, sed do eiusmod tempor |
| incididunt ut labore et dolore magna |
\ aliqua. /
-----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
'''
cowsay_one_line = cowsay('Checkio rulezz')
assert cowsay_one_line == expected_cowsay_one_line, 'Wrong answer:\n%s' % cowsay_one_line
cowsay_two_lines = cowsay('A longtextwithonlyonespacetofittwolines.')
assert cowsay_two_lines == expected_cowsay_two_lines, 'Wrong answer:\n%s' % cowsay_two_lines
cowsay_many_lines = cowsay('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
'eiusmod tempor incididunt ut labore et dolore magna aliqua.')
assert cowsay_many_lines == expected_cowsay_many_lines, 'Wrong answer:\n%s' % cowsay_many_lines
Nov. 21, 2014
Comments: