Python Forum

Full Version: How do you add the results together each time a function is called?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I made a program that randomly adds numbers between 1 and 10 to a list 1,000 times and then counts the number of times each number occurs in that list. The results are given as percentages.

import random

# Declaring the variables I'm going to use
list_of_numbers = []
list_length = 0
ones = 0
twos = 0
threes = 0
fours = 0
fives = 0
sixes = 0
sevens = 0
eights = 0
nines = 0
tens = 0

# Adding a random number between 1 and 10 to my list_of_numbers 1,000 times
while list_length < 1000:
    list_of_numbers.append(random.randint(1, 10))
    list_length += 1

# Counting the number of times each number between 1 and 10 appears in the list
for each in list_of_numbers:
    if each == 1:
        ones += 1
    elif each == 2:
        twos += 1
    elif each == 3:
        threes += 1
    elif each == 4:
        fours += 1
    elif each == 5:
        fives += 1
    elif each == 6:
        sixes += 1
    elif each == 7:
        sevens += 1
    elif each == 8:
        eights += 1
    elif each == 9:
        nines += 1
    else:
        tens += 1

# Printing the results as percentages
def print_percents(num_count, num_title):
    percent = 100 * (num_count / list_length) # <--- Notice that, inexplicably, I'm able to use a variable from the script's namespace in a function and without error.
    print(str(num_title).capitalize() + ": " + str(percent) + "%")

print_percents(ones, "ones")
print_percents(twos, "twos")
print_percents(threes, "threes")
print_percents(fours, "fours")
print_percents(fives, "fives")
print_percents(sixes, "sixes")
print_percents(sevens, "sevens")
print_percents(eights, "eights")
print_percents(nines, "nines")
print_percents(tens, "tens")
It works. But now suppose I wanted to add all the percentages together to make sure they add up to 100%. How would I do that (most easily and with as little code as possible) without using global variables?
First, a list would be a better way to store the results. If you have counts = [0] * 11, then you can avoid the if/elif chain. I would also eliminate looping through twice:

for num in range(1000):
    counts[random.randint(1, 10)] += 1
Then a simple list comprehension gets the percentages:

percentages = [count / 1000 for count in counts]
Note that your ability to use list_length in a function is not inexplicable. If Python can't find the value in the function scope, it will check the module/global scope for it. That is, as long as you haven't done an assignment to that name, which flags the name as local scope to Python.

Then you can check that sum(percentages) == 1. I expect it will be wrong due to the minor inaccuracies of floating point math, but it should be close.
Did you consider using numpy to solve this problem? if you use numpy, you can easily generate array of random numbers and then count each number, something like this:

from collections import Counter
import numpy as np
Counter(np.random.randint(0, 10, 1000))
(Jul-31-2019, 01:42 AM)ichabod801 Wrote: [ -> ]First...

I don't understand how you're using num in

for num in range(1000):
    counts[random.randint(1, 10)] += 1
Num doesn't appear in the indented line.

(Jul-31-2019, 03:22 AM)scidam Wrote: [ -> ]Did you consider using numpy to solve this problem? if you use numpy, you can easily generate array of random numbers and then count each number, something like this:

from collections import Counter
import numpy as np
Counter(np.random.randint(0, 10, 1000))

Thanks, my data-scientist friend told me about that. I just wanted to see if I could do it without importing any more modules.
(Aug-08-2019, 11:18 PM)Exsul Wrote: [ -> ]I don't understand how you're using num

For loops require a loop variable. You don't have to use that loop variable, and you often don't if you are just trying to do something repeatedly. But you still need to have a loop variable. If you don't put one there you'll get a syntax error.
(Aug-09-2019, 12:48 AM)ichabod801 Wrote: [ -> ]
(Aug-08-2019, 11:18 PM)Exsul Wrote: [ -> ]I don't understand how you're using num

For loops require a loop variable. You don't have to use that loop variable, and you often don't if you are just trying to do something repeatedly. But you still need to have a loop variable. If you don't put one there you'll get a syntax error.

Ah, I get it now. Still working through what the rest of your code means. XD (I'm such a noob.)
(Jul-31-2019, 01:42 AM)ichabod801 Wrote: [ -> ]First, a list would be a better way to store the results. If you have counts = [0] * 11, then you can avoid the if/elif chain.

I'm not understanding what we are doing by defining counts as

 
counts = [0] * 11
(Aug-09-2019, 12:48 AM)ichabod801 Wrote: [ -> ]For loops require a loop variable. You don't have to use that loop variable, and you often don't if you are just trying to do something repeatedly. But you still need to have a loop variable. If you don't put one there you'll get a syntax error.
In these cases you can use the underscore _ character as variable name.
for _ in range(1000):
Underscore uses cases
(Aug-09-2019, 05:05 AM)ThomasL Wrote: [ -> ]In these cases you can use the underscore _ character as variable name.

I think it's better to use clear, descriptive variable names.

counts = [0] * 11
In Python you can multiply sequences (lists and string) by scalars (ints). [0] * 11 makes a list of 11 zeros. 'spam' * 5 makes 'spam spam spam spam spam '. Note that this is fine for strings and lists of integers, strings, or tuples. If you do it with lists of lists, like [[]] * 5, it will cause problems.
(Aug-09-2019, 01:32 PM)ichabod801 Wrote: [ -> ]I think it's better to use clear, descriptive variable names.
I totally agree in cases variables are used in the code,
variables with descriptive names that are not used are contradictive.
Pages: 1 2