Utilities

Utility functions for simulchip with enhanced type safety.

class simulchip.utils.FactionCode[source]

Bases: str, Enum

Valid faction codes in Netrunner.

ANARCH = 'anarch'
CRIMINAL = 'criminal'
SHAPER = 'shaper'
ADAM = 'adam'
APEX = 'apex'
SUNNY_LEBEAU = 'sunny-lebeau'
HAAS_BIOROID = 'haas-bioroid'
JINTEKI = 'jinteki'
NBN = 'nbn'
WEYLAND = 'weyland-consortium'
NEUTRAL_CORP = 'neutral-corp'
NEUTRAL_RUNNER = 'neutral-runner'
__new__(value)
__format__(format_spec)

Returns format using actual value type unless __str__ has been overridden.

simulchip.utils.extract_decklist_id(url)[source]

Extract decklist ID from a NetrunnerDB URL.

Parameters:

url (str) – Full NetrunnerDB URL

Return type:

Optional[str]

Returns:

The decklist ID or None if invalid URL

Raises:

ValueError – If url is empty

Examples

>>> extract_decklist_id("https://netrunnerdb.com/en/decklist/7a9e2d43-bd55-45d0-bd2c-99cad2d17d4c/deck-name")
'7a9e2d43-bd55-45d0-bd2c-99cad2d17d4c'
>>> extract_decklist_id("https://netrunnerdb.com/decklist/view/12345")
'12345'
simulchip.utils.get_faction_symbol(faction_code)[source]

Get a symbol for each faction with validation.

Parameters:

faction_code (str) – Faction code from NetrunnerDB

Return type:

str

Returns:

A text symbol representing the faction

simulchip.utils.format_card_count(count, card_name)[source]

Format a card count and name for display with validation.

Parameters:
  • count (int) – Number of copies

  • card_name (str) – Name of the card

Return type:

str

Returns:

Formatted string like “3x Card Name”

Raises:

ValueError – If count is negative or card_name is empty

simulchip.utils.sanitize_filename(filename, max_length=50)[source]

Sanitize a string for use as a filename.

Parameters:
  • filename (str) – String to sanitize

  • max_length (int) – Maximum length of the result

Return type:

str

Returns:

Sanitized filename safe for all platforms

Raises:

ValueError – If filename is empty after sanitization

simulchip.utils.get_faction_short_name(faction_code)[source]

Get a short name for a faction suitable for filenames.

Parameters:

faction_code (str) – Faction code from NetrunnerDB

Return type:

str

Returns:

Short faction name (4 chars max)

simulchip.utils.parse_card_code(card_code)[source]

Parse a card code into pack number and card number.

Parameters:

card_code (str) – Card code like “01001”

Return type:

Tuple[str, str]

Returns:

Tuple of (pack_number, card_number)

Raises:

ValueError – If card code format is invalid

simulchip.utils.format_deck_size(card_count)[source]

Format deck size for display.

Parameters:

card_count (int) – Number of cards in deck

Return type:

str

Returns:

Formatted string like “45 cards”

simulchip.utils.get_faction_side(faction_code)[source]

Determine if a faction is corporation or runner side.

Parameters:

faction_code (str) – Faction code from NetrunnerDB

Return type:

str

Returns:

Either “corporation” or “runner”

Examples

>>> get_faction_side("haas-bioroid")
'corporation'
>>> get_faction_side("anarch")
'runner'

Decklist comparison functionality with enhanced type safety and patterns.

class simulchip.comparison.CardInfo[source]

Bases: object

Detailed information about a card in a decklist.

code: str
title: str
pack_code: str
pack_name: str
type_code: str
faction_code: str
required_count: int
owned_count: int
missing_count: int
property is_identity: bool

Check if this card is an identity.

property is_fully_owned: bool

Check if all required copies are owned.

property ownership_ratio: float

Get ratio of owned to required cards.

__init__(code, title, pack_code, pack_name, type_code, faction_code, required_count, owned_count, missing_count)
Parameters:
  • code (str)

  • title (str)

  • pack_code (str)

  • pack_name (str)

  • type_code (str)

  • faction_code (str)

  • required_count (int)

  • owned_count (int)

  • missing_count (int)

Return type:

None

class simulchip.comparison.DecklistStats[source]

Bases: object

Statistics for a decklist comparison.

total_cards: int = 0
owned_cards: int = 0
missing_cards: int = 0
unique_cards: int = 0
unique_owned: int = 0
unique_missing: int = 0
property completion_percentage: float

Calculate deck completion percentage.

property is_complete: bool

Check if all cards are owned.

__init__(total_cards=0, owned_cards=0, missing_cards=0, unique_cards=0, unique_owned=0, unique_missing=0)
Parameters:
  • total_cards (int)

  • owned_cards (int)

  • missing_cards (int)

  • unique_cards (int)

  • unique_owned (int)

  • unique_missing (int)

Return type:

None

class simulchip.comparison.ComparisonResult[source]

Bases: object

Comprehensive result of comparing a decklist against a collection.

decklist_id: str
decklist_name: str
identity: CardInfo
stats: DecklistStats
cards_by_pack: Dict[str, List[CardInfo]]
cards_by_faction: Dict[str, List[CardInfo]]
missing_cards: List[CardInfo]
owned_cards: List[CardInfo]
all_cards: List[CardInfo]
property identity_title: str

