Creating A Deck Of Cards In Python

แชร์
ฝัง
  • เผยแพร่เมื่อ 4 ม.ค. 2025

ความคิดเห็น •

  • @DaveLeCompte
    @DaveLeCompte 17 วันที่ผ่านมา

    @3:33 probably want to do rank and suit for the __str__ method. I was expecting you to go back and show the print card test you had done earlier, showing the __str__ method doing its job.
    Other suggestions:
    - if I'm extracting a single card from the deck, I'd call that "draw" - "deal" suggests to me an entire process of a hand to each player, so maybe deal would take in a hand_size and player_count, and deal out a list of cards for each player.
    - if we're extracting cards from the deck (with deal or draw or some other method), there probably ought to be a way to insert cards back into the deck when you're done with the hand. In some games, it's fine to "burn" the entire deck and start with a new deck, shuffled randomly, but I wouldn't presume this.
    - similarly, I'd leave the decision to shuffle the deck to the user of the class - when I buy a pristine deck of cards, it comes in a sorted order, and I think this is fine for our Deck class. If the user wants it shuffled, that's easy.

    • @jakubication
      @jakubication  17 วันที่ผ่านมา

      Yeah, you're right on that first part. That was simply a mistake I didn't catch in editing the video.
      As for you other suggestions, I would tend to agree. I'm pretty sure in making this video I had the implicit assumption that I could extend this code/video later for Blackjack. And that's how I made most of my design decisions. So: 1) Shuffling would be important within the deck class because unshuffled decks in blackjack would make an easy system to game, 2) There wouldn't be any concept of putting cards back in the deck, 3) Dealing would work fine because you would deal for the player and the dealer/house.
      Of course the calc_value logic would have to modified and the __str__ method would have to be fixed, but the rest would be easy to use in a game of blackjack.

  • @bilbilzabeli3828
    @bilbilzabeli3828 18 วันที่ผ่านมา +1

    I am not a Python developer, but I think you could also use the ranks array index + 1 to get the rank value...

    • @jakubication
      @jakubication  17 วันที่ผ่านมา

      That may very well work, but I was always taught to make sure my code was easy to read/made sense/was intuitive. Just because the array indicies of the rank's happen to correlate to the value of the card, doesn't mean I should use that. But I do understand what you're saying, thanks for the suggestion.

    • @DaveLeCompte
      @DaveLeCompte 17 วันที่ผ่านมา

      That works for several of the cards in this case, but 10, J, Q all have value 10 and K has value 0 for the expected use case here, so you still need to special case those.
      For me, I'd probably put the rank to value computation in game logic, outside of the deck logic, which would make the deck and card classes reusable for many different games.

  • @moktatafatforyou-2378
    @moktatafatforyou-2378 19 วันที่ผ่านมา +1

    Great example for practicing oop in python, thank you ❤

    • @jakubication
      @jakubication  19 วันที่ผ่านมา +1

      You're welcome! Glad you liked it 👍

  • @adamkormendi5904
    @adamkormendi5904 17 วันที่ผ่านมา

    The __init__() is the initializer, not a constructor.
    I wonder if this actually works. The calc_value() method should have been defined as a static method, otherwise the "rank" will be self, actually.
    Also I would still use letters for the suits, and use the __str__() method to do pretty print.
    The "ranks" and "suits" would also be class variables in my book.

    • @jakubication
      @jakubication  17 วันที่ผ่านมา

      I never actually knew that first part about constructor vs initializer. Thanks for the knowledge.
      I'm not certain on this, but I think because I called calc_value as a class method (using the name of the class, Card), that is why everything works as intended.
      Reasonable people can disagree on what to use/do for the suits.
      Finally, no disrespect, I see no world where ranks and suits would make sense as class variables. If you're having to "initialize" each card with __init__, shouldn't eàch card have instance variables? Or are you saying at the deck level it should have 52 class variables that each have a rank and suit?
      Ultimately I made the decisions I made in this video because I want to appeal to a beginner level audience. If I use time in the video to pontificate on constructor vs initializer, or introducing a new (to the viewer) kind of method like a static method, then I feel strongly like I'm disrespecting the viewer's intelligence and time. The aim of the video is just create a deck of cards in Python, so I try my best to avoid getting into the weeds.

    • @adamkormendi5904
      @adamkormendi5904 16 วันที่ผ่านมา

      @@jakubication You know it is an initializer, because it has "self" as parameter. So "self" should already been created, we are just giving values here.
      "that is why everything works as intended"
      I have tried, indeed it does work. But I would have added @staticmethod on top of the calc function and use "self" instead of Card. Because if you create an instance of the Card, - e.g. c = Card() - then calling c.calc_value() would throw an error.
      "I see no world where ranks and suits would make sense as class variables."
      I wrote "suits" not suits, because I meant the array you use to generate the deck and not a specific suit value. They could be class variables, so they can be queried from outside of the class as Deck.suits.
      Also "ranks" could be a dictionary, so that you can add a value to each, no need for a method to do that

  • @codewizard01
    @codewizard01 18 วันที่ผ่านมา

    What IDE theme you are using?

    • @jakubication
      @jakubication  18 วันที่ผ่านมา +1

      Brogrammer, in Sublime

    • @codewizard01
      @codewizard01 18 วันที่ผ่านมา

      @@jakubication Thanks

  • @JoeJacksonMhmm
    @JoeJacksonMhmm 21 วันที่ผ่านมา

    interesting

  • @ireonus
    @ireonus 20 วันที่ผ่านมา

    In line 6 , why do you create another Card class within the Card constructor method , does that not create an infinite loop ?
    Also I feel to import a method to shuffle a list is cheating ? It could be better if you wrote your own function to shuffle it , maybe split the deck into n decks then merge them in alternating order m amount of times to mimic the riffle shuffle , it does not matter as long as your shuffle function is your own!
    Just giving the thumbs up for taking the time and courage to create it !

    • @jakubication
      @jakubication  20 วันที่ผ่านมา +3

      For you first point, I believe you're talking about the line, self.value = Card.calc_value(self.rank). That wouldn't create an infinite loop. It's written that way because, calc_value is a class method (belongs to the card class, not a particular card instance) so I couldn't call self.calc_value, so the only other option is to call Card.calc_value.
      And as for the shuffling method, I was always taught in college CS classes 3 main things, don't implement your own code to handle money (floating point imprecision), don't write your own cryptography code (someone smarter than you will surely crack it almost instantly), and don't write your own code to generate random values. (I don't remember the why for this one but presumably the answer is if this were apart of a serious gambling game at a casino, and you're randomness functionality was easily understood, then it's basically an easy money glitch). So that's my reason for that. Basically, if it's not the main part of the project I'm working on (the deck of cards and the cards themselves surely are the more important part then the cards being shuffled), then if someone has already written code for me to easily do a thing, then why reinvent the wheel. Hopefully that explains it. Thank you for the kind words at the end of your comment as well

    • @DaveLeCompte
      @DaveLeCompte 17 วันที่ผ่านมา

      > to import a method to shuffle a list is cheating ?
      random.shuffle() exists for exactly this reason. If you want to flex and write your own, you certainly can, and if it's fun, or if you're asked to for a programming interview, then sure. But for most use cases, the standard implementation is as good and better than one's own implementation.
      The OP gives 3 examples of when to not write your own implementation, but if the standard implementation works, then don't repeat the effort.