[Example(), Example1()) multiple commands error

Viewed 48

i"m having trouble understanding this error and even more trying to fix it. I have 3 buttons, Paper, Rock and Scissors. They were previously only linked to my Game() but since I made a function called Delete to delete my label that kept repeating the message. I added it but i get errors i can't even understand


    File "c:\Users\MiroP\WUA\Random.py", line 105, in <lambda>
        (ScissorsButton := Button(root, image = scissors, bg="white", bd=0, command=lambda:[Game(player_choice_string=Game), Delete()]("scissors"))).pack(pady=10)
      File "c:\Users\MiroP\WUA\Random.py", line 100, in Game
        win_lose_tie_label = Label(root, text="Your choice was: "+player_choice_string+" and the enemy's choice was: "+computer_input, font=("Verdana", 5),bg = "white", bd=0).pack()       
    TypeError: can only concatenate str (not "function") to str

my code:


    #Import List
    from ast import Delete
    from sqlite3 import Row
    from tkinter import *
    from random import randint
    from tkinter import font
    from tkinter.tix import COLUMN
    from turtle import color
    from tkinter import ttk
    import random
    from PIL import ImageTk,Image
    #Basics
    root = Tk()
    root.title("Rock Paper Scissors -Made by Trapgrave")
    root.iconbitmap("c:/images/star.ico")
    root.config(bg="white")
    
        #Images
    rock = PhotoImage(file="c:/images/rock.png")
    paper = PhotoImage(file="c:/images/paper.png")
    scissors = PhotoImage(file="c:/images/scissors.png")
    rock = PhotoImage(file="c:/images/rock.png")
    paper = PhotoImage(file="c:/images/paper.png")
    scissors = PhotoImage(file="c:/images/scissors.png")
        #-
    Choose = Label(root, font=("Roboto", 15), text = "Rock, Paper, Scissors!", bg="white").pack(side = TOP)
    
        #Storing points
    user_points = 0
    computer_points = 0
        #Options
    
    def Delete():
        user_points.destroy()
        win_lose_tie_label.destroy()
    def Game(player_choice_string):
        print("player chose: {}".format(player_choice_string))
    
    
    
    
    
    
    
        global user_points, computer_points
    
        options = ["rock", "paper", "scissors"]
        computer_input = random.choice(options)
    
        if player_choice_string == "rock":
            if computer_input == "rock":
                print("Your input is rock")
                print("Computer input is rock")
                print("It is a tie!")
            elif computer_input == "paper":
                print("Your input is rock")
                print("Computer input is paper")
                print("you lost!")
                computer_points += 1
            elif computer_input == "scissors":
                print("Your input is rock")
                print("Computer input is scissors")
                print("you win!")
                user_points += 1
    
        elif player_choice_string == "paper":
            if computer_input == "rock":
                print("Your input is paper")
                print("Computer input is rock")
                print("You win!")
                user_points += 1
            elif computer_input == "paper":
                print("Your input is paper")
                print("Computer input is paper")
                print("It is a tie!")
            elif computer_input == "scissors":
                print("Your input is paper")
                print("Computer input is scissors")
                print("you lost!")
                user_points += 1
    
        elif player_choice_string == "scissors":
            if computer_input == "rock":
                print("Your input is scissors")
                print("Computer input is rock")
                print("You lost!")
                computer_points += 1
            elif computer_input == "paper":
                print("Your input is scissors")
                print("Computer input is paper")
                print("You win!")
                user_points += 1
            elif computer_input == "scissors":
                print("Your input is scissors")
                print("Computer input is scissors")
                print("It is a tie!")   
        global points_label
        global win_lose_tie_label
        points_label = Label(root, text="You have "+ str(user_points) + " and the enemy now has: " + str(computer_points) + "!", bg="white", bd=0).pack()
        win_lose_tie_label = Label(root, text="Your choice was: "+player_choice_string+" and the enemy's choice was: "+computer_input, font=("Verdana", 5),bg = "white", bd=0).pack()
    
    
    (RockButton := Button(root, image = rock, bg="white", bd=0,command=lambda:[Game(), Delete()]("rock"))).pack(side = LEFT)
    (PaperButton := Button(root, image = paper, bg="white", bd=0,command=lambda:[Game(), Delete()]("paper"))).pack(side = RIGHT)
    (ScissorsButton := Button(root, image = scissors, bg="white", bd=0, command=lambda:[Game(), Delete()]("scissors"))).pack(pady=10)
    
    root.geometry("500x500")
    root.mainloop()

1 Answers

Your error shows different code than you show in question.

But it also show that problem can be because you use wrong values.

Error shows

[Game(player_choice_string=Game), Delete()]("scissors")

so you assign function to variable player_choice_string=Game and later your "text"+player_choice_string+"text" means "text"+Game+"text"

It should be

[Game("scissors"), Delete()]

I thin you wouldn't have this problem if you would use normal function instead of [ ]

def func_game():
    Game("scissors")
    Delete()

