📓 Programming in Python — End Sem Notes
Unit I  |  Python Basics  |  2024
Unit I
Introduction to Python Programming

Python — high-level, interpreted language by Guido van Rossum (1991). Supports procedural, OOP & functional paradigms.

Zen of Python: "Readability counts."  → run import this in shell ✨
1. Key Features
  • Dynamic Typing — no need to declare variable types
  • Interpreted — runs line by line via Python Virtual Machine (PVM)
  • Portable — runs on Windows, macOS, Linux
  • Interoperable — integrates with C/C++, Java, .NET
  • Python 3.x is current (recommended over 2.x)

2. Data Types
TypeKeywordExampleMutable?
Integerintx = 42No
Floatfloatpi = 3.14No
Stringstr'hello'No
BooleanboolTrue / FalseNo
Listlist[1, 2, 3]Yes
Tupletuple(10, 20)No
Dictionarydict{'a': 1}Yes
Setset{1, 2, 3}Yes
NoneTypeNonex = NoneNo
🐍 data_types.py
# Integer x = 5 print(type(x)) # <class 'int'> # Float y = 3.14 print(type(y)) # <class 'float'> # String (immutable!) s = 'hello' print(s.upper()) # HELLO # Boolean flag = True print(type(flag)) # <class 'bool'>
📝 String Notes
Strings are immutable — any "modification" creates a new string object.
Supports raw strings r'raw\n' and multi-line '''text'''

3. String Operations
Concatenation (+)
concat
s1 = "Hello" s2 = "World" print(s1 + s2) # HelloWorld
Replication (*)
replicate
s = "Ha" print(s * 3) # HaHaHa
Useful String Methods
  • len(s) — length of string
  • s.lower() / s.upper() — case conversion
  • s.strip() — remove leading/trailing whitespace
  • s.split(',') — split into list
  • ','.join(lst) — join list into string
  • s.find('x') — returns index, -1 if not found
  • s.replace('a','b') — replace occurrences
  • s[1:4] — slicing

4. Operators
TypeOperatorsExample
Arithmetic+ - * / // % **10 // 3 = 3
Comparison== != < > <= >=5 > 3 → True
Logicaland or notTrue and False → False
Membershipin, not in3 in [1,2,3] → True
Identityis, is notx is y → False
Bitwise& | ^ ~ << >>5 & 3 = 1
Assignment= += -= *= /= %= **=x += 5
Mixing Boolean + Comparison:
(num % 2 == 0) and (num > 10) — checks both conditions simultaneously!

5. Flow Control
if-elif-else
conditionals.py
x = 10 if x > 5: print("x is greater than 5") elif x == 5: print("x equals 5") else: print("x is less than 5")
Loops
while loop
i = 0 while i < 5: print(i) i += 1
for loop
for i in range(5): print(i) # 0 1 2 3 4
  • break — exit loop immediately
  • continue — skip current iteration
  • pass — do nothing (placeholder)

6. Modules & sys.exit()
importing.py
import math print(math.sqrt(25)) # 5.0 from math import sqrt print(sqrt(25)) # 5.0 import math as m print(m.sqrt(25)) # 5.0 # Early exit import sys sys.exit(1) # exit with error code 1
⚠️ Standard vs Third-Party
Standard Library — pre-installed (math, os, sys, datetime…)
Third-Party — install via pip install package_name (e.g. requests, numpy)

7. Docstrings & Comments
docstring.py
def add(x, y): '''Add two numbers and return result.''' return x + y print(add.__doc__) # Add two numbers and return result. # Single-line comment ''' Multi-line comment using triple quotes '''
Unit II  |  Functions, Lists, Dicts  |  2024
Unit II
Functions, Exception Handling & Data Structures
1. Functions

Functions = reusable blocks of code. Defined with def keyword.

