Mad Libs Excercise
up vote
2
down vote
favorite
I did the following Excercise from Automate the boring stuff with Python Chapter 8:
Create a Mad Libs program that reads in text files and lets the user
add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB
appears in the text file. For example, a text file may look like this:
The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN
was unaffected by these events. The program would find these
occurrences and prompt the user to replace them.
Enter an adjective:
silly
Enter a noun:
chandelier
Enter a verb:
screamed
Enter a noun:
pickup truck
The following text file would then
be created:
The silly panda walked to the chandelier and then screamed. A nearby
pickup truck was unaffected by these events. The results should be
printed to the screen and saved to a new text file.
I decided to read from all the text files which are in the same folder as the python script.
All new created files then end with _mad.txt
I would like to know if this is a good solution.
Are there any bad practices?
Is the code easy to understand?
What can be improved?
Are there better approaches for some parts int the code?
Please feel free to comment on anything you can find.
Heres the code:
mad_libs.py
"""
Mad Libs
Scans for all .txt files in the working folder.
If a file is found the file is scanned for the keywords
-ADJECTIVE
-NOUN
-ADVERB
-VERB
Then the user is prompted to add a replacing word for the keyword.
A File with the name <source_name>_mad.txt is created in the folder.
In this file the keywords are replaced with the user input
"""
import os
import sys
import re
def filenames_in_script_folder():
"""
Returns all the filenames which are located in the same folder
as this running python script
"""
os.chdir(os.path.dirname(sys.argv[0]))
return os.listdir(os.getcwd())
def words_from_file(filename):
"""
Reads text file and returns all the words in it
"""
file = open(filename)
file_content = file.read()
file.close()
return file_content.split()
def ask_for_replace_word(keyword):
"""
Asks for a replace for mentioned keyword.
Checks if keyword is a vowel to follow english grammar correct
"""
vowel_regex = re.compile('^[aeiou]')
if vowel_regex.search(keyword):
return input("Enter an " + keyword.lower() + "n")
return input("Enter a " + keyword.lower() + "n")
def replace_word(word, keywords):
"""
Replaces provided word if it matches with one of the keywords.
Any non alphabetical signs are ignored in keyword compare
Otherwise returns provided word
"""
no_char_regex = re.compile('[^a-zA-Z]')
clean_word = no_char_regex.sub('', word)
for keyword in keywords:
if clean_word == keyword:
new_word = ask_for_replace_word(keyword)
return word.replace(keyword, new_word)
return word
def write_data_to_file(data, filename):
"""
Writes provided data to file.
If no file exists a new one is created first
"""
file = open(filename, 'w')
file.write(data)
file.close()
def mad_libs():
"""
Main function reads from file, replaces keywords
and writes to new file
"""
for filename in filenames_in_script_folder():
if filename.lower().endswith('.txt'):
new_words =
replaced_a_word = False
for word in words_from_file(filename):
KEYWORDS = ('ADJECTIVE', 'NOUN', 'VERB', 'ADVERB')
replace = replace_word(word, KEYWORDS)
if replace != word:
replaced_a_word = True
new_words.append(replace)
if replaced_a_word:
new_data = ' '.join(new_words)
print(new_data)
write_data_to_file(new_data, filename[:-4] + "_mad.txt")
mad_libs()
Bonus question:
I run Pylint over the code and in the definition of the Keywords in the mad_libs function it gives me:
Severity Code Description Project File Line Suppression State
Message Variable name "KEYWORDS" doesn't conform to snake_case naming
style
Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?
edit:
To see some results when run the programm you need to add a txt file like the example one in the same folder as the script.
I added a panda.txt with the text mentioned aboth and after aks for the words a panda_mad.txt is created in the folder.
python beginner strings file
add a comment |
up vote
2
down vote
favorite
I did the following Excercise from Automate the boring stuff with Python Chapter 8:
Create a Mad Libs program that reads in text files and lets the user
add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB
appears in the text file. For example, a text file may look like this:
The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN
was unaffected by these events. The program would find these
occurrences and prompt the user to replace them.
Enter an adjective:
silly
Enter a noun:
chandelier
Enter a verb:
screamed
Enter a noun:
pickup truck
The following text file would then
be created:
The silly panda walked to the chandelier and then screamed. A nearby
pickup truck was unaffected by these events. The results should be
printed to the screen and saved to a new text file.
I decided to read from all the text files which are in the same folder as the python script.
All new created files then end with _mad.txt
I would like to know if this is a good solution.
Are there any bad practices?
Is the code easy to understand?
What can be improved?
Are there better approaches for some parts int the code?
Please feel free to comment on anything you can find.
Heres the code:
mad_libs.py
"""
Mad Libs
Scans for all .txt files in the working folder.
If a file is found the file is scanned for the keywords
-ADJECTIVE
-NOUN
-ADVERB
-VERB
Then the user is prompted to add a replacing word for the keyword.
A File with the name <source_name>_mad.txt is created in the folder.
In this file the keywords are replaced with the user input
"""
import os
import sys
import re
def filenames_in_script_folder():
"""
Returns all the filenames which are located in the same folder
as this running python script
"""
os.chdir(os.path.dirname(sys.argv[0]))
return os.listdir(os.getcwd())
def words_from_file(filename):
"""
Reads text file and returns all the words in it
"""
file = open(filename)
file_content = file.read()
file.close()
return file_content.split()
def ask_for_replace_word(keyword):
"""
Asks for a replace for mentioned keyword.
Checks if keyword is a vowel to follow english grammar correct
"""
vowel_regex = re.compile('^[aeiou]')
if vowel_regex.search(keyword):
return input("Enter an " + keyword.lower() + "n")
return input("Enter a " + keyword.lower() + "n")
def replace_word(word, keywords):
"""
Replaces provided word if it matches with one of the keywords.
Any non alphabetical signs are ignored in keyword compare
Otherwise returns provided word
"""
no_char_regex = re.compile('[^a-zA-Z]')
clean_word = no_char_regex.sub('', word)
for keyword in keywords:
if clean_word == keyword:
new_word = ask_for_replace_word(keyword)
return word.replace(keyword, new_word)
return word
def write_data_to_file(data, filename):
"""
Writes provided data to file.
If no file exists a new one is created first
"""
file = open(filename, 'w')
file.write(data)
file.close()
def mad_libs():
"""
Main function reads from file, replaces keywords
and writes to new file
"""
for filename in filenames_in_script_folder():
if filename.lower().endswith('.txt'):
new_words =
replaced_a_word = False
for word in words_from_file(filename):
KEYWORDS = ('ADJECTIVE', 'NOUN', 'VERB', 'ADVERB')
replace = replace_word(word, KEYWORDS)
if replace != word:
replaced_a_word = True
new_words.append(replace)
if replaced_a_word:
new_data = ' '.join(new_words)
print(new_data)
write_data_to_file(new_data, filename[:-4] + "_mad.txt")
mad_libs()
Bonus question:
I run Pylint over the code and in the definition of the Keywords in the mad_libs function it gives me:
Severity Code Description Project File Line Suppression State
Message Variable name "KEYWORDS" doesn't conform to snake_case naming
style
Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?
edit:
To see some results when run the programm you need to add a txt file like the example one in the same folder as the script.
I added a panda.txt with the text mentioned aboth and after aks for the words a panda_mad.txt is created in the folder.
python beginner strings file
2
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in afor
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.
– Mast
2 days ago
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I did the following Excercise from Automate the boring stuff with Python Chapter 8:
Create a Mad Libs program that reads in text files and lets the user
add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB
appears in the text file. For example, a text file may look like this:
The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN
was unaffected by these events. The program would find these
occurrences and prompt the user to replace them.
Enter an adjective:
silly
Enter a noun:
chandelier
Enter a verb:
screamed
Enter a noun:
pickup truck
The following text file would then
be created:
The silly panda walked to the chandelier and then screamed. A nearby
pickup truck was unaffected by these events. The results should be
printed to the screen and saved to a new text file.
I decided to read from all the text files which are in the same folder as the python script.
All new created files then end with _mad.txt
I would like to know if this is a good solution.
Are there any bad practices?
Is the code easy to understand?
What can be improved?
Are there better approaches for some parts int the code?
Please feel free to comment on anything you can find.
Heres the code:
mad_libs.py
"""
Mad Libs
Scans for all .txt files in the working folder.
If a file is found the file is scanned for the keywords
-ADJECTIVE
-NOUN
-ADVERB
-VERB
Then the user is prompted to add a replacing word for the keyword.
A File with the name <source_name>_mad.txt is created in the folder.
In this file the keywords are replaced with the user input
"""
import os
import sys
import re
def filenames_in_script_folder():
"""
Returns all the filenames which are located in the same folder
as this running python script
"""
os.chdir(os.path.dirname(sys.argv[0]))
return os.listdir(os.getcwd())
def words_from_file(filename):
"""
Reads text file and returns all the words in it
"""
file = open(filename)
file_content = file.read()
file.close()
return file_content.split()
def ask_for_replace_word(keyword):
"""
Asks for a replace for mentioned keyword.
Checks if keyword is a vowel to follow english grammar correct
"""
vowel_regex = re.compile('^[aeiou]')
if vowel_regex.search(keyword):
return input("Enter an " + keyword.lower() + "n")
return input("Enter a " + keyword.lower() + "n")
def replace_word(word, keywords):
"""
Replaces provided word if it matches with one of the keywords.
Any non alphabetical signs are ignored in keyword compare
Otherwise returns provided word
"""
no_char_regex = re.compile('[^a-zA-Z]')
clean_word = no_char_regex.sub('', word)
for keyword in keywords:
if clean_word == keyword:
new_word = ask_for_replace_word(keyword)
return word.replace(keyword, new_word)
return word
def write_data_to_file(data, filename):
"""
Writes provided data to file.
If no file exists a new one is created first
"""
file = open(filename, 'w')
file.write(data)
file.close()
def mad_libs():
"""
Main function reads from file, replaces keywords
and writes to new file
"""
for filename in filenames_in_script_folder():
if filename.lower().endswith('.txt'):
new_words =
replaced_a_word = False
for word in words_from_file(filename):
KEYWORDS = ('ADJECTIVE', 'NOUN', 'VERB', 'ADVERB')
replace = replace_word(word, KEYWORDS)
if replace != word:
replaced_a_word = True
new_words.append(replace)
if replaced_a_word:
new_data = ' '.join(new_words)
print(new_data)
write_data_to_file(new_data, filename[:-4] + "_mad.txt")
mad_libs()
Bonus question:
I run Pylint over the code and in the definition of the Keywords in the mad_libs function it gives me:
Severity Code Description Project File Line Suppression State
Message Variable name "KEYWORDS" doesn't conform to snake_case naming
style
Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?
edit:
To see some results when run the programm you need to add a txt file like the example one in the same folder as the script.
I added a panda.txt with the text mentioned aboth and after aks for the words a panda_mad.txt is created in the folder.
python beginner strings file
I did the following Excercise from Automate the boring stuff with Python Chapter 8:
Create a Mad Libs program that reads in text files and lets the user
add their own text anywhere the word ADJECTIVE, NOUN, ADVERB, or VERB
appears in the text file. For example, a text file may look like this:
The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN
was unaffected by these events. The program would find these
occurrences and prompt the user to replace them.
Enter an adjective:
silly
Enter a noun:
chandelier
Enter a verb:
screamed
Enter a noun:
pickup truck
The following text file would then
be created:
The silly panda walked to the chandelier and then screamed. A nearby
pickup truck was unaffected by these events. The results should be
printed to the screen and saved to a new text file.
I decided to read from all the text files which are in the same folder as the python script.
All new created files then end with _mad.txt
I would like to know if this is a good solution.
Are there any bad practices?
Is the code easy to understand?
What can be improved?
Are there better approaches for some parts int the code?
Please feel free to comment on anything you can find.
Heres the code:
mad_libs.py
"""
Mad Libs
Scans for all .txt files in the working folder.
If a file is found the file is scanned for the keywords
-ADJECTIVE
-NOUN
-ADVERB
-VERB
Then the user is prompted to add a replacing word for the keyword.
A File with the name <source_name>_mad.txt is created in the folder.
In this file the keywords are replaced with the user input
"""
import os
import sys
import re
def filenames_in_script_folder():
"""
Returns all the filenames which are located in the same folder
as this running python script
"""
os.chdir(os.path.dirname(sys.argv[0]))
return os.listdir(os.getcwd())
def words_from_file(filename):
"""
Reads text file and returns all the words in it
"""
file = open(filename)
file_content = file.read()
file.close()
return file_content.split()
def ask_for_replace_word(keyword):
"""
Asks for a replace for mentioned keyword.
Checks if keyword is a vowel to follow english grammar correct
"""
vowel_regex = re.compile('^[aeiou]')
if vowel_regex.search(keyword):
return input("Enter an " + keyword.lower() + "n")
return input("Enter a " + keyword.lower() + "n")
def replace_word(word, keywords):
"""
Replaces provided word if it matches with one of the keywords.
Any non alphabetical signs are ignored in keyword compare
Otherwise returns provided word
"""
no_char_regex = re.compile('[^a-zA-Z]')
clean_word = no_char_regex.sub('', word)
for keyword in keywords:
if clean_word == keyword:
new_word = ask_for_replace_word(keyword)
return word.replace(keyword, new_word)
return word
def write_data_to_file(data, filename):
"""
Writes provided data to file.
If no file exists a new one is created first
"""
file = open(filename, 'w')
file.write(data)
file.close()
def mad_libs():
"""
Main function reads from file, replaces keywords
and writes to new file
"""
for filename in filenames_in_script_folder():
if filename.lower().endswith('.txt'):
new_words =
replaced_a_word = False
for word in words_from_file(filename):
KEYWORDS = ('ADJECTIVE', 'NOUN', 'VERB', 'ADVERB')
replace = replace_word(word, KEYWORDS)
if replace != word:
replaced_a_word = True
new_words.append(replace)
if replaced_a_word:
new_data = ' '.join(new_words)
print(new_data)
write_data_to_file(new_data, filename[:-4] + "_mad.txt")
mad_libs()
Bonus question:
I run Pylint over the code and in the definition of the Keywords in the mad_libs function it gives me:
Severity Code Description Project File Line Suppression State
Message Variable name "KEYWORDS" doesn't conform to snake_case naming
style
Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?
edit:
To see some results when run the programm you need to add a txt file like the example one in the same folder as the script.
I added a panda.txt with the text mentioned aboth and after aks for the words a panda_mad.txt is created in the folder.
python beginner strings file
python beginner strings file
edited yesterday
asked 2 days ago
Sandro4912
711121
711121
2
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in afor
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.
– Mast
2 days ago
add a comment |
2
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in afor
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.
– Mast
2 days ago
2
2
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in a
for
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.– Mast
2 days ago
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in a
for
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.– Mast
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
Thanks for sharing your code!
Almost everything looks good to me.
- You have documentation for the module :)
- You have documentations for all your functions.
- Naming seems good to me.
- I did not see 'unpythonic' things in your code, maybe someone more experimented will have more to say on this?
- You use a linter
The major things I would change is adding a __main__
to your script.
if __name__ == "__main__":
mad_libs()
When you run you script with python mad_libs.py
it will behave the same but if you import your module in another script, it will not execute the function upon importing, which is I think the desired behavior.
As for improvements:
- you could use type annotations to do static validation with MyPy
- write some tests with unittest, pytest, nose ...
Very nice code in my opinion
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Thanks for sharing your code!
Almost everything looks good to me.
- You have documentation for the module :)
- You have documentations for all your functions.
- Naming seems good to me.
- I did not see 'unpythonic' things in your code, maybe someone more experimented will have more to say on this?
- You use a linter
The major things I would change is adding a __main__
to your script.
if __name__ == "__main__":
mad_libs()
When you run you script with python mad_libs.py
it will behave the same but if you import your module in another script, it will not execute the function upon importing, which is I think the desired behavior.
As for improvements:
- you could use type annotations to do static validation with MyPy
- write some tests with unittest, pytest, nose ...
Very nice code in my opinion
add a comment |
up vote
1
down vote
Thanks for sharing your code!
Almost everything looks good to me.
- You have documentation for the module :)
- You have documentations for all your functions.
- Naming seems good to me.
- I did not see 'unpythonic' things in your code, maybe someone more experimented will have more to say on this?
- You use a linter
The major things I would change is adding a __main__
to your script.
if __name__ == "__main__":
mad_libs()
When you run you script with python mad_libs.py
it will behave the same but if you import your module in another script, it will not execute the function upon importing, which is I think the desired behavior.
As for improvements:
- you could use type annotations to do static validation with MyPy
- write some tests with unittest, pytest, nose ...
Very nice code in my opinion
add a comment |
up vote
1
down vote
up vote
1
down vote
Thanks for sharing your code!
Almost everything looks good to me.
- You have documentation for the module :)
- You have documentations for all your functions.
- Naming seems good to me.
- I did not see 'unpythonic' things in your code, maybe someone more experimented will have more to say on this?
- You use a linter
The major things I would change is adding a __main__
to your script.
if __name__ == "__main__":
mad_libs()
When you run you script with python mad_libs.py
it will behave the same but if you import your module in another script, it will not execute the function upon importing, which is I think the desired behavior.
As for improvements:
- you could use type annotations to do static validation with MyPy
- write some tests with unittest, pytest, nose ...
Very nice code in my opinion
Thanks for sharing your code!
Almost everything looks good to me.
- You have documentation for the module :)
- You have documentations for all your functions.
- Naming seems good to me.
- I did not see 'unpythonic' things in your code, maybe someone more experimented will have more to say on this?
- You use a linter
The major things I would change is adding a __main__
to your script.
if __name__ == "__main__":
mad_libs()
When you run you script with python mad_libs.py
it will behave the same but if you import your module in another script, it will not execute the function upon importing, which is I think the desired behavior.
As for improvements:
- you could use type annotations to do static validation with MyPy
- write some tests with unittest, pytest, nose ...
Very nice code in my opinion
answered yesterday
Julien Rousé
679517
679517
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208713%2fmad-libs-excercise%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
"Shouldnt this be ALLCAPS like i did because these words are supposed to be constants?" Not true. You re-assign the values in a
for
loop. Should you take out the assignment to the top level, outside of any loops or function calls, yes, then it would be a pseudo-const.– Mast
2 days ago