Question: I want to make a randomizer for the SPECIAL stats from Fallout New Vegas, i've built most of the code, but there's cases that the sum of the variables exceed/are below the cap of 40.

Is there a way to limit them, or in cases that the sum is below or over 40, distribute the difference?

```
strength = random.randint(1, 10)
perception = random.randint(1, 10)
endurance = random.randint(1, 10)
charisma = random.randint(1, 10)
intelligence = random.randint(1, 10)
agility = random.randint(1, 10)
luck = random.randint(1, 10)
sum = strength + perception + endurance + charisma + intelligence + agility + luck

diff = 40 - sum
if diff < 0:
    diff = (diff * - 1)

print("=======================")
print("Strength:", strength)
print("Perception:", perception)
print("Endurance:", endurance)
print("Charisma:", charisma)
print("Intelligence:", intelligence)
print("Agility:", agility)
print("Luck:", luck)
print("Total:", sum)
print("Difference:", diff)
print("=======================")

```

Answer: 
Instead of generating seven independent random numbers, generate seven numbers less than 40, and use their differences to generate your stats.

```
import random

STATMAX = 10

# generate six random numbers, sorted, to use as dividers in the range
rand_numbers = sorted(random.choices(range(40), k=6))
# calculate stats by taking the differences between them
stat_numbers = [(j - i) for (i, j) in zip([0] + rand_numbers, rand_numbers + [40])]
# for values higher than 10, dump the excess values into other stats
excess_points = sum(max(s - STATMAX, 0) for s in stat_numbers)
# also, drop stats above 10 before redistributing the points
stat_numbers = [min(s, STATMAX) for s in stat_numbers]
while excess_points > 0:
    idx = random.randint(0, len(stat_numbers) - 1)
    # this approach favors balanced stats by only adding one point at a time
    # an alternate approach would be to add as many points as possible, which
    # would favor imbalanced stats (i.e. minmaxing)
    if stat_numbers[idx] < STATMAX:
        stat_numbers[idx] += 1
        excess_points -= 1

strength, perception, endurance, charisma, intelligence, agility, luck = stat_numbers

```

You can tailor this approach in a few different ways. For example, if you want a chance of rolling less than 40 total stats, you could generate *seven* random numbers instead, and use the last random number as an endpoint instead of 40.
I would not recommend generating the attributes independently from each other (Green Cloak Guy has provided an instructive answer on how this can be done better).

That said, if for some reason you want to do it nonetheless, you can distribute the differences across the attributes as follows:

```
import random

strength = random.randint(1, 10)
perception = random.randint(1, 10)
endurance = random.randint(1, 10)
charisma = random.randint(1, 10)
intelligence = random.randint(1, 10)
agility = random.randint(1, 10)
luck = random.randint(1, 10)

list_attributes = [strength, perception, endurance, charisma, intelligence, agility, luck]
sum_attributes = sum(list_attributes)
diff = 40 - sum_attributes

if diff != 0:
    diff_partial = diff/len(list_attributes)
    for i, attribute in enumerate(list_attributes):
        list_attributes[i] = attribute + diff_partial

strength, perception, endurance, charisma, intelligence, agility, luck = list_attributes

```

Keep in mind that, since `random` returns `float` values, your updated attributes will be `float`s as well. In case you need them as `int`, you could, for example, use `int()` inside the `for` loop.