Programming thread

Skip ML if you want to learn anything. You're starting from nothing; you are inevitably going to have to trust the LLM because you don't have any knowledge to fall back on to know if it's just lying to you, or worse, correct but giving very, very bad advice, and then you're fucked. It's already chopped your legs off while you're still trying to crawl.

Just program something, anything. Read the error messages and try to understand them, learn from your mistakes. If you want to learn you'll learn.
Well when it does something to the code that I don't understand I ask it to explain, and then I try to read more about the subject elsewhere. For example I was just trying to write a rock paper scissors game in python. it wasn't working so I asked GPT what was wrong with it, in response it put a dictionary literal in. Which, despite taking computer science 101 (where I was taught python), I had never heard of. So I asked it what it was and from there read more about it.

But you're probably right. It does feel like cheating and I need to take a more active role in troubleshooting my code.
 
Well when it does something to the code that I don't understand I ask it to explain, and then I try to read more about the subject elsewhere. For example I was just trying to write a rock paper scissors game in python. it wasn't working so I asked GPT what was wrong with it, in response it put a dictionary literal in. Which, despite taking computer science 101 (where I was taught python), I had never heard of. So I asked it what it was and from there read more about it.

But you're probably right. It does feel like cheating and I need to take a more active role in troubleshooting my code.
I find it's a good supplement for documentation, especially when the real documentation is poor or maybe just a pain, but for problem solving it is mostly miss with rare, shitty, hits. Seriously, ask it to solve a classic algorithm like depth first search, then ask it to modify it to do something slightly different. Like do depth first search but have it color the nodes in a specific pattern along the way.
 
I find it's a good supplement for documentation, especially when the real documentation is poor or maybe just a pain, but for problem solving it is mostly miss with rare, shitty, hits. Seriously, ask it to solve a classic algorithm like depth first search, then ask it to modify it to do something slightly different. Like do depth first search but have it color the nodes in a specific pattern along the way.
I mentioned a pretty good article about this sort of issue earlier in this thread.

As mentioned in the article, it seems pretty competent at basic, well understood algorithms already in wide use. The kinda shit that has a wikipedia page and dozens of answers on stack overflow explaining how to implement basic homework assignment versions of said algorithms.

But if you need a specific application with unintuitive corner cases, the LLM will give it a try, but often the LLM is worryingly bad at just admitting when it can't get it right. It'll just keep throwing shit at you, even after several cycles of pointing out failure scenarios of the LLM's solution.

LLMs would have a lot more confidence with programmers if it included the ability to just give up on your request if it's unable to solve it.
 
Had some entry-level questions about mobile app development for programming an idea I've been throwing together. Putting it under a spoiler so uninterested thread-goers can ignore, but I appreciate any input.

My biggest initial concern is that while my idea is definitely a slam dunk, if a more competent programmer learns about it before I can finish it then they'll steal the concept and push it out before me. Is this a valid concern or am I being a paranoid jackass?

Anyways, without too many specifics, I’m working on a program that involves a dataset of objects where each object is composed of a structured sequence of components. When a user submits a query object, the app evaluates it by comparing its components to all other objects in the dataset and their components, scoring similarity based on patterns like shared subsequences, position of matching elements, and overall overlap. The goal is to return a ranked list of the most similar objects.

I've made a working prototype in Python by fucking around with ChatGPT generated code and a database, and the concept absolutely works so far. At this point, I imagine that my next steps would be planning what the stack would look like, learning the various programming languages for each portion of the stack, and then to start putting together real code that isn't LLM generated nonsense. Endgoal is an app on the Play Store or App Store supported by ads and paywalled "premium features."

So, would the frontend be like HTML/CSS/JS, the backend be python, and then the database would be some SQL program? This is where I'm a retard and no longer have any idea what I'm doing; I figure as long as I have a grasp of what this hypothetical stack looks like, I can self-teach the necessary programming languages or hire a coding tutor, even if it takes me awhile to complete.
 
Had some entry-level questions about mobile app development for programming an idea I've been throwing together. Putting it under a spoiler so uninterested thread-goers can ignore, but I appreciate any input.

My biggest initial concern is that while my idea is definitely a slam dunk, if a more competent programmer learns about it before I can finish it then they'll steal the concept and push it out before me. Is this a valid concern or am I being a paranoid jackass?

Anyways, without too many specifics, I’m working on a program that involves a dataset of objects where each object is composed of a structured sequence of components. When a user submits a query object, the app evaluates it by comparing its components to all other objects in the dataset and their components, scoring similarity based on patterns like shared subsequences, position of matching elements, and overall overlap. The goal is to return a ranked list of the most similar objects.

