0

I am working on a project that I have to get user input, put it into a list, pass that list to multiple funcitons for manipulation, and then return the data as new lists. I was originally having trouble getting the lists to pass without altering the original list until I found out I was able to use .copy(). Well, now that I have "passed" the original list down to the functions I am using to manipulate the user input data, the manipulations for sorting the input by most and least amount of vowels are no longer working.

import sys
def main():
    words = []
    wordCount = 0
    userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
    while True:
        if len(userWord)<8:
            print("Please print at least 8 words, try again.")
            sys.exit()
        elif wordCount<=8 and userWord[wordCount] != 'bye':
            words.append(userWord[wordCount])
            wordCount = wordCount + 1
        else:
            break
    def most_vowels(): #broken - not sorting by most amount of vowels - giving original list
        words4 = words.copy()
        sorted (words4, key = lambda word: sum(ch in 'aeiou' for ch in word),
                reverse = True)
        print ('Your list of words sorted by most amount of vowels: ',words4)
    most_vowels()

    def least_vowels(): #broken - not sorting by most amount of vowels - giving original list
        words5 = words.copy()
        sorted (words5, key = lambda word: sum(ch in 'aeiou' for ch in word))
        print ('Your list of words sorted by least amount of vowels: ',words5)
    least_vowels()

main()

Prior to adding the words4 = words.copy() and words5 = words.copy(), both of these functions worked exactly like they were suppose to. Since I added this in, they are no longer working and they now just output the original list in its original order instead of sorting the words by most amount of vowels and least amount of vowels. Can anyone tell me what I am doing wrong? Thank you!

SSparks
  • 25
  • 6

2 Answers2

0

Issues-

  1. You have to store the sorted array like:

    words4 = sorted (words4, key = lambda word: sum(ch in 'aeiou' for ch in word))

  2. Your indentation is not correct for the functions

  3. You did not pass the value to the functions

Fixed Code:

import sys
def main():
    words = []
    wordCount = 0
    userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
    print(userWord)
    while True:
        if len(userWord)<8:
            print("Please print at least 8 words, try again.")
            sys.exit()
        elif wordCount >= 8 and userWord[wordCount] != 'bye':
            words.append(userWord[wordCount])
            wordCount = wordCount + 1
        else:
            break
    most_vowels(userWord)
    least_vowels(userWord)
def most_vowels(words): #broken - not sorting by most amount of vowels - giving original list
    words4 = words.copy()
    words4 = sorted (words4, key = lambda word: sum(ch in 'aeiou' for ch in word), reverse = True)
    print ('Your list of words sorted by most amount of vowels: ',words4)

def least_vowels(words): #broken - not sorting by most amount of vowels - giving original list
    words5 = words.copy()
    words5 = sorted (words5, key = lambda word: sum(ch in 'aeiou' for ch in word))
    print ('Your list of words sorted by least amount of vowels: ',words5)

main()
Yash
  • 3,438
  • 2
  • 17
  • 33
  • Note: the output of `least_vowels` is just the reversed output of `most_vowels`. No reason to go over it twice. So, you could return the result of one function to `main()` and then just print it twice (once forward, once reversed). – nostradamus Aug 29 '19 at 14:52
  • I now completely understand what I did wrong. Thank you both very much for your help. – SSparks Aug 29 '19 at 15:04
  • Happy to help. :) – Yash Aug 29 '19 at 15:04
0

In Python, sorted(list) returns a sorted copy of a list and list.sort() sorts the list in place (see this answer). So what you're doing here is making a sorted copy of the list, not assigning it to anything, and then printing the original list.

import sys
def main():
    words = []
    wordCount = 0
    userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split(' ')
    while True:
        if len(userWord)<8:
            print("Please print at least 8 words, try again.")
            sys.exit()
        elif wordCount<8 and userWord[wordCount] != 'bye':
            words.append(userWord[wordCount])
            wordCount = wordCount + 1
        else:
            break
    def most_vowels(): #broken - not sorting by most amount of vowels - giving original list
        words4 = words.copy()
        words4.sort(key = lambda word: sum(ch in 'aeiou' for ch in word),
                reverse = True)
        print ('Your list of words sorted by most amount of vowels: ',words4)
    most_vowels()

    def least_vowels(): #broken - not sorting by most amount of vowels - giving original list
        words5 = words.copy()
        words5.sort(key = lambda word: sum(ch in 'aeiou' for ch in word))
        print ('Your list of words sorted by least amount of vowels: ',words5)
    least_vowels()

main()

This works for me on https://www.katacoda.com/courses/python/playground.

I also changed the bounds on wordCount to be < instead of <= because giving exactly 8 words will cause a list indexing error otherwise; I would recommend using a for loop here instead because there's less opportunity for error. Something like:

import sys
def main():
    words = []
    userWord = input("Enter at least 8 words or 'bye' to leave the program: ").split()
    if len(userWord)<8:
        print("Please print at least 8 words, try again.")
        sys.exit()
    for i in range(len(userWord)):
        if i >= 8 or userWord[i] == 'bye':
            break
        else:
            words.append(userWord[i])

This should do the same thing, but without risk of list indexing errors. str.split() with no arguments probably does what you want (see docs), using ' ' as the separator will give you empty strings in the result if someone accidentally hits the spacebar twice.

Charles Gleason
  • 416
  • 5
  • 8