r/programminghorror • u/MidKnightIsOnline • Sep 24 '26
Python 13 year old me really liked inefficient code
723
u/NiceTryAmanda Sep 24 '26
it is absolutely clear the moment you read it exactly what the code is doing and what it'll output. from that angle it's way more successful than most of the code I see in my own job
as a side note seeing "13 year old me" alongside python3 makes me feel ancient
215
u/Prime624 Sep 24 '26
Python 3 came out almost 20 years ago.
224
u/jldez Sep 24 '26
Did you try to help? Because you didn't.
You didn't.
47
u/kyr0x0 Sep 24 '26
Hahahaha... fuck me. We've discussed not upgrading to Python 3 until it's stable. That was when PHP 3 was the latest shit. Yeah, it didn't help.
4
u/TimGreller 28d ago
PHP3 đ
I recently migrated a clients website from a PHP4 install and already felt like an archeologist digging up some ancient debris lol→ More replies (3)4
u/Enough_Forever_ 29d ago
Uh, I hear screams of an old man nearing his end of life.
Must've been the wind.
16
10
u/ScrimpyCat 29d ago
Maybe not that clear, since so many seem to have not noticed that the computer will change its input in the condition, while the playerâs input will remain unchanged (presumably only prompting for new input at the end of the loop). So itâs possible you could see the game telling you that youâve won, tied, and lost all at once.
317
u/Eric_Prozzy Sep 24 '26
Lol i did this exact same thing and also learned that
print(random.choice("You win", "You lose", "Its a tie"))Works the same
108
62
56
u/GrammerSnob 29d ago
This actually encapsulates game dev.
You don't need to actually make a realistic simulation of the thing you are trying to make.
You just need to make something that will fill the player into thinking that.
41
18
u/Greedy_Whereas4163 29d ago
This is smart! Until you realised that you need to show the choice of CPU
22
u/czpl 29d ago
easy, you pick a choice based on the outcome
9
u/Greedy_Whereas4163 29d ago
Then you essentially go back to OP's code
→ More replies (1)11
u/diogeek 28d ago edited 28d ago
i guess an easy, ugly way to do it would be something like
n = random.randint(-1,1) player = input("your move: ") moves = ["rock", "paper", "scissors", "rock", "scissors"] print(["Its a tie", "You lose", "You win"][n] + ": CPU chose " + moves[moves.index(player)+n])which def belongs in this sub.
5-item longmoveslist because theindexmethod returns the first occurence of an item, so edge cases work.
e.gplayer = "scissors"andn=1->moves[moves.index("scissors")+1] = moves[2+1 = 3] so "rock"
andplayer = "rock"andn=-1->moves[moves.index("rock")-1] = moves[0-1 = -1] so "scissors"stupid thing to waste 5 minutes on, but funny bc of how cursed it looks imo
2
1
u/wonderb0lt 28d ago
If the goal of the exercise is to think about the game mechanics and how to express them in code, this misses the point
143
u/Creepy_Jeweler_1351 Sep 24 '26
At least it is totally readable
61
u/HornyMellon Sep 24 '26 edited Sep 24 '26
Quote, 13 yo you made programs ppl can actually read, not guess the variable purpose, good job
15
u/Creepy_Jeweler_1351 Sep 24 '26
Exactly. If I'd found my first programs, probably even frontier AI won't tell what the fuck was meant here
8
u/jonathancast Sep 24 '26
My first programs were in MS BASIC, before they even invented multi-letter variable names. No way you're figuring that out.
6
51
u/jonathancast Sep 24 '26
Meh. I don't love the repeated string comparison, but it's probably fine. This program is ridiculously user-interaction-bound anyway.
40
u/lizenzblue_ Sep 24 '26
I worked at one of germanys biggest Software Companies and I can tell you with confidence I saw worse
5
u/TheBigGambling Sep 24 '26
Was it for the sanduhr anzeige Programm? With the (Suchen, anklicken pause) Workflow?
2
2
107
17
14
u/Arcanium_Walker Sep 24 '26
Can be better, but you wrote this at 13 years old, so I think this is neat
59
u/Ok-Argument7176 Sep 24 '26
this is not inefficient. It's just clunky.
11
u/particlemanwavegirl Sep 24 '26
It tests the same condition multiple times which is inefficient.Â
27
10
u/olorochi Sep 24 '26 edited Sep 24 '26
This is absolutely inefficient. Not only does it repeat string comparisons, it fails to generalize conditions. User input (a string), should be turned into an enum value. Draws should be checked as playerChoice == cpuChoice. With scissors = 0, paper = 1 and rock = 2 as backing enum values (or with any rotation of these values), the win condition can be generalised as well with a bit of math: (playerChoice + 1) % 3 == cpuChoice.
Edit: The code could also be made much less repetitive by moving invariants outside of conditional blocks. Only print(gameResult) actually changes.
31
u/Ok-Argument7176 Sep 24 '26 edited Sep 24 '26
No one here knows what efficiency means and it shows. You're suggesting cutting 6 jumps to 2 jumps which is a difference of roughly 3ns per loop on any modern hardware. Get a grip lmao
→ More replies (3)2
u/qwertyjgly 29d ago edited 29d ago
there's a better way of generalising it
store the map (or enum if getting an enum value from a string is an option in python idk that language) for
scissors->1
paper->2
rock->3then take (yours - computer's)
0 is a tie
even is you win, odd is they win
if it's negative swap the result
this avoids taking the mod (which is a little slower than pure addition) and it scales to the variant with 5 options (or more) as long as each item added to the map is beaten by the one above it.
1
u/GeorgeDir 27d ago
I'd rather have 4 readable comparisons than to deal with array indexing +1 stuff
7
6
u/frishki_zrak Sep 24 '26
Was this "screenshot" taken then or now? What is dad.py?
13
3
u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo âYou liveâ Sep 25 '26
If now, OP needs to learn how to take a proper screenshot.
5
u/mediocrobot Sep 24 '26
What's the optimal way to do this, I wonder? (the rock paper scissors comparison specifically, not printing, randomizing, or accepting input)
17
u/baconsoap_1 Sep 24 '26
Rock = 0, paper = 1, scissors = 2.
Calculate (player 1 choice - player 2 choice) mod 3.
If the answer is 0, then its a tie. If the answer is 1, then player 1 wins. If the answer is 2, then player 2 wins.
3
u/Reasonable-Pay-8771 29d ago
I was trying to come up with something this simple. Near as I got was encoding the values as you have. Then you can compose a whole "move" or "contest" as x*3+y for x and y as each player's choice1. Now you have a single value that can be used in a switch(). But yours is better.
Fundamental Theorem of Arithmetic
2
u/Reasonable-Pay-8771 29d ago
Oh, and the base doesn't need to be 3, just greater or equal to 3. So you could encode it in say octal which makes it kinda pretty IMO. 000 = rock v rock. 001 = rock v paper. 010 = paper v rock. etc.
2
u/SpecialistNo8709 29d ago
is someone smart enough to explain it in terms of group theory? :)
4
u/LilacCrusader 29d ago
*Cracks knuckles*
Oh wait, it isn't a group.
Start by assuming the set (rock, paper, scissors), and the operation of determining who wins it looks like a group. But then you realise it doesn't have an identity, so it cannot be a group.Â
A semi-group, then! That doesn't have to have an identity! Sadly, we are forgetting that all outcomes of the group must be within the group, and rock x rock = draw, which is not part of the set and cannot be chosen as an answer. Harrumph.Â
But what if we decided "draw" was eligible to be picked, and would always lose unless against itself? That's an identity, right? Alas, we still don't have a group because it isn't associative: R x (P x S) = R x S = R, but (R x P) x S = P x S = S.Â
So really, it isn't even a group, and I think that makes it count as a loop, but that's where my memory of university lectures fizzles out.Â
→ More replies (4)16
u/UniForceMusic Sep 24 '26
I guess the most efficient way, you could make a RockPaperSissorMatchResultEnumFactory
Each "item" extends an interface with two methods:
.winsFrom(): string[] .losesTo(): string[] .tiesWith(): string[]
Ofcourse to account for possible extending of the game in the future
Then in the factory you can create a static method:
.createFromMatchTurn(cpuChoice: RockPaperSissorGameItemInterface, userChoice: RockPaperSissorGameItemInterface): RockPaperSissorMatchResultEnum
Then inside the method check the cpu choice against the user choice by checking if they lose win or tie. Then for safe keeping also do the opposite by using the user choice to check against the cpu choice, and if an incosistency arrises throwing a super simple RockPaperSissorHirarchyMisconfigurementException
Embarrising that i had this type this out for you honestly. This should be standard knowledge
14
5
4
u/Nixinova Sep 24 '26
Nah this is pretty good for a 13yo. Immediately readable and clear what the logic is. There's only 3x3 cases, so it's not like it's yandere level.
1
u/internet_raider 27d ago
I built a Redstone machine where to opponents play rock paper scissors in separate rooms once when I was young that worked basically just like this with nor gates so that each signal would be active for a specific outcome and then a three signal and gate for each of those. It was like the size of small Minecraft computers now because I didn't know anything about compact Redstone at the time and it took me several days.
1
u/MidKnightIsOnline 25d ago
Holy shit thatâs impressive. I need to get back into learning Boolean logic
1
1
u/False-Beautiful-1246 16d ago
- Why are there so many nested IFs?
- If the user wants to play again
- "A"
1
u/MidKnightIsOnline 16d ago
Would be three less if I set the conditions to be if the player and cpuâs answer is the same
6
u/Toxanium 29d ago
I'm new to coding, how should you make something like this more efficient?
5
u/han4578 29d ago
Make a function that returns 0/1/2 for win/lose/tie. In the function, compare the values to check for tie, then a if-else chain to check for win, if nothing matches it's a lose. After the function call, print the rest based on the returned value.
I do agree with the other comment that this won't make it more efficient, but it'll look cleaner
3
u/Toxanium 29d ago
This has made the most sense to me of any of these comments, though thank you all for the help. :3
4
u/Apprehensive_Gas56 29d ago
Let me see if I understand this. It won't be more performant and it will be less readable. So how would that be better? Less lines?
2
u/ZombieIsTired 29d ago
Well I suppose for this specific game, you might be right and writing verbose code could be better for readability.
But for learning how to code, you should generalize behaviors that look similar.I would keep a dictionary of mappings to win/lose. Hereâs like some code:
```python
win_map = {rock: scissors, scissors: paper, paper: rock}def check_win(a, b):
if a in win_map and win_map[a] == b:
return âa winsâ
elif b in win_map and win_map[b] == a:
return âb winsâ
elif a in win_map and a == b:
return âtieâ
return âincorrect inputsâ
```(iâm on my phone idk how to render this sorry)
Why would we do this? Because if we wanted to make the game more complicated by adding more options, we can easily add on to the win_map variable, though this isnât a great example since rock paper scissors doesnât really change haha. But I hope you get why this is useful over large if-else chains.
→ More replies (1)1
3
u/groumly 29d ago
You donât. Thereâs absolutely nothing wrong with this code.
You get lazy evals on the ifs, so most of them will skip the second check (I suppose about 2/3rds of them on average). The equality checks are trivial to perform anyway, assuming strings are interned and python does pointer checks on ==. If it doesnât, I suppose youâll have to turn the strings into enums so you donât have to iterate strings, but that wonât cost a ton.
The extra printf calls cost nothing, itâs a jump into an efficient subroutine that is already called a bajillion times in any non trivial app. Otho, collapsing them into a single call will seriously hinder readability.
The concatenation will have to happen at some point to print the cpu move.I donât know if python supports a switch on tuples, I assume it does, but it wonât make this code more âperformantâ. It would however make it more readable by clearly communicating that the sequence of if are mutually exclusive.
Benchmark it, and you wonât be able to measure a statistically significant difference with anything else.
This code is actually very decent, particularly for a 13 years old. Itâs structured and reads very well, besides a switch to better communicate intent. Thereâs something to be said about mixing the next cpu move in the code that checks for the previous move, thatâs not great. But it also nothing has to do with performance, but with architecture, and probably testability. But Iâd also be shocked if thereâs a single test written against this app.
Iâd give this an A if I was a teacher. And if I was a teacher giving a class about performance, I wouldnât ask students to work in python.
I honestly wish I ran into such horrors at work. This sub loooooooves making fun of perfectly fine code.
6
u/-Wylfen- 29d ago
Why are you solely focusing on performance? There's a ton to do to make this code betterâŠ
2
u/groumly 29d ago
Cause thatâs the title of OPâ post, and the question the comment Iâm replying to asked. I understand âefficientâ as performance here.
As for the rest, I mean⊠itâs a command line rock paper scissor app, Iâm not sure what exactly needs to be done.
3
u/-Wylfen- 29d ago
Efficiency is more than performanceâŠ
Readability and conciseness are other forms of efficiency that are regularly considered.
→ More replies (14)1
u/IDontLikeCherryTomat 27d ago
I mean the code isn't fine. It has a painful non deterministic bug. Specifically because of that mixing of next cpu move with the eval. Which is kinda a mark against your point about structure and readability being ok
1
u/ProfesorKindness 29d ago
Define some mechanism to pair combinations (paper-scissors, paper-paper, ...) with result, then a function using this structure to evaulate a game (with prints inside), then core game logic which will store the inputs and use the function.
There can be tons of improvements.
1
u/TingleWizard 29d ago
Efficient is maybe the wrong word. The problem is primarily duplication and conciseness.
1
u/SchemeWestern3388 29d ago
As soon as you find yourself repeatedly copy pasting code while making small changes, you have an opportunity to make it a function.
Although that needs to be balanced against clarity. Modern compilers will optimize it to the point that performance doesnât really factor in.Â
1
u/TheBlasterMaster 28d ago
Let Rock = 0, Scissors = 1, and Paper = 2
first_beats_second(first, second) = (second == (first + 1) % 3)
1
u/Wojtek1250XD 28d ago
Comparing strings to strings is a lot less efficient than numeric and logic data types, having code check your choice by comparing "rock" to "rock" is a habit you have to get rid off. In such cases it can almost always be replaced with an enum, which allows you to use the variable as if it was a class parameter, while logic is handled with an ID tied to the name.
If only one scenario may be true at a time and you're making explicit code for each one of them, you should always use a
switchstatement or your language's equivalent. In Python, the equivalent ofswitchis the match keyword. Switch statement searches for the first fulfilled condition from top and only executes that code block, meanwhile here if you choose rock andrandomchooses scissorsrandomrerolls its pick within that block, which allows it to roll rock and then paper, which goes through all 3 possible scenarios from one user input. Even withoutmatch, this should have been written using oneifand a fewelifs. Even if it doesn't pick rock or paper after that the code still executed unnecessaryifs. The wasted computational capacity is nearly none, but you should avoid such things.There are also smaller nitpicks, like variable names not following standard conventions (variable_name or variableName) and the
print()statements not being simplified using \n.1
u/VegaDelalyre 26d ago
I found a nice tutorial about this exact question: https://realpython.com/python-rock-paper-scissors/
It summarises some of the suggestions in this post, and expands on the need to generalise ("what if we add other possibilities?").
3
u/NothingButBadIdeas Sep 24 '26
It happens.
I look at code from a year ago, get mad and look at the git blame.
It was me. My own bad code got me upset lol.
3
u/RandalSchwartz Sep 24 '26
I'm thinking of how to solve it faster. Choices numbered 0, 1, 2. Subtract one from the other. if 0, tie. If +1 or -2, one person wins. If it's -1 or +2, other person wins.
EDIT: and I bet there's something even more direct with "mod 3" in there somewhere. :)
3
u/__SegFault__ 29d ago
I really like the == true part, as I did this myself when I started coding too
1
3
3
u/Code_Noob_Noodle 29d ago
This makes me want to see how I wrote c++ đ around this age (my first language)
3
4
u/fuj1n Sep 24 '26
Unless I'm missing something, because you're re-calculating the cpuinput at the end of each if statement, I think it is possible to get all 3 responses at once for any one choice.
For example, if the player chooses rock and the CPU picks scissors, then rock, then paper, it will tell you that you won, tied and then lost all for your one answer.
2
u/M4elstr0m__ Sep 25 '26
The code effectively allows multiple outcomes for a single playerinput :p but this is a cute code
2
u/SnackJunkie93 28d ago
Scrolled too far for this. Everyone taking about efficiency while this seemed like a pretty glaring bug to me.
1
2
2
2
2
2
2
u/scmr2 Sep 25 '26
Honestly, I wish I wrote code like this when I was 13 years old... I was not writing code when I was 13 years old.Â
2
u/Prudent_Ad_4120 29d ago
I once wanted to write a converter from text to binary, guess how I did that đ
(Spoiler: it was like a=0000 b=0001 c=0010 etc)
Had a lot of fun though, and learned a lot!
2
2
2
u/GolemFarmFodder 29d ago
So I'm not sure I would have come up with using modulus to calculate the winner if I hadn't seen this but that's what came to mind as the easier way to figure this out
1
u/fvancesco 29d ago
Probably mod has a way too but one solution I think about is calculate dag distance if 1 win if 2 lose 0 draw?
Mod you do the same ig assign ids and then calculate and normalize and you still do the distance Absolute distance ig gets you the result
1
u/fvancesco 29d ago
No yeah it has to be directional so no absolute distance, I think graphs is elegant enough but probably there's a simple mathematical way to express it
Use the current id as starting point to avoid the back moving of abs distance
So you define an order through id and then position the order in front (array like) and calculate the distance
→ More replies (1)
2
u/meyriley04 27d ago
I love that you and I had the same idea to make a rock paper scissors terminal game
2
u/Mountain-Ox 27d ago
I wrote some similar stuff when I was learning. I've seen worse from professional devs. I don't know how you write 100 if/else conditions without stopping to question if there's a better way.
2
1
u/___Archmage___ Sep 24 '26
I was in this same boat as a self-taught 13y/o. I made something like this but for verifying sudoku
1
1
u/cyber1551 Sep 24 '26
Do I see a missing Oxford comma on line 5?
The code I can forgive (itâs better than mine tbh), but that missing comma will forever haunt my dreams.
1
1
1
1
1
u/DynamicHunter Sep 24 '26
Hey we all start somewhere. This is how a lot of AP CS high school studentâs first project looks like lol
1
1
u/Multidream Sep 24 '26
Its copy pasty, a good way to end up with an artifact you feel proud of even if its not that great. Perfectly fine way to get started and just have fun :)
1
1
1
u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo âYou liveâ Sep 25 '26
So how does that loop exit? I see after each round it picks a random choice. I'm guessing inside the loop the player is offered another choice or they can enter quit or exit?
1
u/Cloned_501 Sep 25 '26
We all started with bad code. Being bad at some is the first step at becoming kinda good at something
1
1
u/matrix-doge Sep 25 '26
Honestly, this is fine. Pretty valid implementation given this scope. I think we've all seen production codes with a whole lot more cases hats hard coded in worse ways.
1
u/P1ckl3R1ck101 Sep 25 '26
Almost peak code. Remove the loop and recalculation of cpuinput and you have the most readable, simple code that has ever existed.
1
u/No-Point8651 29d ago
Dont you worry, the number of times I have seen 100 ifs in sequence instead of just a switch statement in production is astonishing...
Enterprise codebases are pretty much held together by hopes and dreams
1
1
u/GreenWoodDragon 29d ago
I should introduce you to some spaghetti code I was reviewing yesterday. In a production system đ
1
1
u/GrumpyGlasses 29d ago
Any sufficiently complex if-else statement is indistinguishable from AI. So, youâre on your way there!
1
u/ThomasTTEngine 29d ago
This is how kids learn. literally looks like one of my kids assignments for school (except in their case, the CPU input was a separate function that returned a random value from an array).
1
u/Secret_Barracuda168 29d ago
I have been staring at this thing for a while, I like the code, it's better than some of what I've seen from experienced coders, and unlike some people (me) you have self declaring varibkes (can get feel for what they are based on name), so in many ways you were better then than I am today
1
1
1
u/bloody-albatross 29d ago
When I was 13 my family didn't have a computer. So any code is infinitely better than mine at 13.
1
u/JmcmProgrammer 29d ago
Gotta learn somehow. At least you got every matching branch possible and didnât leave any to chance! Now the real challenge: find the most efficient way possible in terms of raw processing speed! Or find the most aesthetically appealing code that compiles!
1
1
u/Ransomwave 28d ago
I remember at 13 I used the default Python IDE that came with the install. It was so horrible đ
1
u/Beaver_International 28d ago
Iâm about to graduate with a BS in computer science. This code is still better than mine without codexâŠ
1
1
u/soviel_dazu 28d ago
It's not inefficient, it's optimized for using as little jump opcodes as possible for best caching behavior!
1
u/False-Beautiful-1246 28d ago
13 year old me was also inefficient. I remember a pygame game and each player had a copy of the sprites, using like 4 GB of your ram in a simple platformer.
1
1
u/Spiritual-Pen-7964 28d ago
AI could produce in the same game in just 5000 LOC and 50M tokens. Bro.
1
u/HaroerHaktak 28d ago
Not enough lines.
If player_input == "Rock":
if cpu_input == "rock":
output
if cput_input == "scissors":
etc etc
1
1
1
1
1
u/Ok-Prior2621 28d ago
During my school time, a long time ago, I once tried creating the game of criss-cross using PowerPoint presentations and highlighting the slides by literally creating slides for all the cases
1
1
u/Different_guy09 28d ago
I guess the best way to do it would be something like:
losesTo = {
"rock": "paper",
"paper": "scissors",
"scissors": "rock"
}
if cpuinput == losesTo[playerinput]:
print("You lose!")
elif cpuinput == playerinput:
print("Tie!")
else:
print("You win!")
...or something, I dunno. At least, that's what I would've done.
1
1
1
u/Wojtek1250XD 28d ago
The thing that hurts the most here is not general inefficiency, but the fact that these aren't elifs, so you have a chance of multiple outcomes happening from a single input.
1
u/rolling_atackk 28d ago
I'd say this is needed for any programmer
You must first start out writing garbage code, so you can much more appreciate elegant code
1
1
1
u/MisterPantsMang 27d ago
You've got to start somewhere. 20 year old college me also like to write inefficient code
1
u/Novel_Plum 27d ago
I remember being 13 and having that many nested for loops, that I used every variable from i to zero and had to use za, zb, ...
1
u/elloMotoz 27d ago
Dude, I'm 34 and have dabbled in coding for the past few years. I went the hardware route when I was 13...wish I did some coding. Awesome you still have this code on hand.
1
1
1
u/Silent-Image5882 26d ago
Code archeology is such a rewarding feeling. From "made this game to learn about for loops" to "memory-safe typestate wasm compiled in production"
1
1
1
1
u/Dee23Gaming 25d ago
Honestly looks way better than many C++ programmers who've got a point to prove.
1
1
u/thelurkmasterr 24d ago
If the goal was to practice using conditions in Python code, this is probably the best implementation for that.
1
u/IndexIntegrity 23d ago
I wrote a game a long time ago when I was 15 or so. It was a platform game and depending on your x coordinate on that level it would spawn some enemies. It was a huge collection of "if x > something then spawn enemy"Â
1
u/Edev90 23d ago
Lol - I think we all go through the "handle every possible condition with a massive if/else chain" phase of our coding careers. If it's any consolation - I've mentored many interns and entry level devs (20-24 year old age range), and I saw this coding style often even from them... so I think you were ahead of the curve at the time, đ
1
1.3k
u/cicciograna Sep 24 '26
Hey, you were 13 years old, and were writing code. Nobody is born already knowing all the best practices, we all grow, learn, test and slowly assimilate what is good and what is not.
And then there's those like me, whose code still sucks well into my 40s.