#๐Ÿ”’ how to add the total sum of a list of class objects

282 messages ยท Page 1 of 1 (latest)

wet vortex
#

Im working on card game logic using class objects to represent cards with rank and suit variables and lists to manage player hand stuff how would i find the total of the ranks in any given hand

steep treeBOT
#

@wet vortex

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

wet vortex
#

card class and deck making bits if useful

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"{self.rank}{self.suit}"

deck = [Card(rank, suit) for rank in range(1, 14) for suit in suits]
hollow schooner
wet vortex
#

its blackjack so j q k 10 and ace 1 or 11 im also figuring out how to get that to translate but i havnt hit a roadblock w that yet

glass jetty
#

Something like
sum(card.rank for card in deck) ?

hollow schooner
hollow schooner
#

you probably will also want a mapping (dict) so you know what rank is what card

wet vortex
#

im kinda mkaing a dict atm but idk how to add values from the list if theyre class objects

hollow schooner
#

you would use the rank attribute of the card

glass jetty
#

Something like
sum(scores[card.rank] for card in deck) ?

hollow schooner
glass jetty
#

Where care scores is the dict of scores

#

Yeah you need to add it after

wet vortex
#
def royal2value(facecard, total):
    royals = ["J", "Q", "K"]
    
    if (facecard == "A"):
        if (total >= 21):
            return 11
        else:
            return 1

    while True:
        if any(item == facecard for item in royals):
            return 10

this is what i have atm for royals

glass jetty
#

Why the while True ?

hollow schooner
#

yeah this seems a bit overkill

#

create something like

def score_hand(hand)
wet vortex
#

return breaks and if its an ace it doesnt get that far

hollow schooner
#

a simple function that takes in a list of cards

glass jetty
wet vortex
#

factual

#

lol u right

hollow schooner
#

Would you know how to make a hand of cards from that deck?

native vessel
#

not sure if it'd be too complex, but I'd make a childclass for royal cards and aces to simplify the logic for me

hollow schooner
#

basically, deal 2 cards to a hand?

still coral
hollow schooner
wet vortex
#
def deal(player):
    player.append(deck[0])
    discard.append(deck[0])
    del deck[0]


while (len(player) !=2):
    deal(player)
    deal(dealer)
#

this is what i have just to deal the inital hands

hollow schooner
#

is there a reason you need to keep track of discarded cards?

wet vortex
#

recycle

hollow schooner
#

just reinitialize the deck at the start of the round

#

you never need to interact with discarded cards in blackjack

wet vortex
#

true but i wanna do other card games that might take from discard like trash figured it could be useful to use

hollow schooner
#

but now the same card is in the player's hand AND the discard

#

that doesn't quite make sense

#

at the end of the round of blackjack, you could take every players' cards and put them into the discard list instead

#

but not until the round is over

wet vortex
#

good call

hollow schooner
#

!e

import random


suits = ['hearts', 'spades', 'clubs', 'diamonds']
class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"{self.rank}{self.suit}"

deck = [Card(rank, suit) for rank in range(1, 14) for suit in suits]
random.shuffle(deck)
hand = [deck.pop(), deck.pop()]
print(hand)
steep treeBOT
wet vortex
#

ill just reinitialize the deck for rn

hollow schooner
#

have a look at this code

still coral
#

and also make sure when you deal the card you remove it from the deck
using pop like Fashoomp

hollow schooner
#

does this make sense for dealing the card to hand? This is just so we can eventually test the scoring function

wet vortex
#

remind me what .pop is again

hollow schooner
#

it removes the last item from a list

#

so here, we're treating the end of the list as the "top" of the deck

still coral
#

if you want the first you do .pop(0)

wet vortex
hollow schooner
still coral
#

true

hollow schooner
wet vortex
#

depends on what you mean by it but wait pop would take from deck and put it in hand no deal func needed

hollow schooner
wet vortex
#

fair

hollow schooner
#

How would you look at each card's rank in the hand using a loop?

wet vortex
#

not really thats what i was needing help w

hollow schooner
#

do you know how to loop through a list of strings?

wet vortex
#

