Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Pysimplegui fecha ao iniciar, não acho o erro

import random
import PySimpleGUI as sg


class Visualizador:

    def __init__(self):
        self.valores = [0]

    def __eq__(self, other):
        return self.valores[-1] != other.numero_final or self.valores == other.numero_final

    @staticmethod
    def dado(quantos_lados):
        dado = random.randrange(1, quantos_lados + 1)
        return dado

    def arquivo_hist(self, valor):
        self.valores.append(valor)
        return self.valores

    def sem_numero_repetido(self, numero_final):

        i = 0
        while numero_final != self.valores[-1] and i < 1:
            antirepeticao = self.arquivo_hist(numero_final)
            i += 1
            return antirepeticao

    def tem_numero_repetido(self, numero_final, quantos_lados):
        while self.valores[-1] == numero_final:
            numero_final = self.dado(quantos_lados)
            return numero_final

    def mostra_para_o_usuario(self):

        while True:
            dice = str(values[1])
            lado = dice.split(sep='d')
            quantos_lados, vezes, n = lado[-1], lado[0], 1
            quantos_lados, vezes = int(quantos_lados), int(vezes)
            while n <= vezes:
                numero_final = self.dado(quantos_lados)
                refatorado = self.refatorado_com_e_sem_repeticao(numero_final, quantos_lados)
                print(refatorado)
                n += 1

    def refatorado_com_e_sem_repeticao(self, numero_final, quantos_lados):

        if self.valores[-1] != numero_final:
            self.sem_numero_repetido(numero_final)
            return numero_final

        else:
            numero_refatorado = self.tem_numero_repetido(numero_final, quantos_lados)
            self.arquivo_hist(numero_refatorado)
            return numero_refatorado


# layout
layout = [
    [sg.Text("Bem vindo ao Dice Roller!!")],
    [sg.Text("Escolha quais e quantos dados rolar.")],
    [sg.Text("Como por exemplo: 1d4; 5d20.")],
    [sg.Text("Qual dado quer rodar??"), sg.Input()],
    [sg.Button("Rolar!"), sg.Button("Cancelar")],
    [sg.Output()]
]
# janela
janela = sg.Window("Dice Roller 1.0", layout=layout)


while True:
    event, values = janela.Read()
    # parar o processo
    if event == sg.WINDOW_CLOSED or event == "Cancelar":
        break
    # roda os dados
    if event == "Rolar!":
        Visualizador().mostra_para_o_usuario()

eu tinha feito um código parar rodar diversos tipos de dados sem repetição de um número, mas ao adaptar para fazer uma interface não funciona mais.

2 respostas
solução!

Oi Guilherme, tudo bem?

Na função mostra_para_o_usuario temos alguns pontos a se pensar:

  • Quando clicamos em "Rolar" e é redirecionado para a função mostra_para_o_usuario estamos dentro de um loop infinito (o loop que captura os eventos), porém, dentro dessa função também temos um loop infinito (while True), ou seja, há uma redundância que fará com que o código printe diversas vezes os dados calculados.

  • Temos uma variável chamada values responsável por pegar o valor que o usuário digita, porém, essa variável não está sendo passada como parâmetro da função.

  • A variável values é um dicionário(formado por chave e valor), portanto, iremos acessar o valor que o usuário digitou por meio da chave. E nesse caso, a chave do dicionário por padrão é o número 0 e não o número 1.

Após as mudanças citadas acima, o código fica da seguinte maneira:

import random
import PySimpleGUI as sg


class Visualizador:

    def __init__(self):
        self.valores = [0]

    def __eq__(self, other):
        return self.valores[-1] != other.numero_final or self.valores == other.numero_final

    @staticmethod
    def dado(quantos_lados):
        dado = random.randrange(1, quantos_lados + 1)
        return dado

    def arquivo_hist(self, valor):
        self.valores.append(valor)
        return self.valores

    def sem_numero_repetido(self, numero_final):

        i = 0
        while numero_final != self.valores[-1] and i < 1:
            antirepeticao = self.arquivo_hist(numero_final)
            i += 1
            return antirepeticao

    def tem_numero_repetido(self, numero_final, quantos_lados):
        while self.valores[-1] == numero_final:
            numero_final = self.dado(quantos_lados)
            return numero_final

    def mostra_para_o_usuario(self, values):
        dice = str(values[0])
        lado = dice.split(sep='d')
        quantos_lados, vezes, n = lado[-1], lado[0], 1
        quantos_lados, vezes = int(quantos_lados), int(vezes)
        while n <= vezes:
            numero_final = self.dado(quantos_lados)
            refatorado = self.refatorado_com_e_sem_repeticao(numero_final, quantos_lados)
            print(refatorado)
            n += 1

    def refatorado_com_e_sem_repeticao(self, numero_final, quantos_lados):

        if self.valores[-1] != numero_final:
            self.sem_numero_repetido(numero_final)
            return numero_final

        else:
            numero_refatorado = self.tem_numero_repetido(numero_final, quantos_lados)
            self.arquivo_hist(numero_refatorado)
            return numero_refatorado


# layout
layout = [
    [sg.Text("Bem vindo ao Dice Roller!!")],
    [sg.Text("Escolha quais e quantos dados rolar.")],
    [sg.Text("Como por exemplo: 1d4; 5d20.")],
    [sg.Text("Qual dado quer rodar??"), sg.Input()],
    [sg.Button("Rolar!"), sg.Button("Cancelar")],
    [sg.Output()]
]
# janela
janela = sg.Window("Dice Roller 1.0", layout=layout)


while True:
    event, values = janela.Read()
    # parar o processo
    if event == sg.WINDOW_CLOSED or event == "Cancelar":
        break
    # roda os dados
    if event == "Rolar!":
        Visualizador().mostra_para_o_usuario(values)

Qualquer dúvida estou por aqui.

Abraços e bons estudos!

Muito obrigado pela ajuda, eu tava me quebrando com esse código, me ajudo bastante :D.