Skip to content

Commit 735914d

Browse files
committed
Added OOPs and few errors fixed
1 parent 7efa042 commit 735914d

File tree

2 files changed

+271
-4
lines changed

2 files changed

+271
-4
lines changed

Phase1.ipynb

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,212 @@
17781778
"print(f\"The largest number in the array is: {largest}\")"
17791779
]
17801780
},
1781+
{
1782+
"cell_type": "markdown",
1783+
"metadata": {},
1784+
"source": [
1785+
"## OOPs"
1786+
]
1787+
},
1788+
{
1789+
"cell_type": "code",
1790+
"execution_count": null,
1791+
"metadata": {},
1792+
"outputs": [],
1793+
"source": [
1794+
"class Person:\n",
1795+
"\n",
1796+
" # Dunder Methods: Pre-defined functions for any class, starts and ends with \"__\"\n",
1797+
" # __init__ # Constructor: Initializes the class\n",
1798+
" def __init__(self, full_name: str, occ: str, age: int,networth: int) -> None:\n",
1799+
" self.name = Name(full_name) # Using the Name class to split the name this is called Composition of classes (defined below)\n",
1800+
" self.occ = occ\n",
1801+
" self.age = age\n",
1802+
" self.networth = networth\n",
1803+
"\n",
1804+
" # __setattr__ # Setter: Sets the value of an attribute\n",
1805+
" def __setattr__(self, name, value) -> None:\n",
1806+
" # Define expected types for each attribute\n",
1807+
" type_hints = {\n",
1808+
" \"name\": Name, # compare the type of value \"name\" with the type of Name class\n",
1809+
" \"occ\": str, # compare the type of value \"occ\" with the type of str\n",
1810+
" \"age\": int, # compare the type of value \"age\" with the type of int\n",
1811+
" \"networth\": int, # compare the type of value \"networth\" with the type of int\n",
1812+
" } \n",
1813+
"\n",
1814+
" if name in type_hints: # Check if the attribute has a type hint\n",
1815+
" expected_type = type_hints[name]\n",
1816+
" if not isinstance(value, expected_type):\n",
1817+
" raise TypeError(f\"Attribute '{name}' must be of type {expected_type.__name__}, got {type(value).__name__}\")\n",
1818+
" \n",
1819+
" super().__setattr__(name, value) # Use this as the default behavior to set the attribute\n",
1820+
"\n",
1821+
" # __str__ # String representation of the class\n",
1822+
" def __str__(self):\n",
1823+
" return f\"{self.name}, Age: {self.age}\"\n",
1824+
"\n",
1825+
" # __eq__ # Equality: Compares two objects made from this class\n",
1826+
" def __eq__(self, other):\n",
1827+
" return self.name == other.name and self.age == other.age\n",
1828+
"\n",
1829+
" # Decorators: Modify a function\n",
1830+
" def hello(fx):\n",
1831+
" def mfx(*args, **kwargs):\n",
1832+
" print(f\"Hello from {fx.__name__}\")\n",
1833+
" func = fx(*args, **kwargs)\n",
1834+
" return func\n",
1835+
" return mfx\n",
1836+
"\n",
1837+
" # Functions of class\n",
1838+
" @hello # Decorator modifing a function\n",
1839+
" def info(self) -> str:\n",
1840+
" return f\"I am {self.name.name} {self.name.surname}, I am a {self.occ}\"\n",
1841+
" \n",
1842+
" # Function without a decorator \n",
1843+
" def actualincome(self) -> str:\n",
1844+
" taxslab = round(self.networth, 2) if (self.networth < 250000) else round(self.networth * 0.2, 2) if (self.networth > 250000 and self.networth) < 500000 else round(self.networth * 0.3, 2)\n",
1845+
" ipa = round(self.networth - taxslab, 2)\n",
1846+
" ipm = round(ipa/12, 2)\n",
1847+
" return f\"{self.name.name} {self.name.surname} earns {self.networth}\\n\\t pays {taxslab}\\n\\t accounting to {ipa} per annum \\n\\t accounting to {ipm} per month\"\n",
1848+
" \n",
1849+
" # Getter and Setter\n",
1850+
" @property # Getter: Gets networth in a function \"income\"\n",
1851+
" def income(self) -> int:\n",
1852+
" return self.networth\n",
1853+
"\n",
1854+
" @income.setter # Setter: Sets newnetworth to self.networth using a function \"newincome\"\n",
1855+
" def newincome(self, newnetworth) -> None:\n",
1856+
" self.networth = newnetworth\n",
1857+
"\n",
1858+
" @property # Getter: Gets name in a function \"name\" \n",
1859+
" def name(self) -> str: \n",
1860+
" return self._name\n",
1861+
"\n",
1862+
" @name.setter # Setter: Sets name to self.name using a function \"name\" used as name.name from \".name\" Name class then \".name\" Person class\n",
1863+
" def name(self, value: str) -> None:\n",
1864+
" self._name = value\n",
1865+
"\n",
1866+
" @property # Getter: Gets surname in a function \"surname\" \n",
1867+
" def surname(self) -> str:\n",
1868+
" return self._surname\n",
1869+
"\n",
1870+
" @surname.setter # Setter: Sets surname to self.surname using a function \"surname\" used as name.surname from \".name\" Name Person class then \".surname \"Name class\n",
1871+
" def surname(self, value: str) -> None:\n",
1872+
" self._surname = value\n",
1873+
"\n",
1874+
"\n",
1875+
"\n",
1876+
"# Helping Class\n",
1877+
"\n",
1878+
"# Name class to split the name and use it in Person class\n",
1879+
"class Name:\n",
1880+
" def __init__(self, full_name: str) -> None:\n",
1881+
" name_parts = full_name.split()\n",
1882+
" self._name = name_parts[0]\n",
1883+
" self._surname = name_parts[1] if len(name_parts) > 1 else \"\"\n",
1884+
"\n",
1885+
" @property\n",
1886+
" def name(self) -> str:\n",
1887+
" return self._name\n",
1888+
"\n",
1889+
" @name.setter\n",
1890+
" def name(self, value: str) -> None:\n",
1891+
" self._name = value\n",
1892+
"\n",
1893+
" @property\n",
1894+
" def surname(self) -> str:\n",
1895+
" return self._surname\n",
1896+
"\n",
1897+
" @surname.setter\n",
1898+
" def surname(self, value: str) -> None:\n",
1899+
" self._surname = value\n",
1900+
"\n",
1901+
" def __str__(self) -> str:\n",
1902+
" return f\"{self._name} {self._surname}\".strip() # Handles cases with missing surname"
1903+
]
1904+
},
1905+
{
1906+
"cell_type": "code",
1907+
"execution_count": null,
1908+
"metadata": {},
1909+
"outputs": [],
1910+
"source": [
1911+
"# Subclass Employee inherits from Person\n",
1912+
"class Employee(Person):\n",
1913+
" def __init__(self, full_name: str, occ: str, age: int, networth: int, position: str) -> None:\n",
1914+
" # Call the parent class's constructor to initialize inherited attributes\n",
1915+
" super().__init__(full_name, occ, age, networth)\n",
1916+
" self.position = position\n",
1917+
"\n",
1918+
" # Overriding __setattr__ to include type checking for 'position'\n",
1919+
" def __setattr__(self, name, value) -> None:\n",
1920+
" # Extend the type hints from the parent class\n",
1921+
" type_hints = {\n",
1922+
" \"position\": str, # Add type checking for 'position'\n",
1923+
" }\n",
1924+
"\n",
1925+
" # Combine parent type hints with the current class's type hints\n",
1926+
" parent_type_hints = getattr(super(), \"__setattr__\").__annotations__ if hasattr(super(), \"__setattr__\") else {}\n",
1927+
" type_hints.update(parent_type_hints)\n",
1928+
"\n",
1929+
" # Check for type validation\n",
1930+
" if name in type_hints:\n",
1931+
" expected_type = type_hints[name]\n",
1932+
" if not isinstance(value, expected_type):\n",
1933+
" raise TypeError(f\"Attribute '{name}' must be of type {expected_type.__name__}, got {type(value).__name__}\")\n",
1934+
"\n",
1935+
" # Call the parent class's __setattr__ to set the attribute\n",
1936+
" super().__setattr__(name, value)\n",
1937+
"\n",
1938+
" # Overriding the __str__ method to include position\n",
1939+
" def __str__(self):\n",
1940+
" return f\"{self.name}, Age: {self.age}, Position: {self.position}\"\n",
1941+
"\n",
1942+
" # Adding a new method specific to Employee\n",
1943+
" def promote(self, new_position: str) -> None:\n",
1944+
" old_position = self.position\n",
1945+
" self.position = new_position\n",
1946+
" print(f\"{self.name.name} {self.name.surname} has been promoted from {old_position} to {new_position}.\")"
1947+
]
1948+
},
1949+
{
1950+
"cell_type": "code",
1951+
"execution_count": null,
1952+
"metadata": {},
1953+
"outputs": [],
1954+
"source": [
1955+
"# Making an object a using class Person\n",
1956+
"a = Person(\"Anmol\", \"Developer\", 16, 150)\n",
1957+
"\n",
1958+
"# Using getter and setter to get and set a value\n",
1959+
"print(f\"Using getter to see networth, Networth is {a.income} before Setter\")\n",
1960+
"a.newincome = 70000000\n",
1961+
"\n",
1962+
"a.name.surname = \"Raj\"\n",
1963+
"\n",
1964+
"print(dir(a)) # shows all function of a class\n",
1965+
"\n",
1966+
"# Using methods of class\n",
1967+
"print(a.info())\n",
1968+
"print(a.actualincome())\n",
1969+
"\n",
1970+
"# Dunder Methods\n",
1971+
"p1 = Person(\"Ujjwal\", \"Developer\", 15, 150)\n",
1972+
"p2 = Person(\"Joy\", \"Developer\", 15, 150)\n",
1973+
"\n",
1974+
"print(p1) # Calls __str__\n",
1975+
"print(p1 == p2) # Calls __eq__\n",
1976+
"\n",
1977+
"# Create an instance of Employee\n",
1978+
"employee = Employee(\"Anmol Raj\", \"Developer\", 16, 7000000, \"Junior Developer\")\n",
1979+
"\n",
1980+
"# Demonstrate the new functionality\n",
1981+
"print(employee) # Calls overridden __str__\n",
1982+
"\n",
1983+
"# Promote the employee\n",
1984+
"employee.promote(\"Senior Developer\")"
1985+
]
1986+
},
17811987
{
17821988
"cell_type": "markdown",
17831989
"metadata": {},

Phase2.ipynb

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
{
1111
"cell_type": "code",
12-
"execution_count": null,
12+
"execution_count": 1,
1313
"metadata": {},
1414
"outputs": [],
1515
"source": [
@@ -335,7 +335,7 @@
335335
},
336336
{
337337
"cell_type": "code",
338-
"execution_count": null,
338+
"execution_count": 14,
339339
"metadata": {},
340340
"outputs": [],
341341
"source": [
@@ -363,7 +363,7 @@
363363
},
364364
{
365365
"cell_type": "code",
366-
"execution_count": null,
366+
"execution_count": 16,
367367
"metadata": {},
368368
"outputs": [],
369369
"source": [
@@ -375,7 +375,68 @@
375375
"execution_count": null,
376376
"metadata": {},
377377
"outputs": [],
378-
"source": []
378+
"source": [
379+
"df = pd.DataFrame(\n",
380+
" [\n",
381+
" [\"A\", 10, 20, 10, 26],\n",
382+
" [\"B\", 20, 25, 15, 21],\n",
383+
" [\"C\", 12, 15, 19, 6],\n",
384+
" [\"D\", 10, 18, 11, 19],\n",
385+
" ],\n",
386+
" columns=[\"Team\", \"Round 1\", \"Round 2\", \"Round 3\", \"Round 4\"],\n",
387+
")\n",
388+
"\n",
389+
"print(df)\n",
390+
"\n",
391+
"df.plot(x=\"Team\", kind=\"bar\", stacked=True, title=\"Stacked Bar Graph by dataframe\")\n",
392+
"\n",
393+
"plt.show()"
394+
]
395+
},
396+
{
397+
"cell_type": "code",
398+
"execution_count": null,
399+
"metadata": {},
400+
"outputs": [],
401+
"source": [
402+
"df = pd.DataFrame(\n",
403+
" [\n",
404+
" [\"Ram\", 10, 20, 10],\n",
405+
" [\"Shyam\", 20, 25, 15],\n",
406+
" [\"Sita\", 12, 15, 19],\n",
407+
" [\"Gita\", 10, 18, 11],\n",
408+
" ],\n",
409+
" columns=[\"Name\", \"Studied\", \"Slept\", \"Played\"],\n",
410+
")\n",
411+
"\n",
412+
"print(df)\n",
413+
"\n",
414+
"ax = df.plot(x=\"Name\", kind=\"barh\", stacked=True, mark_right=True)\n",
415+
"plt.title(\"Stacked Bar Graph\")\n",
416+
"\n",
417+
"df_total = df[\"Studied\"] + df[\"Slept\"] + df[\"Played\"]\n",
418+
"df_rel = df[df.columns[1:]].div(df_total, axis=0) * 100\n",
419+
"\n",
420+
"for n in df_rel.columns:\n",
421+
" for i, (cs, ab, pc) in enumerate(\n",
422+
" zip(df.iloc[:, 1:].cumsum(axis=1)[n], df[n], df_rel[n])\n",
423+
" ):\n",
424+
" plt.text(\n",
425+
" cs - ab / 2,\n",
426+
" i,\n",
427+
" f\"{np.round(pc, 1)}%\",\n",
428+
" va=\"center\",\n",
429+
" ha=\"center\",\n",
430+
" color=\"white\",\n",
431+
" )\n",
432+
"\n",
433+
"for i, total in enumerate(df_total):\n",
434+
" plt.text(\n",
435+
" total, i, str(total), va=\"center\", ha=\"left\", color=\"black\", fontweight=\"bold\"\n",
436+
" )\n",
437+
"\n",
438+
"plt.show()"
439+
]
379440
},
380441
{
381442
"cell_type": "markdown",

0 commit comments

Comments
 (0)