{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Data classes\n",
    "\n",
    "[pep 557](https://peps.python.org/pep-0557/#why-not-just-use-namedtuple)\n",
    "\n",
    "Mutable [namedtuple](namedtuple) with defaults and support annotation\n",
    "\n",
    "```{note}\n",
    "\n",
    "Read mamedtuple first\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass\n",
    "from typing import Tuple\n",
    "\n",
    "@dataclass( init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)\n",
    "class InventoryItem:\n",
    "    '''Class for keeping track of an item in inventory.'''\n",
    "    name: str\n",
    "    unit_price: float\n",
    "    quantity_on_hand: int = 0\n",
    "\n",
    "    def total_cost(self) -> float:\n",
    "        return self.unit_price * self.quantity_on_hand"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The @dataclass decorator will add the equivalent of these methods to the InventoryItem class:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0) -> None:\n",
    "    self.name = name\n",
    "    self.unit_price = unit_price\n",
    "    self.quantity_on_hand = quantity_on_hand\n",
    "def __repr__(self):\n",
    "    return f'InventoryItem(name={self.name!r}, unit_price={self.unit_price!r}, quantity_on_hand={self.quantity_on_hand!r})'\n",
    "def __eq__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) == (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented\n",
    "def __ne__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) != (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented\n",
    "def __lt__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) < (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented\n",
    "def __le__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) <= (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented\n",
    "def __gt__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) > (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented\n",
    "def __ge__(self, other):\n",
    "    if other.__class__ is self.__class__:\n",
    "        return (self.name, self.unit_price, self.quantity_on_hand) >= (other.name, other.unit_price, other.quantity_on_hand)\n",
    "    return NotImplemented"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
