3
\$\begingroup\$

This is a riot analysis app. Collect data using the riot API and shows the user various data. Nothing too in depth.

GUI file - This file is the GUI file for the program. I have the class that make the rest of the frames of the program. After clicking the button to search for a summoner, it will collect data from another class in game and return a list of 5 data's with each being a different type(kill, death, assists, vision, wins). I have two global variable that I don't want to use in DataCollected class, I can't seem to find a way not to use them.

import tkinter as tk
from tkinter import font as tkfont
from getId import id_collected
from games import Game
from wins import is_player_good


class RiotApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (StartPage, MenuPage, KillPage, DeathPage, CsPage, HonestPage):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
    
        tk.Frame.__init__(self, parent)
        c = DataCollected()
        self.controller = controller
        self.label = tk.Label(self, text="Enter summoner name:", width = 20, font = ("bold", 20))
        self.label.place(x=90,y=53)
        self.entry = tk.Entry(self)
        self.entry.place(x=190,y=130)
        
        self.button = tk.Button(self, text="Search",width = 20, bg = 'brown', fg = 'white',
                            command=lambda: data_collected(self,controller))
        self.button.place(x=180,y=200)

        def data_collected(self,controller):
        
            name = self.entry.get()
            Key = '****************************************'
            a = id_collected(name, Key)
            if a != 'NO':
                controller.show_frame("MenuPage")
                c.collect_data(name, Key)
            else:
                controller.show_frame('StartPage')

class DataCollected():
    
    def collect_data(self, name, Key):

        num_games = 20
        game = Game()
        accId = id_collected(name, Key)
        game_list = game.find_game_ids(accId, Key, num_games)
        global stat_list
        stat_list = game.game_data(game_list, Key, name, num_games)
        global honest
        honest = is_player_good(stat_list[5])

class MenuPage(tk.Frame,DataCollected):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Main Menu", font=controller.title_font)
        label.place(x=180,y=50)
        button = tk.Button(self, text="Kill Average",width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("KillPage")).place(x=180,y=100)
        button = tk.Button(self, text="Death Average",width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("DeathPage")).place(x=180,y=150)
        button = tk.Button(self, text="Cs Average",width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("CsPage")).place(x=180,y=200)
        button = tk.Button(self, text="Honest Truth",width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("HonestPage")).place(x=180,y=250)
        button = tk.Button(self, text="Back",width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("StartPage")).place(x=180,y=300)

class KillPage(tk.Frame, DataCollected):
    
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.label = tk.Label(self, text = 'Kills Average', width=20,font=("bold", 20))
        self.label.place(x=90, y=100)
        self.label1 = tk.Label(self, text = ' ', width=20,font=("bold", 20))
        self.label1.place(x=90, y=150)
        self.label1.after(1000, self.refresh_label)
        self.button = tk.Button(self, text = "Back", width = 20, bg = 'brown', fg = 'white',
                        command=lambda: controller.show_frame("MenuPage")).place(x=180,y=300)

    def refresh_label(self):
        self.label1.configure(text = stat_list[1])
        self.label1.after(1000,self.refresh_label)

class DeathPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.label = tk.Label(self, text = 'Deaths Average', width=20,font=("bold", 20))
        self.label.place(x=90, y=100)
        self.label2 = tk.Label(self, text="", width=20,font=("bold", 20))
        self.label2.place(x=90, y=150)
        self.label2.after(1000, self.refresh_label)
        self.button = tk.Button(self, text="Back", width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("MenuPage")).place(x=180,y=300)

    def refresh_label(self):
        self.label2.configure(text = stat_list[0])
        self.label2.after(1000,self.refresh_label)

class CsPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.label = tk.Label(self, text = 'Cs Average', width=20,font=("bold", 20))
        self.label.place(x=90, y=100)
        self.label3 = tk.Label(self, text="", width=20,font=("bold", 20))
        self.label3.place(x=90,y=150)
        self.label3.after(1000, self.refresh_label)
        self.button = tk.Button(self, text="Back", width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("MenuPage")).place(x=180,y=300)

    def refresh_label(self):
        self.label3.configure(text = stat_list[4])
        self.label3.after(1000,self.refresh_label)

class HonestPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.label = tk.Label(self, text = 'Honest Truth', width=20,font=("bold", 20))
        self.label.place(x=90, y=100)
        self.label4 = tk.Label(self, text = " ", width=20,font=("bold", 20))
        self.label4.place(x=90,y=150)
        self.label4.after(1000, self.refresh_label())
        self.button = tk.Button(self, text = "Back", width = 20, bg = 'brown', fg = 'white',
                           command=lambda: controller.show_frame("MenuPage")).place(x=180,y=300)

    def refresh_label(self):
        self.label4.configure(text = honest)
        self.label4.after(1000,self.refresh_label)

if __name__ == "__main__":

    stat_list = [1,1,1,1,1,1,1]
    honest = ' '
    root = RiotApp()
    root.geometry("500x500")
    root.mainloop()

Game file - This file start by collecting game ids and using the game ids to collect the stats of said summoner in each of there 20 games. Then returns it to gui file.

import requests