I've made a working prototype in Python by fucking around with ChatGPT generated code and a database, and the concept absolutely works so far. At this point, I imagine that my next steps would be planning what the stack would look like, learning the various programming languages for each portion of the stack, and then to start putting together real code that isn't LLM generated nonsense. Endgoal is an app on the Play Store or App Store supported by ads and paywalled "premium features."

So, would the frontend be like HTML/CSS/JS, the backend be python, and then the database would be some SQL program? This is where I'm a retard and no longer have any idea what I'm doing; I figure as long as I have a grasp of what this hypothetical stack looks like, I can self-teach the necessary programming languages or hire a coding tutor, even if it takes me awhile to complete.
I mean, the concept you're describing sounds very similar to something like elasticsearch. Which is what I'd suggest you use for your backend data store.
 
Would any of you guys be willing to take a look at the rock paper scissors game I made and give me your thoughts? It's a very simple game and ChatGPT helped me a lot, but I do feel like I learned a lot from making it. I'd like to know if there's anything I could do to improve this in your eyes, or if there's some major way in which I'm fucking up. Also, what other projects would you suggest doing at this skill level?



Python:
import random
game_choices = ["rock","paper","scissors"]

winning_combos ={"rock": "scissors",
                "paper": "rock",
                "scissors": "paper"}

def get_player_choice():
    while True:
        player = input("Choose rock, paper or scissors: ").lower()   
        if player == ("gun"):
            print("Hey that's cheating!")
        elif player not in game_choices:
            print("invalid input, only use rock paper or scissors")
        else:
            return player

while True:

    npc = random.choice(game_choices)
    player = get_player_choice()

    print("You chose", player)
    print("Computer chose", npc)
        
    if npc == player:
        print("Draw")
    elif winning_combos[player]==npc:
        print("You win!")
    else:
        print("Computer wins")
        
    play_again = input("Would you like to play again? (yes/no): ").lower()
    if play_again not in ["yes","y"]:
        print("Thanks for playing!")
        break
 
but often the LLM is worryingly bad at just admitting when it can't get it right.
LLM have a "helpfulness" bias, saying "I can't answer that" is an unhelpful looking sentence while making something up produces more output and so looks more attractive. I do wonder what an LLM trained to be pessimistic and keep things short would look like, and if that would cut down on hallucinations, sadly, it's output would also likely be less marketable.
 
I prefer menu systems where menu options correspond to an index + 1 (as an example) as it's easier on the user and yourself. You could also then use that value and compare integers instead of strings if you want to keep performance in mind early on. It's kind of nitpicky and negligible for this but I think helps build a good foundation of having options.
1) Rock
2) Paper
3) Scissors
Select one:
To determine the winner, if you're using ints in sequential order like you already have it where the higher value wins except where rock (1) beats scissors (3), you can get around that with modular arithmetic to "wrap" the values to determine the winner and then apply that so you're really checking that they're "1 apart" and the difference is negative such that paper (2) beats rock (1), explained below. Otherwise the computer wins because they chose something 2 steps away.

For example, rock (1) - scissors (3) = -2.
-2 mod 3 = 1 It equals 1 so player wins.
scissors (3) - rock (1) = 2.
2 mod 3 = 2 Does not equal 1 so computer wins.
Python:
if (player - npc) % 3 == 1:
    print("You win!")
else:
    print("Computer wins")
To handle a draw you'd store the value and check if they're the same so it'd be 0 mod 3 = 0.
Python:
outcome_val = (player - npc) % 3
if outcome_val == 0:
    print("Draw.")
elif outcome_val == 1:
    print("You win!")
else:
    print("Computer wins")
Again this is all nitpicky and with Python in particular there's a focus on readability so many would rather you didn't do this but it's good to have options and be deliberate in your choice. You could get even more in depth with the if/else ordering based on probability to minimize comparisons but that matters even less here. It would be reasonable to do normal less than/greater than comparisons for each combination in this case and it's not a pain to maintain as is. If you decided to add more options it would snowball fast, though and become a mess whereas the above would still work with small changes.

And not all languages handle modular arithmetic the same way, for example C/C++ with negative operands will give a negative result.
 
Last edited:
Would any of you guys be willing to take a look at the rock paper scissors game I made and give me your thoughts?
For a game this small, why not extend your "winning_combos" idea and make a lookup table containing all the outcomes? Your throws are the columns labelled on top, computer's throws are the rows labelled on the left. Matrix cells list the winner.

RockPaperScissors
RockDrawYouComputer
PaperComputerDrawYou
ScissorsYouComputerDraw

Obviously this doesn't scale well, but that's another story.

Also, what other projects would you suggest doing at this skill level?
Someone else here was doing gambling games as a learning exercise, I thought that was a good idea.
 
