0

I need help with a function I have to write which includes a while loop that will continue going until the user enters an empty input and once that happens, the function will return the number of times a name has been entered

So far my code is:

while True:
    name = input('Enter a name:')

    lst = name.split()
    count={}
    for n in lst:
        if n in count:
            count[n]+=1

    for n in count:
        if count[n] == 1:
            print('There is {} student named {}'.format(count[n],\
                                                    n))
        else:

            print('There are {} students named {}'.format(count[n],\
                                                        n))

This doesn't repeat it only asks the user once and returns 1

the output should look like:

Enter next name:Bob
Enter next name:Mike
Enter next name:Bob
Enter next name:Sam
Enter next name:Mike
Enter next name:Bob
Enter next name:

There is 1 student named Sam
There are 2 students named Mike
There are 3 students named Bob
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
user2101463
  • 343
  • 1
  • 4
  • 14

4 Answers4

1
    for n in lst:
        if n in count:
            count[n]+=1

In your above code, n is never added to your count dict. i.e. count is still empty after the loop..

zzk
  • 1,347
  • 9
  • 15
  • Actually, it is going to fail at first `+= 1` with `KeyError`. This is because there is no value for the `n`. – pepr Mar 12 '13 at 12:45
  • 1
    @pepr no. `count[n]+=1` will not be executed as `n in count` is `False` – zzk Mar 12 '13 at 18:14
1

What @zzk is saying is

for n in lst:
    if n in count:
        count[n]+=1
    else:
        count[n]=1

For a mostly functioning answer using everyones suggestions

count= {}

while True:

    name = raw_input('Enter a name:')
    lst = name.split()

    for n in lst:
        count[n] = count.get(n, 0) + 1

    if not lst:
        for n in count:
            if count[n] == 1:
                print('There is {} student named {}'.format(count[n],n))
            else:
                print('There are {} students named {}'.format(count[n],n))
        break
John
  • 13,197
  • 7
  • 51
  • 101
  • The four lines from the `if` down can be replaced by `count[n] = count.get(n, 0) + 1`. The `.get()` is similar to `[]` except it can take a default value. – pepr Mar 12 '13 at 12:47
1

Except for the fact that you never add n to your count dictionary, you initialize this dictionary again and again with each iteration of the while-loop. You have to put it outside of the loop.

count= {}

while True:
    name = input('Enter a name:')

    lst = name.split()
    for n in lst:
        if n in count:
            count[n] += 1
        else:
            count[n] = 1

    for n in count:
        if count[n] == 1:
            print('There is {} student named {}'.format(count[n],\
                                                    n))
        else:

            print('There are {} students named {}'.format(count[n],\
                                                        n))
pemistahl
  • 9,304
  • 8
  • 45
  • 75
1

The following is a bit overkill. This is only to know that there is the standard module collections and it contains the Counter class. Anyway, I prefer the simple solution as used in the question (after removing errors). The first function reads the inputs and breaks when empty name is entered. The second function displays the result:

#!python3

import collections


def enterStudents(names=None):

    # Initialize the collection of counted names if it was not passed
    # as the argument.
    if names is None:
        names = collections.Counter()

    # Ask for names until the empty input.
    while True:
        name = input('Enter a name: ')

        # Users are beasts. They may enter whitespaces.
        # Strip it first and if the result is empty string, break the loop.
        name = name.strip()
        if len(name) == 0:
            break

        # The alternative is to split the given string to the first
        # name and the other names. In the case, the strip is done
        # automatically. The end-of-the-loop test can be based 
        # on testing the list.
        #
        # lst = name.split()
        # if not lst:
        #     break
        #
        # name = lst[0]
        #                   (my thanks to johnthexiii ;)


        # New name entered -- update the collection. The update
        # uses the argument as iterable and adds the elements. Because
        # of this the name must be wrapped in a list (or some other 
        # iterable container). Otherwise, the letters of the name would
        # be added to the collection.
        #
        # The collections.Counter() can be considered a bit overkill.
        # Anyway, it may be handy in more complex cases.    
        names.update([name])    

    # Return the collection of counted names.    
    return names


def printStudents(names):
    print(names)   # just for debugging

    # Use .most_common() without the integer argument to iterate over
    # all elements of the collection.
    for name, cnt in names.most_common():
        if cnt == 1:
            print('There is one student named', name)
        else:
            print('There are {} students named {}'.format(cnt, name))


# The body of a program.
if __name__ == '__main__':
    names = enterStudents()
    printStudents(names)

There are parts of the code that can be removed. The name argument in enterStudents() allows to call the function to add names to the existing collection. The initialization to None is used to make the empty initial collection as the default one.

The name.strip() is not neccessary if you want to collect everything, including whitespaces.

It prints on my console

c:\tmp\___python\user\so15350021>py a.py
Enter a name: a
Enter a name: b
Enter a name: c
Enter a name: a
Enter a name: a
Enter a name: a
Enter a name:
Counter({'a': 4, 'b': 1, 'c': 1})
There are 4 students named a
There is one student named b
There is one student named c    
pepr
  • 20,112
  • 15
  • 76
  • 139
  • 1
    If you're going to go to those lenghts should probably consider normalizing input (i.e. user .lower()). Should probably use raw_input instead of input. You're not stripping white space off of what you put into your Counter, not sure if Counter handles that on its own. – John Mar 12 '13 at 13:27
  • 1
    @johnthexiii: My +1. He or she uses Python 3 -- then `input()` is OK. Stripping added. The alternative with `.split()` in comments. Thanks for the comments ;) – pepr Mar 12 '13 at 13:37