I think I have ideas to why this is happening but I don't know how to fix it. Can you help me with where I need to start on with my code and ways to fix it. Here is the results I wanted (For this example the Name = Bob and Role = Gunner):

I'm a little hesitant to post this because the code is a giant mess. But you said you didn't want a re-write you just wanted to see your code fixed, so here it is fixed. I've commented everything I changed

#renamed stat to player, the point of the object shouldn't be to hold just the stats, should hold all information
#pertaining to the player / dicer
class Dicer():
#levelm, totalexp, health removed from constructor
def __init__(self, name, role, health, attack, defense):
self.name = name #changed Name to name
self.level = 1
self.totexp = 0
self.role = role #changed Role to role
self.health = health
self.attack = attack
self.defense = defense
self.exp = 0
#instance function to print the stats of the dicer
def print_info(self):
print(
"Here is your Dicer's information:\nDicer's name: {0}\nLevel: {1}\nExperience: {2}\nRole:"\
" {3}\nRole Stats:\nHealth: {4}\nAttack: {5}\nDefense: {6}".format(self.name, self.level, self.totexp, self.role, self.health, self.attack, self.defense)
)
def choose_name():
while(True):
Name = input("What is your Dicer's name?:\n").title()
if(any(Bad_Words in Name.lower() for Bad_Words in [])):
print("That's an inappropriate name! Try again")
elif(len(Name) < 3):
print("That name is too short! Try again.")
elif(len(Name) > 16):
print("That name is too long! Try again.")
else:
#you have to return the name so you can use it later
return Name
def choose_role():
#removed all the lambdas here
Roles = {
'mage': (100, 40, 10), #(Health, Attack, Defense)
'warrior': (100, 30, 20),
'gunner': (100, 20, 30),
'archer': (100, 10, 40)
}
while(True):
Role = input("What role do you want to be?\nChoices:\n1. Mage\n2. Warrior\n3. Gunner\n4. Archer\n").title()
if(Role.lower() in (Roles)):
#don't just return None, return the name of the role and it's 3-tuple stats
#returning the role and it's stats from a function is not the best way to do this
return Role, Roles[Role.lower()]
else:
print("That's not a role! Try again.")
dicer_name = choose_name()
dicer_role_name, dicer_role_stats = choose_role()
#create a dicer using the stats returned from chose_role() function
mainDicer = Dicer(dicer_name, dicer_role_name, dicer_role_stats[0], dicer_role_stats[1], dicer_role_stats[2])
mainDicer.print_info()