Someone else here was doing gambling games as a learning exercise, I thought that was a good idea.
I really like that idea, I like it so much that I just made this:
Python:
import random

x = 0
y = 0
cash = 100

def gamba_game():
    
    global x
    global y
    global cash

    game_roll = random.randint(1,100)

    print("You bet $10")

    if game_roll > 51:
        print("Yes!")
        x = x + 1
        cash = cash + 10
        print(f"You won $10, \nyour balance is ${cash}")
        gamba_sesh()
    else:
        print("No")
        y = y + 1
        cash = cash - 10
        print(f"You lost $10, \nyour balance is ${cash}")
        gamba_sesh()

def gamba_start():
    
    while True:
        play =  input("Welcome to the casino! \nYou have $100, \nbets are $10. \nWould you like to play?(yes/no): ")

        if play in ["yes","y"]:
            return gamba_game()
        else:
            print("That's prbably a good idea")
            break

def gamba_sesh():
    
    global x
    global y
    global cash

    while True:
        
        if cash == 0:
            print("Dude I just lost it all")
            print(f"wins {x}")
            print(f"losses {y}")
            break
        else:
            play_again = input("Play again (yes/no): ")
            
            if play_again in ["yes","y"]:
                gamba_game()
                break
            else:
                print("One more and I'm out!")
                gamba_game()
                break

gamba_start()

And I did it all without asking ChatGPT one question. I used a lot of functions because I just learned what they are and I want to learn more about them. I had a big issue where the game over message looped as many times as you had played the game. It took me like a half hour to figure out that I needed to put "break" at the end of the if and else statements in the "play again" section.

This was kinda a shitpost, but I feel like I learned a lot and it was really fun. To do this more seriously I'll need to figure out how to make it so you can bet variable amounts of cash (and do games that aren't a slightly weighted coin flip). Thank you for the advice and suggestion.
 
Would any of you guys be willing to take a look at the rock paper scissors game I made and give me your thoughts?
I would tweak the user input slightly.

The program accepts a short form for "yes", but this is not indicated to the user (and also comes after an input which did not accept a short form). The short form is typically indicated by brackets. For yes/no, or any other input with a default option, invalid input should still be rejected, only taking the default path if the user input is actually empty.

I would also add a "quit" option.

Code:
$ rps.py

Choose your move:
[R]ock [P]aper [S]cissors [Q]uit
> r

You chose: Rock
Computer chose: Paper
You Win!

Play again? [y/N]
>

Thanks for playing!

Also, what other projects would you suggest doing at this skill level?
Extend your program to support "rock, paper, scissors, lizard, Spock". There are two chains to consider;

- rock < paper < scissors < Spock < lizard
- rock < Spock < paper < lizard < scissors



And I did it all without asking ChatGPT one question.
I think this answers the question as to whether or not ChatGPT is a good substitute for documentation and tutorials... and also why the damage is not limited to "LLM written" code. You have created a program which appears to work, but which you do not understand.

It took me like a half hour to figure out that I needed to put "break" at the end of the if and else statements in the "play again" section.
Both of those while True loops are redundant as both branches of the if/else will break from the loop on the first iteration.

I had a big issue where the game over message looped as many times as you had played the game.
This is because gamba_game() calls gamba_sesh() which calls gamba_game(), etc. This kind of thing (mutual recursion) is generally something that you want to avoid (especially in Python). You still have a bug where the player cannot quit after starting.



gamba_start() is also returning the value of gamba_game(), even though gamba_game() doesn't return anything. not that it matters, because the value is not being used anyway. In C, this would be a cause of the dreaded "undefined behaviour" that people love to fearmonger; Python is very helpful in that it simply ignores the problem, doesn't tell you, and pretends that it never happened.

The gamba_start() and gamba_sesh() functions probably want to be merged. The gamba_sesh() function should manage the players cash, wager, game selection, etc., and gamba_game() should simply return True/False depending on the outcome of the game.

You don't need those global variables, throw them into a "player_data" dict and pass them to gamba_sesh() instead. And why are the wins/losses variables called x/y? You don't have to pay for each character these days.

You'll also get a RuntimeError after 250 games, because of the recursion limit. Increase the starting cash to 1000, start a game, and just hold the enter button down (exploiting the bug mentioned earlier) and you will see.

I'll need to figure out how to make it so you can bet variable amounts of cash
You already know how to take user input, you just need to convert the string to a number.

- https://docs.python.org/3/library/functions.html#int
- https://docs.python.org/3/library/functions.html#float

Unless I'm blind, it doesn't say that the function will throw ValueError if the input cannot be converted. Python loves to throw exceptions around as part of regular control flow so you should probably get to know them.

- https://docs.python.org/3/reference/executionmodel.html#exceptions
 