Get identity title for backwards compatibility.

property identity_faction: str

Get identity faction for backwards compatibility.

property total_cards: int

Get total cards for backwards compatibility.

property owned_cards_count: int

Get owned cards count for backwards compatibility.

property missing_cards_count: int

Get missing cards count for backwards compatibility.

property missing_by_pack: Dict[str, List[CardInfo]]

Get missing cards grouped by pack for backwards compatibility.

property owned_by_pack: Dict[str, List[CardInfo]]

Get owned cards grouped by pack for backwards compatibility.

__init__(decklist_id, decklist_name, identity, stats, cards_by_pack=<factory>, cards_by_faction=<factory>, missing_cards=<factory>, owned_cards=<factory>, all_cards=<factory>)
Parameters:
Return type:

None

exception simulchip.comparison.DecklistComparisonError[source]

Bases: Exception

Custom exception for comparison errors.

class simulchip.comparison.DecklistComparer[source]

Bases: object

Compare decklists against local collection with validation.

IDENTITY_TYPE_CODE: Final[str] = 'identity'
__init__(api_client, collection_manager)[source]

Initialize comparer with validation.

Parameters:
Raises:

TypeError – If arguments are of incorrect type

Return type:

None

compare_decklist(decklist_id)[source]

Compare a decklist against local collection with comprehensive analysis.

Parameters:

decklist_id (str) – NetrunnerDB decklist ID

Return type:

ComparisonResult

Returns:

Detailed comparison result

Raises:
get_proxy_cards(comparison_result)[source]

Get list of cards that need proxies.

Parameters:

comparison_result (ComparisonResult) – Result from compare_decklist

Return type:

List[CardInfo]

Returns:

List of cards that need proxies, sorted by pack and title

get_proxy_cards_for_generation(comparison_result, all_cards=False)[source]

Get list of cards for proxy generation with all_cards option.

Parameters:
  • comparison_result (ComparisonResult) – Result from compare_decklist

  • all_cards (bool) – If True, return all cards; if False, return only missing cards

Return type:

List[CardInfo]

Returns:

List of cards for proxy generation

format_comparison_report(comparison_result)[source]

Format comparison result as a readable report.

Parameters:

comparison_result (ComparisonResult) – Result from compare_decklist

Return type:

str

Returns:

Formatted report string

get_pack_requirements(comparison_result)[source]

Get pack requirements for missing cards.

Parameters:

comparison_result (ComparisonResult) – Result from compare_decklist

Return type:

Dict[str, Dict[str, int]]

Returns:

Dictionary mapping pack names to card requirements

Cache management for card data and images.

class simulchip.cache.CacheManager[source]

Bases: object

Manages caching of card data and images.

__init__(cache_dir=None)[source]

Initialize cache manager.

Parameters:

cache_dir (Optional[Path]) – Directory for cache storage (defaults to .cache)

get_cached_cards()[source]

Get cached card data.

Return type:

Optional[Dict[str, Any]]

Returns:

Dictionary of card data or None if not cached

cache_cards(cards_data)[source]

Cache card data.

Parameters:

cards_data (Dict[str, Any]) – Card data to cache

Return type:

None

get_cached_packs()[source]

Get cached pack data.

Return type:

Optional[List[Dict[str, Any]]]

Returns:

List of pack data or None if not cached

cache_packs(packs_data)[source]

Cache pack data.

Parameters:

packs_data (List[Dict[str, Any]]) – Pack data to cache

Return type:

None

get_card_image_path(card_code, extension='png')[source]

Get path for cached card image.

Parameters:
  • card_code (str) – Card code

  • extension (str) – File extension

Return type:

Path

Returns:

Path to image file

has_card_image(card_code)[source]

Check if card image is cached.

Parameters:

card_code (str) – Card code

Return type:

bool

Returns:

True if image is cached

get_card_image(card_code)[source]

Get cached card image.

Parameters:

card_code (str) – Card code

Return type:

Optional[Image]

Returns:

PIL Image or None if not cached

download_and_cache_image(card_code, image_url)[source]

Download and cache card image.

Parameters:
  • card_code (str) – Card code

  • image_url (str) – URL to download image from

Return type:

Optional[Image]

Returns:

PIL Image or None if download fails

clear_cache()[source]

Clear all cached data.

Return type:

None

get_cache_stats()[source]

Get cache statistics.

Return type:

Dict[str, Any]

Returns:

Dictionary with cache stats

get_cache_metadata()[source]

Get cache metadata including timestamps and pack info.

Return type:

Dict[str, Any]

Returns:

Dictionary with cache metadata or empty dict if not exists

update_cache_metadata(metadata)[source]

Update cache metadata.

Parameters:

metadata (Dict[str, Any]) – Metadata dictionary to save

Return type:

None

get_latest_pack_date(packs)[source]

Get the release date of the most recent pack.

Parameters:

packs (List[Dict[str, Any]]) – List of pack data

Return type:

Optional[str]

Returns:

Latest release date string or None

is_cache_valid(packs=None)[source]

Check if cache is still valid based on pack releases.

Parameters:

packs (Optional[List[Dict[str, Any]]]) – Optional pack data to check against

Return type:

bool

Returns:

True if cache is valid, False if it needs refresh

mark_cache_fresh(packs)[source]

Mark cache as freshly updated with pack info.

Parameters:

packs (List[Any]) – Current pack data

Return type:

None