3
\$\begingroup\$

I need to clean up and simplify this code (I am a beginner in Python):

print ("Type in four inputs.") 
word_first = raw_input("What is your first input? ") 
word_second = raw_input("What is your second input? ") 
word_third = raw_input("What is your third input? ") 
word_fourth = raw_input("What is your fourth input? ")

list_of_words = [word_first, word_second, word_third, word_fourth]
print
print sorted(list_of_words, key=len)

def average(numbers):
    return sum(numbers)/len(numbers)

all_words = word_first, word_second, word_third, word_fourth 
words_total = word_first, word_second, word_third, word_fourth.split()
length_words = [len(word) for word in words_total]

word_first_length = len(word_first)
word_second_length = len(word_second)
word_third_length = len(word_third)
word_fourth_length = len(word_fourth)
total_letters = word_first_length + word_second_length + word_third_length + 
word_fourth_length
average_length = total_letters / 4
print
print ("Shortest input is: ") + (min((word for word in list_of_words if word), key=len))
print ("Average length is %.1f.") %(average_length)
\$\endgroup\$

3 Answers 3

2
\$\begingroup\$

Up to, and including the line list_of_words, your code looks good. But then it gets confusing.

To summarize what your program is supposed to do:

  • 4 times: read a word from the user
  • put all these words in a list
  • sort this list by the word length
  • print the first element of the list (which is the shortest)
  • take a break (in other words, no need to sort the rest of the list, since it is already sorted)
  • ask your teacher about the unclear specification:
    • the average word length of what exactly: the whole list, or the rest?
    • why should the rest of the words be sorted when there is no requirement to print them afterwards?

Your definition of the average function was already good, you just didn't use it.

In Python, the above instructions could look like:

words = [first_word, second_word, third_word, fourth_word]
sorted_words = sorted(words, key=len)
sorted_lengths = [len(word) for word in sorted_words]

print('Shortest word: {}'.format(sorted_words[0]))
print('Remaining words: {}'.format(sorted_words[1:]))
print('Longest word: {}'.format(sorted_words[-1]))
print('Average word length: {}'.format(average(sorted_lengths)))
print('Average remaining word length: {}'.format(average(sorted_lengths[1:])))

Basically, you already had all the ingredients for solving the problem, you just mixed them up a bit.

\$\endgroup\$
2
  • \$\begingroup\$ This chages the behaviour of the original program, since it does not check whether an empty string (non-word) has been entered. words = [word for word in (first_word, second_word, third_word, fourth_word) if word] and avg = average(len(word) for word in (first_word, second_word, third_word, fourth_word)) \$\endgroup\$ Nov 13, 2017 at 10:33
  • \$\begingroup\$ Futhermore, nobody asked to print the longest word and remaining word length. \$\endgroup\$ Nov 13, 2017 at 10:38
2
\$\begingroup\$

There’s a lot of repetition in your code. I assume all you’re trying to do is get four words as input, make a list of them, sort them based on their lengths, find the length of each word, the number of characters in all these words and average of the lengths of the words, finally print the shortest word and the average length.

print ("Type in four inputs.")

You could be more specific:

print("Type in four words separated by a space.")

Get a list of four words with one raw_input()

list_of_words = raw_input('> ').split()

If you want a tuple of words, you could convert a list to a tuple:

all_words = tuple(list_of_words)

If you're trying to put all the words into a list, you could remove

words_total = word_first, word_second, word_third, word_fourth.split()

because you already have a list of the words above.

Note all_words and words_total are almost similar except the former is a tuple and the latter a list. Decide if you want them both.

length_words = [len(word) for word in words_total]

I'm changing words_total in the above to list_of_words and

word_first_length = len(word_first)
word_second_length = len(word_second)
word_third_length = len(word_third)
word_fourth_length = len(word_fourth)

I would have the above four values in a dictionary so you've pairs of words and their lengths.

lengths_of_words = {word: len(word) for word in list_of_words}

Now that I've a dictionary above, I could sum its values.

total_letters = sum(lengths_of_words.values())

Instead of the constant divisor 4, use len(list) to let Python get the divisor for you:

average_length = total_letters / len(list_of_words)

There's already a list above, so the generator in this print() is not needed.

print("Shortest input is: ") + (min((word for word in list_of_words if word), key=len))

That can be changed to:

print("Shortest input is: " + min(list_of_words, key=len))

I can't see average(numbers) function used anywhere in your code.

print("Average length is %.1f.") %(average_length)

You get a TypeError with the above, so rewrite it as:

print("Average length is %.1f." % average_length)

I agree with @Coal_'s suggestion: If you're starting out with Python, learn Python 3. For advice on choosing between Python 2 and Python 3, see Python 2 or 3.

That said, I would rewrite your code, like so:

list_of_words = raw_input("Type in four words separated by a space: ").split()

# Sort the words by their lengths and print them
print("\nSorting the words by their lengths and printing them:")
print(sorted(list_of_words, key=len))

# Create an empty dictionary
lengths_of_words = {}

# Loop through the list and add each word and its length to the above dictionary
for word in list_of_words:
    lengths_of_words[word] = len(word)

# With dict comprehension, it can be written in a one-liner:
# lengths_of_words = {word: len(word) for word in list_of_words}

total_letters = sum(lengths_of_words.values())
average_length = total_letters / len(list_of_words)

print("\nThe shortest word is: " + min(list_of_words, key=len))
print("Average length is {}.".format(average_length))

Running it:

Type in four words separated by a space: Python language is popular

Sorting the words by their lengths and printing them:
['is', 'Python', 'popular', 'language']

The shortest word is: is
Average length is 5.75.
>>>

You can visualize its execution in Python 2.7 at Python Tutor

\$\endgroup\$
1
\$\begingroup\$

If you're starting out with Python right now, learn Python 3. There's a couple of reasons to do this:

  • Python 2 is starting to become outdated and won't be supported for much longer.

  • If you start a project in Python 3, maintaining backward compatibility (usually up to Python 2.6 / 2.7) is easy to do.

  • Python 3 supports awesome new / improved features like string formatting, function annotations, and proper Unicode / bytes object handling.

\$\endgroup\$
2
  • \$\begingroup\$ The pyformat page is outdated. In python 3.6 you can do: foo = '123'; print(f'{foo}'). \$\endgroup\$ Nov 13, 2017 at 10:27
  • \$\begingroup\$ There's already a GitHub issue about f-strings, though you're right, that was two years ago. \$\endgroup\$
    – Daniel
    Nov 13, 2017 at 11:07

Your Answer

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

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