for item in list?

hollow schooner
#

yes, it's the exact same for a list of cards

#

a list can hold anything

#

str

#

int

#

Card

#

for card in hand

wet vortex
#

would something like this owrk?
total = for item in hand + Card.rank

hollow schooner
#

let's not try and do it all in one line

wet vortex
#

</3

hollow schooner
#

start with a basic for loop

hollow schooner
wet vortex
#
for item in player:
    total += Card.rank

eh?

hollow schooner
#

use the variables from my example

#

for card in hand

#

do you understand the difference between "class" and "instance"?

wet vortex
#

ill be honest i barely understand classes as they are

hollow schooner
#

do you understand str?

#

int?

wet vortex
#

ye

hollow schooner
#

!e

print(str)
print(int)
steep treeBOT
hollow schooner
#

those are both "classes"

#

or we also call them "datatypes"

wet vortex
#

did not know they were classes only knew them to be datatypes

hollow schooner
#

datatypes/classes are "blueprints" for how we create data

#

so if str is a class, what's an instance?

#

an instance is the actual creation of data based on that datatype

#

"hello" is an instance of str

#

123 is an instance of int

#

[] is an instance of list

#

we can have many instances from a single class

#
x = "foo"
y = "bar"
#

here we have 2 str instances

wet vortex
#

following along so far

hollow schooner
#

ok, so making str and int instances is simple

#

if we want str, we just use ""

#

if we want int, we just type a number

#

but for custom classes, it's slightly different

#
class Animal:
    pass


dog = Animal()
#

if we want an instance of the Animal class, we have to call it like we would a function

#

Animal is the class
Animal() is the instance

#

does that make sense?

wet vortex
#

yeah

#

btw if ur not already u should be a teacher im following along better than the free harvard cs50 lectures

hollow schooner
#

I've done some mentoring/tutoring in the past

#

ok so just like any other class, we can have multiple instances from 1 class

#
dog = Animal()
cat = Animal()
#
class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
#

now let's look at the simple Card class

#

do you understand what __init__ does?

wet vortex
#

initialize but honestly what that means is just kinda magic to me

hollow schooner
#

do you know the term "method"?

wet vortex
#

like class function

hollow schooner
#

yes, it's a function that is called from an instance

#

like list.append

#

or str.upper

#

those are methods

#

they are functions, but more specifically, they are called methods

#

any method name with __ before/after the name is called a "dunder method"

#

"dunder" because "double underscore"

wet vortex
#

silly

hollow schooner
#

dunder methods are reserved named by python. Simply defining them into your class gives your class new behaviour

#

There's many dunder methods, but there's only a few keys ones you really need to worry about

#

__init__ is "initialize", yes. It kinda does 2 things

#

It is automatically called when an instance is created

#

!e

class Animal:
    
    def __init__(self):
        print("I am born!")


dog = Animal()
steep treeBOT
wet vortex
#

lol

hollow schooner
#

so simply by doing Animal(), we are automatically calling the class __init__

#

!e

class Animal:
    
    def __init__(self):
        print("I am born!")


dog = Animal()
cat = Animal()
steep treeBOT
hollow schooner
#

make 2 instances, get 2 prints

#

the other thing it does is receive the arguments of the instance

#

!e

class Animal:
    
    def __init__(self, colour):
        print(f"I am a {colour} animal!")


dog = Animal('brown')
cat = Animal('green')
steep treeBOT
hollow schooner
#

so if we add a parameter to __init__, then we must also provide an argument when creating our instance

#

does that make sense?

wet vortex
#

yeah and btw i did not know you do anything other than initialize variables with __init__

hollow schooner
#

it's entirely up to you what you put inside __init__

#

whatever sort of "setup" you think your instance will need before it is ready to use

wet vortex
#

that makes sense i just never saw it in examples when looking into classes

hollow schooner
#

well, I haven't quite finished initializing here

#

what we want is to create "attributes"

#

any data that belongs to an instance is an attribute of that instance

#

we need to make use of self to store it as an attribute

#
class Animal:
    
    def __init__(self, colour):
        self.colour = colour
#