functions.py
# 1. No parameters def greet(): print("Hello, World!") # 2. With parameters def greet(name): print(f"Hello, {name}!") # 3. Default parameter def greet(name="Guest"): print(f"Hello, {name}!") # 4. Keyword arguments greet(name="Alice") # 5. Variable args (*args) def calc_sum(*args): return sum(args) # 6. Keyword variable args (**kwargs) def calc_total(**kwargs): return sum(kwargs.values()) calc_total(apple=2, banana=3) # 5
Types of Functions
TypeDescriptionExample
Built-inPre-installed in Pythonprint(), len(), type()
User-definedMade with defdef add(x,y): ...
LambdaAnonymous, one-expressionadd = lambda x,y: x+y
RecursiveCalls itselfFactorial, Fibonacci
GeneratorUses yielddef countdown(n): yield n
Higher-orderTakes/returns functionsmap(), filter()
DecoratorModifies another function@my_decorator
2. Return Values & None
return_none.py
def absolute(x): if x >= 0: return x else: return -x # No return → returns None def greet(n): print(n) r = greet("hi") # r is None # None check if result is None: print("No value returned")

3. Scope — Local vs Global
Local Scope
Variables inside a function. Only accessible within the function. Accessing outside → NameError
Global Scope
Variables outside functions. Accessible everywhere. Use global x inside function to modify.
scope.py
x = 10 # global def my_func(): global x x = 20 # modifies global x print(x) # 20 my_func() print(x) # 20 (global changed)
Without global: assignment inside function creates a new local variable — global remains unchanged!

4. Exception Handling
exceptions.py
try: x = 10 / 0 except ZeroDivisionError as e: print("Error:", e) except ValueError: print("Value error!") else: print("No errors!") # runs if no exception finally: print("Always runs") # cleanup # Raise manually if x < 0: raise ValueError("Must be non-negative") # Custom exception class MyError(Exception): pass
  • Exceptions propagate up the call stack until caught or program terminates
  • Always use finally for resource cleanup (files, connections)

5. Lists

Ordered, mutable, allows duplicates. Defined with [ ]

lists.py
lst = [1, 2, 3, 4, 5] # Indexing (0-based) print(lst[0]) # 1 print(lst[-1]) # 5 (last) # Slicing [start:stop:step] print(lst[1:4]) # [2, 3, 4] # Methods lst.append(6) # add to end lst.extend([7,8]) # add multiple lst.insert(2, 99) # insert at index lst.remove(3) # remove first occurrence lst.pop() # remove & return last lst.sort() # sort ascending lst.reverse() # reverse in place # List comprehension squares = [x**2 for x in range(1,6)] # [1, 4, 9, 16, 25]

6. Dictionaries

Key-value pairs. Mutable. Keys must be unique & immutable. { }

dicts.py
d = {"name": "John", "age": 30} # Access d["name"] # "John" d.get("age") # 30 # Add / Modify d["city"] = "Delhi" # Delete del d["age"] d.pop("city") # Iterate for k, v in d.items(): print(k, ":", v) d.keys() # all keys d.values() # all values
7. Augmented Assignment Operators
OperatorEquivalentExampleResult
+=x = x + nx = 5; x += 38
-=x = x - nx = 10; x -= 46
*=x = x * nx = 3; x *= 26
/=x = x / nx = 12; x /= 34.0
%=x = x % nx = 15; x %= 43
**=x = x ** nx = 2; x **= 38
//=x = x // nx = 17; x //= 53
Unit III  |  Reading & Writing Files  |  2024
Unit III
File Handling, os.path & Organizing Files
1. Reading & Writing Files
ModeMeaning
'r'Read (default)
'w'Write (creates/truncates)
'a'Append (adds to end)
'rb'Read binary
'wb'Write binary
files.py
# Reading with open('file.txt', 'r') as f: content = f.read() # entire file line = f.readline() # one line lines = f.readlines() # list of lines # Writing with open('file.txt', 'w') as f: f.write("Hello, World!") # Appending with open('file.txt', 'a') as f: f.write("\nNew line")
Always use with statement!
It auto-closes the file even if an error occurs — no need for f.close()

2. File Paths & os.path Module
Absolute Path
Complete path from root
/Users/name/docs/file.txt
Relative Path
Relative to current working dir
docs/file.txt
os_path.py
import os # Join paths (cross-platform) p = os.path.join('docs', 'file.txt') os.path.exists(p) # does path exist? os.path.isfile(p) # is it a file? os.path.isdir(p) # is it a directory? os.path.basename(p) # 'file.txt' os.path.dirname(p) # 'docs' os.path.abspath(p) # absolute path os.getcwd() # current directory os.chdir('/home') # change directory

