Reputation: 61
I am attempting to create a script that will take in user input (only letters) and output ASCII art to the user. The two output methods are Horizontal or Vertical. The issue I have is how do I print the dictionary values horizontally.
Here is what I have so far:
def convert(string, horv):
#Dictionary with '#' to create the art, only a and b in here so far
letters = {"a":" ## \n # #\n# #\n######\n# #\n# #",
"b":"##### \n# # \n##### \n# #\n# #\n#####"}
#making the word into a list so i can use each letter to call a key in the
# dictionary
word_broken = list(string)
if horv == "1":
#horizontal is easy
for letter in word_broken:
print(letters[letter])
else:
#My attempts at tring to print out the art line by line,
#aka top of a - top of b- middle of a- middle of b so on...
#ends in failure
for letter in word_broken:
b = letters[letter]
for value in letter:
split_value = b.split("\n")
for obj in split_value:
print(obj, end="")
#user input
word = input("Word to conver: ")
#Hor or Vert
direction = input("1 for vert 2 for hor: ")
convert(word, direction)
The attempt was to split the art at the \n mark then print it piece by piece. Any ideas would be greatly appreciated!
P.S. this is my first post to this site so I i forgot something or didn't do something right please let me know for the future. Thanks!
Upvotes: 2
Views: 8343
Reputation: 5383
There is a subtle problem in your letters definition. It will become apparent when you dont ise \n
but rather use lists to represent this. Look at the following code:
In [254]: map(len, letters['a'].split('\n'))
Out[254]: [7, 5, 6, 6, 6, 6]
In [255]: map(len, letters['b'].split('\n'))
Out[255]: [7, 7, 7, 6, 6, 5]
This means that your letters wont be aligned when you flip them. For that, you need to make sure that they are aligned. Let us use a specific example (which is the general solution): la = letters['a'].split('\n')
. We shall use this for all subsequent results. Now defind a pretty-printing function: def pprint(l): print '\n'.join(l)
which can be used for quickly printing your letters. Using this, the horizontal print is easy:
In [257]: pprint(la)
##
# #
# #
######
# #
# #
For the vertical print, you will need to first make sure that everything is of the same length, otherwise you will miss a few lines:
In [258]: pprint(map(lambda m: ''.join(m) , zip(*la)))
####
# #
# #
# #
# #
This is because, not all strings are the same length. So first find the max length lMax = max(map(len, la))
and make everything the same length before taking the zip
:
In [266]: la1 =[ l.ljust(lMax) for l in la]
In [267]: pprint(map(lambda m: ''.join(m) , zip(*la1)))
####
# #
# #
# #
# #
####
Now all you have to do is to string together everything in a function :)
Upvotes: 1
Reputation: 1103
The fundamental problem with your horizontal part is that you're looping over the letters first, and then the parts. This will inevitably result in all of the parts of the first letter being printed before any parts of the second letter. What you need is loop by parts and then by letters. So like this:
for row_num in range(6): # 6 because the ascii art you've defined has six rows.
for letter in word_broken:
b = letters[letter]
split_value = b.split("\n")
print(split_value[row_num], end="")
print("") # Go to the next line
You'll also need to do two other things you might not have thought of:
end=""
to end=" "
like georg did. I like this better than my two ideas.Upvotes: 0
Reputation: 215029
Simpler than you think:
letters = {
"a": [
" ## ",
" # # ",
"# #",
"######",
"# #",
"# #",
],
"b": [
"##### ",
"# #",
"##### ",
"# #",
"# #",
"##### ",
]
}
str = 'abab'
for row in range(len(letters['a'])):
for letter in str:
print(letters[letter][row], end=" ")
print()
Basically, each letter is a list of rows. Make number-of-rows passes, on each pass print one row from each letter.
To print vertically:
for letter in str:
print("\n".join(letters[letter]) + "\n")
Upvotes: 5