if youre not using 6502 assembly youre doing it wrong
The author of this post:
images.webp
 
And I did it all without asking ChatGPT one question. I used a lot of functions because I just learned what they are and I want to learn more about them. I had a big issue where the game over message looped as many times as you had played the game. It took me like a half hour to figure out that I needed to put "break" at the end of the if and else statements in the "play again" section.

I decided to do an annotated edit of your gamba sesh code in order to improve upon it, I hope that it helps you learn.

I don't code in Python normally, some stuff might not be stylistically correct, but I hope this helps in some way.

Python:
import random

# We use a class to represent game state instead of globals.
# There's a variety of reasons to do this, it:
# - isolates state, so you can write more functional code
# - keeps the Game State out of the global scope, thus maintaining separation of concerns
# - allows for multiple games to be played, or multiple different players
# - makes for easy serialization (saving) of the game state, if wanted
# - makes it easier to extend
# - etc.
class GameState:
    wins = 0
    losses = 0
    cash = 100
  
    # This constructor allows for GameStates to be created in memory with an arbitrary number of wins, losses and cash.
    # For example, you can use this with serialization to save a game state and load it later
    # You could also add a difficulty selection to start with less or more money
    def __init__(self, wins=0, losses=0, cash=100):
        self.wins = wins
        self.losses = losses
        self.cash = cash
  
    # I'm not sure if this is stylistically best practice in Python, or if it would be preferred to have a top-level
    # factory function. This function just creates a new game with defaults.
    # It can be argued this is unnecessary given GameState's default constructor, but I feel it adds legibility.
    @staticmethod
    def create_default():
        return GameState()

# The following has been removed and moved to Game State.
# x = 0 - renamed to wins. You should try and always have descriptive variable names
# y = 0 - renamed to losses.
# cash = 100

def gamba_game(game_state, stake):
 
# The following lines were removed. You should generally avoid managing state like this.
# Instead, consider these as inputs, and pass them as function parameters. Where possible, parameterize everything.
# In this case, we expect a GameState which contains these variables
#    global x
#    global y
#    global cash

    game_roll = random.randint(1,100)

    print(f"You bet ${stake}")

    if game_roll > 51:
        print("Yes!")
        game_state.wins = game_state.wins + 1
        game_state.cash = game_state.cash + stake # I modified the hard-coded value of 10 to be `stake` instead, this way you can play higher or lower stake games
        print(f"You won ${stake}, \nyour balance is ${game_state.cash}")
#        gamba_sesh() ; removed because this causes unbounded recursion
    else:
        print("No")
        game_state.losses = game_state.losses + 1
        game_state.cash = game_state.cash - stake
        print(f"You lost ${stake}, \nyour balance is ${game_state.cash}")
#        gamba_sesh() ; removed because this causes unbounded recursion

def gamba_start(game_state):
    print("Welcome to the casino! \n")
    stake = 10
  
    while True:
        player_input =  input(f"You have ${game_state.cash}, \nbets are ${stake}. \nWould you like to play? [Y]es/[N]o: ")
      
        # Validates the input, before if someone input capital Y or N it would quit
        player_input = player_input.lower()
      
        # Use a match statement when comparing input to a known, limited set of options.
        match player_input:
            case "y" | "yes":
                gamba_game(game_state, stake)
            case "n" | "no":
                print("That's prbably a good idea")
                break
            case _:
                print("Unrecognized Input.")
      
        # Changed to be smaller than or equal to 0
        # In normal cases, you wouldn't go below zero,
        # But if in the future you allow the player to change the stake,
        # There could come a circumstance where the player attempts to bet more money than they have
        # and they can continue playing with negative cash
        # Generally, it's important to think about whether or not you want EXACTLY 0,
        # Or 0 or less.
        if game_state.cash <= 0:
            print("Dude I just lost it all")
            print(f"wins {game_state.wins}")
            print(f"losses {game_state.losses}")
            break
      
        print()
        print(f"{game_state.wins} wins / {game_state.losses} losses")
      
#        if player_input in ["yes","y"]:
#            return gamba_game()
#        else:
#            print("That's prbably a good idea")
#            break

# All of the following is removed as unecessary
# def gamba_sesh(game_state):
#    # global x
#    # global y
#    # global cash

#    while True:
#     
#        if cash == 0:
#            print("Dude I just lost it all")
#            print(f"wins {x}")
#            print(f"losses {y}")
#            break
#        else:
#            play_again = input("Play again (yes/no): ")
#         
#            if play_again in ["yes","y"]:
#                gamba_game()
#                break
#            else:
#                print("One more and I'm out!")
#                gamba_game()
#                break

game_state_singleton = GameState.create_default()
gamba_start(game_state_singleton)
 
Back