class Game:

    def find_game_ids(self, accId, key, num_games):
        i = 0
        GAMEID = []
        num_games = 20
        url_match_list = ('https://na1.api.riotgames.com/lol/match/v4/matchlists/by-account/' + (accId) + '?queue=420&endIndex=20&api_key=' + (key))
        response2 = requests.get(url_match_list)
        # Adding 20 games into the list
        while num_games > 0:
            GAMEID.append('https://na1.api.riotgames.com/lol/match/v4/matches/'+str(response2.json()['matches'][i]['gameId']) + '?api_key=' + (key))
            i = i + 1
            num_games = num_games - 1

        return GAMEID

    def game_data(self, game_list, key, sumName, num_games):

        wins = []
        deaths = []
        deaths = []
        kills = []
        assists = []
        visions = []
        csTotal = []
        # Finding the data of said summoner in each game id
        for urls in game_list:
            response = requests.get(urls)
            resp_json = response.json()
            Loop = 0
            index = 0
            while Loop <= 10:

                if resp_json['participantIdentities'][index]['player']['summonerName'] != sumName:
                    Loop = Loop+1
                    index = index+1
                elif resp_json['participantIdentities'][index]['player']['summonerName'] == sumName:

                    deaths.append(resp_json['participants'][index]['stats']['deaths'])
                    kills.append(resp_json['participants'][index]['stats']['kills'])
                    assists.append(resp_json['participants'][index]['stats']['assists'])
                    visions.append(resp_json['participants'][index]['stats']['visionScore'])
                    csTotal.append(resp_json['participants'][index]['stats']['totalMinionsKilled'])
                    wins.append(resp_json['participants'][index]['stats']['win'])

                    break
        # Finding avg of each stat
        deaths = sum(deaths)/num_games
        kills = sum(kills)/num_games
        assists = sum(assists)/num_games
        visions = sum(visions)/num_games
        csTotal = sum(csTotal)/num_games
        wins = sum(wins)/num_games
        stat_list = []
        stat_list.append(deaths) #0
        stat_list.append(kills) #1
        stat_list.append(assists) #2
        stat_list.append(visions) #3
        stat_list.append(csTotal) #4
        stat_list.append(wins) #5

        return stat_list

Get id file - This file collect the summoner id for the Game class in game file.

import requests

def id_collected(sumName, key):
    # COLLECTING DATA TO BE INSERTING FOR MATCHLIST DATABASE
    url = ('https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/'+(sumName)+'?api_key='+ 
(key))
    response = requests.get(url)
    if response.status_code == 200:
        accId = (response.json()['accountId'])
        return accId
    else: 
        accId = 'NO'
        return accId

wins file - This file will use the stat_list[5] to determine whether the player has been good in past 20 games and will return a phrase.

import random


def is_player_good(winlist):

    if winlist < 0.33:
        message = ['DIS MANE STINKS', 'run while you can', 'I repeat, YOU ARE NOT WINNING THIS', 'I predict a fat L', 'Have fun trying to carry this person', 'He is a walking trash can', 'He needs to find a new game', 'BAD LUCK!!!']
        return (random.choice(message))

    elif winlist > 0.33 and winlist <= 0.5:
        message = ['Losing a bit', 'Not very good', 'He needs lots of help', 'Your back might hurt a little', 'Does not win much']
        return (random.choice(message))

    elif winlist > 0.5 and winlist <= 0.65:
        message = ['He is ight', 'He can win a lil', 'You guys have a decent chance to win', 'Serviceable', 'Should be a dub']
        return (random.choice(message))

    elif winlist > 0.65:
        message = ['DUB!', 'You getting carried', 'His back gonna hurt a bit', 'winner winner chicken dinner', 'Dude wins TOO MUCH', 'You aint even gotta try', 'GODLIKE']
        return (random.choice(message))
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Please fix your title so that it states what your code does, also edit your question and explain the purpose of your code properly \$\endgroup\$
    – user228914
    Oct 12, 2020 at 9:28
  • 4
    \$\begingroup\$ Where are those globals mentioned in the topic? \$\endgroup\$
    – G. Sliepen
    Oct 12, 2020 at 10:51
  • \$\begingroup\$ they are in DataCollected class \$\endgroup\$ Oct 12, 2020 at 16:35

1 Answer 1

3
\$\begingroup\$

Local variables

Since F is a local variable - even though it's technically a reference to a class, and classes are capitalized - F should be lower-case. Also, it deserves to have a name that isn't one letter. Key should also be lower-case.

Lambdas

This:

command=lambda: data_collected(self,controller))

does not deserve to be a lambda. Since you're also storing controller on self, it's better to simply make a method on the class for this, and pass a bound reference to that method for command.

Position-sensitive lists

stat_list[5]

is a code smell. My guess is that this is a list of statistics, where each position in the list is a different kind of statistic. This should be converted to a class, or at the least, a named tuple.

In-place addition

i = i + 1

should be

i += 1

Range testing

winlist > 0.33 and winlist <= 0.5

should be

0.33 < winlist <= 0.5

Parens

This:

return (random.choice(message))

does not need outer parens and should remove them.

Typo?

In He is ight.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for the tips. You have any suggestions for the global variables in DataCollected class? I heard using global variables are not good. The problem is that frames are already made so I can't seem to collect the data and put it into the labels for the frames. \$\endgroup\$ Oct 13, 2020 at 21:43
  • \$\begingroup\$ If I have this right, HonestPage.refresh_label relies on being able to read honest, which you've made a global in DataCollected.collect_data. This seems like the former is the UI and the latter is the logic or data layer. The place where these fail to be connected is StartPage.__init__, where DataCollected is initialized but then no references are made to it. This needs to change or move so that there are references between the data collector and the user interface. \$\endgroup\$
    – Reinderien
    Oct 14, 2020 at 2:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.