Skip to content

Commit da1db0b

Browse files
committed
Update OOPs_2.ipynb
1 parent 681d7cc commit da1db0b

File tree

1 file changed

+225
-59
lines changed
  • Module 1 - Python Programming/05. Object Oriented Programming

1 file changed

+225
-59
lines changed

Module 1 - Python Programming/05. Object Oriented Programming/OOPs_2.ipynb

Lines changed: 225 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,36 +1083,245 @@
10831083
"cell_type": "markdown",
10841084
"metadata": {},
10851085
"source": [
1086-
"## **Abstraction**"
1086+
"## **Abstraction**\n",
1087+
"Abstraction is the process of **hiding the implementation details** and **exposing only the relevant functionality** to the user.\n",
1088+
"\n",
1089+
"In Python, abstraction is implemented using the **abc module**.\n",
1090+
"\n",
1091+
"```python\n",
1092+
"from abc import ABC, abstractmethod\n",
1093+
"```\n",
1094+
"- **ABC:** Abstract Base Class\n",
1095+
"- **@abstractmethod:** Decorator to define abstract methods (methods without implementation)\n",
1096+
"\n",
1097+
"| Concept | Purpose |\n",
1098+
"| ----------------- | ------------------------------------------------ |\n",
1099+
"| `ABC` | Create abstract base classes |\n",
1100+
"| `@abstractmethod` | Force child classes to implement certain methods |\n",
1101+
"\n",
1102+
"\n",
1103+
"#### **Why Use Abstraction?**\n",
1104+
"1. Forces subclasses to implement specific methods.\n",
1105+
"2. Defines a clear contract/interface for developers.\n",
1106+
"3. Ensures consistency across different implementations.\n",
1107+
"4. Reduces coupling between components.\n",
1108+
"\n",
1109+
"#### **What Abstraction is not?**\n",
1110+
"Not just hiding variables with `__` (**that’s encapsulation i.e. hiding internal data/state**)\n"
10871111
]
10881112
},
10891113
{
10901114
"cell_type": "code",
1091-
"execution_count": 36,
1115+
"execution_count": 4,
10921116
"metadata": {
10931117
"ExecuteTime": {
10941118
"end_time": "2018-05-31T17:28:10.195940Z",
10951119
"start_time": "2018-05-31T17:28:10.183162Z"
10961120
}
10971121
},
1122+
"outputs": [],
1123+
"source": [
1124+
"from abc import ABC, abstractmethod\n",
1125+
"\n",
1126+
"class Animal(ABC):\n",
1127+
" \n",
1128+
" @abstractmethod\n",
1129+
" def make_sound(self):\n",
1130+
" pass\n",
1131+
"\n",
1132+
" def sleep(self):\n",
1133+
" print(\"Sleeping...\")\n",
1134+
"\n",
1135+
"# This will throw an error:\n",
1136+
"# animal = Animal()\n",
1137+
"\n",
1138+
"class Dog(Animal):\n",
1139+
" def make_sound(self):\n",
1140+
" print(\"Woof!\")\n",
1141+
"\n",
1142+
"class Cat(Animal):\n",
1143+
" def make_sound(self):\n",
1144+
" print(\"Meow!\")"
1145+
]
1146+
},
1147+
{
1148+
"cell_type": "code",
1149+
"execution_count": 5,
1150+
"metadata": {},
10981151
"outputs": [
10991152
{
1100-
"data": {
1101-
"text/plain": [
1102-
"'\\nProcess of highlighting the set of services & hiding the implementation\\nis called ABSTRACTION.\\n'"
1103-
]
1104-
},
1105-
"execution_count": 36,
1106-
"metadata": {},
1107-
"output_type": "execute_result"
1153+
"name": "stdout",
1154+
"output_type": "stream",
1155+
"text": [
1156+
"Woof!\n",
1157+
"Sleeping...\n"
1158+
]
11081159
}
11091160
],
11101161
"source": [
1111-
"# Abstraction means HIDING\n",
1112-
"'''\n",
1113-
"Process of highlighting the set of services & hiding the implementation\n",
1114-
"is called ABSTRACTION.\n",
1115-
"'''"
1162+
"d = Dog()\n",
1163+
"\n",
1164+
"d.make_sound()\n",
1165+
"d.sleep()"
1166+
]
1167+
},
1168+
{
1169+
"cell_type": "markdown",
1170+
"metadata": {},
1171+
"source": [
1172+
"#### **Observation**\n",
1173+
"1. You can't instantiate Animal directly.\n",
1174+
"2. Any subclass must implement make_sound(), or it'll raise an error.\n",
1175+
"3. Common behavior like sleep() can still be implemented in the base class."
1176+
]
1177+
},
1178+
{
1179+
"cell_type": "markdown",
1180+
"metadata": {},
1181+
"source": [
1182+
"#### **Real Time Example of Abstraction**\n",
1183+
"\n",
1184+
"You’re building a payment system for an edtech platform that allows students to purchase courses using UPI (Unified Payments Interface). But students use different UPI apps — PhonePe, Google Pay, Paytm, BHIM, etc.\n",
1185+
"\n",
1186+
"Without Abstraction, you’d have scattered logic, tightly coupling your app with every UPI provider’s implementation. \n",
1187+
"Whereas, with abstraction: \n",
1188+
"- You define a common interface for any UPI-based payment processor.\n",
1189+
"- Each UPI app then implements the common logic behind the scenes, hiding differences.\n",
1190+
"\n",
1191+
"Let's do the implementation in three steps:\n",
1192+
"1. Abstract Class (Interface)\n",
1193+
"2. Concrete Implementations\n",
1194+
"3. Usage Layer"
1195+
]
1196+
},
1197+
{
1198+
"cell_type": "code",
1199+
"execution_count": 6,
1200+
"metadata": {},
1201+
"outputs": [],
1202+
"source": [
1203+
"# Step 1: Abstract Class i.e. UPIPaymentProcessor\n",
1204+
"\n",
1205+
"from abc import ABC, abstractmethod\n",
1206+
"\n",
1207+
"class UPIPaymentProcessor(ABC):\n",
1208+
" \n",
1209+
" @abstractmethod\n",
1210+
" def pay(self, user_id: str, amount: float, upi_id: str):\n",
1211+
" \"\"\"Process a UPI payment\"\"\"\n",
1212+
" pass\n",
1213+
"\n",
1214+
" @abstractmethod\n",
1215+
" def generate_receipt(self) -> str:\n",
1216+
" \"\"\"Generate transaction receipt\"\"\"\n",
1217+
" pass"
1218+
]
1219+
},
1220+
{
1221+
"cell_type": "code",
1222+
"execution_count": 7,
1223+
"metadata": {},
1224+
"outputs": [],
1225+
"source": [
1226+
"# Step 2: Concrete Implementations\n",
1227+
"\n",
1228+
"# PhonePe\n",
1229+
"class PhonePeProcessor(UPIPaymentProcessor):\n",
1230+
" def pay(self, user_id, amount, upi_id):\n",
1231+
" print(f\"[PhonePe] Sending ₹{amount} request to {upi_id} for User {user_id}\")\n",
1232+
" self.transaction_id = f\"PP_{user_id}_TXN001\"\n",
1233+
" \n",
1234+
" def generate_receipt(self):\n",
1235+
" return f\"[PhonePe] Receipt #{self.transaction_id}\"\n",
1236+
"\n",
1237+
"\n",
1238+
"# GooglePay\n",
1239+
"class GooglePayProcessor(UPIPaymentProcessor):\n",
1240+
" def pay(self, user_id, amount, upi_id):\n",
1241+
" print(f\"[GPay] Processing ₹{amount} to {upi_id} for User {user_id}\")\n",
1242+
" self.transaction_id = f\"GPay_{user_id}_TXN002\"\n",
1243+
" \n",
1244+
" def generate_receipt(self):\n",
1245+
" return f\"[GPay] Receipt #{self.transaction_id}\"\n",
1246+
"\n",
1247+
"\n",
1248+
"# Paytm\n",
1249+
"class PaytmProcessor(UPIPaymentProcessor):\n",
1250+
" def pay(self, user_id, amount, upi_id):\n",
1251+
" print(f\"[Paytm] ₹{amount} sent to {upi_id} for User {user_id}\")\n",
1252+
" self.transaction_id = f\"PTM_{user_id}_TXN003\"\n",
1253+
" \n",
1254+
" def generate_receipt(self):\n",
1255+
" return f\"[Paytm] Receipt #{self.transaction_id}\"\n"
1256+
]
1257+
},
1258+
{
1259+
"cell_type": "code",
1260+
"execution_count": 8,
1261+
"metadata": {},
1262+
"outputs": [],
1263+
"source": [
1264+
"# Step 3: Usage Layer\n",
1265+
"\n",
1266+
"def checkout(processor: UPIPaymentProcessor, user_id: str, amount: float, upi_id: str):\n",
1267+
" processor.pay(user_id, amount, upi_id)\n",
1268+
" receipt = processor.generate_receipt()\n",
1269+
" print(receipt)"
1270+
]
1271+
},
1272+
{
1273+
"cell_type": "code",
1274+
"execution_count": 10,
1275+
"metadata": {},
1276+
"outputs": [
1277+
{
1278+
"name": "stdout",
1279+
"output_type": "stream",
1280+
"text": [
1281+
"[PhonePe] Sending ₹999.0 request to user@ibl for User U101\n",
1282+
"[PhonePe] Receipt #PP_U101_TXN001\n"
1283+
]
1284+
}
1285+
],
1286+
"source": [
1287+
"# Run various payment processors\n",
1288+
"checkout(PhonePeProcessor(), \"U101\", 999.0, \"user@ibl\")"
1289+
]
1290+
},
1291+
{
1292+
"cell_type": "code",
1293+
"execution_count": 11,
1294+
"metadata": {},
1295+
"outputs": [
1296+
{
1297+
"name": "stdout",
1298+
"output_type": "stream",
1299+
"text": [
1300+
"[GPay] Processing ₹499.0 to user@okhdfcbank for User U102\n",
1301+
"[GPay] Receipt #GPay_U102_TXN002\n"
1302+
]
1303+
}
1304+
],
1305+
"source": [
1306+
"checkout(GooglePayProcessor(), \"U102\", 499.0, \"user@okhdfcbank\")"
1307+
]
1308+
},
1309+
{
1310+
"cell_type": "code",
1311+
"execution_count": 12,
1312+
"metadata": {},
1313+
"outputs": [
1314+
{
1315+
"name": "stdout",
1316+
"output_type": "stream",
1317+
"text": [
1318+
"[Paytm] ₹799.0 sent to user@paytm for User U103\n",
1319+
"[Paytm] Receipt #PTM_U103_TXN003\n"
1320+
]
1321+
}
1322+
],
1323+
"source": [
1324+
"checkout(PaytmProcessor(), \"U103\", 799.0, \"user@paytm\")"
11161325
]
11171326
},
11181327
{
@@ -1339,7 +1548,7 @@
13391548
"cell_type": "markdown",
13401549
"metadata": {},
13411550
"source": [
1342-
"#### **Real Time Example**\n",
1551+
"#### **Real Time Example of Encapsulation**\n",
13431552
"\n",
13441553
"Consider the example of a geographical system that needs to deal with coordinates. There is only a certain range of values for which latitude and longitude make sense. Outside of those values, a coordinate cannot exist. We can create an object to represent a coordinate, but in doing so we must ensure that the values for latitude are at all times within the acceptable ranges. And for this, we can use properties:"
13451554
]
@@ -1377,49 +1586,6 @@
13771586
" self._longitude = long_value"
13781587
]
13791588
},
1380-
{
1381-
"cell_type": "markdown",
1382-
"metadata": {},
1383-
"source": [
1384-
"#### **Private Method**"
1385-
]
1386-
},
1387-
{
1388-
"cell_type": "code",
1389-
"execution_count": 41,
1390-
"metadata": {
1391-
"ExecuteTime": {
1392-
"end_time": "2018-05-31T17:41:40.583150Z",
1393-
"start_time": "2018-05-31T17:41:40.567487Z"
1394-
}
1395-
},
1396-
"outputs": [
1397-
{
1398-
"name": "stdout",
1399-
"output_type": "stream",
1400-
"text": [
1401-
"Updating Software....\n",
1402-
"Driving\n"
1403-
]
1404-
}
1405-
],
1406-
"source": [
1407-
"class Car:\n",
1408-
" def __init__(self):\n",
1409-
" self.__updateSoftware()\n",
1410-
" \n",
1411-
" def drive(self):\n",
1412-
" print('Driving')\n",
1413-
" \n",
1414-
" def __updateSoftware(self):\n",
1415-
" print('Updating Software....')\n",
1416-
" \n",
1417-
"myCar = Car()\n",
1418-
"myCar.drive()\n",
1419-
"\n",
1420-
"mycar.__updateSoftware()"
1421-
]
1422-
},
14231589
{
14241590
"cell_type": "markdown",
14251591
"metadata": {},

0 commit comments

Comments
 (0)