Freddie R Freddie R - 1 year ago 79
Python Question

How to round to specific values in Python

I am working on an algorithm to automatically create character sheets for a roleplaying game. In the game, you have attributes which you put points into to increase them. However, at a certain value it takes 2 points to increase the value of the actual attribute by 1. You start of with a certain number of points, and each attribute has a value of 1 by default

I have a program that randomly assigns the points, however I am stuck as to how I then change these values (that are in a dictionary) to round down when necessary.

For example, if I put 3 points in "strength", thats fine, I get a "strength" value of 3 (including tha base 1). However, if I put 4 points in, I still should only have a value of 4. It should take 5 points (plus the base 1) in order to get a value of 5. It then takes another 2 points to get a value of 6, 3 points to get a value of 7 and 3 points to get a value of 8.

The code I am currently using to assign the attibutes looks like this:

attributes = {}
row1 = ['strength', 'intelligence', 'charisma']
row2 = ['stamina', 'willpower']
row3 = ['dexterity', 'wits', 'luck']

def assignRow(row, p): # p is the number of points you have to assign to each row
rowValues = {}
for i in range(0, len(row)-1):
val = randint(0, p)
rowValues[row[i]] = val + 1
p -= val
rowValues[row[-1]] = p + 1
return attributes.update(rowValues)

assignRow(row1, 7)
assignRow(row2, 5)
assignRow(row3, 3)

What I want is just a simple function that takes the dictionary "attributes" as a parameter, and converts the number of points each attribute has to the proper value it should be.

"strength": 4
stays as
"strength": 4
, but
"wits": 6"
goes down to
"wits": 5"
, and
"intelligence: 9
goes down to
"intelligence: 7"

I'm somewhat new to using dictionaries and so the ways I would normally approach this:

def convert(list):
for i in range(len(list)):
if list[i] <= 4:
list[i] = list[i]
if list[i] in (5, 6):
list[i] -= 1
if list[i] in (7, 8):
list[i] -= 2
if list[i] in (9, 10):
list[i] = 6
if list[i] in (11, 12, 13):
list[i] = 7
list[i] = 8

Not efficient or pretty but still a solutuion. However, you can't just loop over indexes in a dictionary so I am not entirely sure how to go about something like this.

General explanation or function would be appreciated.

Answer Source

Seems that bisection algo suits your needs pretty well - points to "invest" is always sorted and defined. Create array with reference points and you're good to without bunch of ifs:

>>> from bisect import bisect
>>> points_to_invest = [1, 2, 3, 4, 6, 8, 10, 13]
>>> bisect(points_to_invest, 1)
>>> bisect(points_to_invest, 4)
>>> bisect(points_to_invest, 5)
>>> bisect(points_to_invest, 6)

This approach will give you way easier maintainability for future

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download