HandsDecksCards 1.0.0
HandsDecksCards provides Python classes representing playing cards, decks of cards, and hands of cards, to be used to create card games.
Requires Python: >=3.12
Keywords: playing card, card, console, game, hand, deck

# HandsDecksCards

Source code: [GitHub](https://github.com/KevinRGeurts/HandsDecksCards)
---
HandsDecksCards is a Python package that provides classes representing playing cards, decks of cards, and hands of cards.
It can be used to help create card games coded in Python.

## Usage
Note that all the usage examples below assume that the ```HandsDecksCards``` package has been installed from PyPi, and is available for import.
If this is not the case, and you are just working with the source code, adjust the import statements by dropping the leading 'HandsDecksCards.' from the module paths.

### Using Card class
```python
from HandsDecksCards.card import Card

# Create cards: King of Hearts and 10 of Diamonds
c_kh = Card('H', 'K')
c_10d = Card('D', '10')
# Card implements __str__()
print(f"Created cards: {c_kh}, {c_10d}")
# You can get the suit of a card
print(f"Suit of {c_10d}: {c_10d.suit}")
# You can get the pips of a card
print(f"Pips of {c_10d}: {c_10d.pips}")
# You can get the count of a card
print(f"Count of {c_kh}: {c_kh.count_card()}")
# Card implements __lt__(), so a list of Card objects, can be sorted (A high)
cards = [c_kh, c_10d]
cards.sort()
print(f"Sorted cards (low to high): {cards}")
# Or Card objects an be directly compared:
print(f"10 is less than king?: {c_10d < c_kh}")
# Card provides a utility function that can create a list of Card objects from a string representation
card_list = Card().make_card_list_from_str('AS KH QD JC 10H 2S')
print(f"Created card list from string: {card_list}")
```

### Using Deck class
```python
from HandsDecksCards.deck import Deck

# Create a deck of cards
d = Deck()
# Draw 5 cards from the deck
drawn = d.draw(5)
print(f"Drew 5 cards from deck: {drawn}")
# How many cards remain in the deck? Deck implements __len__().
print(f"Cards remaining in deck: {len(d)}")
# What cards remain in the deck? Deck implements __str__().
print(f"Cards remaining in deck: {d}")
```

Note that the deck module also provided a ShoeDeck class, which represents multiple decks of cards shuffled together. It also
provides a StackedDeck class, which represents a deck of cards with a predefined draw order, useful for testing.

### Using Hand class
```python
from HandsDecksCards.card import Card
from HandsDecksCards.hand import Hand

# Create an empty hand of cards
h = Hand()
# Create a list of cards
card_list = Card().make_card_list_from_str('AS KH QD JC 10H 2S AC')
# Add cards to the hand. Typically this would be done by drawing from a deck, but here we will just add a list of chosen cards.
h.add_cards(card_list)
print(f"Hand after adding cards: {h}")
# Count the cards in the hand
print(f"Count of hand (ace low): {h.count_hand()}")
# Get information about the hand
hand_info = h.hand_info()
print(f"Hand info: {hand_info}")
# How many cards are in the hand?
print(f"Number of cards in hand: {hand_info.Num_Aces + hand_info.Num_Other}")
print(f"Number of cards in hand: {h.get_num_cards()}")
# How many aces are in the hand?
print(f"Number of aces in hand: {h.get_num_aces()}")
# What aces are in the hand?
aces = h.get_aces()
# Can iterate a Hand object to get the cards in the hand
for a in aces:
    print(f"Ace in hand: {a}")
# How many non-ace cards are in the hand?
print(f"Number of non-ace cards in hand: {h.get_num_non_aces()}")
# Which non-ace cards are in the hand?
non_aces = h.get_non_aces()
# Hand defines __repr__(), so can use eval() to recreate a Hand object
print(f"Non-ace cards in hand: {eval(repr(non_aces))}")
# Remove the last card from the hand
removed_card = h.remove_card()
print(f"Removed card: {removed_card}")
print(f"Remaining cards in hand: {h}")
# Remove the 3rd card (index 2) from the hand
removed_card = h.remove_card(2)
print(f"Removed card at index 2: {removed_card}")
print(f"Remaining cards in hand: {h}")
```

## Demonsration
A demonstration of Card, Deck, and Hand functionality, based on the usage examples above, is provided in
the main.py file in the src\HandsDecksCards directory. To run this demonstration, type ```python -m HandsDecksCards.main``` in a terminal window.

## Unittests

Unittests for the HandsDecksCards are in the tests directory, with filenames starting with test_. To run the unittests,
type ```python -m unittest discover -s ..\..\tests -v``` in a terminal window in the src\HandsDecksCards directory.

## License
MIT License. See the LICENSE file for details