-3

so I have this code to calculate the value of the variable chance and print it there are no error codes but when it gets to the print statement no matter what compiler I use to compile it nothing appears in the output

There is no error so I don't have anything to go off of

import math

luck = 54
justice = 0
compassion = 1
bravery = 1
truth = 2
coreType = "Legendary"
baseChance = 0.01
element = "Light"

import math
valid = True
if coreType == "Common":
    coreRarity = 1
elif coreType == "Rare":
    coreRarity = 1.5
elif coreType == "Legendary":
    coreRarity = 3
else:
    print("Invalid core type")
    valid = False

if justice > compassion and justice > truth and justice > bravery:
    idea = "justice"
elif compassion > justice and compassion > truth and compassion > bravery:
    idea = "compassion"
elif truth > compassion and truth > justice and truth > bravery:
    idea = truth
elif bravery > compassion and bravery > truth and bravery > justice:
    idea = "bravery"
else:
    idea = "all"

if idea == "justice" and (element == "Light" or element == "Shadow"):
    boost = justice
elif idea == "truth" and (element == "Ice" or element == "Wind"):
    boost = truth
elif idea == "compassion" and (element == "Earth" or element == "Lightning"):
    boost = compassion
elif idea == "bravery" and (element == "Fire" or element == "Water"):
    boost = bravery
elif idea == "all":
    boost = bravery #basicly the above determines what the highest idea is and sets it but if the highest is all it means they are all the same so It doesn't matter one one the boost's value is cause its all the same

if valid == True:
    chance = math.max(math.sqrt(luck*0.01*1.3)+0.95,1)*0.01*(0.01*(100+5*idea)*coreRarity*baseChance)
    if coreType == "common":
        chance =* 0.25
    print(chance)

It's supposed to print the value of chance but prints nothing

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58

2 Answers2

1

You have two issues with your code:

  • chance =* 0.25 should be chance *= 0.25 (here is a list of all assignmet operators)

  • the module math doesn't have a max attribute, so I would recommend you trying max() instead of math.max()

That beeing said try replacing your current if statement (the one at the end) with this one:

if valid == True:
    chance = max(math.sqrt(luck*0.01*1.3)+0.95,1)*0.01*(0.01*(100+5*idea)*coreRarity*baseChance)
    if coreType == "common":
        chance *= 0.25
    print(chance)

Hope this helps

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58
0

There's a lot of ways this code can be improved:

Setting coreRarity - This code below:

valid = True
if coreType == "Common":
    coreRarity = 1
elif coreType == "Rare":
    coreRarity = 1.5
elif coreType == "Legendary":
    coreRarity = 3
else:
    print("Invalid core type")
    valid = False

can be made into a dictionary lookup

coreRarityDict = {
    "Common": 1,
    "Rare": 1.5,
    "Legendary": 3
}

To set valid and coreRarity uses readable dictionary methods

valid = coreType in coreRarityDict
if valid:
    coreRarity = coreRarityDict[coreType] # dictionary lookup
else:
    print("Invalid core type")

Setting idea - The next part:

if justice > compassion and justice > truth and justice > bravery:
    idea = "justice"
elif compassion > justice and compassion > truth and compassion > bravery:
    idea = "compassion"
elif truth > compassion and truth > justice and truth > bravery:
    idea = truth
elif bravery > compassion and bravery > truth and bravery > justice:
    idea = "bravery"
else:
    idea = "all"

The logic here is basically boils down to which is the (strict) maximum of justice, compassion, truth, bravery. If there is a ties for the maximum, set idea to "all". Note idea = truth looks like it should be idea = "truth"

Again let's use a dictionary

ideasDict = {
    "justice": justice,
    "compassion": compassion,
    "truth": truth,
    "bravery": bravery, 
}

To set idea we want the key with the strict largest value See - Getting key with maximum value in dictionary?

idea = max(ideasDict, key=lambda x: ideasDict[x])

To check for ties we can count the number of times this idea value occurs in our dictionary - see Python 2.7 Counting number of dictionary items with given value

sum(1 for x in ideasDict.values() if x == idea)

Combining this,

idea = max(ideasDict, key=lambda x: ideasDict[x])
idea_freq = sum(1 for x in ideasDict.values() if x == idea)
if idea_freq > 1:
    idea = "all"

Setting boost - This code

if idea == "justice" and (element == "Light" or element == "Shadow"):
    boost = justice
elif idea == "truth" and (element == "Ice" or element == "Wind"):
    boost = truth
elif idea == "compassion" and (element == "Earth" or element == "Lightning"):
    boost = compassion
elif idea == "bravery" and (element == "Fire" or element == "Water"):
    boost = bravery