attributes can be accessed from any other method in the class

#

and directly from the instance outside of the class (if necessary)

#
dog = Animal('brown')
#

so if I make an instance named dog and I want to know what colour it is, I can do dog.colour

#

!e

class Animal:
    
    def __init__(self, colour):
        self.colour = colour


dog = Animal('brown')
print(dog.colour)
steep treeBOT
hollow schooner
#

any questions?

wet vortex
#

nop

hollow schooner
#

ok, so using your Card class, give me an example of making a Card instance

#

just 1 Card

wet vortex
#

card = Card(7, 'Hearts')

hollow schooner
#

nice ๐Ÿ™‚

wet vortex
#

yippie

hollow schooner
#

how would you print out the rank of that card?

wet vortex
#

Card.rank

hollow schooner
#

๐Ÿ™‚

#

wait no

#

be careful with card and Card

#

capital for the class name

#

never capital for instance variables

wet vortex
#

that probably explains why this wasnt working

for card in player:
    total += Card.rank
hollow schooner
#

yes exactly

#

but, there's still some logic issues there

#

do you understand what __repr__ does in your class?

wet vortex
#

represent to my knowledge just makes the data readable to users

hollow schooner
#

!e

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit


card = Card(7, 'Hearts')
print(card)
steep treeBOT
hollow schooner
#

without __repr__, our instance looks like this

#

this is the default output if we try and print an instance

wet vortex
#

yeah i got 52 of those when printing the deck before adding the repr bit

hollow schooner
#

let's clean up the __repr__ first to match actual card ranks

#
CARD_LOOKUP = {
    1: 'Ace'
    2: '2',
    3: '3',
    4: '4'
}
#

create a dict like this (but fill in the rest of it)

wet vortex
#
suits = ["โ™ฅ", "โ™ ", "โ™ข", "โ™ง"]
ranks = ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"]
#

ive got this already

hollow schooner
#

that works too

#

instead of range

#

now, with repr, the goal is to return a string that represents the instance

wet vortex
#

yeee i had to change that when i got the face card func working

hollow schooner
#

so if we do this
card = Card('A', 'Hearts')

#

our repr should return
Card('A', 'Hearts')

wet vortex
#

that should be what ive got atm

hollow schooner
#

not quite

#

!e

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"{self.rank}{self.suit}"



card = Card('A', 'Hearts')
print(card)
steep treeBOT
wet vortex
#

do you mean like a space inbetween cuz rn i have the symbols in stead of words that i think look cleaner when theres no space so it would look like
Aโ™ฅ

hollow schooner
#

with the word Card and the ()

wet vortex
#

o

#
    def __repr__(self,):
        return f"Card({self.rank}, {self.suit})"
#

cant imagine this is what you mean

hollow schooner
#

why can't you imagine?

#

that's 99% right

#

__repr__ is meant to be a representation of the instance

wet vortex
#

figured the card() bit was something on its own

hollow schooner
#

!e

text = 'abc'
print(text)
print(repr(text))
steep treeBOT
hollow schooner
#

if we look at str, the repr returns including the ''

hollow schooner
wet vortex
#

B) thought it said "thats a neat way"

hollow schooner
#

!e

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"Card({self.rank!r}, {self.suit!r})"



card = Card('A', 'Hearts')
print(card)
steep treeBOT
hollow schooner
#

check out the !r in the f-string now

wet vortex
#

oh fun

hollow schooner
#

ranks = ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"]

#

I would also update this list to be all strings, even the digits

#

it's not a good idea to have a list of mixed types

#

and just because something is a digit doesn't mean it has to be int

wet vortex
#

true i figured it would make it easier to only have to deal w face cards if they came up but i can imagine just sending them all through the translator func isnt a bad idea

hollow schooner
#

ok, let's get back to having a deck and a hand now

#

since hopefully you better understand instances

wet vortex
#

better than i did lol

#

i hope

hollow schooner
#

!e

import random

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"Card({self.rank!r}, {self.suit!r})"

