Programa de análise de motim

Oct 12 2020

Este é um aplicativo de análise de distúrbios. Colete dados usando a API riot e mostre vários dados ao usuário. Nada muito profundo.

Arquivo GUI - Este arquivo é o arquivo GUI do programa. Eu tenho a classe que faz o resto dos frames do programa. Após clicar no botão para procurar por um invocador, ele coletará dados de outra classe no jogo e retornará uma lista de 5 dados com cada um sendo um tipo diferente (matar, morrer, assistências, visão, vitórias). Eu tenho duas variáveis ​​globais que não quero usar na classe DataCollected, não consigo encontrar uma maneira de não usá-las.

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

Arquivo de jogo - Este arquivo começa coletando ids de jogos e usando os ids de jogos para coletar as estatísticas do invocador em cada um dos 20 jogos. Em seguida, retorna para o arquivo 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

Obter arquivo de id - Este arquivo coleta a id do invocador para a classe Game no arquivo do jogo.

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

ganha arquivo - Este arquivo usará o stat_list[5]para determinar se o jogador foi bom nos últimos 20 jogos e retornará uma 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))

Respostas

3 Reinderien Oct 14 2020 at 02:00

Variáveis ​​locais

Uma vez que Fé uma variável local - mesmo que seja tecnicamente uma referência a uma classe, e as classes são maiúsculas - Fdeve ser minúsculo. Além disso, ele merece ter um nome que não seja uma letra. Keytambém deve ser minúsculo.

Lambdas

Este:

command=lambda: data_collected(self,controller))

não merece ser um lambda. Desde que você também está armazenando controllerem self, é melhor do que simplesmente fazer um método na classe para isso, e passar uma referência ligada a esse método para command.

Listas sensíveis à posição

stat_list[5]

é um cheiro de código. Meu palpite é que esta é uma lista de estatísticas, onde cada posição na lista é um tipo diferente de estatística. Isso deve ser convertido em uma classe, ou pelo menos, uma tupla nomeada.

Adição no local

i = i + 1

deveria estar

i += 1

Teste de alcance

winlist > 0.33 and winlist <= 0.5

deveria estar

0.33 < winlist <= 0.5

Parênteses

Este:

return (random.choice(message))

não precisa de parênteses externos e deve removê-los.

Erro de digitação?

Em He is ight.