I am attempting to adapt the Python Plotly example on 'Adding Sliders to Animations in Python' to a barchart but am getting a 'Figure field is invalid' message.
I am trying to adapt the input data to reflect that of a bar chart rather than a scatter chart (used in the example). I have created a grid:
Which I am using with the following code:
years = ['2007','2008','2009']
items = ['Name_1','Name_2']
col_name_template = '{column}'
for year in years:
frame = {'data': [], 'name': str(year)}
x_list = []
y_list = []
for item in items:
x_list.append(grid.get_column_reference(col_name_template.format(column='name')))
y_list.append(grid.get_column_reference(col_name_template.format(column=year)))
frame['data'].append(go.Bar(
x=x_list,
y=y_list
))
figure['frames'].append(frame)
slider_step = {'args': [
[year],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': year,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
py.icreate_animations(figure, 'barchart example')
When trying to plot I get the following error:
Figure field is invalid. Reason: Raw data arrays are not allowed at this endpoint. Use grid references instead. Raw data found at the following paths in the figure...
How do I use only grid references but also ensure that a bar chart is plotted rather than a scatter chart?
I used the offline method of plotting plotly.offline.iplot which doesn't require grid references. The only downside of animations with bar charts is that transitions aren't currently supported.
Code below (including buttons and slider):
from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML
init_notebook_mode(connected = True)
years = ['2010', '2011', '2012']
items = ['A', 'B', 'C', 'D']
count = [
[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2]
]
figure = {
'data': [{
'type': 'bar',
'x': items,
'y': count[0]
}],
'layout': {
'xaxis': {
'title': 'X',
'gridcolor': '#FFFFFF',
'linecolor': '#000',
'linewidth': 1,
'zeroline': False,
'autorange': False
},
'yaxis': {
'title': 'Y',
'gridcolor': '#FFFFFF',
'linecolor': '#000',
'linewidth': 1,
'range': [0, 5],
'autorange': False
},
'title': 'Example Title',
'hovermode': 'closest',
'updatemenus': [{
'type': 'buttons',
'buttons': [{
'label': 'Play',
'method': 'animate',
'args': [None, {
'frame': {
'duration': 500,
'redraw': True
},
'fromcurrent': True,
'transition': {
'duration': 300,
'easing': 'quadratic-in-out'
}
}]
},
{
'label': 'End',
'method': 'animate',
'args': [None, {
'frame': {
'duration': 0,
'redraw': True
},
'fromcurrent': True,
'mode': 'immediate',
'transition': {
'duration': 0
}
}]
}
],
'direction': 'left',
'pad': {
'r': 10,
't': 87
},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}]
},
'frames': []
}
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {
'size': 20
},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'
},
'transition': {
'duration': 300,
'easing': 'cubic-in-out'
},
'pad': {
'b': 10,
't': 50
},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
for index, year in enumerate(years):
frame = {
'data': [{
'type': 'bar',
'x': items,
'y': count[index]
}],
'name': str(year)
}
figure['frames'].append(frame)
slider_step = {
'args': [
[year],
{
'frame': {
'duration': 300,
'redraw': True
},
'mode': 'immediate',
'transition': {
'duration': 300
}
}
],
'label': year,
'method': 'animate'
}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
iplot(figure)
Related
I have a json array on python which I want to filter based on the value of : my_json_array['models']['variants']['condition']['type']
my json array looks like the following :
my_json_array = [
{'id': 1,
'models': [
{'color': {'code': '#626262', 'name': 'Gray'},
'variants': [{'id': 1,
'condition': [{'id': 1,
'type': 'type1',
'value': 14900},
{'id': 2,
'type': 'type2',
'value': 14000}]]
]
}]
I'm looking for a method to remove condition items with type = type2. The output should look like this :
my_json_array = [{
'id': 1,
'models': [
{'color': {'code': '#626262', 'name': 'Gray'},
'variants': [{'id': 1,
'condition': [{'id': 1,
'type': 'type1',
'value': 14900}]]
]
}]
Do you mean this?
my_json_array = [
{
'id': 1,
'models': [
{
'color': {'code': '#626262', 'name': 'Gray'},
'variants': [
{
'id': 1,
'condition': [
{
'id': 1,
'type': 'type1',
'value': 14900
},
{
'id': 2,
'type': 'type2',
'value': 14000
}
]
}
]
}
]
}
]
for mydict in my_json_array:
for model in mydict['models']:
for variant in model['variants']:
for condition in variant['condition']:
if condition['type']=="type2":
variant['condition'].remove(condition)
print(my_json_array) # [{'id': 1, 'models': [{'color': {'code': '#626262', 'name': 'Gray'}, 'variants': [{'id': 1, 'condition': [{'id': 1, 'type': 'type1', 'value': 14900}]}]}]}]
I have below list of dicts
[{
'NAV': 50,
'id': '61e6b2a1d0c32b744d3e3b2d'
}, {
'NAV': 25,
'id': '61e7fbe2d0c32b744d3e6ab4'
}, {
'NAV': 30,
'id': '61e801cbd0c32b744d3e7003'
}, {
'NAV': 30,
'id': '61e80663d0c32b744d3e7c51'
}, {
'NAV': 30,
'id': '61e80d9ad0c32b744d3e8da6'
}, {
'NAV': 30,
'id': '61e80f5fd0c32b744d3e93f0'
}, {
'NAV': 30,
'id': '61e90908d0c32b744d3ea967'
}, {
'NAV': 30,
'id': '61ea7cf3d0c32b744d3ed1b2'
}, {
'NAV': 50,
'id': '61fa387127e14670f3a67194'
}, {
'NAV': 30,
'id': '61fa3cea27e14670f3a6772c'
}, {
'Amount': 30,
'id': '61e6b373d0c32b744d3e3d14'
}, {
'Amount': 30,
'id': '61e6b49cd0c32b744d3e3ea0'
}, {
'Amount': 25,
'id': '61e7fe90d0c32b744d3e6ccd'
}, {
'Amount': 20,
'id': '61e80246d0c32b744d3e7242'
}, {
'Amount': 20,
'id': '61e80287d0c32b744d3e74ae'
}, {
'Amount': 20,
'id': '61e80253d0c32b744d3e733e'
}, {
'Amount': 34,
'id': '61e80697d0c32b744d3e7edd'
}, {
'Amount': 20,
'id': '61e806a3d0c32b744d3e7ff9'
}, {
'Amount': 30,
'id': '61e80e0ad0c32b744d3e906e'
}, {
'Amount': 30,
'id': '61e80e22d0c32b744d3e9198'
}, {
'Amount': 20,
'id': '61e81011d0c32b744d3e978e'
}, {
'Amount': 20,
'id': '61e8104bd0c32b744d3e9a92'
}, {
'Amount': 20,
'id': '61e81024d0c32b744d3e98cd'
}, {
'Amount': 20,
'id': '61e90994d0c32b744d3eac2b'
}, {
'Amount': 20,
'id': '61e909aad0c32b744d3ead76'
}, {
'Amount': 50,
'id': '61fa392a27e14670f3a67337'
}, {
'Amount': 50,
'id': '61fa393727e14670f3a67347'
}, {
'Amount': 50,
'id': '61fa3d6727e14670f3a67750'
}, {
'Amount': 150,
'id': '61fa3d7127e14670f3a67760'
}]
Above list contains dict which has key as NAV and Amount. I need to find the max value separately among all the dicts for NAV and Amount. So that output is
NAV = 50
Amount = 150
I have tried some approach like:
max(outList, key=lambda x: x['NAV'])
But this is giving me keyerror of 'NAV'. What is the best way to do it?
I don't understand why you are calling Current NAV ($ M). It doesn't exist in the list you have provided. Anyway, I came up with the code below:
def getMax(value):
if "NAV" in value:
return value["NAV"]
else:
return value["Amount"]
max(outList, key= getMax)
If you are interested in finding the max value for NAV and Amount separately, you can try filtering the list out and then calling the lambda as you used before.
print(max([x["NAV"] for x in outList if "NAV" in x]))
print(max([x["Amount"] for x in outList if "Amount" in x])
you could try something like this:
print max([i["NAV"] for i in t if "NAV" in i])
print max([i["Amount"] for i in t if "Amount" in i])
Result:
50
150
def max_from_list(t_list, key):
return max([i[key] for i in t_list if key in i])
if you are not only looking for NAV and Amount, maybe you can do as below:
from collections import defaultdict
res = defaultdict(list)
for i in d:
for k, v in i.items():
if k != 'id':
res[k] = max(res.get(k, 0), v)
You are on the right track with your max solution:
assuming your list is called outList (BTW, that is not a pythonic name, try out_list instead)
nav = max(outList, key=lambda item: item.get("NAV", float("-inf")))['NAV']
amount = max(outList, key=lambda item: item.get("Amount", float("-inf")))['Amount']
I have collated some data on world happiness index reports from 2015 to 2019, which you can access here and download the dataset. I want to make an animation slider of happiness vs some other factor (like economy, health, etc) over the years. Below is my code:
import pandas as pd
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot
from plotly.graph_objs import *
init_notebook_mode()
from chart_studio.grid_objs import Grid, Column
from plotly.tools import FigureFactory as FF
dataset = pd.read_csv('Full dataset.csv')
dataset.drop(['Family', 'Standard Error'], axis=1, inplace=True)
years_from_col = set(dataset['year'])
years_ints = sorted(list(years_from_col))
years = [str(year) for year in years_ints]
# make list of continents
continents = []
for continent in dataset['Continent']:
if continent not in continents:
continents.append(continent)
df = pd.DataFrame()
# make grid
for year in years:
for continent in continents:
dataset_by_year = dataset[dataset['year'] == int(year)]
dataset_by_year_and_cont = dataset_by_year[dataset_by_year['Continent'] == continent]
for col_name in dataset_by_year_and_cont:
# each column name is unique
temp = '{year}+{continent}+{header}_grid'.format(
year=year, continent=continent, header=col_name
)
#if dataset_by_year_and_cont[col_name].size != 0:
df = df.append({'value': list(dataset_by_year_and_cont[col_name]), 'key': temp}, ignore_index=True)
figure = {
'data': [],
'layout': {},
'frames': []
}
figure['layout']['xaxis'] = {'title': 'Economy (GDP per Capita)', 'type': 'log', 'autorange': True}
figure['layout']['yaxis'] = {'title': 'Happiness Score', 'autorange': True}
figure['layout']['hovermode'] = 'closest'
figure['layout']['showlegend'] = True
figure['layout']['sliders'] = {
'args': [
'slider.value', {
'duration': 400,
'ease': 'cubic-in-out'
}
],
'initialValue': '2015',
'plotlycommand': 'animate',
'values': years,
'visible': True
}
figure['layout']['updatemenus'] = [
{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': False},
'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}
]
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
custom_colors = {
'Asia': 'rgb(171, 99, 250)',
'Europe': 'rgb(230, 99, 250)',
'Africa': 'rgb(99, 110, 250)',
'North America': 'rgb(25, 211, 243)',
'South America': 'rgb(25, 163, 243)',
'Oceania': 'rgb(50, 170, 255)'
}
col_name_template = '{year}+{continent}+{header}_grid'
year = 2015
for continent in continents:
data_dict = {
'x': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Economy (GDP per Capita)'
), 'value'].values[0],
'y': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Happiness Score'
), 'value'].values[0],
'mode': 'markers',
'text': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Country'
), 'value'].values[0],
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Generosity'
), 'value'].values[0],
'color': custom_colors[continent]
},
'name': continent
}
figure['data'].append(data_dict)
for year in years:
frame = {'data': [], 'name': str(year)}
for continent in continents:
data_dict = {
'x': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Economy (GDP per Capita)'
), 'value'].values[0],
'y': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Happiness Score'
), 'value'].values[0],
'mode': 'markers',
'text': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Country'
), 'value'].values[0],
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': df.loc[df['key']==col_name_template.format(
year=year, continent=continent, header='Generosity'
), 'value'].values[0],
'color': custom_colors[continent]
},
'name': continent
}
frame['data'].append(data_dict)
figure['frames'].append(frame)
slider_step = {'args': [
[year],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': year,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
iplot(figure, config={'scrollzoom': True})
It produces animation of a blank viz, like so:
What went wrong? And how do I fix it?
import pandas as pd
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()
dataset = pd.read_csv('https://raw.githubusercontent.com/PrashantSaikia/Happiness-Index/master/Full%20dataset.csv')
years = list(dataset['year'].sort_values().unique())
continents = list(dataset['Continent'].sort_values().unique())
layout = {
'xaxis': {
'title': 'Economy (GDP per Capita)',
'type': 'log',
'autorange': True
},
'yaxis': {
'title': 'Happiness Score',
'autorange': True
},
'hovermode': 'closest',
'showlegend': True,
'updatemenus': [{
'buttons': [
{
'args': [None, {'frame': {'duration': 600, 'redraw': True}, 'fromcurrent': True, 'transition': {'duration': 0}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate', 'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}],
'sliders': [{
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}]
}
custom_colors = {
'Asia': 'rgb(171, 99, 250)',
'Europe': 'rgb(230, 99, 250)',
'Africa': 'rgb(99, 110, 250)',
'North America': 'rgb(25, 211, 243)',
'South America': 'rgb(25, 163, 243)',
'Oceania': 'rgb(50, 170, 255)'
}
data = []
year = years[0]
for continent in continents:
df = dataset[(dataset['Continent'] == continent) & (dataset['year'] == year)]
data.append(go.Scatter(x=df['Economy (GDP per Capita)'],
y=df['Happiness Score'],
text=df['Country'],
mode='markers',
marker={
'size': 100 * df['Generosity'],
'color': custom_colors[continent]
},
name=continent))
frames = []
for year in years[1:]:
frame = {'data': [], 'name': str(year)}
for continent in continents:
df = dataset[(dataset['Continent'] == continent) & (dataset['year'] == year)]
frame['data'].append(go.Scatter(x=df['Economy (GDP per Capita)'],
y=df['Happiness Score'],
text=df['Country'],
mode='markers',
marker={
'size': 100 * df['Generosity'],
'color': custom_colors[continent]
},
name=continent))
frames.append(go.Frame(data=frame['data'], name=frame['name']))
slider_step = {
'args': [
[str(year)],
{'frame': {'duration': 600, 'redraw': True},
'mode': 'immediate',
'transition': {'duration': 200}}
],
'label': str(year),
'method': 'animate'
}
layout['sliders'][0]['steps'].append(slider_step)
figure = go.Figure(data=data, layout=layout, frames=frames)
iplot(figure)
I'm making a script for the game and i need help about grabbing dictionary information out of json.
So far I've dealt with list and I didn't had problem grabbing that information.
req['result']['trades'][key]['output']
This is my try of grabbing the info after which i get error list indices must be integers, not dict.
Any help greatly appreciated.
json print, i have removed some account sensitive data.
{
'fue_step': 30,
'type': 'm',
'rubies': xxx,
'might': xxx,
'race': 'xxx',
'result': {
'trades': [
{
'id': 13,
'requirement': ['VenomTrapPart', 1],
'token_cost': 1,
'output': ['VulcansBlessingRare', 1],
'name': 'VenomVulcan',
'enabled': True
},
{
'id': 14,
'requirement': ['EternalRune', 50],
'token_cost': 1,
'output': ['ColossalMite500TroopPrizeItem', 1],
'name': 'EternalColossal',
'enabled': True
},
{
'id': 86,
'requirement':['RenameProclamation', 25],
'token_cost': 1,
'output': ['TimeTrickstersBag', 1],
'name': 'RenameTrick',
'enabled': True
},
{
'id': 95,
'requirement': ['FireDragonBlaze', 1],
'token_cost': 1,
'output': ['FireTroop1000TroopPrizeItem', 10],
'name': 'BlazeFireTroop',
'enabled': True
},
{
'id': 100,
'requirement': ['StoneDragonQuake', 1],
'token_cost': 1,
'output': ['StoneTroop10kTroopPrizeItem', 1],
'name': 'StoneDQStoneTroop',
'enabled': True
},
{
'id': 113,
'requirement': ['VulcansBlessing15Elite', 3],
'token_cost': 1,
'output': ['VulcansBlessing16Elite', 1],
'name': '15 --> 16 Elite',
'enabled': True
},
{
'id': 114,
'requirement': ['LunaPowder', 25],
'token_cost': 1,
'output': ['IceTroop50kTroopPrizeItem', 1],
'name': 'Luna Powder --> Soul Reapers',
'enabled': True
},
{
'id': 115,
'requirement': ['GreaterCrystalDefense', 5],
'token_cost': 1,
'output': ['MasterCrystalDefense', 1],
'name': 'Greater Defense --> Master Defense',
'enabled': True
},
{
'id': 116,
'requirement': ['NanoCanisters', 3],
'token_cost': 1,
'output': ['TestroniusDeluxe', 1],
'name': 'Nano Canisters for Deluxes',
'enabled': True
},
{
'id': 117,
'requirement': ['VulcansBlessing16Common', 3],
'token_cost': 1,
'output': ['VulcansBlessing17Common', 1],
'name': "Common +16's for Common +17",
'enabled': True
}
],
'trades_today': 0,
'doubloons_left': 9567,
'free_trades_left': 1,
'success': True,
'auto_confirm': True,
'trade_reset_date':1450771200
},
'client_cachebreaker': '1449879464'
I edited your edit to include indentation in your JSON so that it is more readable. As soon as the edit is approved, you'll be able to see it.
Here is an example of how to access a value deep within the object:
print req['result']['trades'][4]['name']
Output:
StoneDQStoneTroop
If you want to access dicts within a list by their values, here is a post that explains a few ways to do so. This would allow you, for example, to find a dict in req['result']['trades'] by its 'id' value instead of by its index within the 'trades' list.
I'm trying to script a simple Character Generator that I can use for Pen and Paper RPG's. I was thinking about storing all my information in a nested dictionary and saving it into a JSON file.
However, while creating the following dictionary, I receive as error:
nhashable type: 'dict', focussing on {'cha': 1}}}
core_phb = {
'races': {
'Human': {
{'abilities': 'None'},
{'alignment': 'Neutral'},
{'size': 'Medium'},
{'speed': 6},
{'languages': 'Common'},
{'ability_modifiers': {
{'str': 1},
{'dex': 1},
{'con': 1},
{'int': 1},
{'wis': 1},
{'cha': 1}}}
},
'Dwarf': {
{'abilities': [
'ability1',
'ability2'
]},
{'alignment': 'Lawful Good'},
{'size': 'Medium'},
{'speed': 5},
{'languages': [
'Common',
'Dwarven'
]},
{'ability_modifiers': [
{'con': 2},
{'wis': 1}
]}
},
'Elf': {
{'abilities': [
'ability1',
'ability2'
]},
{'alignment': 'Chaotic Good'},
{'size': 'Medium'},
{'speed': 6},
{'languages': [
'Common',
'Elven'
]},
{'ability_modifiers': [
{'dex': 2},
{'int': 1}
]}
}
},
'classes': {
{'Fighter': {}},
{'Ranger': {}},
{'Wizard': {}}
},
'ability_scores': [
{'Str': 'str'},
{'Dex': 'dex'},
{'Con': 'con'},
{'Int': 'int'},
{'Wis': 'wis'},
{'Cha': 'cha'}]
}
I am simply trying to create the dictionary, not calling any keys from it.
As I understand from TypeError: unhashable type: 'dict' , I can use frozenset() to get keys.
Is there a better way to do what I am trying to do?
You seem to be making dictionaries {...} incorrectly for Python.
Lists look like this:
[ {'a': 1}, {'b': 1}, {'c': 1} ]
Dictionaries look like this:
{ 'a': 1, 'b': 2, 'c': 3 }
If I'm guessing the behavior you want correctly, then you probably wanted something like this:
human = {
'abilities': 'None',
'alignment': 'Neutral',
'size': 'Medium',
'speed': 6,
'languages': 'Common',
'ability_modifiers': {
'str': 1,
'dex': 1,
'con': 1,
'int': 1,
'wis': 1,
'cha': 1
}
}
The problem is not with the dicts, but with the sets. The elements of a set must be hashable. In
core_phb = {
'races': {
'Human': {
{'abilities': 'None'},
{'alignment': 'Neutral'},
{'size': 'Medium'},
{'speed': 6},
{'languages': 'Common'},
{'ability_modifiers': {
{'str': 1},
{'dex': 1},
{'con': 1},
{'int': 1},
{'wis': 1},
{'cha': 1}}}
},
'Dwarf': {
{'abilities': [
'ability1',
'ability2'
]},
{'alignment': 'Lawful Good'},
{'size': 'Medium'},
{'speed': 5},
{'languages': [
'Common',
'Dwarven'
]},
{'ability_modifiers': [
{'con': 2},
{'wis': 1}
]}
},
'Elf': {
{'abilities': [
'ability1',
'ability2'
]},
{'alignment': 'Chaotic Good'},
{'size': 'Medium'},
{'speed': 6},
{'languages': [
'Common',
'Elven'
]},
{'ability_modifiers': [
{'dex': 2},
{'int': 1}
]}
}
},
'classes': {
{'Fighter': {}},
{'Ranger': {}},
{'Wizard': {}}
},
'ability_scores': [
{'Str': 'str'},
{'Dex': 'dex'},
{'Con': 'con'},
{'Int': 'int'},
{'Wis': 'wis'},
{'Cha': 'cha'}]
}
the key is fine, but the value is an illegal set, because its elements are dicts. You could make frozensets from the sets and you'd be OK.
{frozenset({1})}
{frozenset({1})}
{{1}}
Traceback (most recent call last):
Python Shell, prompt 7, line 1
builtins.TypeError: unhashable type: 'set'
I think this :
'Human': {
{'abilities': 'None'},
{'alignment': 'Neutral'},
{'size': 'Medium'},
{'speed': 6},
{'languages': 'Common'},
{'ability_modifiers': {
{'str': 1},
{'dex': 1},
{'con': 1},
{'int': 1},
{'wis': 1},
{'cha': 1}}}
},
should be a list. Otherwise, each of the comma-separated elements is a mutable element which you are trying to store in a set. You are already doing it right with the very last entry:
'ability_scores': [
{'Str': 'str'},
{'Dex': 'dex'},
{'Con': 'con'},
{'Int': 'int'},
{'Wis': 'wis'},
{'Cha': 'cha'}]
so why not all the others?