{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "3b69e803-b8ac-4a4c-97bb-fa14d59e71ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The nb_mypy extension is already loaded. To reload it, use:\n",
      "  %reload_ext nb_mypy\n"
     ]
    }
   ],
   "source": [
    "# OOPs Notebook by RLM3\n",
    "#commment out to stop type checking\n",
    "%load_ext nb_mypy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "67e0bac4-9676-4664-83c0-0ed27d84f527",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "EPSILON = 1e-6 # [0-1] - grid size or fidelity (smaller is, is smaller)\n",
    "\n",
    "tuple4 = tuple[float,float,float,float] #vector t[3]=0, point t[3]=1\n",
    "\n",
    "# this can be replaced with math.isclose()\n",
    "def float_is_equal(a:float, b:float, eps=EPSILON)->bool:\n",
    "    return math.fabs(a-b) < eps\n",
    "    \n",
    "def tuple_is_equal(a:tuple4, b:tuple4, eps=EPSILON)->bool:\n",
    "    return \\\n",
    "        float_is_equal(a[0], b[0], eps) and \\\n",
    "        float_is_equal(a[1], b[1], eps) and \\\n",
    "        float_is_equal(a[2], b[2], eps) and \\\n",
    "        float_is_equal(a[3], b[3], eps)\n",
    "\n",
    "def tuple_neg(a:tuple4)->tuple4:\n",
    "    return (-a[0], -a[1], -a[2], -a[3])\n",
    "\n",
    "def tuple_add(a:tuple4,b:tuple4)->tuple4:\n",
    "    return (a[0]+b[0], a[1]+b[1], a[2]+b[2], a[3]+b[3])\n",
    "\n",
    "def tuple_sub(a:tuple4,b:tuple4)->tuple4:\n",
    "    return (a[0]-b[0], a[1]-b[1], a[2]-b[2], a[3]-b[3])\n",
    "\n",
    "def tuple_is_point(tuple:tuple4)->bool:\n",
    "    return int(tuple[-1]) == 1 \n",
    "\n",
    "def get_vector(x:float,y:float,z:float)->tuple4:\n",
    "    return (x,y,z,0)\n",
    "\n",
    "def get_point(x:float,y:float,z:float)->tuple4:\n",
    "    return (x,y,z,1)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "6b2d10ec-fa8f-4f20-912d-12c300cab7b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "arrow = get_point(0,0,0)\n",
    "bow = get_vector(0,1,-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "7155ba3b-1c06-4d12-a618-f835d0952dcc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 0, 0, 1)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arrow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "059e4e0f-ded6-4f78-a058-b70b89e80c6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 1, -1, 0)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "a0e9ca22-69aa-46f7-9cc7-583a62cbc5cf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 0, 0, 1, 0, 1, -1, 0)"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "what_is_it = arrow + bow\n",
    "what_is_it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "4c8da28f-5f7b-4f7f-bc4a-b9a57d45cc7b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#clearly this is not working"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "bfb8ce19-ec35-4a58-88ed-96a892a2dfe4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 1, -1, 1)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "what_is_it_2 = tuple_add(arrow, bow)\n",
    "what_is_it_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "ef01fd45-64b7-4c56-a118-760267f8dc73",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "<cell>8: \u001b[1m\u001b[31merror:\u001b[m Self argument missing for a non-static method (or an invalid type for self)  \u001b[m\u001b[33m[misc]\u001b[m\n",
      "<cell>11: \u001b[1m\u001b[31merror:\u001b[m Self argument missing for a non-static method (or an invalid type for self)  \u001b[m\u001b[33m[misc]\u001b[m\n",
      "<cell>14: \u001b[1m\u001b[31merror:\u001b[m Self argument missing for a non-static method (or an invalid type for self)  \u001b[m\u001b[33m[misc]\u001b[m\n"
     ]
    }
   ],
   "source": [
    "class Tuple4:\n",
    "    def __init__(self, x:float, y:float, z:float, p:float):\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "        self.z = z\n",
    "        self.p = p\n",
    "\n",
    "    def from_tuple4(t4:tuple4):\n",
    "        return Tuple4(t4[0],t4[1],t4[2],t4[3])\n",
    "        \n",
    "    def get_point(x:float, y:float, z:float):\n",
    "        return Tuple4(x,y,z,1)\n",
    "\n",
    "    def get_vector(x:float, y:float, z:float):\n",
    "        return Tuple4(x,y,z,0)\n",
    "    \n",
    "    def __repr__(self): #this will give us something nice in jupyter notebook when we eval in place\n",
    "        return \"(\" + str(self.x) + \", \" + str(self.y) + \", \" + str(self.z) + \", \" + str(self.p) + \")\"\n",
    "        \n",
    "    def __eq__(self:Tuple4, other):\n",
    "        return tuple_is_equal((self.x, self.y, self.z, self.p), (other.x, other.y, other.z, other.p))\n",
    "\n",
    "    def __add__(self:Tuple4, other):\n",
    "        if (isinstance(other, Tuple4)):\n",
    "            return tuple_add((self.x, self.y, self.z, self.p), (other.x, other.y, other.z, other.p))\n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "3e8d1937-8dc5-4190-bb83-15f8166ca0fb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 1, -1, 0)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_bow = Tuple4.get_vector(0, 1, -1)\n",
    "new_bow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "29d99361-cc80-4495-826f-1a1fa2ad920f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 0, 0, 1)"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_arrow = Tuple4.get_point(0,0,0)\n",
    "new_arrow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "87913ac1-a79b-43da-8b5f-f03c6b481559",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_bow == new_arrow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "e37a5de4-d19e-45d2-8bd4-4936d6a6ca58",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_new_bow = Tuple4.get_vector(0,1,-1)\n",
    "new_bow == new_new_bow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "f9e251d4-acdd-4b78-a20f-8891e70f3d97",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_bow != new_arrow #we get this for free with __eq__()?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "id": "40291108-23b0-46f4-98f3-37cc960f0db2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 1, -1, 1)"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "object_added_bow = new_bow + new_arrow\n",
    "object_added_bow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "id": "0eccd990-bc17-4e04-8185-74b7c414effe",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert(object_added_bow == what_is_it_2) #same as tuple4 implementation from above"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c2ab863-2d03-4ca7-940f-fdc1d5abf5fa",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