suits = ["โ™ฅ", "โ™ ", "โ™ข", "โ™ง"]
ranks = ["A", '2', '3', '4', '5', '6', '7', '8', '9', '10', "J", "Q", "K"]
deck = [Card(rank, suit) for rank in ranks for suit in suits]
random.shuffle(deck)
hand = [deck.pop(), deck.pop()]
print(hand)
steep treeBOT
hollow schooner
#

here we now have a hand of 2 cards

#

make a loop to go through the hand and print out the value rank

wet vortex
#

like total?

hollow schooner
#

1 thing at a time

#

just print the rank

wet vortex
#

!e

import random

class Card:
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    def __repr__(self,):
        return f"Card({self.rank!r}, {self.suit!r})"

suits = ["โ™ฅ", "โ™ ", "โ™ข", "โ™ง"]
ranks = ["A", '2', '3', '4', '5', '6', '7', '8', '9', '10', "J", "Q", "K"]
deck = [Card(rank, suit) for rank in ranks for suit in suits]
random.shuffle(deck)
hand = [deck.pop(), deck.pop()]
print(hand)

for card in hand:
    print(card.rank)
steep treeBOT
hollow schooner
#

ok, so to score a blackjack hand, we have 3 possibilities for a card

#

it's worth it's number value
it's worth 10
it's an ace

#

you can do this using if/elif

#

if card.rank.isdigit()

wet vortex
#

are you asking me to?

hollow schooner
#

yes

#

ignore ace for a moment

#

now make a total var

#

and if the rank is a number, add that number

#

if the rank is j, q, k, then add 10

wet vortex
#
total = 0
if (card.rank == "J" or "Q" or "k"):
    total += 10
else:
    total += card.rank
#

feels wrong

hollow schooner
#

a few issues here

#

you don't have the loop

#

you can't use or like that

wet vortex
#

true

#

damn

hollow schooner
#

and you need elif here

#

because we will be adding the ace back in

wet vortex
hollow schooner
#

if only

wet vortex
#

xd

hollow schooner
#
total = 0
for card in hand:
    if card.rank.isdigit():  # numbers
        total += int(card.rank)
    elif card.rank in {'J', 'Q', 'K'}:  # royals
        total += 10
#

have a look at this

#

does this make sense?

wet vortex
#

other than discovering .isdigit and in {} yeah

hollow schooner
#

.isdigit() let's us check if a string is numerical

#

and if it is, we know we can safely convert it using int()

#

I don't want to use else for the Ace here even though you probably good

#

idk, maybe you got dealt the instructions card or a joker

#

let's use elif for Ace still

#
total = 0
aces = 0
for card in hand:
    if card.rank.isdigit():  # numbers
        total += int(card.rank)
    elif card.rank in {'J', 'Q', 'K'}:  # royals
        total += 10
    elif card.rank == 'A':
        total += 11
        aces += 1
#

here's how we're going to handle it

#

if it's an ace, we'll assume it's worth 11, but we'll also keep track of how many aces we have in our hand

wet vortex
hollow schooner
#

if we have a jack and an ace, that's 21. 10 for jack, 11 for ace

#

we ONLY want Ace to be 1 if 11 would cause a bust

#

so, after we're done scoring our hand, we can check if we busted

hollow schooner
#

if we busted AND we have an ace in our hand, we can subtract 10 from our score

#

subtracting 10 basically says "treat that ace as 1 instead of 11"

wet vortex
#

also better solution than i had though to do

hollow schooner
#

we can repeat this until we're either out of aces, or we no longer bust

#

I'll quickly show you the logic, but then I need to go!

#
for card in hand:
    if card.rank.isdigit():  # numbers
        total += int(card.rank)
    elif card.rank in {'J', 'Q', 'K'}:  # royals
        total += 10
    elif card.rank == 'A':
        total += 11
        aces += 1

    while total > 21 and aces > 0:
        total -= 10
        aces -= 1
#

this while loop takes care of it

wet vortex
#

alright youve been great hopefully i catch ur eye when i eventually run into issues making scoundrel lol

hollow schooner
#

Alright gtg, good luck!

wet vortex
#

thanks!!

steep treeBOT
#
Python help channel closed using Discord native close action

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.