-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
159 lines (149 loc) · 5.48 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import streamlit as st
import duckdb
import polars as pl
import requests
import plotly.express as px
st.set_page_config(layout="wide")
def init_connection():
'''Function to establish connection to MotherDuck'''
motherduck_token = st.secrets['MOTHERDUCK_TOKEN']
return duckdb.connect(f'md:clash_royale?motherduck_token={motherduck_token}', read_only=True)
@st.cache_data
def cr_card_images() -> pl.DataFrame:
'''Function to query data warehouse raw table for cards and their images'''
with init_connection() as conn:
df = conn.sql('SELECT * FROM raw.card_images_reference').pl()
return df
def most_common_cards(grouping: str) -> px.bar:
with init_connection() as conn:
query = f'''
WITH card_appearances AS (
SELECT
card_name.cards_list AS card,
COUNT(*) AS deck_appearances
FROM fct_battle
JOIN
(
SELECT
deck_id,
card_name
FROM
deck_dim,
UNNEST(deck_dim.cards_list) AS card_name
) AS unnested_cards ON fct_battle.deck_id = unnested_cards.deck_id
GROUP BY card_name
ORDER BY deck_appearances DESC
)
SELECT card_appearances.*, card_dim.{grouping}
FROM card_appearances
JOIN card_dim on card_appearances.card = card_dim.card_name
ORDER BY deck_appearances DESC;
'''
df = conn.sql(query=query).pl()
fig = px.bar(
df,
x='card',
y='deck_appearances',
color=grouping,
labels={'deck_appearances': 'Number of Deck Appearances', 'card': 'Card', grouping: grouping.replace('_', ' ').capitalize()}
)
fig.update_layout(xaxis={'categoryorder':'total descending'})
return fig
def elixir_cost_by_arena() -> px.bar:
with init_connection() as conn:
query = '''
SELECT arena_name, AVG(average_elixir_cost) AS average_elixir_cost
FROM (
SELECT DISTINCT player_id, fct_battle.deck_id, arena_name, average_elixir_cost
FROM fct_battle
JOIN
(
SELECT deck_id, average_elixir_cost
FROM deck_dim
) AS deck_cost ON deck_cost.deck_id = fct_battle.deck_id
WHERE arena_name IS NOT NULL
)
GROUP BY arena_name;
'''
df = conn.sql(query=query).pl()
fig = px.bar(
data_frame=df,
x='arena_name',
y='average_elixir_cost',
color='arena_name',
labels={'average_elixir_cost': 'Average Elixir Cost of Decks Used', 'arena_name': 'Arena Name'}
)
fig.update_xaxes(
categoryorder='array',
categoryarray= [f'Arena {i}' for i in range(1, 24)] + ['Legendary Arena', 'Clan League']
)
fig.update_layout(showlegend=False)
return fig
def deck_usage_past_thirty_days():
query = f"""
SELECT battle_date, cards_list, COUNT(*) AS usage
FROM (
SELECT DISTINCT battle_id, date_dim.battle_date, cards_list
FROM fct_battle
JOIN deck_dim ON fct_battle.deck_id = deck_dim.deck_id
JOIN date_dim ON fct_battle.date_id = date_dim.date_id
WHERE date_dim.battle_date > current_date() - INTERVAL 90 DAY
AND fct_battle.deck_selection_method <> 'predefined'
)
GROUP BY 1, 2
ORDER BY 1 ASC, 3 DESC
"""
with init_connection() as conn:
df = conn.execute(query=query).pl()
df = conn.sql('PIVOT df ON battle_date USING SUM(usage) GROUP BY cards_list').pl()
df = df.fill_null(0).to_pandas()
df['concatenated'] = df.iloc[:,1:].apply(lambda row: row.to_list(), axis=1)
df['total_usage'] = df['concatenated'].apply(sum)
df = df.sort_values(by=['total_usage'], ascending=False)
df = df[['cards_list', 'concatenated', 'total_usage']]
return df
def get_card_info() -> pl.DataFrame:
'''Queries data warehouse for card dimension table'''
with init_connection() as conn:
query = 'SELECT * FROM card_dim'
df = conn.sql(query=query).pl()
df = df.join(other=cr_card_images(), on='card_name')
return df
def card_appearances_by_elixir_cost() -> px.scatter:
query = '''
WITH card_appearances AS (
SELECT
card_name.cards_list AS card,
COUNT(*) AS deck_appearances
FROM fct_battle
JOIN
(
SELECT
deck_id,
card_name
FROM
deck_dim,
UNNEST(deck_dim.cards_list) AS card_name
) AS unnested_cards ON fct_battle.deck_id = unnested_cards.deck_id
GROUP BY card_name
ORDER BY deck_appearances DESC
)
SELECT card_appearances.*, elixir_cost
FROM card_appearances
JOIN card_dim ON card_appearances.card = card_dim.card_name
'''
with init_connection() as conn:
df = conn.sql(query).pl()
fig = px.bar(
df,
x='elixir_cost',
y='deck_appearances',
color='card',
text='card',
labels={
'elixir_cost': 'Elixir Cost',
'deck_appearances': 'Cumulative Deck Appearances'
},
)
fig.update_layout(showlegend=False)
return fig