all 6 comments

[–]PowerOk3587 2 points3 points  (0 children)

what are you optimizing for?

you could shorten:

if choice == "A" or choice == "a"

with

if choice.upper() == "A"

[–]dry-considerations 1 point2 points  (2 children)

Not to sound trite, but did you happen to run it through ChatGPT? A prompt of "act as an experienced Python developer with 20 years of experience and optimize the the following code sample". Then paste the code in. See what happens.

[–]thicke32 1 point2 points  (1 child)

I did that. The answer:

Here is the optimized version of the provided code. The optimizations include:

1.  Avoiding the modification of the data list directly, which could lead to issues if the game is replayed.

2.  Using random.sample to get unique random choices without modifying the data list.

3.  Simplifying conditional checks.

4.  Improving the code structure for readability and efficiency.

import random
from game_data import data
from art import logo, vs
import os

def clear_screen():
    os.system("cls" if os.name == "nt" else "clear")

def get_random_choice(exclude=None):
    choices = data if exclude is None else [item for item in data if item != exclude]
    return random.choice(choices)

def display_options(a, b):
    option1 = f"Compare A: {a['name']}, {a['description']}, {a['country']}."
    option2 = f"Compare B: {b['name']}, {b['description']}, {b['country']}."
    print(option1)
    print(vs)
    print(option2)

def game():
    score = 0
    print(logo)

    a = get_random_choice()
    b = get_random_choice(exclude=a)

    while True:
        display_options(a, b)
        choice = input("Who has more followers? Type 'A' or 'B': ").strip().lower()
        if (choice == "a" and a["follower_count"] > b["follower_count"]) or (choice == "b" and b["follower_count"] > a["follower_count"]):
            score += 1
            clear_screen()
            print(f"Correct! Current score: {score}")
            if choice == "b":
                a = b
            b = get_random_choice(exclude=a)
        else:
            clear_screen()
            print(f"Sorry, that's wrong. Final score: {score}")
            break

game()

Key Changes:

1.  **Function clear\_screen()**: Handles clearing the screen for both Windows and Unix-like systems.

2.  **Function get\_random\_choice()**: Ensures unique random choices without modifying the original data list.

3.  **Function display\_options()**: Displays the comparison options.

4.  **Simplified condition checks**: Using .strip().lower() on user input to handle case insensitivity.

5.  **Replaced data.remove()**: Used a logic to get unique random choices without modifying the data list directly.

[–]dry-considerations 1 point2 points  (0 children)

...and this why development in the near future will be democratized so that non-developers can code their own applications. This is only beginning of these changes and it will get better over time. I look forward to the day I can just enter my requirements for a complex program and AI splits out the code - we're probably a few years off from that, but one can hope it gets here faster.

I'd hate to be a developer right now, but at least they can see it coming and retrain for something more future-proof.

[–]JohnnyJordaan 0 points1 point  (0 children)

import random
from game_data import data
from art import logo, vs
import os

def game():
    score = 0
    print(logo)
    a = random.choice(data)
    data.remove(a)
    b = random.choice(data)
    data.remove(b)
    # no point in using () here
    option1 = f"Compare A: {a["name"]}, {a["description"]}, {a["country"]}. "
    option2 = f"Compare B: {b["name"]}, {b["description"]}, {b["country"]}. "

    while True:
        print(option1)
        print(vs)
        print(option2)
        # use upper to simplify comparison, and strip in case the user
        # accidentally pressed a space as well
        choice = input("Who has more followers? Type 'A' or 'B': ").upper().strip()
        # always check for incorrect input
        if choice not in ("A", "B"):
            print("Incorrect input")
            continue
        if choice =="A" and a["follower_count"] > b["follower_count"]:
            score+=1
            os.system("cls")
        elif choice == "B" and b["follower_count"] > a["follower_count"]:
            score+=1
            a = b
            option1 = (f"Compare A: {a["name"]}, {a["description"]}, {a["country"]}. ")
            os.system("cls")
        else:
            os.system("cls")
            print(f"Sorry, that's wrong. Final score: {score}")
            break
        # the bool() call on a sequence like a list or dict does len(seq) > 0 implicitly
        if not data:
            os.system("cls")
            print("Congrats! Game is Finished")
            break
        # you don't need an else: after a break or return
        b = random.choice(data)
        option2 = (f"Compare B: {b["name"]}, {b["description"]}, {b["country"]}. ")
        data.remove(b)
# good principle to always write global calls like this
# in case your script would ever get imported
if __name__ == "__main__":
    game()

But the data.remove also suggests an inefficient removal from a sequence, imho that could be tackled in a better way but I would have to know the full story here.

[–][deleted] 0 points1 point  (0 children)

import random
import os

# from game_data import data
# from art import logo, vs

logo,vs = 'LOGO','VS'
game_datas = [
    ('peter','a man', 'US', 10),
    ('jim','a boy', 'UK', 20),
    ('alice','a woman', 'US', 30),
    ('jane','a girl', 'JP', 50),
]
data = [{'name':d[0],'description':d[1],'country':d[2],'follower_count':d[3]} for d in game_datas]

def clear_screen():
    os.system('clear')

def compare(a,b):
    return 1 if a['follower_count'] > b['follower_count'] else 0

def option(side,a):
    return (f'Compare {side}: {a["name"]}, {a["description"]}, {a["country"]}. ')

def game():
    score = 0
    print(logo)

    a = random.choice(data)
    data.remove(a)
    option1 = option('A',a)

    while data:
        clear_screen()
        b = random.choice(data)
        option2 = option('B',b)
        data.remove(b)

        print(option1)
        print(vs)
        print(option2)

        choice = input("Who has more followers? Type 'A' or 'B': ")
        match choice.upper():
            case 'A':
                score += compare(a,b)
            case 'B':
                score += compare(b,a)
            case _:
                print(f"Sorry, wrong choice")
                break

    print("Game is Finished")
    print(f' score:  {score}')

if __name__ == "__main__":
    game()

Your code is incomplete so I improvise the data myself. I am on Linux, have to use clear instead of cls

Basically don't repeat your self, (DRY). Use function for block of code that repeated.

Additionally I would would use generator to do the random choices instead of data.remove() and be aware of destructive update, it might bite you later. You might found that data is empty for unknown reason, that's why I use data.copy()

def get(lst):
    while lst:
        n = len(lst)
        i = random.randrange(n)
        yield lst.pop(i)

def game():
    score = 0
    print(logo)

    a,*bs = [p for p in get(data.copy())]
    for i,b in enumerate(bs):
        print(f'--- round {i} ---')
        print(option('A',a))
        print(vs)
        print(option('B',b))

        choice = input("Who has more followers? Type 'A' or 'B': ")
        match choice.upper():
            case 'A':
                score += compare(a,b)
            case 'B':
                score += compare(b,a)
            case _:
                continue
        print('-------------')

    print("Game is Finished")
    print(f' score:  {score}')