W6 - Shorts 📚🔍- Introduction to Python (A Transition from C)

Video 🎦 - Python

Read more here
CS50 IDE: https://cs50.dev/ (Online VSCode)
CS50 Library Documentation: https://manual.cs50.io/#cs50.h

#CS50x #C #Computer_Science #VisualStudioCode

🔙 Previous Part | Next Part 🔜

↩️ Go Back

Table of Contents:

🔙 Previous Part | Next Part 🔜

↩️ Go Back


A) Introducing Python: A Transition from C

1. Overview: Python's Popularity


2. Python Compared to C

Key Takeaway:
Python is a beginner-friendly yet powerful language that simplifies many of C's complexities while offering robust tools for modern applications. With its concise syntax and wide adoption, Python is an essential language to learn for software development, data science, and beyond.


3. Writing Python Code


4. Python Versions


5. Getting Started

To begin writing and running Python programs:

  1. Create a .py file in CS50 IDE.

  2. Open a terminal and run:

    python3 program.py
    
  3. Use the interactive Python interpreter for experimentation:

    python3
    

B) Variables in Python: A Comparison with C

1. Key Differences from C (Declaration and Initialization)

  1. No Type Declaration:

    • In Python, you don’t need to specify a type (like int, string).
    • The type is determined automatically based on the assigned value.
    • Example:
      • C:

        int x = 54;
        
      • Python:

        x = 54
        
  2. Initialization Required:

    • Variables must be initialized when declared.
    • Python does not allow:
      • C:

        int x;  // Declaration without initialization.
        
      • Python: Not allowed. You must assign a value:

        x = None  # Assign `None` if you don't yet have a value.
        

2. Differences in Syntax


3. Strings in Python


4. Dynamic Typing (Variable are Flexible)


D) Conditional Statements in Python: A Comparison with C

1. Basic Structure: if Statements

Key Differences:


2. if-else Statements

Key Differences:


3. if-elif-else Statements

Key Differences:


4. Ternary (Conditional) Operator

Key Differences:


5. User Input: native input() function

Key Points:


Summary of Python Features: Conditional Statements

Python’s syntax is designed to be closer to plain English, making it easier to read and write. With practice, these differences become intuitive and second nature.


E) Loops in Python: A Comparison with C

1. while Loops

Key Differences:

  1. No Type Declaration: counter = 0 instead of int counter = 0.
  2. No Parentheses: Conditions in while do not require parentheses.
  3. No Semicolons: Lines in Python don’t end with semicolons.
  4. No ++ Operator: Use counter += 1 instead of counter++.
  5. Automatic Newline in print(): Unlike printf, print() automatically adds a newline.

2. for Loops

Key Differences:

  1. range() Function:
    • range(100) generates numbers from 0 to 99 (not including 100).
    • Syntax: range(start, stop, step)
      • Default: start=0, step=1.
  2. No Initialization/Condition/Increment: Python’s for loop uses a simpler for x in range syntax.
  3. No Semicolons or Parentheses.

3. Counting by Twos

Explanation of range():


Summary of Python Loop Features:

  1. No Do-While Loops:

    • Python lacks do-while loops, but you can simulate them using while True with a break.
  2. Simplified Syntax:

    • No semicolons, type declarations, or increment (++) operators.
    • Indentation is used instead of curly braces.
  3. range() is Powerful:

    • Handles counting, skipping, and defining ranges in a single function.

Python’s loops are cleaner and more readable than C, making them easier for beginners while remaining powerful for advanced use cases.


F) Understanding Lists in Python: A More Flexible Array

Python's lists offer a significant upgrade over arrays in C due to their flexibility, ease of use, and ability to store mixed data types. Here's an overview of how lists in Python compare with arrays in C and the powerful operations they enable.

1. Creating Lists


2. Adding Elements to Lists


3. Removing Elements from Lists


4. Accessing Elements


5. Length and Iteration


6. Differences from C Arrays


7. Advanced Features: List Comprehension

List comprehensions allow you to create lists in a single, concise line.


8. Summary of relevant List Functions

Function Description
append(x) Adds x to the end of the list
insert(i, x) Inserts x at index i
remove(x) Removes the first occurrence of x
pop(i) Removes and returns the element at index i
clear() Removes all elements from the list
len(list) Returns the number of elements in the list
list(range(start, stop, step)) Generates a list from start to stop by step

Python lists simplify many tasks that are cumbersome with C arrays, making them a versatile tool for programmers. They eliminate the need for manual memory management, provide flexibility, and offer a rich set of built-in functionalities.


G) Understanding Tuples in Python: Ordered and Immutable Data

Tuples in Python provide a way to store ordered, immutable data collections. They are similar to structures in C where the order matters, but the data is fixed and cannot be changed after creation. Here's how tuples work and why they are useful.

1. What is a Tuple?


2. Creating Tuples


3. Accessing Tuple Elements


4. Example: A List of Tuples

You can store tuples inside a list for more complex data structures:

