Skip to content

Instantly share code, notes, and snippets.

@ChanceToZoinks
Last active April 23, 2022 17:37
Show Gist options
  • Save ChanceToZoinks/aacdb407862f4b20a7abdaebc65cb66a to your computer and use it in GitHub Desktop.
Save ChanceToZoinks/aacdb407862f4b20a7abdaebc65cb66a to your computer and use it in GitHub Desktop.
poeninja exploration notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2\n",
"import requests"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"MAIN_ENDPOINT = f\"https://poe.ninja/api/data/0/getbuildoverview\"\n",
"\n",
"PARAMS = {\"overview\": \"archnemesis\", \"type\": \"exp\", \"language\": \"en\"}\n",
"\n",
"def try_get_builds(url, params):\n",
" r = requests.get(url=url, params=params)\n",
" try:\n",
" return r.json()\n",
" except:\n",
" return {}\n",
"\n",
"data = try_get_builds(MAIN_ENDPOINT, PARAMS)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def get_user_ascendancy(user_idx: int, api_data: dict):\n",
" asc_idx = api_data[\"classes\"][user_idx]\n",
" return api_data[\"classNames\"][asc_idx]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def summarize_player(idx, data):\n",
" classes = data['classes']\n",
" names = data['names']\n",
" name = names[idx]\n",
" person_class = classes[idx]\n",
" class_name = get_user_ascendancy(idx, data)\n",
" return (name, person_class, class_name)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def get_skill_enjoyers(skills, data):\n",
" enjoyers = []\n",
" for skill_id, skill_map in data['activeSkillUse'].items():\n",
" if int(skill_id) in skills:\n",
" enjoyers = [data['names'][x] for x in skill_map]\n",
" return enjoyers"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('시불세끼정한아시불하면서세끼쳐묵하는정한아란뜻', 9, 'Necromancer')\n",
"['Rotkojyra']\n"
]
}
],
"source": [
"solya_si = 9391 # case study randomly chosen necro. they are using (phantasmal) cremation as their main skill\n",
"print(summarize_player(solya_si, data))\n",
"cremation = 115 # conductivity in allSkills vs cremation in activeSkills, 69 in skill details\n",
"phant_cremation = 412 # divergent multistrike in allSkills vs phantasmal_cremation in activeSkills\n",
"crema_enjoyers = get_skill_enjoyers([cremation, phant_cremation], data)\n",
"print(crema_enjoyers[:10]) # a lot of duplicated names and mostly aurabot/aurastacker names e.g. mostly Ascendants, notably Solya_Si is NOT in here"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('AuraStack_Cafu', 0, 'Ascendant')\n",
"False\n"
]
}
],
"source": [
"aurastack_cafu = 345 # case 2, they are 2nd in the list of people using active skill 115, note that this person is ACTUALLY using spark\n",
"spark = 9 # 9 is spark in activeSkills but phant flame wall in allSkills\n",
"anom_spark = 10 # 10 is anom spark in activeSkills but cwdt in allSkills\n",
"print(summarize_player(aurastack_cafu, data))\n",
"spark_enjoyers = get_skill_enjoyers([spark, anom_spark], data)\n",
"print(data['names'][aurastack_cafu] in spark_enjoyers) # hmmmmmm thats weird they arent in the list?"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('MaximusMazorkis', 0, 'Ascendant')\n",
"True\n",
"False\n"
]
}
],
"source": [
"maximus_mazorkis = 1 # this person is interesting because they seemingly show up EVERYWHERE multiple times, while not having an active skill (aurabot)\n",
"print(summarize_player(maximus_mazorkis, data))\n",
"print(data['names'][maximus_mazorkis] in spark_enjoyers) # hmmmmmm\n",
"print(data['names'][maximus_mazorkis] in crema_enjoyers) # HMMMMMMMMMMMMMMMMM, interesting... this suggests that activeSkillUse is not doing what we think"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# i suspect skillDetails is the actual skill data despite how things are labeled in the json\n",
"def get_player_details(idx, data):\n",
" for i, skill in enumerate(data['skillDetails']):\n",
" for person, l in skill['dps'].items():\n",
" if (p:=int(person)) == idx:\n",
" return (summarize_player(p, data), f\"skill={skill['name']}\", f\"dps={l[0]}\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(('시불세끼정한아시불하면서세끼쳐묵하는정한아란뜻', 9, 'Necromancer'), 'skill=Volatile Dead', 'dps=656469')\n",
"(('AuraStack_Cafu', 0, 'Ascendant'), 'skill=Spark', 'dps=24688130')\n",
"None\n"
]
}
],
"source": [
"print(get_player_details(solya_si, data))\n",
"print(get_player_details(aurastack_cafu, data))\n",
"print(get_player_details(maximus_mazorkis, data)) # finally"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('그냥달려나갑니다', 0, 'Ascendant')\n",
"('촉수언냐보빨러', 0, 'Ascendant')\n",
"('Kamilea', 9, 'Necromancer')\n"
]
}
],
"source": [
"print(summarize_player(588, data))\n",
"print(summarize_player(588+345, data))\n",
"print(summarize_player(588+345+7377, data))"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"def find_characters_by_skill(skill_idx: int, data: dict):\n",
" pointer = data['activeSkillUse'][str(skill_idx)][0]\n",
" for i in data['activeSkillUse'][str(skill_idx)][1:]:\n",
" yield pointer\n",
" pointer += i\n",
"\n",
"def get_first_n_by_skill(n: int, skill_idx: int, data: dict):\n",
" return [x for x, _ in zip(find_characters_by_skill(skill_idx, data), range(n))]\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Player: 그냥달려나갑니다[idx = 588, asc = Ascendant] playing Cremation\n",
"Player: 촉수언냐보빨러[idx = 933, asc = Ascendant] playing Cremation\n",
"Player: Kamilea[idx = 8310, asc = Necromancer] playing Cremation\n",
"Player: A_Eversummer[idx = 8314, asc = Necromancer] playing Cremation\n",
"Player: Tilex_Archnemesis[idx = 8315, asc = Necromancer] playing Cremation\n",
"Player: Быстродевка[idx = 8317, asc = Necromancer] playing Cremation\n",
"Player: ArchOrrn[idx = 8329, asc = Necromancer] playing Cremation\n",
"Player: Arc_rcA[idx = 8330, asc = Necromancer] playing Cremation\n",
"Player: Soulwrest_eon[idx = 8332, asc = Necromancer] playing Cremation\n",
"Player: Aumoa[idx = 8338, asc = Necromancer] playing Cremation\n"
]
}
],
"source": [
"for c in get_first_n_by_skill(10, cremation, data):\n",
" print(f\"Player: {data['names'][c]}[idx = {c}, asc = {get_user_ascendancy(c, data)}] playing {data['activeSkills'][cremation]['name']}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "b4ce2f0dc144901d4fb795765c0e9d0e664fe68b03571c1bd51a368dd3d1aba0"
},
"kernelspec": {
"display_name": "Python 3.8.10 ('poeninja')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
# %%
%load_ext autoreload
%autoreload 2
import requests
# %%
MAIN_ENDPOINT = f"https://poe.ninja/api/data/0/getbuildoverview"
PARAMS = {"overview": "archnemesis", "type": "exp", "language": "en"}
def try_get_builds(url, params):
r = requests.get(url=url, params=params)
try:
return r.json()
except:
return {}
data = try_get_builds(MAIN_ENDPOINT, PARAMS)
# %%
def get_user_ascendancy(user_idx: int, api_data: dict):
asc_idx = api_data["classes"][user_idx]
return api_data["classNames"][asc_idx]
# %%
def summarize_player(idx, data):
classes = data['classes']
names = data['names']
name = names[idx]
person_class = classes[idx]
class_name = get_user_ascendancy(idx, data)
return (name, person_class, class_name)
# %%
def get_skill_enjoyers(skills, data):
enjoyers = []
for skill_id, skill_map in data['activeSkillUse'].items():
if int(skill_id) in skills:
enjoyers = [data['names'][x] for x in skill_map]
return enjoyers
# %%
solya_si = 9391 # case study randomly chosen necro. they are using (phantasmal) cremation as their main skill
print(summarize_player(solya_si, data))
cremation = 115 # conductivity in allSkills vs cremation in activeSkills, 69 in skill details
phant_cremation = 412 # divergent multistrike in allSkills vs phantasmal_cremation in activeSkills
crema_enjoyers = get_skill_enjoyers([cremation, phant_cremation], data)
print(crema_enjoyers[:10]) # a lot of duplicated names and mostly aurabot/aurastacker names e.g. mostly Ascendants, notably Solya_Si is NOT in here
# %%
aurastack_cafu = 345 # case 2, they are 2nd in the list of people using active skill 115, note that this person is ACTUALLY using spark
spark = 9 # 9 is spark in activeSkills but phant flame wall in allSkills
anom_spark = 10 # 10 is anom spark in activeSkills but cwdt in allSkills
print(summarize_player(aurastack_cafu, data))
spark_enjoyers = get_skill_enjoyers([spark, anom_spark], data)
print(data['names'][aurastack_cafu] in spark_enjoyers) # hmmmmmm thats weird they arent in the list?
# %%
maximus_mazorkis = 1 # this person is interesting because they seemingly show up EVERYWHERE multiple times, while not having an active skill (aurabot)
print(summarize_player(maximus_mazorkis, data))
print(data['names'][maximus_mazorkis] in spark_enjoyers) # hmmmmmm
print(data['names'][maximus_mazorkis] in crema_enjoyers) # HMMMMMMMMMMMMMMMMM, interesting... this suggests that activeSkillUse is not doing what we think
# %%
# i suspect skillDetails is the actual skill data despite how things are labeled in the json
def get_player_details(idx, data):
for i, skill in enumerate(data['skillDetails']):
for person, l in skill['dps'].items():
if (p:=int(person)) == idx:
return (summarize_player(p, data), f"skill={skill['name']}", f"dps={l[0]}")
# %%
print(get_player_details(solya_si, data))
print(get_player_details(aurastack_cafu, data))
print(get_player_details(maximus_mazorkis, data)) # finally
# %%
print(summarize_player(588, data))
print(summarize_player(588+345, data))
print(summarize_player(588+345+7377, data))
# %%
def find_characters_by_skill(skill_idx: int, data: dict):
pointer = data['activeSkillUse'][str(skill_idx)][0]
for i in data['activeSkillUse'][str(skill_idx)][1:]:
yield pointer
pointer += i
def get_first_n_by_skill(n: int, skill_idx: int, data: dict):
return [x for x, _ in zip(find_characters_by_skill(skill_idx, data), range(n))]
# %%
for c in get_first_n_by_skill(10, cremation, data):
print(f"Player: {data['names'][c]}[idx = {c}, asc = {get_user_ascendancy(c, data)}] playing {data['activeSkills'][cremation]['name']}")
# %%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment