0% found this document useful (0 votes)
52 views39 pages

Python Assignment Solutions - Mid Semester Exam

The document contains solutions for a Python mid-semester exam, covering topics such as Python's overview, mutable vs immutable data types, a comprehensive operations calculator, a library management system, properties and operations of sets, list analysis functions, and the beginner-friendly nature of Python. Each section includes explanations, examples, and code snippets to illustrate the concepts. The document serves as a practical guide for understanding various Python programming concepts and functionalities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views39 pages

Python Assignment Solutions - Mid Semester Exam

The document contains solutions for a Python mid-semester exam, covering topics such as Python's overview, mutable vs immutable data types, a comprehensive operations calculator, a library management system, properties and operations of sets, list analysis functions, and the beginner-friendly nature of Python. Each section includes explanations, examples, and code snippets to illustrate the concepts. The document serves as a practical guide for understanding various Python programming concepts and functionalities.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Python Assignment Solutions - Mid Semester Exam

Each question carries 5 marks

Question 1: Python Overview and Benefits


Explanation of Python: Python is a high-level, interpreted, object-oriented programming language
created by Guido van Rossum in 1991. It emphasizes code readability and simplicity through its clean
syntax.

Benefits justifying global acceptance:

1. Readable and Simple Syntax - Easy to learn and maintain


2. Cross-platform Compatibility - Runs on Windows, Linux, macOS

3. Extensive Standard Library - "Batteries included" philosophy


4. Large Community Support - Vast ecosystem of third-party packages

5. Versatile Applications - Web development, AI/ML, data science, automation


6. Rapid Development - Faster prototyping and development cycles
7. Free and Open Source - No licensing costs

Question 2: Mutable vs Immutable Data Types


Mutable Data Types can be modified after creation:

Lists, Dictionaries, Sets

Immutable Data Types cannot be modified after creation:

Strings, Tuples, Numbers, Frozensets

python
# Mutable Examples
my_list = [1, 2, 3]
print("Original list:", my_list)
my_list[0] = 10 # Modifying existing list
print("Modified list:", my_list)

my_dict = {'a': 1, 'b': 2}


my_dict['c'] = 3 # Adding new key-value pair
print("Modified dict:", my_dict)

# Immutable Examples
my_string = "Hello"
# my_string[0] = 'h' # This would cause an error
new_string = my_string.replace('H', 'h') # Creates new string
print("Original string:", my_string)
print("New string:", new_string)

my_tuple = (1, 2, 3)
# my_tuple[0] = 10 # This would cause an error
print("Tuple remains:", my_tuple)

Question 3: Comprehensive Operations Calculator

python
def comprehensive_calculator():
print("=== Comprehensive Operations Calculator ===")

# Input two numbers


num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

print(f"\nOperations on {num1} and {num2}:")


print("=" * 50)

# Arithmetic Operations
print("\n1. ARITHMETIC OPERATIONS:")
print(f"Addition: {num1} + {num2} = {num1 + num2}")
print(f"Subtraction: {num1} - {num2} = {num1 - num2}")
print(f"Multiplication: {num1} * {num2} = {num1 * num2}")
if num2 != 0:
print(f"Division: {num1} / {num2} = {num1 / num2}")
print(f"Floor Division: {num1} // {num2} = {num1 // num2}")
print(f"Modulus: {num1} % {num2} = {num1 % num2}")
else:
print("Division by zero not allowed")
print(f"Exponentiation: {num1} ** {num2} = {num1 ** num2}")

# Relational Operations
print("\n2. RELATIONAL OPERATIONS:")
print(f"{num1} == {num2}: {num1 == num2}")
print(f"{num1} != {num2}: {num1 != num2}")
print(f"{num1} > {num2}: {num1 > num2}")
print(f"{num1} < {num2}: {num1 < num2}")
print(f"{num1} >= {num2}: {num1 >= num2}")
print(f"{num1} <= {num2}: {num1 <= num2}")

# Logical Operations (using boolean conversion)


print("\n3. LOGICAL OPERATIONS:")
bool1, bool2 = bool(num1), bool(num2)
print(f"bool({num1}) and bool({num2}): {bool1 and bool2}")
print(f"bool({num1}) or bool({num2}): {bool1 or bool2}")
print(f"not bool({num1}): {not bool1}")
print(f"not bool({num2}): {not bool2}")

# Bitwise Operations (converting to integers)


int1, int2 = int(num1), int(num2)
print("\n4. BITWISE OPERATIONS:")
print(f"{int1} & {int2} (AND): {int1 & int2}")
print(f"{int1} | {int2} (OR): {int1 | int2}")
print(f"{int1} ^ {int2} (XOR): {int1 ^ int2}")
print(f"~{int1} (NOT): {~int1}")
print(f"{int1} << 2 (Left Shift): {int1 << 2}")
print(f"{int1} >> 2 (Right Shift): {int1 >> 2}")

# Assignment Operations
print("\n5. ASSIGNMENT OPERATIONS:")
result = num1
print(f"result = {num1}: {result}")
result += num2
print(f"result += {num2}: {result}")
result -= num2
print(f"result -= {num2}: {result}")
result *= num2
print(f"result *= {num2}: {result}")
if num2 != 0:
result /= num2
print(f"result /= {num2}: {result}")

# Run the calculator


comprehensive_calculator()

Question 4: Library Management System

python
class LibraryManagement:
def __init__(self):
self.books = {
'Python Programming': 5,
'Data Structures': 3,
'Web Development': 4,
'Machine Learning': 2
}
self.borrowed_books = []

def display_menu(self):
print("\n=== LIBRARY MANAGEMENT SYSTEM ===")
print("1. Add New Book")
print("2. Borrow a Book")
print("3. Return a Book")
print("4. Display All Available Books")
print("5. Exit")

def add_book(self):
book_name = input("Enter book name: ").strip()
try:
quantity = int(input("Enter quantity: "))
if book_name in self.books:
self.books[book_name] += quantity
else:
self.books[book_name] = quantity
print(f"✅ Successfully added {quantity} copies of '{book_name}'")
except ValueError:
print("❌ Please enter a valid quantity")

def borrow_book(self):
book_name = input("Enter book name to borrow: ").strip()
if book_name in self.books and self.books[book_name] > 0:
self.books[book_name] -= 1
self.borrowed_books.append(book_name)
print(f"✅ Successfully borrowed '{book_name}'")
else:
print("❌ Book not available or out of stock")

def return_book(self):
book_name = input("Enter book name to return: ").strip()
if book_name in self.borrowed_books:
self.borrowed_books.remove(book_name)
if book_name in self.books:
self.books[book_name] += 1
else:
self.books[book_name] = 1
print(f"✅ Successfully returned '{book_name}'")
else:
print("❌ This book was not borrowed from our library")

def display_books(self):
print("\n📚 AVAILABLE BOOKS:")
print("-" * 40)
if self.books:
for book, quantity in self.books.items():
status = "Available" if quantity > 0 else "Out of Stock"
print(f"{book}: {quantity} copies ({status})")
else:
print("No books available")

def run(self):
while True:
self.display_menu()
try:
choice = int(input("Enter your choice (1-5): "))

if choice == 1:
self.add_book()
elif choice == 2:
self.borrow_book()
elif choice == 3:
self.return_book()
elif choice == 4:
self.display_books()
elif choice == 5:
print("Thank you for using Library Management System!")
break
else:
print("❌ Invalid choice! Please select 1-5")

except ValueError:
print("❌ Please enter a valid number")

# Run the system


if __name__ == "__main__":
library = LibraryManagement()
library.run()
Question 5: Python Sets Properties and Operations
Properties of Python Sets:

1. Unordered - No index-based access

2. Unique elements - No duplicates allowed

3. Mutable - Can add/remove elements

4. Iterable - Can loop through elements

5. Support mathematical operations - Union, intersection, etc.

python
def set_operations():
print("=== SET OPERATIONS ===")

# Input two sets


print("Enter elements for Set 1 (separated by spaces):")
set1_input = input().split()
set1 = set(map(int, set1_input))

print("Enter elements for Set 2 (separated by spaces):")


set2_input = input().split()
set2 = set(map(int, set2_input))

print(f"\nSet 1: {set1}")
print(f"Set 2: {set2}")

# Check relationships
print("\n=== SET RELATIONSHIPS ===")

if set1.issubset(set2):
print("Set 1 is a SUBSET of Set 2")
elif set1.issuperset(set2):
print("Set 1 is a SUPERSET of Set 2")
elif set1.isdisjoint(set2):
print("Set 1 and Set 2 are DISJOINT (no common elements)")
else:
print("Sets have some common elements but neither is subset/superset")

# Additional set operations


print("\n=== ADDITIONAL OPERATIONS ===")
print(f"Union: {set1.union(set2)}")
print(f"Intersection: {set1.intersection(set2)}")
print(f"Difference (Set1 - Set2): {set1.difference(set2)}")
print(f"Symmetric Difference: {set1.symmetric_difference(set2)}")

# Run the program


set_operations()

Question 6: List Analysis Function

python
def analyze_list(numbers):
"""
Find maximum, second maximum, smallest, and N-largest values from a list
"""
if not numbers:
return "Empty list provided"

# Remove duplicates and sort


unique_nums = list(set(numbers))
unique_nums.sort(reverse=True)

print(f"Original list: {numbers}")


print(f"Unique sorted (desc): {unique_nums}")

# Results dictionary
results = {}

# Maximum value
results['maximum'] = max(numbers)

# Second maximum
if len(unique_nums) >= 2:
results['second_maximum'] = unique_nums[1]
else:
results['second_maximum'] = "Only one unique value exists"

# Smallest value
results['smallest'] = min(numbers)

return results

def get_n_largest(numbers, n):


"""Get N largest elements"""
unique_nums = list(set(numbers))
unique_nums.sort(reverse=True)
return unique_nums[:n]

# Main program
def main():
print("=== LIST ANALYSIS PROGRAM ===")

# Get input from user


try:
numbers_input = input("Enter numbers separated by spaces: ")
numbers = list(map(int, numbers_input.split()))
# Analyze the list
results = analyze_list(numbers)

print("\n=== RESULTS ===")


for key, value in results.items():
print(f"{key.replace('_', ' ').title()}: {value}")

# Get N-largest values


try:
n = int(input(f"\nEnter N for N-largest values (max {len(set(numbers))}): "))
n_largest = get_n_largest(numbers, n)
print(f"Top {n} largest values: {n_largest}")
except ValueError:
print("Invalid input for N")

except ValueError:
print("Please enter valid integers only")

# Run the program


if __name__ == "__main__":
main()

Question 7: Python as Beginner-Friendly Language


Why Python is Beginner-Friendly:

Python is considered beginner-friendly due to its design philosophy that emphasizes code readability and
simplicity. The language uses English-like syntax that makes it intuitive for new programmers to
understand and write code.

Five Practical Benefits:

1. Simple and Clean Syntax


No complex punctuation like braces or semicolons

Indentation-based structure promotes clean code


Example: if x > 5: print("Greater than 5")

2. Interactive Learning Environment


IDLE and Python shell for immediate feedback
Jupyter notebooks for educational purposes

Easy experimentation and testing

3. Extensive Documentation and Community


Comprehensive official documentation
Large community support on Stack Overflow, Reddit
Numerous tutorials and learning resources

4. Rich Standard Library


Built-in modules for common tasks

Reduces need to write complex code from scratch


Example: import datetime for date operations

5. Cross-Platform Compatibility
Write once, run anywhere

Same code works on Windows, macOS, Linux

No compilation needed - interpreted language

Question 8: Lists vs Tuples Mutability


Lists are Mutable - Can be Modified:

python

# Lists can be changed after creation


my_list = [1, 2, 3, 4, 5]
print("Original list:", my_list)

# Modifying elements
my_list[0] = 10
print("After modification:", my_list)

# Adding elements
my_list.append(6)
print("After adding element:", my_list)

# Removing elements
my_list.remove(2)
print("After removing element:", my_list)

# Extending list
my_list.extend([7, 8])
print("After extending:", my_list)

Tuples are Immutable - Cannot be Modified:

python
# Tuples cannot be changed after creation
my_tuple = (1, 2, 3, 4, 5)
print("Original tuple:", my_tuple)

# These operations would cause errors:


# my_tuple[0] = 10 # TypeError
# my_tuple.append(6) # AttributeError
# my_tuple.remove(2) # AttributeError

# To "modify" a tuple, you must create a new one


new_tuple = my_tuple + (6, 7)
print("New tuple with additional elements:", new_tuple)

# Converting tuple to list for modifications


temp_list = list(my_tuple)
temp_list[0] = 10
modified_tuple = tuple(temp_list)
print("Modified tuple (via list conversion):", modified_tuple)

Impact on Program Design:

1. Memory Efficiency: Tuples use less memory than lists


2. Performance: Tuples are faster for iteration and access

3. Data Integrity: Tuples prevent accidental modifications


4. Dictionary Keys: Only immutable types (like tuples) can be dictionary keys

5. Function Returns: Tuples are ideal for returning multiple values

Question 9: Operator Demonstration Script

python
def demonstrate_operators():
print("=== PYTHON OPERATORS DEMONSTRATION ===")

# Get input from user


try:
num1 = int(input("Enter first integer: "))
num2 = int(input("Enter second integer: "))

print(f"\nDemonstrating operators with {num1} and {num2}")


print("=" * 60)

# 1. ARITHMETIC OPERATORS
print("\n1. ARITHMETIC OPERATORS:")
print(f" Addition: {num1} + {num2} = {num1 + num2}")
print(f" Subtraction: {num1} - {num2} = {num1 - num2}")
print(f" Multiplication: {num1} * {num2} = {num1 * num2}")

if num2 != 0:
print(f" Division: {num1} / {num2} = {num1 / num2}")
print(f" Floor Division: {num1} // {num2} = {num1 // num2}")
print(f" Modulus: {num1} % {num2} = {num1 % num2}")
else:
print(" Division operations skipped (division by zero)")

print(f" Exponentiation: {num1} ** {num2} = {num1 ** num2}")

# 2. COMPARISON OPERATORS
print("\n2. COMPARISON OPERATORS:")
print(f" Equal to: {num1} == {num2} → {num1 == num2}")
print(f" Not equal to: {num1} != {num2} → {num1 != num2}")
print(f" Greater than: {num1} > {num2} → {num1 > num2}")
print(f" Less than: {num1} < {num2} → {num1 < num2}")
print(f" Greater than or equal: {num1} >= {num2} → {num1 >= num2}")
print(f" Less than or equal: {num1} <= {num2} → {num1 <= num2}")

# 3. LOGICAL OPERATORS
print("\n3. LOGICAL OPERATORS:")
bool1 = bool(num1) # Convert to boolean
bool2 = bool(num2)
print(f" bool({num1}) = {bool1}")
print(f" bool({num2}) = {bool2}")
print(f" AND: {bool1} and {bool2} = {bool1 and bool2}")
print(f" OR: {bool1} or {bool2} = {bool1 or bool2}")
print(f" NOT: not {bool1} = {not bool1}")
print(f" NOT: not {bool2} = {not bool2}")
# 4. ASSIGNMENT OPERATORS
print("\n4. ASSIGNMENT OPERATORS:")
result = num1
print(f" result = {num1} → result = {result}")

result += num2
print(f" result += {num2} → result = {result}")

result -= num2
print(f" result -= {num2} → result = {result}")

result *= num2
print(f" result *= {num2} → result = {result}")

if num2 != 0:
result //= num2
print(f" result //= {num2} → result = {result}")

result **= 2
print(f" result **= 2 → result = {result}")

except ValueError:
print("❌ Please enter valid integers only!")
except Exception as e:
print(f"❌ An error occurred: {e}")

# Run the demonstration


if __name__ == "__main__":
demonstrate_operators()

Question 10: Banking Software System

python
class BankingSystem:
def __init__(self):
self.accounts = {}
self.current_account = None

def display_menu(self):
print("\n" + "="*40)
print(" BANKING SOFTWARE SYSTEM")
print("="*40)
print("1. Create Account")
print("2. Login to Account")
print("3. Deposit Funds")
print("4. Withdraw Cash")
print("5. View Balance")
print("6. Account Statement")
print("7. Logout")
print("8. Exit System")
print("="*40)

def create_account(self):
print("\n--- CREATE NEW ACCOUNT ---")
account_no = input("Enter account number: ")

if account_no in self.accounts:
print("❌ Account already exists!")
return

name = input("Enter account holder name: ")


initial_deposit = float(input("Enter initial deposit (minimum ₹500): "))

if initial_deposit < 500:


print("❌ Minimum initial deposit is ₹500!")
return

self.accounts[account_no] = {
'name': name,
'balance': initial_deposit,
'transactions': [f"Account created with initial deposit: ₹{initial_deposit}"]
}

print(f"✅ Account created successfully!")


print(f"Account Number: {account_no}")
print(f"Account Holder: {name}")
print(f"Initial Balance: ₹{initial_deposit}")

def login(self):
print("\n--- LOGIN TO ACCOUNT ---")
account_no = input("Enter account number: ")

if account_no not in self.accounts:


print("❌ Account not found!")
return False

name = input("Enter account holder name: ")


if name.lower() != self.accounts[account_no]['name'].lower():
print("❌ Invalid account holder name!")
return False

self.current_account = account_no
print(f"✅ Login successful! Welcome, {self.accounts[account_no]['name']}")
return True

def deposit(self):
if not self.current_account:
print("❌ Please login first!")
return

print("\n--- DEPOSIT FUNDS ---")


try:
amount = float(input("Enter deposit amount: ₹"))

if amount <= 0:
print("❌ Please enter a valid amount!")
return

self.accounts[self.current_account]['balance'] += amount
self.accounts[self.current_account]['transactions'].append(
f"Deposited: ₹{amount}"
)

print(f"✅ ₹{amount} deposited successfully!")


print(f"Current Balance: ₹{self.accounts[self.current_account]['balance']}")

except ValueError:
print("❌ Please enter a valid numeric amount!")

def withdraw(self):
if not self.current_account:
print("❌ Please login first!")
return

print("\n--- WITHDRAW CASH ---")


try:
amount = float(input("Enter withdrawal amount: ₹"))

if amount <= 0:
print("❌ Please enter a valid amount!")
return

current_balance = self.accounts[self.current_account]['balance']

if amount > current_balance:


print("❌ Insufficient funds!")
print(f"Available Balance: ₹{current_balance}")
return

if current_balance - amount < 500: # Minimum balance check


print("❌ Minimum balance of ₹500 must be maintained!")
return

self.accounts[self.current_account]['balance'] -= amount
self.accounts[self.current_account]['transactions'].append(
f"Withdrawn: ₹{amount}"
)

print(f"✅ ₹{amount} withdrawn successfully!")


print(f"Remaining Balance: ₹{self.accounts[self.current_account]['balance']}")

except ValueError:
print("❌ Please enter a valid numeric amount!")

def view_balance(self):
if not self.current_account:
print("❌ Please login first!")
return

account = self.accounts[self.current_account]
print(f"\n--- ACCOUNT BALANCE ---")
print(f"Account Number: {self.current_account}")
print(f"Account Holder: {account['name']}")
print(f"Current Balance: ₹{account['balance']}")

def account_statement(self):
if not self.current_account:
print("❌ Please login first!")
return

account = self.accounts[self.current_account]
print(f"\n--- ACCOUNT STATEMENT ---")
print(f"Account Number: {self.current_account}")
print(f"Account Holder: {account['name']}")
print(f"Current Balance: ₹{account['balance']}")
print("\nTransaction History:")
print("-" * 30)

for i, transaction in enumerate(account['transactions'], 1):


print(f"{i}. {transaction}")

def logout(self):
if self.current_account:
print(f"✅ Logged out successfully from account {self.current_account}")
self.current_account = None
else:
print("❌ No user currently logged in!")

def run(self):
print("Welcome to Banking Software System!")

while True:
self.display_menu()

try:
choice = int(input("Enter your choice (1-8): "))

if choice == 1:
self.create_account()
elif choice == 2:
self.login()
elif choice == 3:
self.deposit()
elif choice == 4:
self.withdraw()
elif choice == 5:
self.view_balance()
elif choice == 6:
self.account_statement()
elif choice == 7:
self.logout()
elif choice == 8:
print("Thank you for using Banking Software System!")
break
else:
print("❌ Invalid choice! Please select 1-8")

except ValueError:
print("❌ Please enter a valid number!")
except KeyboardInterrupt:
print("\n\nSystem interrupted. Goodbye!")
break

# Run the banking system


if __name__ == "__main__":
bank = BankingSystem()
bank.run()

Question 11: Set Theory Operations


Set Theory Operations in Python:

Union (|): All elements from both sets


Intersection (&): Common elements only
Difference (-): Elements in first set but not in second

Symmetric Difference (^): Elements in either set but not in both


Subset: All elements of one set exist in another

Superset: Contains all elements of another set


Disjoint: No common elements

python
def set_theory_operations():
print("=== SET THEORY OPERATIONS ===")

# Input two sets


print("Enter elements for Set A (space-separated):")
set_a_input = input().split()
set_a = set(map(int, set_a_input))

print("Enter elements for Set B (space-separated):")


set_b_input = input().split()
set_b = set(map(int, set_b_input))

print(f"\nSet A: {sorted(set_a)}")
print(f"Set B: {sorted(set_b)}")
print("="*50)

# Basic Set Operations


print("\n🔸 BASIC SET OPERATIONS:")
print(f"Union (A ∪ B): {sorted(set_a.union(set_b))}")
print(f"Intersection (A ∩ B): {sorted(set_a.intersection(set_b))}")
print(f"Difference (A - B): {sorted(set_a.difference(set_b))}")
print(f"Difference (B - A): {sorted(set_b.difference(set_a))}")
print(f"Symmetric Difference (A ⊕ B): {sorted(set_a.symmetric_difference(set_b))}")

# Relationship Tests
print("\n🔸 SET RELATIONSHIPS:")

# Subset test
if set_a.issubset(set_b):
print("✅ Set A is a SUBSET of Set B (A ⊆ B)")
elif set_b.issubset(set_a):
print("✅ Set B is a SUBSET of Set A (B ⊆ A)")
else:
print("❌ Neither set is a subset of the other")

# Superset test
if set_a.issuperset(set_b):
print("✅ Set A is a SUPERSET of Set B (A ⊇ B)")
elif set_b.issuperset(set_a):
print("✅ Set B is a SUPERSET of Set A (B ⊇ A)")
else:
print("❌ Neither set is a superset of the other")

# Disjoint test
if set_a.isdisjoint(set_b):
print("✅ Sets A and B are DISJOINT (A ∩ B = ∅)")
else:
print("❌ Sets A and B are NOT disjoint (they share common elements)")

# Additional Information
print(f"\n🔸 ADDITIONAL INFORMATION:")
print(f"Size of Set A: {len(set_a)}")
print(f"Size of Set B: {len(set_b)}")
print(f"Size of Union: {len(set_a.union(set_b))}")
print(f"Size of Intersection: {len(set_a.intersection(set_b))}")

# Equal sets check


if set_a == set_b:
print("✅ Sets A and B are EQUAL")
else:
print("❌ Sets A and B are NOT equal")

# Run the program


if __name__ == "__main__":
set_theory_operations()

Question 12: List Element Analysis

python
def analyze_integer_list():
print("=== INTEGER LIST ANALYSIS ===")

try:
# Get input from user
print("Enter integers separated by spaces:")
numbers_input = input().split()
numbers = [int(x) for x in numbers_input]

if not numbers:
print("❌ Empty list provided!")
return

print(f"Original List: {numbers}")


print("="*50)

# Find highest element


highest = max(numbers)
print(f"🥇 Highest Element: {highest}")

# Find second highest element


unique_numbers = list(set(numbers))
unique_numbers.sort(reverse=True)

if len(unique_numbers) >= 2:
second_highest = unique_numbers[1]
print(f"🥈 Second Highest Element: {second_highest}")
else:
print("🥈 Second Highest Element: Only one unique value exists")

# Find smallest element


smallest = min(numbers)
print(f"🏆 Smallest Element: {smallest}")

# Find top N largest elements


try:
n = int(input(f"\nEnter N for top N largest elements (max {len(unique_numbers)}): "))
if n > 0 and n <= len(unique_numbers):
top_n = unique_numbers[:n]
print(f"🔝 Top {n} Largest Elements: {top_n}")
else:
print(f"❌ N should be between 1 and {len(unique_numbers)}")
except ValueError:
print("❌ Invalid input for N")

# Additional statistics
print(f"\n📊 ADDITIONAL STATISTICS:")
print(f"Total elements: {len(numbers)}")
print(f"Unique elements: {len(unique_numbers)}")
print(f"Sum of all elements: {sum(numbers)}")
print(f"Average: {sum(numbers)/len(numbers):.2f}")

except ValueError:
print("❌ Please enter valid integers only!")
except Exception as e:
print(f"❌ An error occurred: {e}")

# Run the analysis


if __name__ == "__main__":
analyze_integer_list()

Question 13: Python vs Java/C++ Comparison


How Python's Simplicity and Flexibility Differ from Java/C++:

Python prioritizes developer productivity and code readability over execution speed, making it
fundamentally different from statically-typed, compiled languages like Java and C++.

Five Key Differences with Examples:

1. Syntax Simplicity

python

# Python - Simple and readable


def greet(name):
print(f"Hello, {name}!")

greet("World")

java
// Java - More verbose
public class HelloWorld {
public static void main(String[] args) {
greet("World");
}

public static void greet(String name) {


System.out.println("Hello, " + name + "!");
}
}

2. Dynamic Typing vs Static Typing

python

# Python - Dynamic typing


x = 10 # Integer
x = "Hello" # Now string
x = [1, 2, 3] # Now list

java

// Java - Static typing


int x = 10; // Must declare type
String y = "Hello"; // Different variable needed
ArrayList<Integer> z = new ArrayList<>(); // Complex declaration

3. Memory Management

python

# Python - Automatic garbage collection


my_list = [1, 2, 3, 4, 5]
# Memory automatically managed

cpp

// C++ - Manual memory management


int* array = new int[5]{1, 2, 3, 4, 5};
// Must remember to: delete[] array;

4. Interpreted vs Compiled

python
# Python - Run directly
print("Hello World") # Execute immediately with python script.py

cpp

// C++ - Compilation required


#include <iostream>
int main() {
std::cout << "Hello World" << std::endl;
return 0;
}
// Must compile first: g++ -o program program.cpp, then ./program

5. Built-in Data Structures

python

# Python - Rich built-in types


my_dict = {"name": "John", "age": 25}
my_list = [1, 2, 3]
my_set = {1, 2, 3}

java

// Java - Import required for advanced structures


import java.util.HashMap;
import java.util.ArrayList;
import java.util.HashSet;

HashMap<String, Integer> map = new HashMap<>();


ArrayList<Integer> list = new ArrayList<>();
HashSet<Integer> set = new HashSet<>();

Question 14: Strings vs Lists Mutability


Immutable Strings vs Mutable Lists:

python
def demonstrate_mutability():
print("=== IMMUTABLE STRINGS vs MUTABLE LISTS ===")

# STRING OPERATIONS (Immutable)


print("\n🔸 STRING OPERATIONS (IMMUTABLE):")
original_string = "Hello"
print(f"Original string: '{original_string}'")
print(f"String ID: {id(original_string)}")

# Attempting to "modify" string


modified_string = original_string + " World"
print(f"After concatenation: '{modified_string}'")
print(f"New string ID: {id(modified_string)}")
print(f"Original unchanged: '{original_string}'")

# String methods create new strings


upper_string = original_string.upper()
print(f"Upper case: '{upper_string}'")
print(f"Upper string ID: {id(upper_string)}")

replaced_string = original_string.replace('l', 'x')


print(f"After replace: '{replaced_string}'")
print(f"Original still: '{original_string}'")

# Demonstrating string immutability


print("\n❌ These operations would cause errors:")
print("# original_string[0] = 'h' # TypeError: 'str' object does not support item assignment")
print("# original_string.append('!') # AttributeError: 'str' object has no attribute 'append'")

# LIST OPERATIONS (Mutable)


print("\n🔸 LIST OPERATIONS (MUTABLE):")
original_list = [1, 2, 3, 4, 5]
print(f"Original list: {original_list}")
print(f"List ID: {id(original_list)}")

# Modifying list in-place


original_list[0] = 10
print(f"After modifying index 0: {original_list}")
print(f"Same list ID: {id(original_list)}")

# Adding elements
original_list.append(6)
print(f"After appending: {original_list}")
print(f"Same list ID: {id(original_list)}")

# Removing elements
original_list.remove(2)
print(f"After removing 2: {original_list}")
print(f"Same list ID: {id(original_list)}")

# Extending list
original_list.extend([7, 8])
print(f"After extending: {original_list}")
print(f"Same list ID: {id(original_list)}")

# List slicing creates new list


sliced_list = original_list[2:5]
print(f"Sliced list: {sliced_list}")
print(f"Sliced list ID: {id(sliced_list)}")

# PERFORMANCE COMPARISON
print("\n🔸 PERFORMANCE IMPLICATIONS:")

# String concatenation (inefficient for large operations)


result_string = ""
for i in range(5):
result_string += str(i) # Creates new string each time
print(f"String concatenation result: '{result_string}'")

# List operations (efficient)


result_list = []
for i in range(5):
result_list.append(i) # Modifies existing list
print(f"List append result: {result_list}")

# Converting between types


print(f"\nConverting list to string: '{''.join(map(str, result_list))}'")
print(f"Converting string to list: {list(result_string)}")

# Run demonstration
if __name__ == "__main__":
demonstrate_mutability()

Question 15: Comprehensive Operator Evaluation

python
def comprehensive_operator_evaluation():
print("="*60)
print(" COMPREHENSIVE PYTHON OPERATOR EVALUATION")
print("="*60)

try:
# Get user input
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

print(f"\nEvaluating all operators with {num1} and {num2}")


print("="*60)

# 1. ARITHMETIC OPERATORS
print("\n🔹 1. ARITHMETIC OPERATORS")
print("-" * 30)
print(f"{'Operation':<20} {'Expression':<15} {'Result'}")
print("-" * 30)
print(f"{'Addition':<20} {f'{num1} + {num2}':<15} {num1 + num2}")
print(f"{'Subtraction':<20} {f'{num1} - {num2}':<15} {num1 - num2}")
print(f"{'Multiplication':<20} {f'{num1} * {num2}':<15} {num1 * num2}")

if num2 != 0:
print(f"{'Division':<20} {f'{num1} / {num2}':<15} {num1 / num2:.4f}")
print(f"{'Floor Division':<20} {f'{num1} // {num2}':<15} {num1 // num2}")
print(f"{'Modulus':<20} {f'{num1} % {num2}':<15} {num1 % num2}")
else:
print(f"{'Division':<20} {'N/A (÷0)':<15} {'Undefined'}")

print(f"{'Exponentiation':<20} {f'{num1} ** {num2}':<15} {num1 ** num2}")

# 2. RELATIONAL/COMPARISON OPERATORS
print("\n🔹 2. RELATIONAL/COMPARISON OPERATORS")
print("-" * 40)
print(f"{'Operation':<25} {'Expression':<10} {'Result'}")
print("-" * 40)
print(f"{'Equal to':<25} {f'{num1} == {num2}':<10} {num1 == num2}")
print(f"{'Not equal to':<25} {f'{num1} != {num2}':<10} {num1 != num2}")
print(f"{'Greater than':<25} {f'{num1} > {num2}':<10} {num1 > num2}")
print(f"{'Less than':<25} {f'{num1} < {num2}':<10} {num1 < num2}")
print(f"{'Greater than or equal':<25} {f'{num1} >= {num2}':<10} {num1 >= num2}")
print(f"{'Less than or equal':<25} {f'{num1} <= {num2}':<10} {num1 <= num2}")

# 3. LOGICAL OPERATORS
print("\n🔹 3. LOGICAL OPERATORS")
print("-" * 40)
bool1, bool2 = bool(num1), bool(num2)
print(f"{'Boolean Values:':<25} num1={bool1}, num2={bool2}")
print(f"{'Logical AND':<25} {f'{bool1} and {bool2}':<10} {bool1 and bool2}")
print(f"{'Logical OR':<25} {f'{bool1} or {bool2}':<10} {bool1 or bool2}")
print(f"{'Logical NOT (num1)':<25} {f'not {bool1}':<10} {not bool1}")
print(f"{'Logical NOT (num2)':<25} {f'not {bool2}':<10} {not bool2}")

# 4. BITWISE OPERATORS (on integer parts)


print("\n🔹 4. BITWISE OPERATORS")
print("-" * 45)
int1, int2 = int(num1), int(num2)
print(f"Integer values: {int1}, {int2}")
print(f"Binary: {bin(int1)}, {bin(int2)}")
print("-" * 45)
print(f"{'Operation':<20} {'Expression':<15} {'Result':<10} {'Binary'}")
print("-" * 45)
print(f"{'Bitwise AND':<20} {f'{int1} & {int2}':<15} {int1 & int2:<10} {bin(int1 & int2)}")
print(f"{'Bitwise OR':<20} {f'{int1} | {int2}':<15} {int1 | int2:<10} {bin(int1 | int2)}")
print(f"{'Bitwise XOR':<20} {f'{int1} ^ {int2}':<15} {int1 ^ int2:<10} {bin(int1 ^ int2)}")
print(f"{'Bitwise NOT (num1)':<20} {f'~{int1}':<15} {~int1:<10} {bin(~int1 & 0xFFFFFFFF)}")
print(f"{'Left Shift (<<2)':<20} {f'{int1} << 2':<15} {int1 << 2:<10} {bin(int1 << 2)}")
print(f"{'Right Shift (>>2)':<20} {f'{int1} >> 2':<15} {int1 >> 2:<10} {bin(int1 >> 2)}")

# 5. ASSIGNMENT OPERATORS
print("\n🔹 5. ASSIGNMENT OPERATORS")
print("-" * 40)
print("Demonstrating with a variable 'x' starting with num1:")

x = num1
print(f"{'Simple Assignment':<25} x = {num1:<10} → x = {x}")

x += num2
print(f"{'Addition Assignment':<25} x += {num2:<9} → x = {x}")

x -= num2
print(f"{'Subtraction Assignment':<25} x -= {num2:<9} → x = {x}")

x *= num2
print(f"{'Multiplication Assignment':<25} x *= {num2:<9} → x = {x}")

if num2 != 0:
x /= num2
print(f"{'Division Assignment':<25} x /= {num2:<9} → x = {x:.4f}")

x //= 2
print(f"{'Floor Division Assignment':<25} x //= 2{'':<8} → x = {x}")
x %= 3
print(f"{'Modulus Assignment':<25} x %= 3{'':<8} → x = {x}")

x **= 2
print(f"{'Exponent Assignment':<25} x **= 2{'':<8} → x = {x}")

# 6. MEMBERSHIP OPERATORS (with strings)


print("\n🔹 6. MEMBERSHIP OPERATORS")
print("-" * 35)
str_num1 = str(int(num1))
test_string = f"Numbers: {int(num1)}, {int(num2)}"
print(f"Test string: '{test_string}'")
print(f"'{str_num1}' in test_string: {str_num1 in test_string}")
print(f"'{str_num1}' not in test_string: {str_num1 not in test_string}")

# 7. IDENTITY OPERATORS
print("\n🔹 7. IDENTITY OPERATORS")
print("-" * 30)
a, b = num1, num1
c = num2
print(f"a = {a}, b = {b}, c = {c}")
print(f"a is b: {a is b}")
print(f"a is c: {a is c}")
print(f"a is not c: {a is not c}")

# 8. OPERATOR PRECEDENCE EXAMPLE


print("\n🔹 8. OPERATOR PRECEDENCE EXAMPLE")
print("-" * 40)
complex_expr = num1 + num2 * 2 - num1 / 2
print(f"Expression: {num1} + {num2} * 2 - {num1} / 2")
print(f"Result (left to right): {complex_expr}")
print("Order: Multiplication/Division first, then Addition/Subtraction")

except ValueError:
print("❌ Error: Please enter valid numeric values!")
except Exception as e:
print(f"❌ An unexpected error occurred: {e}")

# Run the comprehensive evaluation


if __name__ == "__main__":
comprehensive_operator_evaluation()

Question 16: Fundamental Data Types in Python


Python supports several fundamental data types:
python
def demonstrate_data_types():
print("=== FUNDAMENTAL DATA TYPES IN PYTHON ===")
print()

# 1. NUMERIC TYPES
print("🔸 1. NUMERIC TYPES")
print("-" * 30)

# Integer
integer_var = 42
print(f"Integer: {integer_var} (type: {type(integer_var).__name__})")

# Float
float_var = 3.14159
print(f"Float: {float_var} (type: {type(float_var).__name__})")

# Complex
complex_var = 3 + 4j
print(f"Complex: {complex_var} (type: {type(complex_var).__name__})")

# 2. SEQUENCE TYPES
print(f"\n🔸 2. SEQUENCE TYPES")
print("-" * 30)

# String
string_var = "Hello, Python!"
print(f"String: '{string_var}' (type: {type(string_var).__name__})")

# List
list_var = [1, 2, 3, "mixed", True]
print(f"List: {list_var} (type: {type(list_var).__name__})")

# Tuple
tuple_var = (10, 20, 30, "immutable")
print(f"Tuple: {tuple_var} (type: {type(tuple_var).__name__})")

# 3. MAPPING TYPE
print(f"\n🔸 3. MAPPING TYPE")
print("-" * 30)

# Dictionary
dict_var = {"name": "Alice", "age": 30, "city": "New York"}
print(f"Dictionary: {dict_var} (type: {type(dict_var).__name__})")

# 4. SET TYPES
print(f"\n🔸 4. SET TYPES")
print("-" * 30)

# Set
set_var = {1, 2, 3, 4, 5}
print(f"Set: {set_var} (type: {type(set_var).__name__})")

# Frozenset
frozenset_var = frozenset([1, 2, 3, 4])
print(f"Frozenset: {frozenset_var} (type: {type(frozenset_var).__name__})")

# 5. BOOLEAN TYPE
print(f"\n🔸 5. BOOLEAN TYPE")
print("-" * 30)

# Boolean
bool_var_true = True
bool_var_false = False
print(f"Boolean True: {bool_var_true} (type: {type(bool_var_true).__name__})")
print(f"Boolean False: {bool_var_false} (type: {type(bool_var_false).__name__})")

# 6. NONE TYPE
print(f"\n🔸 6. NONE TYPE")
print("-" * 30)

# NoneType
none_var = None
print(f"None: {none_var} (type: {type(none_var).__name__})")

# PRACTICAL EXAMPLES IN ACTION


print(f"\n🔸 PRACTICAL EXAMPLES")
print("-" * 30)

# String operations
print(f"String length: {len(string_var)}")
print(f"String uppercase: {string_var.upper()}")

# List operations
list_var.append("new_item")
print(f"List after append: {list_var}")

# Dictionary operations
dict_var["occupation"] = "Engineer"
print(f"Dictionary after adding key: {dict_var}")

# Set operations
set_var.add(6)
print(f"Set after adding element: {set_var}")
# Type checking
print(f"\nType checking examples:")
print(f"isinstance(42, int): {isinstance(42, int)}")
print(f"isinstance(3.14, float): {isinstance(3.14, float)}")
print(f"isinstance([1,2,3], list): {isinstance([1,2,3], list)}")

# Run the demonstration


if __name__ == "__main__":
demonstrate_data_types()

Question 17: Quadratic Equation Solver

python
import math

def solve_quadratic():
print("=== QUADRATIC EQUATION SOLVER ===")
print("Solves equations of the form: ax² + bx + c = 0")
print("="*50)

try:
# Input coefficients
a = float(input("Enter coefficient a: "))
b = float(input("Enter coefficient b: "))
c = float(input("Enter coefficient c: "))

print(f"\nSolving: {a}x² + {b}x + {c} = 0")

# Check if it's actually a quadratic equation


if a == 0:
if b == 0:
if c == 0:
print("✅ All coefficients are zero - infinite solutions!")
else:
print("❌ No solution exists (0 = non-zero constant)")
else:
# Linear equation: bx + c = 0
root = -c / b
print(f"✅ This is a linear equation.")
print(f"✅ Solution: x = {root}")
return

# Calculate discriminant
discriminant = b**2 - 4*a*c
print(f"\nDiscriminant (Δ) = b² - 4ac = {b}² - 4({a})({c}) = {discriminant}")

# Determine nature of roots


if discriminant > 0:
print("✅ Discriminant > 0: Two distinct real roots")

root1 = (-b + math.sqrt(discriminant)) / (2*a)