elif idea == "all":
    boost = bravery #basically the above determines what the highest idea is and sets it but if the highest is all it means they are all the same so It doesn't matter one one the boost's value is cause its all the same

Notice you are repeating if idea == "xx": boost = xx Reusing the dictionary the code would look like

if idea == "justice" and (element == "Light" or element == "Shadow"):
    boost = ideasDict[idea]
elif idea == "truth" and (element == "Ice" or element == "Wind"):
    boost = ideasDict[idea]
elif idea == "compassion" and (element == "Earth" or element == "Lightning"):
    boost = ideasDict[idea]
elif idea == "bravery" and (element == "Fire" or element == "Water"):
    boost = ideasDict[idea]
elif idea == "all":
    boost = bravery #basically the above determines what the highest idea is and sets it but if the highest is all it means they are all the same so It doesn't matter one one the boost's value is cause its all the same

That's a lot of repeating boost = ideasDict[idea]! Let's simplify further! Note the elif can just be made as an if as your conditions are non-overlapping: idea can't be both == "justice" and == "truth". Let's use a dictionary again

elementsBoostDict = {
    "justice": ["Light", "Shadow"],
    "compassion": ["Ice", "Wind"],
    "truth": ["Earth", "Lightning"],
    "bravery": ["Fire", "Water"], 
}

if idea == "all":
    boost = bravery
elif element in elementsBoostDict[idea]:
    boost = ideasDict[idea]

Notice boost may not be set e.g idea == "justice" and element == "ice" and boost is not used anywhere else in your code? Is this intended?

Calculating chance - this is your code

if valid == True:
    chance = math.max(math.sqrt(luck*0.01*1.3)+0.95,1)*0.01*(0.01*(100+5*idea)*coreRarity*baseChance)
    if coreType == "common":
        chance =* 0.25
    print(chance)

Note idea is a string (I get error TypeError: unsupported operand type(s) for +: 'int' and 'str' after previously correcting to idea = "truth") and should be replaced by it's relative value.

The line if valid == True: can be simplified to if valid: Your chance calculation includes a lot of hard coded numbers and can be simplified 0.01*0.01 = 0.0001. Let's move this into a function with some defaults. Also as luck is a percentage we'll use luck=0.54 and remove the multiplication by 0.01.

def chance_calc(coreType, coreRarity, idea, luck=0.54, baseChance=0.01):
    temp  = math.max(math.sqrt(luck * 1.3) + 0.95, 1)
    chance = temp * 0.0001 * (100 + 5 * ideasDict[idea]) * coreRarity * baseChance
    if coreType == "common":
        chance *= 0.25
    return chance

Final code

import math

justice = 0
compassion = 1
bravery = 1
truth = 2
coreType = "Legendary"
element = "Light"

coreRarityDict = {
    "Common": 1,
    "Rare": 1.5,
    "Legendary": 3
}

ideasDict= {
    "justice": justice,
    "compassion": compassion,
    "truth": truth,
    "bravery": bravery, 
}

elementsBoost = {
    "justice": ["Light", "Shadow"],
    "compassion": ["Ice", "Wind"],
    "truth": ["Earth", "Lightning"],
    "bravery": ["Fire", "Water"], 
}

# set coreRarity
valid = coreType in coreRarityDict
if valid:
    coreRarity = coreRarityDict[coreType]
else:
    print("Invalid core type")

# set idea
idea = max(ideasDict, key=lambda x: ideasDict[x])
idea_freq = sum(1 for x in ideasDict.values() if x == idea)
if idea_freq > 1:
    idea = "all"

# set boost
if idea == "all":
    boost = bravery
elif element in elementsBoost[idea]:
    boost = ideasDict[idea]

def chance_calc(coreType, coreRarity, idea, luck=0.54, baseChance=0.01):
    temp  = math.max(math.sqrt(luck * 1.3) + 0.95, 1)
    chance = temp * 0.0001 * (100 + 5 * ideasDict[idea]) * coreRarity * baseChance
    if coreType == "common":
        chance *= 0.25
    return chance

if valid:
    chance = chance_calc(coreType, coreRarity, idea)
    print(chance)

# result 0.0005899919528666251

Final thoughts and post mortem

There's a high chance I changed what you intended or made some error.

Using a structured data type like a dictionary has the benefit of simplifying code and provides methods we can use. An alternative could be using classes which could combine ideasDict and elementsBoost.

If idea is "all" then ideasDict[idea] will return None and chance_calc will return an error.

boost is not used

If ideasDict[idea] is big enough the chance may be bigger than 1.

The chance calculation looks like it could be improved. A good idea might be to write down a bunch of combinations of justice, compassion, bravery, truth, coreType, element and what chance you would like for each and then try to write a function that gets close to this.

Andrew Allen
  • 6,512
  • 5
  • 30
  • 73