So I got kinda bored and was wondering if it was possible to make this code shorter without modifying anything except a file named coin.py...

from random import*;c=['heads','tails'];print('u win'if choice(c)==input(' / '.join(c)+': ')else'u lose')

The program asks the user for either "heads" or "tails", if the result from random.choice(c) matches the user's input, print "you win" to the console. Otherwise print "you lose" to the console.


heads / tails: tails
u win

heads / tails: tails
u lose

(no loop needed btw, just run once)

Maintaining all its functionality & having the EXACT same output

Have fun, stack exchage :)

Update: Security practices don't matter for this question

  • 4
    \$\begingroup\$ Please take a look at On "golf this for me" tips questions. Your question should at minimum explain exactly what is the functionality that our further-golfed code should reproduce. \$\endgroup\$
    – xnor
    May 19, 2023 at 2:15
  • 7
    \$\begingroup\$ While your code decides the "correct" guess of heads and tails before you guess, there's no observable way to tell this from it just ignoring your guess and randomly saying you were right or wrong. Is it OK to shorten the code this way? \$\endgroup\$
    – xnor
    May 19, 2023 at 2:24
  • 2
    \$\begingroup\$ Is it necessary to handle when the input is neither heads nor tails? \$\endgroup\$ May 19, 2023 at 2:27
  • 1
    \$\begingroup\$ Also, welcome to Code Golf! \$\endgroup\$ May 19, 2023 at 3:58
  • 1
    \$\begingroup\$ @xnor: Probabilistically you could detect randomly saying right or wrong if the user repeatedly enters something that is neither head nor tails many times; if they enter edge every time, the current code will always say they lose, while just randomly picking the winner would tell them they won ~50% of the time. \$\endgroup\$ May 19, 2023 at 17:03

1 Answer 1


Few improvements off the top of my head:

  1. (Shaves two characters) You don't need a list, a tuple will do, so:


    can shorten to (parentheses around tuples are optional when it has at least one item and it's unambiguous):

  2. (Shaves four characters) You can interleave the two output strings into a single one, and do a slice skipping by 2, with the start point based on your condition, shaving:

    print('u win'if choice(c)==input(' / '.join(c)+': ')else'u lose')

    down to:

    print('uu  lwoisne'[choice(c)==input(' / '.join(c)+': ')::2])
    # Or if you prefer, no change in length:
    print('u','lwoisne'[choice(c)==input(' / '.join(c)+': ')::2])
  3. (Shaves five characters) Use printf-style formatting to construct your string, now that c is a tuple, this is cheap:

    print('uu  lwoisne'[choice(c)==input(' / '.join(c)+': ')::2])


    print('uu  lwoisne'[choice(c)==input('%s / %s: '%c)::2])
  • 2
    \$\begingroup\$ Instead of 3 you can do '%s / %s: '%c. \$\endgroup\$
    – loopy walt
    May 19, 2023 at 5:36
  • \$\begingroup\$ @loopywalt: Good point; forgot that the switch to tuple would enable that. Updated. The final line shaves the same number of characters either way, but it saves the four characters spent unpacking in the second line, so it's a much nicer win. \$\endgroup\$ May 19, 2023 at 16:56
  • \$\begingroup\$ Amazing! This code is 94 characters long! \$\endgroup\$
    – Eric
    May 19, 2023 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.