ScissorsButton = Button(root, image=scissors, bg="white", bd=0, command=func_game)
ScissorsButton.pack(pady=10)

But all this code will have always the same problem. It will create labels and later delete them and you will not see these labels - because tkinter first executes all your functions and later it redraw widgets in window.

It would need root.update() inside code to redraw widgets. And it may need sleep(1) to display it for some time (1s).

def func_game():
    Game("scissors")
    root.update()   # force `tkinter` to redraw widgets in window
    # after 1s run `Delete()`
    time.sleep(1)
    Delete()

ScissorsButton = Button(root, image=scissors, bg="white", bd=0, command=func_game)
ScissorsButton.pack(pady=10)

Or it would need root.after(1000, function_name) to display it - tkinter will have time to redraw window.

def func_game():
    Game("scissors")
    # after 1000ms (1s) run `Delete()`
    root.after(1000, Delete)  # function's name without ()

ScissorsButton = Button(root, image=scissors, bg="white", bd=0, command=func_game)
ScissorsButton.pack(pady=10)

EDIT:

As @acw1668 said in comment: better suggestion is to create labels with empty strings at the beginning, and later only replace text

points_label.config(text=f"You have {user_points} and the enemy now has: {computer_points}!")
win_lose_tie_label.config(text=f"Your choice was: {player_choice_string} and the enemy's choice was: {computer_input}")

and later remove text

points_label.config(text="")
win_lose_tie_label.config(text="")

Full code with my comments.

import random
import tkinter as tk  # PEP8: `import *` is not preferred

# --- functions ---  # PEP8: all functions before main code
                     # PEP8: `lower_case_names` for functions
                     
def game(player_input):
    global user_points          # PEP8: all `global` at the beginning of function (in separated lines
    global computer_points

    print(f"player chose: {player_input}")

    options = ["rock", "paper", "scissors"]
    computer_input = random.choice(options)

    if player_input == "rock":
        if computer_input == "rock":
            print("Your input is rock")
            print("Computer input is rock")
            print("It is a tie!")
        elif computer_input == "paper":
            print("Your input is rock")
            print("Computer input is paper")
            print("you lost!")
            computer_points += 1
        elif computer_input == "scissors":
            print("Your input is rock")
            print("Computer input is scissors")
            print("you win!")
            user_points += 1

    elif player_input == "paper":
        if computer_input == "rock":
            print("Your input is paper")
            print("Computer input is rock")
            print("You win!")
            user_points += 1
        elif computer_input == "paper":
            print("Your input is paper")
            print("Computer input is paper")
            print("It is a tie!")
        elif computer_input == "scissors":
            print("Your input is paper")
            print("Computer input is scissors")
            print("you lost!")
            user_points += 1

    elif player_input == "scissors":
        if computer_input == "rock":
            print("Your input is scissors")
            print("Computer input is rock")
            print("You lost!")
            computer_points += 1
        elif computer_input == "paper":
            print("Your input is scissors")
            print("Computer input is paper")
            print("You win!")
            user_points += 1
        elif computer_input == "scissors":
            print("Your input is scissors")
            print("Computer input is scissors")
            print("It is a tie!")
            
    points_label.config(text=f"You have {user_points} and the enemy now has: {computer_points}!")
    win_lose_tie_label.config(text=f"Your choice was: {player_input} and the enemy's choice was: {computer_input}")

    root.after(2000, delete)  # run after 2000ms (2s)
    
def delete():
    points_label.config(text="")
    win_lose_tie_label.config(text="")

# --- main ---   # PEP8 `lower_case_names` for variables

user_points = 0
computer_points = 0

root = tk.Tk()
root.geometry("500x500")
root.title("Rock Paper Scissors - Made by Trapgrave")
root.iconbitmap("c:/images/star.ico")
root.config(bg="white")

rock = tk.PhotoImage(file="c:/images/rock.png")
paper = tk.PhotoImage(file="c:/images/paper.png")
scissors = tk.PhotoImage(file="c:/images/scissors.png")

choose = tk.Label(root, font=("Roboto", 15), text="Rock, Paper, Scissors!", bg="white")
choose.pack(side='top')

# PEP8: inside `()` parameters without spaces around `=`
rock_button = tk.Button(root, image=rock, bg="white", bd=0, command=lambda:game("rock"))
rock_button.pack(side='left', padx=10, pady=10)

paper_button = tk.Button(root, image=paper, bg="white", bd=0, command=lambda:game("paper"))
paper_button.pack(side='right', padx=10, pady=10)

scissors_button = tk.Button(root, image=scissors, bg="white", bd=0, command=lambda:game("scissors"))
scissors_button.pack(side='bottom', padx=10, pady=10)

points_label = tk.Label(root, text="", bg="white", bd=0)
points_label.pack()

win_lose_tie_label = tk.Label(root, text="", font=("Verdana", 5), bg="white", bd=0)
win_lose_tie_label.pack()

root.mainloop()

PEP 8 -- Style Guide for Python Code

Related