3. Saving Variables — shelve & pprint
shelve_demo.py
import shelve # Store with shelve.open('mydata') as db: db['name'] = 'Alice' db['age'] = 25 # Retrieve with shelve.open('mydata') as db: print(db['name']) # Alice # Pretty print import pprint data = {'a': 1, 'b': [2, 3]} pprint.pprint(data) # Save pformat to file text = pprint.pformat(data) with open('out.txt', 'w') as f: f.write(text)

4. shutil & Organizing Files
shutil_demo.py
import shutil, os shutil.copy('src.txt', 'dst.txt') # copy file shutil.copy2('src.txt', 'dst.txt') # copy + metadata shutil.copytree('src/', 'dst/') # copy directory shutil.move('old.txt', 'new.txt') # move/rename shutil.rmtree('folder/') # delete dir tree shutil.make_archive('arch','zip','src/') # zip folder # Walk directory tree for root, dirs, files in os.walk('.'): for file in files: print(os.path.join(root, file))

5. zipfile Module
zipfile_demo.py
import zipfile # Create ZIP with zipfile.ZipFile('arch.zip', 'w') as zf: zf.write('file1.txt') # Extract ZIP with zipfile.ZipFile('arch.zip', 'r') as zf: zf.extractall('output/') print(zf.namelist()) # list files # Append to existing ZIP with zipfile.ZipFile('arch.zip', 'a') as zf: zf.write('file2.txt')
Unit IV  |  Web Scraping & HTML  |  2024
Unit IV
Web Scraping, requests & HTML
1. Web Scraping Overview

Web scraping = extracting data from websites programmatically.

LibraryPurpose
Beautiful SoupParse HTML/XML documents
RequestsSend HTTP requests, get responses
ScrapyFull web scraping framework (crawl, parse, store)
Basic Steps
  • Send HTTP request (requests library)
  • Parse HTML response (Beautiful Soup)
  • Extract target data (navigate parse tree)
  • Store / process the data
scraper.py
import requests from bs4 import BeautifulSoup url = 'https://example.com' resp = requests.get(url) soup = BeautifulSoup(resp.text, 'html.parser') # Find elements titles = soup.find_all('h3') for t in titles: print(t.text)
⚠️ Ethics of Scraping
Always respect robots.txt and the site's Terms of Service.
Don't send too many requests too fast — rate-limit your scraper!

2. Project: mapit.py (webbrowser)
mapit.py
#! python3 # Opens Google Maps for an address import webbrowser, sys, pyperclip if len(sys.argv) > 1: # From command line address = ' '.join(sys.argv[1:]) else: # From clipboard address = pyperclip.paste() webbrowser.open('https://maps.google.com/maps?q=' + address) # Usage: python mapit.py 123 Main St

3. Downloading Files with requests
download.py
import requests url = 'https://example.com/file.zip' resp = requests.get(url) # Check success if resp.status_code == 200: with open('file.zip', 'wb') as f: f.write(resp.content) else: print('Error:', resp.status_code) # Download large files in chunks resp = requests.get(url, stream=True) with open('big.zip', 'wb') as f: for chunk in resp.iter_content(chunk_size=8192): f.write(chunk)
Status Codes to know:
200 = OK  |  404 = Not Found  |  403 = Forbidden  |  500 = Server Error

4. HTML Basics

HTML = HyperText Markup Language — structures web pages with tags.

structure.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Page Title</title> </head> <body> <h1>Heading</h1> <p>Paragraph text</p> <a href="https://example.com">Link</a> <img src="img.jpg" alt="description"> </body> </html>
Key HTML Attributes
AttributePurpose
idUnique identifier for element
classGroup elements for CSS styling
hrefURL for anchor tags
srcSource URL for images/scripts
✅ HTML + BS4 combo
BeautifulSoup parses HTML, then you navigate tags:
soup.find('h1').text  |  soup.find_all('a')  |  tag['href']
Quick Revision Checklist ✅
□ Data types & mutability
□ Functions (all 7 types)
□ try-except-else-finally
□ List methods (append/pop/sort/index)
□ Dict methods (items/keys/values/get)
□ File modes (r/w/a/rb/wb)
□ os.path functions
□ shutil.copy/move/rmtree
□ requests.get + status codes
□ HTML structure