presidents = [
    ("George Washington", 1789),
    ("John Adams", 1797),
    ("Thomas Jefferson", 1801)
]

5. Iterating Over Tuples

You can iterate over a list of tuples and unpack their elements:

for prez, year in presidents:
    print(f"In {year}, {prez} took office.")

Output:

In 1789, George Washington took office.
In 1797, John Adams took office.
In 1801, Thomas Jefferson took office.

6. Formatting with .format()

Python's print() can format strings using the .format() method, similar to printf in C.


7. Why Tuples?


8. Advanced Usage


Summary of Tuple Characteristics

Feature Description
Immutable Cannot be changed after creation.
Ordered Sequence of elements is fixed.
Unpacking Easily extract values into variables.
Fast More memory-efficient than lists for fixed data.
Use Cases Store coordinates, fixed records, or data that won't change.

Tuples, along with lists and dictionaries, are a cornerstone of Python's flexible data handling capabilities. They provide both simplicity and power when dealing with structured and immutable data.


H) Understanding Dictionaries in Python

Dictionaries in Python provide a flexible and efficient way to associate keys with values, similar in concept to hash tables in other programming languages. Here’s a breakdown of how dictionaries work, their features, and how to use them effectively.

1. What is a Dictionary?


2. Creating a Dictionary


3. Accessing and Modifying Values


4. Iterating Over a Dictionary

a) Iterating Over Keys

for pie in pizzas:
    print(pie)
# Outputs: cheese, pepperoni, vegetable, buffalo chicken, bacon

b) Iterating Over Keys and Values

for pie, price in pizzas.items():
    print(f"A whole {pie} pizza costs ${price}")

Output:

A whole cheese pizza costs $8
A whole pepperoni pizza costs $10
...

5. Key Features

a) Dynamic Keys and Values

You can dynamically check or add keys:

if "vegetable" in pizzas:
    print("Vegetable pizza is available")
else:
    pizzas["vegetable"] = 13

b) Dictionary Methods

print(pizzas.keys())    # Outputs: dict_keys(['cheese', 'pepperoni', ...])
print(pizzas.values())  # Outputs: dict_values([8, 10, ...])
print(pizzas.items())   # Outputs: dict_items([('cheese', 8), ('pepperoni', 10), ...])

6. Formatting Output

a) String Concatenation

print("A whole " + "cheese" + " pizza costs $" + str(9))

b) f-Strings (Preferred)

pie = "cheese"
price = 9
print(f"A whole {pie} pizza costs ${price}")

c) Using .format()

print("A whole {} pizza costs ${}".format("cheese", 9))

7. Unordered Nature of Dictionaries

Example:

pizzas = {"vegetable": 11, "cheese": 8}
for pie, price in pizzas.items():
    print(pie, price)

Order might vary in older Python versions but is consistent in Python 3.7+.


8. Dictionary Use Cases


Summary Table: How to use Dictionaries

Feature Syntax/Method Description
Create Empty Dictionary pizzas = {} Initializes an empty dictionary.
Access a Value pizzas["cheese"] Accesses the value for the key "cheese".
Add/Update Key-Value pizzas["bacon"] = 14 Adds/updates key-value pair.
Check Key Existence "cheese" in pizzas Returns True if "cheese" is a key.
Iterate Over Keys for pie in pizzas: Loops through dictionary keys.
Iterate Over Items for pie, price in pizzas.items(): Loops through key-value pairs.
Dictionary Methods .keys(), .values(), .items() Retrieves keys, values, or both.

Dictionaries in Python provide a flexible and intuitive way to manage key-value pairs without the manual effort required in languages like C. They are a fundamental data structure that significantly simplifies many common programming tasks!

J) Python Functions and main()

In Python, functions are highly flexible, eliminating many of the restrictions and requirements we faced in C. Here's a detailed explanation and examples to help you understand Python's approach to functions and the optional main() construct.

1. Defining a Function

Example: A Simple Function

def square(x):
    return x * x

print(square(5))  # Output: 25

2. Key Differences from C


3. Advanced Function Examples

a) Using Python’s Exponentiation Operator

Python introduces the ** operator for exponentiation.

Example:

def square(x):
    return x ** 2

print(square(5))  # Output: 25

b) A Convoluted Square Function

You can implement the square operation in creative ways. For example:

def square(x):
    result = 0
    for _ in range(x):
        result += x
    return result

print(square(5))  # Output: 25

While not efficient, this demonstrates how Python allows flexibility in function logic.


4. Optional main() Function

Although Python doesn't require a main() function, you can use one for structure, especially in larger programs. Use the following construct to define and call main() explicitly:

Example: Using main()

def main():
    print("This is the main function.")
    print(f"Square of 5 is: {square(5)}")

def square(x):
    return x ** 2

# Ensuring the script runs `main()` only when executed directly
if __name__ == "__main__":
    main()

5. Why Use if __name__ == "__main__":?


6. Function Composition and Usage

Functions can be composed to build more complex programs.

Example: Composing Functions

