{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "20019a62-ec96-4a8d-b928-f5812c027124",
   "metadata": {},
   "source": [
    "## Python and LLM Apps\n",
    "* AI frameworks.\n",
    "* Server-side web development.\n",
    "* Object-oriented or functional."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b02d2a03-5bca-4831-b523-b3aa9f9ab1d6",
   "metadata": {},
   "source": [
    "## Python Syntax\n",
    "* New line to complete a command.\n",
    "* Indentation defines scope.\n",
    "    * Most common: 4 spaces.\n",
    "    * Careful: tab not always work well."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d242a9f2-940d-430d-85bb-47012d4df024",
   "metadata": {},
   "source": [
    "## Variables\n",
    "* No need to be declared, but you can."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "10c00df5-9b26-4f70-b2fa-01cb85c02291",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'str'>\n"
     ]
    }
   ],
   "source": [
    "x = 4        # x is of type int\n",
    "y = str(4)   # y is of type string\n",
    "print(type(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "249d4a43-e15b-4f94-97c2-28bafb512570",
   "metadata": {},
   "source": [
    "* Illegal variable names:\n",
    "    * 2myvar\n",
    "    * my-var\n",
    "    * my var "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96dc25bc-5457-44df-a166-d10ff0e7382e",
   "metadata": {},
   "source": [
    "* Can assign multiple variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7a60d480-ddec-452f-bfc7-aae0da334450",
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b, c = \"Julio\", \"Mariau\", \"Belen\"\n",
    "names = [\"Lourdes\", \"Blanca\", \"Ana\"]\n",
    "d, e, f = names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acbb4d56-e7fc-466b-93ca-b0a70e2bca45",
   "metadata": {},
   "source": [
    "## Arrays or vectors are called Lists in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86c2a800-ba0f-4559-98fe-4cef90c525f4",
   "metadata": {},
   "source": [
    "* Range of indexes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1f21b170-efcc-4b70-b361-048c912600da",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "numbers = [0,1,2,3,4,5,6]\n",
    "print(numbers[2:5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "97f148c2-f39c-476d-80a0-706b550cfe97",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "print(numbers[:4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2a7a7420-8058-4dfe-bdae-10557abd8c25",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3, 4, 5, 6]\n"
     ]
    }
   ],
   "source": [
    "print(numbers[2:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d83b3162-f5fb-4121-86f4-2a81e89b9dca",
   "metadata": {},
   "source": [
    "* Common list operations:\n",
    "    * negative indexing means start from the end\n",
    "    * numbers.insert(1, \"new item\")\n",
    "    * numbers.append(\"last item\")\n",
    "    * numbers.remove(3) #remove number 3\n",
    "    * numbers.pop(0) #remove the first item\n",
    "    * del numbers\n",
    "    * for x in numbers:\n",
    "    * for i in range(len(numbers))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7eec0973-dcd1-419c-b473-76eb5ce9dfac",
   "metadata": {},
   "source": [
    "## Tuples are a peculiar Python thing\n",
    "* store multiple items in a single variable\n",
    "* if only one item, add a comma after the item\n",
    "* ordered\n",
    "* unchangeable (workaround: convert to list, change, and then convert to tuple again)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5f28e520-ba3b-4f14-8082-4c0ab0f8bf5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "myTuple = (0,1,2,3,4,5,6)\n",
    "myOne = (0,)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f45d01a6-0dc3-4954-8990-2ad8a14ad681",
   "metadata": {},
   "source": [
    "## Python dictionaries are similar to JSON objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "63e41ba6-d902-4dd9-b56c-7350acf94e91",
   "metadata": {},
   "outputs": [],
   "source": [
    "myDict = {\n",
    "    \"name\": \"Julio\",\n",
    "    \"lastname\": \"Colomer\"\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35f4a6c2-243d-420d-a425-9556e739ffc3",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f415797c-24b9-443c-834e-af0bab435821",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_function(parameter):\n",
    "    print(\"Hello!\", parameter)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "279b0533-eab1-495c-9628-02ad97adbaa7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello! argument\n"
     ]
    }
   ],
   "source": [
    "my_function(\"argument\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3158e798-95ca-450f-b807-26f36c68c78d",
   "metadata": {},
   "source": [
    "#### Peculiar things to know about Python functions:\n",
    "* arbitrary arguments and keyword arguments: *args and **kargs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "821368df-de68-4db0-9174-8e06d1cd3577",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ID data: Julio\n"
     ]
    }
   ],
   "source": [
    "def person(**individual):\n",
    "    print(\"ID data: \" + individual[\"name\"])\n",
    "\n",
    "person(name=\"Julio\", last=\"Colomer\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1192bd6-0580-4cca-af36-5185f30a2b24",
   "metadata": {},
   "source": [
    "* Lambda function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "197ac577-5a4f-4e3c-af20-0adc65b2aaac",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = lambda parameter : \"Hello \" + parameter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f000b21f-c5f8-4ae2-975c-c5a147729108",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello argument\n"
     ]
    }
   ],
   "source": [
    "print(x(\"argument\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b722db59-d2f6-4e29-ae28-65578bba9a59",
   "metadata": {},
   "source": [
    "* Use of Lambda Function as an anonymous function inside another function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "73f2ae55-d93c-43a2-bdc0-cc2d1377b550",
   "metadata": {},
   "outputs": [],
   "source": [
    "def matchMaker(person1):\n",
    "    return lambda person2 : person2 + \" marries \" + person1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "e19c780a-fe83-47dc-bb9c-679a78b2a1f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "newCouple = matchMaker(\"Robert Mitchum\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "64d00467-ce33-4414-ad55-8d8d7ce622d6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ava Gardner marries Robert Mitchum\n"
     ]
    }
   ],
   "source": [
    "print(newCouple(\"Ava Gardner\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3b79606-9635-4d8a-a2a7-04067a3e755c",
   "metadata": {},
   "source": [
    "## Classes\n",
    "* A class is like a blueprint to create objects.\n",
    "* Python is an object-oriented language: almost everything in Python is an object and it has properties and methods."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b099e65a-1045-4bdf-abfa-65df64b98bc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Dog:\n",
    "    species = \"dog\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "e833f2e6-d78b-48c9-9514-29fb5680e25e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dog\n"
     ]
    }
   ],
   "source": [
    "fido = Dog()\n",
    "print(fido.species)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef8c0eab-8255-4bc2-956f-b2ab0063978d",
   "metadata": {},
   "source": [
    "#### Peculiarities of Python Classes"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51ba835f-1ae7-4ef0-801b-cbc13cf6f33d",
   "metadata": {},
   "source": [
    "* `__init__` is like `constructor` in JS\n",
    "* `self` is like `this` in JS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "837a0010-96e0-46be-b9f7-fe6851b5029c",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Cat:\n",
    "    def __init__ (self, species, age, color):\n",
    "        self.species = species\n",
    "        self.age = age\n",
    "        self.color = color"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "1149ef13-d424-4f7f-825c-62f16c3e3318",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "white\n"
     ]
    }
   ],
   "source": [
    "kitty = Cat(\"cat\", 1, \"white\")\n",
    "print(kitty.color)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c03f8134-6f0e-4d13-ad3a-0cc9e4ecaf98",
   "metadata": {},
   "source": [
    "*`__str__()` represents the object as a string. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "631c8119-5e99-4342-b780-f8f76bf76616",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Cat:\n",
    "    def __init__ (self, species, name, age, color):\n",
    "        self.species = species\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        self.color = color\n",
    "    def __str__(self):\n",
    "        return f\"{self.name} is a {self.color} {self.species}.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "a08fe8b5-ec8a-48d1-8722-9dbed3bf3090",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "misha is a brown cat.\n"
     ]
    }
   ],
   "source": [
    "misha = Cat(\"cat\", \"misha\", 2, \"brown\")\n",
    "print(misha)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27a0d62e-ee47-415d-92f2-73de21c60f4c",
   "metadata": {},
   "source": [
    "## Object Methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "9f5341e0-80c0-4946-acc0-674e8ec4cc37",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Horse:\n",
    "    def __init__ (self, species, name, age, color):\n",
    "        self.species = species\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "        self.color = color\n",
    "    def greetings(self):\n",
    "        print(\"hello, my name is \" + self.name)\n",
    "    def __str__(self):\n",
    "        return f\"{self.name} is a {self.color} {self.species}.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "5bae8026-580b-45fd-9ba9-0bbcb5e67b71",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello, my name is Bucefalo\n"
     ]
    }
   ],
   "source": [
    "bucefalo = Horse(\"horse\", \"Bucefalo\", 3, \"brown\")\n",
    "bucefalo.greetings()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a908f0dd-160e-47e3-a178-3160e6ff45fe",
   "metadata": {},
   "source": [
    "## Object Properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "e6b48d4c-8a6a-410a-97c4-17a2ef231d28",
   "metadata": {},
   "outputs": [],
   "source": [
    "seabiscuit = Horse(\"horse\", \"Seabiscuit\", 2, \"black\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "f3ba7fb5-cb71-4336-b205-bfcd7699d93b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The history saving thread hit an unexpected error (OperationalError('attempt to write a readonly database')).History will not be written to the database.\n"
     ]
    }
   ],
   "source": [
    "seabiscuit.color = \"brown\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "6354b8a5-0ae2-4284-b300-6c5531066675",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "brown\n"
     ]
    }
   ],
   "source": [
    "print(seabiscuit.color)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "283b1c94-1bcd-493d-b85d-899d3db96bf6",
   "metadata": {},
   "source": [
    "## Inheritance\n",
    "* When a class inherits all the methods and properties from another class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "cf66c81d-4d55-4ede-a2b7-66ef65d545c6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mike Olsen\n"
     ]
    }
   ],
   "source": [
    "class Person:\n",
    "  def __init__(self, fname, lname):\n",
    "    self.firstname = fname\n",
    "    self.lastname = lname\n",
    "\n",
    "  def printname(self):\n",
    "    print(self.firstname, self.lastname)\n",
    "\n",
    "class Student(Person):\n",
    "  pass\n",
    "\n",
    "x = Student(\"Mike\", \"Olsen\")\n",
    "x.printname()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ceea6abc-29eb-496b-b4fc-b998dd035952",
   "metadata": {},
   "source": [
    "## Debugging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "6f730e3b-d6a9-44d8-8afc-1853ac78fa0a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "all good!\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "  print(\"all good!\")\n",
    "except:\n",
    "  print(\"An exception occurred\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "cb6a5c8e-5af7-4f0d-a806-ac1ff45b177a",
   "metadata": {},
   "outputs": [
    {
     "ename": "Exception",
     "evalue": "Sorry, no numbers below zero",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mException\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[53], line 4\u001b[0m\n\u001b[1;32m      1\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m----> 4\u001b[0m   \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSorry, no numbers below zero\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "\u001b[0;31mException\u001b[0m: Sorry, no numbers below zero"
     ]
    }
   ],
   "source": [
    "x = -1\n",
    "\n",
    "if x < 0:\n",
    "  raise Exception(\"Sorry, no numbers below zero\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aca22219-87a2-4566-991c-ee6893e2d5b0",
   "metadata": {},
   "source": [
    "## How to get user input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "89ca84d4-6368-4c7d-a5b3-9214ae8de43d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "enter username:  mike\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "your username is: mike\n"
     ]
    }
   ],
   "source": [
    "username = input(\"enter username: \")\n",
    "print(\"your username is: \" + username)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f67af955-2c6c-47d1-b8b5-d4f38b26dbfd",
   "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.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