root2 = (-b - math.sqrt(discriminant)) / (2*a)

print(f"\nRoot 1 = (-{b} + √{discriminant}) / (2×{a}) = {root1:.4f}")


print(f"Root 2 = (-{b} - √{discriminant}) / (2×{a}) = {root2:.4f}")

# Verification
print(f"\nVerification:")
verify1 = a * root1**2 + b * root1 + c
verify2 = a * root2**2 + b * root2 + c
print(f"For root1: {a}×({root1:.4f})² + {b}×({root1:.4f}) + {c} = {verify1:.6f}")
print(f"For root2: {a}×({root2:.4f})² + {b}×({root2:.4f}) + {c} = {verify2:.6f}")

elif discriminant == 0:
print("✅ Discriminant = 0: One repeated real root")

root = -b / (2*a)
print(f"\nRepeated Root = -{b} / (2×{a}) = {root:.4f}")

# Verification
print(f"\nVerification:")
verify = a * root**2 + b * root + c
print(f"{a}×({root:.4f})² + {b}×({root:.4f}) + {c} = {verify:.6f}")

else: # discriminant < 0


print("✅ Discriminant < 0: Two complex conjugate roots")

real_part = -b / (2*a)
imaginary_part = math.sqrt(abs(discriminant)) / (2*a)

print(f"\nReal part = -{b} / (2×{a}) = {real_part:.4f}")


print(f"Imaginary part = ±√{abs(discriminant)} / (2×{a}) = ±{imaginary_part:.4f}")

print(f"\nRoot 1 = {real_part:.4f} + {imaginary_part:.4f}i")


print(f"Root 2 = {real_part:.4f} - {imaginary_part:.4f}i")

# Additional information
print(f"\n📊 ADDITIONAL INFORMATION:")
print(f"Vertex x-coordinate: {-b/(2*a):.4f}")
print(f"Vertex y-coordinate: {a*(-b/(2*a))**2 + b*(-b/(2*a)) + c:.4f}")

if a > 0:
print("Parabola opens upward (minimum point)")
else:
print("Parabola opens downward (maximum point)")

except ValueError:
print("❌ Error: Please enter valid numeric values for coefficients!")
except Exception as e:
print(f"❌ An unexpected error occurred: {e}")

# Alternative implementation with error handling


def robust_quadratic_solver():
"""Enhanced version with comprehensive error handling"""

while True:
try:
print("\n" + "="*50)
print(" ROBUST QUADRATIC EQUATION SOLVER")
print("="*50)

# Input validation loop


while True:
try:
a = float(input("Enter coefficient a (non-zero for quadratic): "))
b = float(input("Enter coefficient b: "))
c = float(input("Enter coefficient c: "))
break
except ValueError:
print("❌ Please enter valid numbers!")

# Solve equation
result = solve_quadratic_equation(a, b, c)
print(result)

# Ask if user wants to continue


continue_choice = input("\nSolve another equation? (y/n): ").lower()
if continue_choice not in ['y', 'yes']:
break

except KeyboardInterrupt:
print("\n\nProgram interrupted. Goodbye!")
break

def solve_quadratic_equation(a, b, c):


"""Core function to solve quadratic equation"""

result = []
result.append(f"Equation: {a}x² + {b}x + {c} = 0")

if a == 0:
if b == 0:
if c == 0:
return "\n".join(result + ["✅ Identity: 0 = 0 (infinite solutions)"])
else:
return "\n".join(result + [f"❌ Contradiction: 0 = {c} (no solution)"])
else:
root = -c / b
return "\n".join(result + [
"✅ Linear equation (a = 0)",
f"Solution: x = {root:.4f}"
])
discriminant = b**2 - 4*a*c
result.append(f"Discriminant = {discriminant}")

if discriminant > 0:
root1 = (-b + math.sqrt(discriminant)) / (2*a)
root2 = (-b - math.sqrt(discriminant)) / (2*a)
result.extend([
"✅ Two distinct real roots:",
f"Root 1 = {root1:.6f}",
f"Root 2 = {root2:.6f}"
])
elif discriminant == 0:
root = -b / (2*a)
result.extend([
"✅ One repeated real root:",
f"Root = {root:.6f}"
])
else:
real = -b / (2*a)
imag = math.sqrt(abs(discriminant)) / (2*a)
result.extend([
"✅ Two complex conjugate roots:",
f"Root 1 = {real:.6f} + {imag:.6f}i",
f"Root 2 = {real:.6f} - {imag:.6f}i"
])

return "\n".join(result)

# Run the solver


if __name__ == "__main__":
choice = input("Choose solver: (1) Simple (2) Robust: ")
if choice == "2":
robust_quadratic_solver()
else:
solve_quadratic()

Question 18: HCF and LCM Calculator

python
def find_hcf_lcm():
print("=== HCF AND LCM CALCULATOR ===")
print("Using Loop Constructs")
print("="*40)

try:
# Input two numbers
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))

if num1 <= 0 or num2 <= 0:


print("❌ Please enter positive integers only!")
return

print(f"\nCalculating HCF and LCM of {num1} and {num2}")


print("="*50)

# Store original values


original_num1, original_num2 = num1, num2

# Method 1: HCF using Euclidean Algorithm


print("🔸 METHOD 1: EUCLIDEAN ALGORITHM FOR HCF")
print("-" * 45)

temp_num1, temp_num2 = num1, num2


step = 1

print("Steps:")
while temp_num2 != 0:
remainder = temp_num1 % temp_num2
print(f"Step {step}: {temp_num1} = {temp_num2} × {temp_num1 // temp_num2} + {remainder}")
temp_num1, temp_num2 = temp_num2, remainder
step += 1

hcf_euclidean = temp_num1
print(f"✅ HCF using Euclidean Algorithm: {hcf_euclidean}")

# Method 2: HCF using Simple Division (Alternative approach)


print(f"\n🔸 METHOD 2: SIMPLE DIVISION METHOD FOR HCF")
print("-" * 45)

smaller = min

You might also like