Programa de análisis de disturbios

Oct 12 2020

Esta es una aplicación de análisis de disturbios. Recopila datos utilizando la API de riot y muestra al usuario varios datos. Nada demasiado en profundidad.

Archivo GUI : este archivo es el archivo GUI del programa. Tengo la clase que hace el resto de los marcos del programa. Después de hacer clic en el botón para buscar un invocador, recopilará datos de otra clase en el juego y devolverá una lista de 5 datos con cada uno de un tipo diferente (muerte, muerte, asistencias, visión, victorias). Tengo dos variables globales que no quiero usar en la clase DataCollected, parece que no puedo encontrar una manera de no usarlas.

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()

Archivo de juego : este archivo comienza recopilando identificadores de juegos y usando los identificadores de juegos para recopilar las estadísticas de dicho invocador en cada uno de los 20 juegos. Luego lo devuelve al archivo gui.

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

Obtener archivo de identificación : este archivo recopila la identificación del invocador para la clase Juego en el archivo del juego.

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

Wings file : este archivo usará el stat_list[5]para determinar si el jugador ha sido bueno en los últimos 20 juegos y devolverá una frase.

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))

Respuestas

3 Reinderien Oct 14 2020 at 02:00

Variables locales

Dado que Fes una variable local, aunque técnicamente es una referencia a una clase y las clases están en mayúscula, Fdebe estar en minúsculas. Además, merece tener un nombre que no sea una letra. Keytambién debe estar en minúsculas.

Lambdas

Esta:

command=lambda: data_collected(self,controller))

no merece ser una lambda. Como también está almacenando controlleren self, es mejor simplemente crear un método en la clase para esto y pasar una referencia vinculada a ese método para command.

Listas sensibles a la posición

stat_list[5]

es un olor a código. Supongo que esta es una lista de estadísticas, donde cada posición en la lista es un tipo diferente de estadística. Esto debería convertirse en una clase, o al menos, una tupla con nombre.

Adición in situ

i = i + 1

debiera ser

i += 1

Prueba de rango

winlist > 0.33 and winlist <= 0.5

debiera ser

0.33 < winlist <= 0.5

Parens

Esta:

return (random.choice(message))

no necesita parientes externos y debe eliminarlos.

¿Error de tipografía?

En He is ight.