Slide 1: Boolean Fundamentals
Python's boolean type represents binary states True and False, forming the foundation of logical operations and control flow. Booleans enable comparison operations, conditional statements, and serve as flags for program state management.
# Basic boolean operations and comparisons
x, y = True, False
# Logical operators
print(f"AND operation: {x and y}") # False
print(f"OR operation: {x or y}") # True
print(f"NOT operation: {not x}") # False
# Comparison operations producing booleans
num1, num2 = 10, 20
is_greater = num1 > num2
is_equal = num1 == num2
print(f"10 > 20: {is_greater}") # False
print(f"10 == 20: {is_equal}") # FalseSlide 2: Advanced Boolean Logic
Boolean algebra in Python extends beyond simple comparisons, allowing complex logical expressions through compound statements and bitwise operations, essential for data validation and control structures.
# Complex boolean expressions and short-circuit evaluation
def is_valid_user(age, verified, permissions):
return (age >= 18 and verified) or permissions.get('admin', False)
# Example usage
user_data = {'age': 25, 'verified': True}
admin_permissions = {'admin': True}
regular_permissions = {'user': True}
# Evaluating different scenarios
print(f"Valid adult user: {is_valid_user(25, True, regular_permissions)}") # True
print(f"Valid admin: {is_valid_user(16, False, admin_permissions)}") # True
print(f"Invalid user: {is_valid_user(16, False, regular_permissions)}") # False
# Bitwise operations with booleans
a, b = True, False
print(f"Bitwise AND: {a & b}") # False
print(f"Bitwise OR: {a | b}") # True
print(f"Bitwise XOR: {a ^ b}") # TrueSlide 3: Integer Operations and Properties
Integers in Python are unbounded, allowing arbitrary-precision arithmetic without overflow concerns. They support a rich set of mathematical operations and serve as the foundation for numerical computations.
# Demonstrating integer operations and properties
# Basic arithmetic
a, b = 1234567890, 987654321
result = a * b
print(f"Large multiplication: {result}")
# Integer division and modulo
x, y = 17, 5
print(f"Integer division: {x // y}") # 3
print(f"Modulo: {x % y}") # 2
print(f"Divmod: {divmod(x, y)}") # (3, 2)
# Bit manipulation
num = 42
print(f"Binary representation: {bin(num)}") # 0b101010
print(f"Left shift by 2: {num << 2}") # 168
print(f"Right shift by 1: {num >> 1}") # 21
print(f"Bitwise complement: {~num}") # -43Slide 4: Advanced Integer Applications
# Advanced integer operations for cryptography and optimization
def prime_factors(n):
factors = []
d = 2
while n > 1:
while n % d == 0:
factors.append(d)
n //= d
d += 1
if d * d > n:
if n > 1:
factors.append(n)
break
return factors
# Binary exponentiation for efficient power calculation
def fast_power(base, exponent, modulus=None):
result = 1
while exponent > 0:
if exponent & 1:
result = result * base if modulus is None else (result * base) % modulus
base = base * base if modulus is None else (base * base) % modulus
exponent >>= 1
return result
# Example usage
number = 84
print(f"Prime factors of {number}: {prime_factors(number)}")
print(f"2^10 = {fast_power(2, 10)}")
print(f"2^10 mod 1000 = {fast_power(2, 10, 1000)}")Slide 5: Float Precision and Mathematics
Floating-point numbers in Python follow IEEE-754 double-precision standard, providing approximately 15-17 decimal digits of precision. Understanding their behavior is crucial for scientific computing.
import math
import decimal
from decimal import Decimal
# Demonstrating float precision and limitations
a = 0.1 + 0.2
b = 0.3
print(f"0.1 + 0.2 == 0.3: {a == b}") # False
print(f"Actual value of 0.1 + 0.2: {a}")
# Using decimal for precise calculations
decimal.getcontext().prec = 28
d1 = Decimal('0.1')
d2 = Decimal('0.2')
d3 = d1 + d2
print(f"Precise decimal calculation: {d3}")
# Mathematical operations
x = 3.14159
print(f"Floor: {math.floor(x)}")
print(f"Ceil: {math.ceil(x)}")
print(f"Round to 2 decimal places: {round(x, 2)}")Slide 6: Float Special Values and Scientific Notation
Python's float type includes special values for handling exceptional cases in scientific computing. Understanding these values and scientific notation is crucial for numerical analysis and scientific calculations.
import math
import numpy as np
# Special float values and representations
inf_pos = float('inf')
inf_neg = float('-inf')
nan = float('nan')
# Scientific notation
scientific = 1.23e-4
print(f"Scientific notation: {scientific}") # 0.000123
# Special value operations
print(f"Infinity check: {math.isinf(inf_pos)}") # True
print(f"NaN check: {math.isnan(nan)}") # True
# Float range and precision
epsilon = np.finfo(float).eps
print(f"Machine epsilon: {epsilon}")
print(f"Max float: {np.finfo(float).max}")
print(f"Min float: {np.finfo(float).min}")
# Handling division by zero
try:
result = 1.0 / 0.0
print(f"1.0/0.0 = {result}") # inf
except ZeroDivisionError as e:
print(f"Error: {e}")Slide 7: Type Conversion and Numeric Systems
Understanding type conversion between numeric types is essential for precise calculations and data processing. Python provides built-in functions for seamless conversion between different number representations.
# Type conversion examples
integer_num = 42
float_num = 3.14159
bool_val = True
# Basic type conversions
print(f"Integer to float: {float(integer_num)}")
print(f"Float to integer: {int(float_num)}")
print(f"Boolean to integer: {int(bool_val)}")
# Number system conversions
decimal_num = 255
print(f"Decimal to binary: {bin(decimal_num)}")
print(f"Decimal to octal: {oct(decimal_num)}")
print(f"Decimal to hex: {hex(decimal_num)}")
# String to number conversions
print(f"Binary string to int: {int('11111111', 2)}")
print(f"Hex string to int: {int('FF', 16)}")
print(f"Octal string to int: {int('377', 8)}")
# Complex number conversion
complex_num = complex(3, 4)
print(f"Complex number: {complex_num}")
print(f"Complex magnitude: {abs(complex_num)}")Slide 8: Real-world Application: Financial Calculations
Financial calculations require precise handling of decimal numbers to avoid rounding errors. This example demonstrates proper monetary calculations using the decimal module.
from decimal import Decimal, ROUND_HALF_UP
import pandas as pd
class FinancialCalculator:
def __init__(self):
self.context = decimal.getcontext()
self.context.rounding = ROUND_HALF_UP
self.context.prec = 6
def compound_interest(self, principal, rate, years):
"""Calculate compound interest with precise decimal arithmetic"""
p = Decimal(str(principal))
r = Decimal(str(rate))
t = Decimal(str(years))
# Formula: A = P(1 + r)^t
amount = p * (Decimal('1') + r) ** t
return amount.quantize(Decimal('0.01'))
def loan_payment(self, principal, rate, years):
"""Calculate monthly loan payment"""
p = Decimal(str(principal))
r = Decimal(str(rate / 12)) # Monthly rate
n = Decimal(str(years * 12)) # Number of payments
# Formula: PMT = P * (r * (1 + r)^n) / ((1 + r)^n - 1)
numerator = r * (Decimal('1') + r) ** n
denominator = (Decimal('1') + r) ** n - Decimal('1')
payment = p * (numerator / denominator)
return payment.quantize(Decimal('0.01'))
# Example usage
calc = FinancialCalculator()
investment = 10000
rate = 0.05
years = 10
result = calc.compound_interest(investment, rate, years)
monthly_payment = calc.loan_payment(investment, rate, years)
print(f"Investment of ${investment} at {rate*100}% for {years} years:")
print(f"Final amount: ${result}")
print(f"Monthly loan payment: ${monthly_payment}")Slide 9: Real-world Application: Data Analysis with Mixed Types
This implementation demonstrates handling mixed data types in a practical data analysis scenario, incorporating boolean flags, integer counts, and float measurements.
import pandas as pd
import numpy as np
from typing import Dict, List, Union
class DataAnalyzer:
def __init__(self, data: List[Dict[str, Union[bool, int, float]]]):
self.df = pd.DataFrame(data)
def analyze_numeric_columns(self) -> Dict[str, Dict[str, float]]:
numeric_cols = self.df.select_dtypes(include=[np.number]).columns
stats = {}
for col in numeric_cols:
stats[col] = {
'mean': float(self.df[col].mean()),
'std': float(self.df[col].std()),
'median': float(self.df[col].median()),
'skew': float(self.df[col].skew())
}
return stats
def boolean_analysis(self) -> Dict[str, float]:
bool_cols = self.df.select_dtypes(include=[bool]).columns
results = {}
for col in bool_cols:
true_ratio = float(self.df[col].mean())
results[col] = true_ratio
return results
# Example usage
data = [
{'id': i,
'value': np.random.normal(100, 15),
'is_valid': np.random.random() > 0.1,
'count': np.random.randint(1, 100)}
for i in range(1000)
]
analyzer = DataAnalyzer(data)
numeric_stats = analyzer.analyze_numeric_columns()
boolean_stats = analyzer.boolean_analysis()
print("Numeric Analysis Results:")
for col, stats in numeric_stats.items():
print(f"\n{col}:")
for metric, value in stats.items():
print(f"{metric}: {value:.2f}")
print("\nBoolean Analysis Results:")
for col, ratio in boolean_stats.items():
print(f"{col} true ratio: {ratio:.2%}")Slide 10: Mathematical Operations with Mixed Types
Understanding type coercion and mathematical operations across different numeric types is crucial for scientific computing and data analysis applications.
class NumericOperations:
@staticmethod
def mixed_type_operations():
# Integer and Float Operations
int_val = 42
float_val = 3.14159
print(f"Mixed Addition: {int_val + float_val}")
print(f"Result Type: {type(int_val + float_val)}")
# Boolean Arithmetic
bool_val = True
print(f"Bool + Int: {bool_val + int_val}")
print(f"Bool * Float: {bool_val * float_val}")
# Complex Numbers
complex_val = complex(1, 2)
print(f"Complex + Float: {complex_val + float_val}")
print(f"Complex * Int: {complex_val * int_val}")
# Mathematical Functions with Mixed Types
import math
print(f"Power (int, float): {pow(int_val, float_val)}")
print(f"Square root of float: {math.sqrt(float_val)}")
print(f"Exponential of int: {math.exp(int_val)}")
# Array Operations
import numpy as np
arr = np.array([int_val, float_val, bool_val])
print(f"Array type: {arr.dtype}")
print(f"Array operations: {arr * 2}")
# Example Usage
ops = NumericOperations()
ops.mixed_type_operations()Slide 11: Type Conversion Edge Cases
Understanding edge cases in type conversion is critical for robust programming. This implementation explores boundary conditions and potential pitfalls when converting between different numeric types.
class TypeConversionHandler:
@staticmethod
def demonstrate_edge_cases():
# Floating point to integer truncation
large_float = 1e20
try:
int_conversion = int(large_float)
print(f"Large float to int: {int_conversion}")
except OverflowError as e:
print(f"Overflow error: {e}")
# Boolean edge cases
print(f"bool('False'): {bool('False')}") # True (non-empty string)
print(f"bool(''): {bool('')}") # False (empty string)
print(f"bool(0.0): {bool(0.0)}") # False
print(f"bool(0.1): {bool(0.1)}") # True
# Float precision limits
small_float = 1e-308
too_small_float = small_float / 1e308
print(f"Very small float: {too_small_float}") # Underflow to 0.0
# Integer division edge cases
print(f"-7 // 3: {-7 // 3}") # Floor division with negative numbers
print(f"-7 % 3: {-7 % 3}") # Modulo with negative numbers
# Special float values
inf = float('inf')
nan = float('nan')
print(f"inf + 1: {inf + 1}")
print(f"inf - inf: {inf - inf}")
print(f"nan == nan: {nan == nan}") # Always False
# Example usage
handler = TypeConversionHandler()
handler.demonstrate_edge_cases()Slide 12: Advanced Real-world Application: Signal Processing
This implementation shows how different numeric types work together in a practical signal processing application, demonstrating type interactions in scientific computing.
import numpy as np
from scipy import signal
from typing import Tuple, List
class SignalProcessor:
def __init__(self, sampling_rate: float):
self.fs = sampling_rate
def generate_signal(self, duration: float) -> Tuple[np.ndarray, np.ndarray]:
"""Generate a test signal with multiple frequency components"""
t = np.linspace(0, duration, int(self.fs * duration), endpoint=False)
# Generate signal with multiple frequencies
signal_clean = (
0.5 * np.sin(2 * np.pi * 10 * t) + # 10 Hz component
0.3 * np.sin(2 * np.pi * 20 * t) + # 20 Hz component
0.2 * np.sin(2 * np.pi * 40 * t) # 40 Hz component
)
return t, signal_clean
def add_noise(self, signal: np.ndarray, snr_db: float) -> np.ndarray:
"""Add Gaussian noise to signal with specified SNR"""
signal_power = np.mean(signal ** 2)
noise_power = signal_power / (10 ** (snr_db / 10))
noise = np.random.normal(0, np.sqrt(noise_power), signal.shape)
return signal + noise
def apply_filter(self, noisy_signal: np.ndarray) -> np.ndarray:
"""Apply a bandpass filter"""
nyquist = self.fs / 2
low_cutoff = 5 / nyquist
high_cutoff = 45 / nyquist
b, a = signal.butter(4, [low_cutoff, high_cutoff], btype='band')
return signal.filtfilt(b, a, noisy_signal)
# Example usage
processor = SignalProcessor(sampling_rate=1000.0)
t, clean_signal = processor.generate_signal(duration=1.0)
noisy_signal = processor.add_noise(clean_signal, snr_db=10)
filtered_signal = processor.apply_filter(noisy_signal)
# Print signal statistics
print(f"Clean signal stats:")
print(f"Mean: {np.mean(clean_signal):.6f}")
print(f"Std: {np.std(clean_signal):.6f}")
print(f"Max: {np.max(clean_signal):.6f}")
print(f"\nNoisy signal stats:")
print(f"Mean: {np.mean(noisy_signal):.6f}")
print(f"Std: {np.std(noisy_signal):.6f}")
print(f"Max: {np.max(noisy_signal):.6f}")
print(f"\nFiltered signal stats:")
print(f"Mean: {np.mean(filtered_signal):.6f}")
print(f"Std: {np.std(filtered_signal):.6f}")
print(f"Max: {np.max(filtered_signal):.6f}")Slide 13: Additional Resources
- "Python's Data Types: Internals and Implementation" - https://arxiv.org/abs/2208.14760
- "Numerical Computing with Python: A Comprehensive Review" - https://arxiv.org/abs/2201.05935
- "Type Systems in Scientific Computing" - https://arxiv.org/abs/2105.09077
- Recommended search terms for further study:
- "Python numeric type system implementation"
- "Scientific computing with Python data types"
- "Floating-point arithmetic in numerical analysis"
- "Boolean algebra implementation in programming languages"