-
Notifications
You must be signed in to change notification settings - Fork 1
1st generate query #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c722199
608f8f7
769766b
1c2e36f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| secret.py | ||
| *__pycache__/* | ||
| .idea/* | ||
| .idea/* | ||
| Pipfile | ||
| Pipfile.lock | ||
| .vscode/settings.json |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,8 +8,133 @@ | |
|
|
||
| # get/find matches | ||
|
|
||
| def generate_query(*heroes): | ||
| """generates an SQL query where hero1+hero2 is vs hero3+hero4""" | ||
| # won't support 2v3's or 1v3's in the case of trilanes | ||
|
|
||
| def select(*heroes): | ||
| """generates select statement for certain num of heroes""" | ||
| select = f"SELECT" | ||
|
|
||
|
|
||
| i = 0 #leave me be sir | ||
| for data in heroes: | ||
| for hero in data: | ||
| if i == 0: | ||
| select = select + f" player_matches.hero_id AS hero1, \n" | ||
| else: | ||
| select = select + f"player_matches{i}.hero_id AS hero{i+1}, \n" | ||
| i = i+1 | ||
| i = 0 | ||
| for hero in data: | ||
| if i == 0: | ||
| select = select + f"player_matches.player_slot AS ps1, \n" | ||
| else: | ||
| select = select + f"player_matches{i}.player_slot AS ps{i+1}, \n" | ||
| i = i+1 | ||
|
Comment on lines
+20
to
+34
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this is harder than it needs to be. How about something like for i, hero in enumerate(heroes):
select += f"player_matches{i}.hero_id AS hero{i}\n"
select += f"player_matches{i}.player_slot AS ps{i}, \n" |
||
|
|
||
| select = select + f"matches.match_id,\n" | ||
| select = select + f"leagues.name leaguename\n" | ||
| return select | ||
|
|
||
| def join(*heroes): | ||
| """generates join statements for certain num of heroes""" | ||
| join = f"FROM player_matches \n" | ||
| i = 0 | ||
| for data in heroes: | ||
| for hero in data: | ||
| if i == 0: | ||
| i = i+1 | ||
| continue | ||
|
Comment on lines
+46
to
+48
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems like this shouldn't be necessary how about something like for i, hero in enumerate(heroes):
if i==0:
continue
else:
join +=...
join += ... |
||
| else: | ||
| join = join + f"JOIN player_matches AS player_matches{i}\n" | ||
| join = join + f"ON player_matches.match_id = player_matches{i}.match_id\n" | ||
| i = i+1 | ||
| join = join + f"JOIN matches\n" | ||
| join = join + f"ON player_matches.match_id = matches.match_id\n" | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you implement my suggestion this has to become |
||
| join = join + f"JOIN leagues using(leagueid)\n" | ||
| return join | ||
|
|
||
| def where(*heroes): | ||
| """generates where statement for certain num of heroes""" | ||
| i = 0 | ||
| where = f"WHERE" | ||
| for data in heroes: | ||
| for hero in data: | ||
| if i == 0: | ||
| where = where + f" player_matches.hero_id = {get_hero_id(hero)}\n" | ||
| i = i+1 | ||
| else: | ||
| where = where + f"AND player_matches{i}.hero_id = {get_hero_id(hero)}\n" | ||
| i = i+1 | ||
|
Comment on lines
+62
to
+69
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only difference is |
||
|
|
||
| #probably need to pass in a timestamp or something at some point for the following | ||
| where = where + f"AND matches.start_time >= extract(epoch FROM timestamp '2018-10-01T06:53:44.537Z')\n" | ||
| return where | ||
|
|
||
| def teams(*heroes): | ||
| """adds onto where statement and specifies which team each hero is on, hero1+hero2 =teamA, hero3+hero4 = teamB""" | ||
| i = 0 | ||
| teams = "" | ||
| for data in heroes: | ||
| for hero in data: | ||
| if i == 0: | ||
| i = i+1 | ||
| continue | ||
| elif i == 1: | ||
| teams = teams + f"AND abs(player_matches.player_slot - player_matches1.player_slot) < 6\n" | ||
| i = i+1 | ||
| elif i == 2: | ||
| teams = teams + f"AND abs(player_matches.player_slot - player_matches2.player_slot) > 123\n" | ||
| i = i+1 | ||
| elif i == 3: | ||
| teams = teams + f"AND abs(player_matches2.player_slot - player_matches3.player_slot) < 6\n" | ||
| teams = teams + f"AND abs(player_matches1.player_slot - player_matches3.player_slot) > 123\n" | ||
| i = i+1 | ||
|
Comment on lines
+79
to
+93
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think we say if it's the first hero in team A, no teams clause. if the hero is >1 item in team A, add same team clause. if in team B, add other team clause, if that makes sense. |
||
| teams = teams + "ORDER BY matches.match_id NULLS LAST LIMIT 200" | ||
| return teams | ||
|
|
||
| return select(heroes) + join(heroes) + where(heroes) + teams(heroes) | ||
|
|
||
|
|
||
| def make_query(hero1, hero2): | ||
| query = f"""SELECT player_matches.hero_id AS hero1, | ||
| player_matches1.hero_id AS hero2, | ||
| player_matches.player_slot AS ps1, | ||
| player_matches1.player_slot AS ps2, | ||
| matches.match_id, | ||
| leagues.name leaguename | ||
| FROM player_matches | ||
| JOIN player_matches AS player_matches1 | ||
| ON player_matches.match_id = player_matches1.match_id | ||
| JOIN matches | ||
| ON player_matches.match_id = matches.match_id | ||
| JOIN leagues using(leagueid) | ||
| WHERE player_matches.hero_id = {get_hero_id(hero1)} | ||
| AND player_matches1.hero_id = {get_hero_id(hero2)} | ||
| AND matches.start_time >= extract(epoch | ||
| FROM timestamp '2020-10-23T06:53:44.537Z') | ||
| AND abs(player_matches.player_slot - player_matches1.player_slot) > 123 | ||
| ORDER BY matches.match_id NULLS LAST LIMIT 200""" | ||
|
|
||
| # def find_matches_by_hero(): | ||
| response = requests.get( | ||
| f"{API_ROOT}/explorer", params=dict(api_key=secret.OPENDOTA_API_KEY, sql=query) | ||
| ) | ||
| return response.json() | ||
|
|
||
|
|
||
| def get_matches(hero1, hero2): | ||
|
|
||
| """returns list of pro match ids played between two heroes""" | ||
|
|
||
| query_response = make_query(hero1, hero2) | ||
| match_list = query_response["rows"] #list of dictionaries for some reason | ||
| result = [] | ||
|
|
||
| for match in match_list: | ||
| return [match['match_id'] for match in match_list] | ||
|
|
||
| return result | ||
|
|
||
|
|
||
| def find_hero(heroname): | ||
|
|
@@ -45,4 +170,4 @@ def load_hero_list(): | |
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,16 @@ def test_find_juggernaut(): | |
| def test_hero_id(): | ||
| juggernaut_id = opendota.get_hero_id("Juggernaut") | ||
| assert juggernaut_id == 8 | ||
|
|
||
|
|
||
| def test_query(): | ||
| print(opendota.make_query("Bloodseeker", "Crystal Maiden")) | ||
| assert type(opendota.make_query("Bloodseeker", "Crystal Maiden")) is dict | ||
|
Comment on lines
+16
to
+17
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will make two separate queries to opendota, eating away at our cap. if you're gonna print, at least assign to an intermediary variable. also, are there stronger assertions we can make beyond "it's a list"? |
||
|
|
||
|
|
||
| def test_get_matches(): | ||
| assert type(opendota.get_matches("Bloodseeker", "Crystal Maiden")) is list | ||
|
|
||
|
|
||
| def test_generate_query(): | ||
| print(opendota.generate_query("Bloodseeker", "Crystal Maiden", "Juggernaut", "Oracle")) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want you to get in the habit of creating more descriptive function names. Conceivably in this project we will be generating many types of queries. What makes this one THE query?
How about
generate_laning_matchups_query?