def main():
    number = 7
    print(f"Square of {number}: {square(number)}")
    print(f"Cube of {number}: {cube(number)}")

def square(x):
    return x ** 2

def cube(x):
    return x ** 3

if __name__ == "__main__":
    main()

7. Summary: Functions in Python

Feature Python Syntax Notes
Define Function def function_name(params): Use def keyword.
No Return Type Needed N/A Python infers the return type.
No Parameter Types N/A Dynamically typed parameters.
Call Function function_name(args) Pass arguments directly.
Exponentiation x ** y x to the power of y.
Optional main() if __name__ == "__main__": Controls script behavior when executed.

This flexibility makes Python functions not only easier to write but also highly adaptable to different programming paradigms.


K) Object-Oriented Programming in Python: An Introduction

Python is an object-oriented programming (OOP) language, and this paradigm focuses on objects that combine properties (data) and methods (functions). Here's a breakdown of how Python implements OOP, including creating and working with classes and methods.

1. Objects and Classes

2. Defining a Class

Example:

class Student:
    # Constructor (called when creating a new object)
    def __init__(self, name, student_id):
        self.name = name  # Property: name
        self.student_id = student_id  # Property: ID

    # Method to change the student ID
    def change_id(self, new_id):
        self.student_id = new_id

    # Method to print student details
    def display(self):
        print(f"{self.name} - {self.student_id}")

3. Understanding self


4. Creating and Using Objects

To create an object (or instance) of the Student class:

# Create a new Student object
student1 = Student("Jane", 10)

# Display initial details
student1.display()  # Output: Jane - 10

# Change the student's ID
student1.change_id(11)

# Display updated details
student1.display()  # Output: Jane - 11

5. Key Features of Classes and Methods

a) Constructor (__init__)

Example:

def __init__(self, name, student_id):
    self.name = name
    self.student_id = student_id

b) Defining Methods

Example:

def change_id(self, new_id):
    self.student_id = new_id

6. Properties vs. Methods


7. Full Example: Student Class

Here’s a complete example to demonstrate Python's object-oriented approach:

class Student:
    # Constructor
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id

    # Method to change the student ID
    def change_id(self, new_id):
        self.student_id = new_id

    # Method to display the student's details
    def display(self):
        print(f"{self.name} - {self.student_id}")


# Create an instance of the Student class
student1 = Student("Jane", 10)

# Display student details
student1.display()  # Output: Jane - 10

# Change the student ID
student1.change_id(11)

# Display updated details
student1.display()  # Output: Jane - 11

8. Key Concepts in OOP

Concept Explanation
Class Blueprint for creating objects.
Object Instance of a class, combining properties and methods.
Property Data associated with an object (e.g., self.name).
Method Functions that belong to a class and operate on its objects.
Constructor (__init__) Special method to initialize an object’s properties.
self Reference to the specific object the method is called on.

9. Extending Functionality

a) Adding More Methods

You can easily add more methods to extend the class's functionality.

Example:

class Student:
    # Constructor
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id

    # Method to change the student's name
    def change_name(self, new_name):
        self.name = new_name

    # Method to compare student IDs
    def has_same_id(self, other_student):
        return self.student_id == other_student.student_id

b) Using the New Methods

# Create two Student objects
student1 = Student("Alice", 10)
student2 = Student("Bob", 10)

# Compare their IDs
print(student1.has_same_id(student2))  # Output: True

10. Summary: OOP

Object-oriented programming in Python focuses on creating reusable, organized, and modular code through the use of classes and objects. Key features like properties, methods, and the self parameter allow for efficient and clean programming practices.


L) Key Takeaways: Python Style, Modules, and Usage

Python emphasizes readability and style. Here's a breakdown of the important points you need to know based on the provided content:

1. Good Style in Python


2. Importing Modules

Example:

import cs50  # Importing the CS50 library
x = cs50.get_int("Enter an integer: ")  # Using a function from the library

3. Running Python Code


4. Making Python Files Executable

To run Python files like a compiled C program (./hello), follow these steps:

  1. Add the Shebang Line:

    • At the top of your Python file, add:

      #!/usr/bin/env python3
      
  2. Change File Permissions:

    • Make the file executable:

      chmod +x your_file.py
      
  3. Run the File:

    • Execute it directly:

      ./your_file.py
      

5. Python Advantages


6. Exploring Python Further


Practical Example

Here’s a Python file example using the concepts:

#!/usr/bin/env python3

import cs50  # Import CS50 library

def main():
    # Get user input
    name = cs50.get_string("What is your name? ")
    print(f"Hello, {name}!")

if __name__ == "__main__":
    main()  # Explicitly calling main()

Steps:

  1. Save it as hello.py.

  2. Make it executable:

    chmod +x hello.py
    
  3. Run it:

    ./hello.py
    

Final Notes: Transitioning from C to Python


🔙 Previous Part | Next Part 🔜

↩️ Go Back


Z) 🗃️ Glossary

File Definition
Uncreated files Origin Note