11# 17.6 - Challenge: Return of the Poet
22# Solution to challenge
33
4+ # Please note that there are many ways to solve this challenge. The code
5+ # contained in this solution is just one way. If your solution is different,
6+ # but work, then you did a great job!
7+
48import tkinter as tk
59from tkinter import filedialog
610import random
711
812
9- def check_unique (word_list ):
13+ # Create the application window
14+ window = tk .Tk ()
15+ window .title ("Make your own poem!" )
16+
17+ # Application Header Frame
18+ header_frame = tk .Frame ()
19+ header_label = tk .Label (master = header_frame )
20+ header_label ["text" ] = "Enter your favorite words, separated by commas."
21+ header_label .pack ()
22+ header_frame .pack (padx = 5 , pady = 5 )
23+
24+ # Application Input Frame
25+ input_frame = tk .Frame ()
26+ # Label widgets for text entry boxes
27+ label_noun = tk .Label (input_frame , text = "Nouns:" )
28+ label_verb = tk .Label (input_frame , text = "Verbs:" )
29+ label_adj = tk .Label (input_frame , text = "Adjectives:" )
30+ label_prep = tk .Label (input_frame , text = "Prepositions:" )
31+ label_adv = tk .Label (input_frame , text = "Adverbs:" )
32+ # Entry widgets for entering nouns, verbs, etc.
33+ entry_noun = tk .Entry (input_frame , width = 80 )
34+ entry_verb = tk .Entry (input_frame , width = 80 )
35+ entry_adj = tk .Entry (input_frame , width = 80 )
36+ entry_prep = tk .Entry (input_frame , width = 80 )
37+ entry_adv = tk .Entry (input_frame , width = 80 )
38+ # Add each label and entry widget to the input_frame using the .grid()
39+ # geometry manager.
40+ label_noun .grid (row = 2 , column = 1 , sticky = tk .E )
41+ entry_noun .grid (row = 2 , column = 2 )
42+ label_verb .grid (row = 3 , column = 1 , sticky = tk .E )
43+ entry_verb .grid (row = 3 , column = 2 )
44+ label_adj .grid (row = 4 , column = 1 , sticky = tk .E )
45+ entry_adj .grid (row = 4 , column = 2 )
46+ label_prep .grid (row = 5 , column = 1 , sticky = tk .E )
47+ entry_prep .grid (row = 5 , column = 2 )
48+ label_adv .grid (row = 6 , column = 1 , sticky = tk .E )
49+ entry_adv .grid (row = 6 , column = 2 )
50+ input_frame .pack (padx = 5 , pady = 5 )
51+ # Button widget for generating a poem
52+ generate_frame = tk .Frame (master = window )
53+ generate_frame .pack (pady = 10 )
54+ generate_button = tk .Button (generate_frame , text = "Generate" )
55+ generate_button .pack ()
56+
57+ # Application Result Frame
58+ # Displays the generated poem
59+ result_frame = tk .Frame (master = window )
60+ result_frame ["relief" ] = tk .GROOVE
61+ result_frame ["borderwidth" ] = 5
62+ result_label = tk .Label (master = result_frame )
63+ result_label ["text" ] = "Your poem:"
64+ result_label .pack (pady = 10 )
65+ result_poem = tk .Label (result_frame )
66+ result_poem ["text" ] = "Press the 'Generate' button to display your poem."
67+ result_poem .pack (padx = 5 )
68+ save_button = tk .Button (result_frame , text = "Save to file" )
69+ save_button .pack (pady = 10 )
70+ result_frame .pack (fill = tk .X , padx = 5 , pady = 5 )
71+
72+
73+ # Button command functions
74+ def are_unique (word_list ):
1075 """Check that all items in a list are unique and return True or False"""
1176 unique_words = []
1277 for word in word_list :
@@ -15,25 +80,25 @@ def check_unique(word_list):
1580 return len (word_list ) == len (unique_words )
1681
1782
18- def make_poem ():
19- """Create a randomly generated poem, returned as a multi-line string """
83+ def generate_poem ():
84+ """Generate a poem and assign it to the `result_poem` Label widget """
2085
21- # split the user input into lists
86+ # Split the user input into lists
2287 noun = entry_noun .get ().split ("," )
2388 verb = entry_verb .get ().split ("," )
2489 adjective = entry_adj .get ().split ("," )
2590 adverb = entry_adv .get ().split ("," )
2691 preposition = entry_prep .get ().split ("," )
2792
28- # make sure that all lists consist of unique words
93+ # Make sure that all lists consist of unique words
2994 if not (
30- check_unique (noun )
31- and check_unique (verb )
32- and check_unique (adjective )
33- and check_unique (adverb )
34- and check_unique (preposition )
95+ are_unique (noun )
96+ and are_unique (verb )
97+ and are_unique (adjective )
98+ and are_unique (adverb )
99+ and are_unique (preposition )
35100 ):
36- result_poem . config ( text = "Please do not enter duplicate words." )
101+ result_poem [ " text" ] = "Please do not enter duplicate words."
37102 return
38103
39104 # Make sure that we got enough words from the user to make a poem
@@ -44,128 +109,83 @@ def make_poem():
44109 or len (preposition ) < 2
45110 or len (adverb ) < 1
46111 ):
47- result_poem . config (
48- text = "Did you think you could get away that easily? \n \
49- Enter at least three nouns, three verbs, three adjectives, \
50- two prepositions and an adverb!"
112+ result_poem [ "text" ] = (
113+ "There was a problem with your input! \n "
114+ " Enter at least three nouns, three verbs, three adjectives, "
115+ " two prepositions and an adverb!"
51116 )
52117 return
53118
54119 # Otherwise, we can go ahead with generating a poem:
55120
56- # Pull three nouns randomly
57- n1 = random .choice (noun )
58- n2 = random .choice (noun )
59- n3 = random .choice (noun )
121+ # Get three nouns randomly
122+ noun1 = random .choice (noun )
123+ noun2 = random .choice (noun )
124+ noun3 = random .choice (noun )
60125
61126 # Make sure that all the nouns are different
62- while n1 == n2 :
63- n2 = random .choice (noun )
64- while n1 == n3 or n2 == n3 :
65- n3 = random .choice (noun )
66-
67- # Pull three different verbs
68- v1 = random .choice (verb )
69- v2 = random .choice (verb )
70- v3 = random .choice (verb )
71- while v1 == v2 :
72- v2 = random .choice (verb )
73- while v1 == v3 or v2 == v3 :
74- v3 = random .choice (verb )
75-
76- # Pull three different adjectives
127+ while noun1 == noun2 :
128+ noun2 = random .choice (noun )
129+ while noun1 == noun3 or noun2 == noun3 :
130+ noun3 = random .choice (noun )
131+
132+ # Get three different verbs
133+ verb1 = random .choice (verb )
134+ verb2 = random .choice (verb )
135+ verb3 = random .choice (verb )
136+ while verb1 == verb2 :
137+ verb2 = random .choice (verb )
138+ while verb1 == verb3 or verb2 == verb3 :
139+ verb3 = random .choice (verb )
140+
141+ # Get three different adjectives
77142 adj1 = random .choice (adjective )
78143 adj2 = random .choice (adjective )
79144 adj3 = random .choice (adjective )
80145 while adj1 == adj2 :
81146 adj2 = random .choice (adjective )
82- while n1 == n3 or n2 == n3 :
147+ while adj1 == adj3 or adj2 == adj3 :
83148 adj3 = random .choice (adjective )
84149
85- # Pull two different prepositions
150+ # Get two different prepositions
86151 prep1 = random .choice (preposition )
87152 prep2 = random .choice (preposition )
88153 while prep1 == prep2 :
89154 prep2 = random .choice (preposition )
90155
91- # Pull one adverb
156+ # Get one adverb
92157 adv1 = random .choice (adverb )
93158
94- if "aeiou" . find ( adj1 [0 ]) != - 1 : # first letter is a vowel
159+ if adj1 [0 ] in "aeiou" : # First letter is a vowel
95160 article = "An"
96161 else :
97162 article = "A"
98163
99164 # Put it all together into a poem
100- poem = f"{ article } { adj1 } { n1 } \n \n "
101- poem = poem + f"{ article } { adj1 } { n1 } { v1 } { prep1 } the { adj2 } { n2 } \n "
102- poem = poem + f"{ adv1 } , the { n1 } { v2 } \n "
103- poem = poem + f"the { n2 } { v3 } { prep2 } a { adj3 } { n3 } "
165+ poem = f"{ article } { adj1 } { noun1 } \n \n "
166+ poem = poem + f"{ article } { adj1 } { noun1 } { verb1 } { prep1 } the { adj2 } { noun2 } \n "
167+ poem = poem + f"{ adv1 } , the { noun1 } { verb2 } \n "
168+ poem = poem + f"the { noun2 } { verb3 } { prep2 } a { adj3 } { noun3 } "
104169
105170 # Place the resulting poem into the label
106- result_poem .config (text = poem )
107-
108-
109- # Create the application window and add a Frame
110- window = tk .Tk ()
111- window .title ("Make your own poem!" )
112- frame = tk .Frame ()
113- # Pad top and left of frame 5 pixels before grid
114- frame .grid (padx = 5 , pady = 5 )
115-
116- # Create and add text labels for text entry boxes
117- label_directions = tk .Label (
118- frame , text = "Enter your favorite words, separated by commas:"
119- )
120- label_directions .grid (row = 1 , column = 1 , sticky = tk .S + tk .E , columnspan = 2 )
121- label_noun = tk .Label (frame , text = "Nouns:" )
122- label_noun .grid (row = 2 , column = 1 , sticky = tk .S + tk .E )
123- label_verb = tk .Label (frame , text = "Verbs:" )
124- label_verb .grid (row = 3 , column = 1 , sticky = tk .S + tk .E )
125- label_adj = tk .Label (frame , text = "Adjectives:" )
126- label_adj .grid (row = 4 , column = 1 , sticky = tk .S + tk .E )
127- label_prep = tk .Label (frame , text = "Prepositions:" )
128- label_prep .grid (row = 5 , column = 1 , sticky = tk .S + tk .E )
129- label_adv = tk .Label (frame , text = "Adverbs:" )
130- label_adv .grid (row = 6 , column = 1 , sticky = tk .S + tk .E )
131-
132- # Create and add space for user entry of text
133- entry_noun = tk .Entry (frame , width = 80 )
134- entry_noun .grid (row = 2 , column = 2 )
135- entry_verb = tk .Entry (frame , width = 80 )
136- entry_verb .grid (row = 3 , column = 2 )
137- entry_adj = tk .Entry (frame , width = 80 )
138- entry_adj .grid (row = 4 , column = 2 )
139- entry_prep = tk .Entry (frame , width = 80 )
140- entry_prep .grid (row = 5 , column = 2 )
141- entry_adv = tk .Entry (frame , width = 80 )
142- entry_adv .grid (row = 6 , column = 2 )
143-
144- # Create and add 'Create poem' button
145- btn_create = tk .Button (frame , text = "Create your poem" , command = make_poem )
146- btn_create .grid (row = 7 , column = 1 , columnspan = 2 )
147-
148- # Create label into which to output the poem
149- result_poem = tk .Label (frame )
150- result_poem .grid (row = 9 , column = 1 , rowspan = 5 , columnspan = 2 )
171+ result_poem ["text" ] = poem
151172
152173
153- def save_file ():
174+ def save_poem_to_file ():
154175 """Save the poem displayed in the output box into a text file"""
155176 type_list = [("Text files" , "*.txt" )]
156177 file_name = filedialog .asksaveasfilename (
157178 filetypes = type_list , defaultextension = "*.txt"
158179 )
159180 # Save file if user entered a file name
160181 if file_name != "" :
161- output_file = open (file_name , "w" )
162- output_file .writelines (result_poem .cget ("text" ))
163- output_file .close ()
182+ with open (file_name , "w" ) as output_file :
183+ output_file .writelines (result_poem ["text" ])
164184
165185
166- # Create and add 'Save your poem' button
167- btn_save = tk . Button ( frame , text = "Save your poem" , command = save_file )
168- btn_save . grid ( row = 15 , column = 1 , columnspan = 2 )
186+ # Assign the commands to the buttons
187+ generate_button [ "command" ] = generate_poem
188+ save_button [ "command" ] = save_poem_to_file
169189
170190# Start the application
171191window .mainloop ()
0 commit comments