10
\$\begingroup\$

I am working through Automate the Boring Stuff. How can I make this code cleaner/better?

#madlibs.py : ABS Chapter 8 Project
#Make mad libs using madlibtemplate.txt file that will prompt user for parts of speech
#Will return new file with replacements called madlib.txt

import re, os

#Create template.txt file if doesn't exist

print("Let's play MadLibs! \n Note: Your current working directory is ", os.getcwd())
if os.path.exists('madlibtemplate.txt') == False:
    print("No template file found. Using default 'madlibtemplate.txt'")
    template = open('madlibtemplate.txt', 'w+')
    template.write("""The ADJECTIVE girl walked to the NOUN and then VERB.
    A nearby NOUN was upset by this.""")
else:
    print("Using your 'madlibtemplate.txt' file:")
    template = open('madlibtemplate.txt', 'r')

#Extract text from template file & turn into list of words

template.seek(0) #reset pointer to beginning of file
text = (template.read()).lower() #make lowercase to match parts of speech

wordregex = re.compile(r'\w+|\s|\S')
words = re.findall(wordregex, text)

#Find and replace parts of speech

for i, word in enumerate(words):
    for part_of_speech in ['adjective', 'noun', 'adverb', 'verb', 'interjection']:
        if word == part_of_speech:
            print('Enter a(n) %s ' % part_of_speech)
            words[i] = input()

madlib_text_unformatted = ''.join(words)

#Capitalize first letter in each sentence (Function found on stackoverflow)

def sentence_case(text):
    # Split into sentences. Therefore, find all text that ends
    # with punctuation followed by white space or end of string.
    sentences = re.findall('[^.!?]+[.!?](?:\s|\Z)', text)

    # Capitalize the first letter of each sentence
    sentences = [x[0].upper() + x[1:] for x in sentences]

    # Combine sentences
    return ''.join(sentences)

madlib_text = sentence_case(madlib_text_unformatted)

#Print result and save to a new file

print('Here we go... \n')
print(madlib_text)

madlib = open('madlib.txt', 'w')
madlib.write(madlib_text)
madlib.close()
template.close()

print("\n This has been saved to file 'madlib.txt'")
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$
  • You could use a bit less comments, most of the code is self-explnatory
  • You could also use a bit more split of the code into functions, e.g. a function to create a default file
  • This is a full script, so it's nice to have the if __name__ == "__main__": condition to call the main function
  • If you use the """ to have a multi-line string, whatever you put will be there, including newlines and tabs. You probably want to split the string by using " on separate lines (see later).
  • Also, if you concatenate that way, you're losing the \n, it's better to use format

Revised code:

#madlibs.py : ABS Chapter 8 Project
#Make mad libs using madlibtemplate.txt file that will prompt user for parts of speech
#Will return new file with replacements called madlib.txt

import re, os

def generate_default_template():
    with open('madlibtemplate.txt', 'w+') as template:
        template.write("The ADJECTIVE girl walked to the NOUN and then VERB. "
                        "A nearby NOUN was upset by this.")

def capitalize_sentences(text):
    sentences = re.findall('[^.!?]+[.!?](?:\s|\Z)', text)
    capitalized_sentences = [sentence.capitalize() for sentence in sentences]
    return ''.join(capitalized_sentences)


def main():
    print("Let's play MadLibs!\nNote: Your current working directory is {0}".format(os.getcwd()))
    if not os.path.exists('madlibtemplate.txt'):
        print("No template file found. Using default 'madlibtemplate.txt'")
        generate_default_template()
    else:
        print("Using your 'madlibtemplate.txt' file:")

    with open('madlibtemplate.txt', 'r') as template:
        template.seek(0)
        text = (template.read()).lower()

    wordregex = re.compile(r'\w+|\s|\S')
    words = re.findall(wordregex, text)

    for i, word in enumerate(words):
        if word in {'adjective', 'noun', 'adverb', 'verb', 'interjection'}:
            print('Enter a(n) %s ' % word)
            words[i] = input()

    madlib_text_unformatted = ''.join(words)
    madlib_text = capitalize_sentences(madlib_text_unformatted)

    print('Here we go... \n')
    print(madlib_text)

    with open('madlib.txt', 'w') as madlib:
        madlib.write(madlib_text)

    print("\nThis has been saved to file 'madlib.txt'")

if __name__ == "__main__":
    main()
  • If you want to capitalize a word, there's the... well, capitalize function for that.
  • When opening files it's nice to use the with keyword, so they'll be closed automatically.
  • You don't need to do a loop when checking the parts of speech, just use the in operator.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.