Question about incrementing based on number of uppercase in a list of strings

Hello! I have a program that creates a list in which each element is a string retrieved via user input. The user continues entering input until ‘q’ is entered to break the while loop and return the list to main(). No issues there.

That list is then passed to the next function as a parameter, where it is iterated to calculate the number of uppers in each string element. I was able to return the correct result, technically, using a for loop and isupper(). But it’s confusing and needs to be fixed.

Code:

def get_strings():
    ''' take input until input = q beaks loop, store inputs in list,
        return list to main() '''
    l_phrases= []
    ask_again = 1
    while ask_again == 1:
        phrases = input("Enter your words/phrases, or q to quit, here: ")
        l_phrases.append(phrases)
        if phrases == "q":
            ask_again = 0
            break
    return l_phrases

def count_caps(l_phrases):
    ''' take input list as parameter, iterate list to tally number of uppers,
        store number in new list, display new list '''
    num_caps = []
    for words in l_phrases:
        caps = sum(1 for letters in words if letters.isupper())
        num_caps.append(caps)
        print(num_caps)
            
def main():
    ''' print elements from list of inputs on separate lines,
        call functions '''
    l_phrases= get_strings()
    for p in l_phrases:
        print(p)
    count_caps(l_phrases)

main()

For input:

Enter your words/phrases, or q to quit, here: How
Enter your words/phrases, or q to quit, here: You
Enter your words/phrases, or q to quit, here: Doin
Enter your words/phrases, or q to quit, here: q

Output:

How
You
Doin
q
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 0]

As I said, technically correct. I would like to understand how I can achieve just displaying the string elements and the final list of uppercase counts in each of those elements.

My desired output:

How
You
Doin
q
[1, 1, 1, 0]

In count_caps it’s printing num_caps for each word because that line is indented more than the for. If it was indent the same amount as the for, it would print only once afterwards.

Also, in get_strings, ask_again is pointless because you’re breaking out of the loop immediately after setting ask_again to 0. You might as well drop that variable and have just while True and the break.

1 Like

I think you want for word not for words and for letter not for letters.
In each case there is one word and one letter. The plural is misleading.

I know (I’ve been told). I don’t know why I still do it. I need to break the habit.

I understand what you mean. My example was just one word, though in the exercise, the inputs varied between one and several words, each of which included zero to several uppercase letters. Which is why I initially thought to use plurals. I should have been more clear in my example.

Sorry to reply twice. I just have to ask though. Can I really use while True: the same way I use ask_again = 1 while ask_again == 1:? Honestly, I always thought when I saw it used, there was a boolean condition in place that I wasn’t seeing due to my inexperience.

Just a small remark, but this:

caps = sum(1 for letters in words if letters.isupper())

can be simplified to just:

caps = sum(letter.isupper() for letter in word)

(I agree with Barry’s comment that singular more correct than plural here)

This works because True has type bool, which is a subclass of int. The value of True is actually 1, and the value of False is 0:

>>> print(True == 1)
True
>>> print(True + True)
2
>>> print(False == 0)
True
>>> print(False * 2)
0
1 Like

while True is a way of saying ‘loop forever’. Sometimes it’s just simpler to do that and use break to leave the loop.

1 Like

Applied all the advice given. More concise, easier to read, output is perfect! Thanks!