Control Flow

Change Topic
  • Conditional statements
  • Ternary Operator or Select
  • Switch / Case
  • Loop Over - Iterables
  • Loop Conditional Exit
  • Co-Routine - Yield
  • Exceptions

Python Language

TypeScript Control-Flow


Conditional

def check_number(num: int) -> str: if num > 0: return "Positive" elif num < 0: return "Negative" else: return "Zero" print(check_number(10)) # "Positive" print(check_number(-5)) # "Negative" print(check_number(0)) # "Zero"

Conditional

function checkNumber(num: number): string { if (num > 0) { return "Positive"; } else if (num < 0) { return "Negative"; } else { return "Zero"; } }

Ternary Operator

result = "Positive" if num > 0 else "Negative" if num < 0 else "Zero"

Ternary and Select Expressions

Ternary operator:

const result = num > 0 ? "Positive" : num < 0 ? "Negative" : "Zero";

Loop Over

Python supports multiple looping constructs.

Basic for loop (iterates over a range of numbers):

for i in range(5): print(i)

Loop over lists (for...in):

numbers = [1, 2, 3] for num in numbers: print(num)

Loop over dictionary keys and values:

user = {"id": 1, "name": "Alice"} for key, value in user.items(): print(f"{key}: {value}")

Enumerate iteration (index + value):

fruits = ["apple", "banana", "cherry"] for index, fruit in enumerate(fruits): print(index, fruit)

Loop Over

TypeScript supports multiple loop constructs.

Basic for loop:

for (let i = 0; i < 5; i++) { console.log(i); }

for...of (iterates over iterable objects):

const numbers: number[] = [1, 2, 3]; for (const num of numbers) { console.log(num); }

for...in (iterates over object keys):

const user = { id: 1, name: "Alice" }; for (const key in user) { console.log(`${key}: ${user[key as keyof typeof user]}`); }

Loop Conditional Exit

Python does not have a built-in do...while loop like some other programming languages. However, you can achieve similar functionality using a while loop with a condition that is checked after the first iteration.

Example: Using a while loop for conditional exit:

count = 0 while count < 5: print(count) count += 1

Emulating a do...while loop:

To emulate a do...while loop (where the condition is checked after the first iteration), you can use a while True loop with a break statement:

count = 0 while True: print(count) count += 1 if count >= 5: break
for i in range(10): if i == 5: break print(i) # Output: 0, 1, 2, 3, 4
for i in range(5): if i == 2: continue print(i) # Output: 0, 1, 3, 4

Loop Conditional Exit

TypeScript allows breaking out of loops based on conditions and also supports do...while loops, which execute at least once before checking the condition.

Basic do...while loop:

do { console.log("Executing at least once"); } while (false);

do...while with condition:

let i = 0; do { console.log(i); i++; } while (i < 5); ``` breaking out of loops based on conditions. ```typescript for (let i = 0; i < 10; i++) { if (i === 5) { break; // Exit loop when i equals 5 } console.log(i); }

Using continue to skip iterations:

for (let i = 0; i < 10; i++) { if (i % 2 === 0) { continue; // Skip even numbers } console.log(i); }

Coroutines and yield

Coroutines in Python are a special type of function that can pause and resume execution. They are often used for asynchronous programming and cooperative multitasking. The yield keyword is used to create generators, which are a type of coroutine.

Using yield to Create Generators: - The yield keyword allows a function to return a value and pause its execution, resuming from where it left off when called again.

def count_up_to(n): count = 0 while count < n: yield count count += 1 # Using the generator for num in count_up_to(5): print(num) # Output: 0, 1, 2, 3, 4

Coroutines are functions that can consume values sent to them using the send() method. They are defined using the yield keyword.

def coroutine_example(): print("Coroutine started") while True: value = yield print(f"Received: {value}") # Using the coroutine coro = coroutine_example() next(coro) # Start the coroutine coro.send(10) # Send a value to the coroutine coro.send(20) # Send another value

yield from for Delegating Generators. The yield from statement is used to delegate part of a generator's operations to another generator.

def sub_generator(): yield 1 yield 2 yield 3 def main_generator(): yield from sub_generator() yield 4 # Using the generator for value in main_generator(): print(value) # Output: 1, 2, 3, 4

Asynchronous Coroutines with async def. In modern Python, coroutines are often used with async def and await for asynchronous programming.

import asyncio async def async_example(): print("Start") await asyncio.sleep(1) # Simulate an asynchronous operation print("End") # Running the coroutine asyncio.run(async_example())

Coroutine and Yield

TypeScript does not support native coroutines or yield, but it supports generator functions which behave similarly.

Generator function with yield:

function* numberGenerator(): Generator<number> { yield 1; yield 2; yield 3; } const gen = numberGenerator(); console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // 3

Using yield in a loop:

function* infiniteCounter(): Generator<number> { let i = 0; while (true) { yield i++; } } const counter = infiniteCounter(); console.log(counter.next().value); // 0 console.log(counter.next().value); // 1 console.log(counter.next().value); // 2

Generators provide a way to implement lazy iteration, similar to coroutines in other languages.


Exception Handling

Python provides a robust mechanism for handling runtime errors using try, except, else, and finally blocks. This allows you to gracefully handle errors and ensure proper cleanup.

Basic Exception Handling: - the try block lets you test a block of code for errors, and the except block lets you handle the error.

try: result = 10 / 0 except ZeroDivisionError as e: print(f"Error: {e}") # Output: Error: division by zero

Catching Multiple Exceptions. You can catch multiple exceptions by specifying them in a tuple.

try: num = int("abc") result = 10 / 0 except (ValueError, ZeroDivisionError) as e: print(f"Error: {e}") # Output: Error: invalid literal for int() with base 10: 'abc'

Using else with try. The else block runs if no exceptions are raised in the try block.

try: result = 10 / 2 except ZeroDivisionError as e: print(f"Error: {e}") else: print(f"Result: {result}") # Output: Result: 5.0

Using finally for Cleanup. The finally block always executes, regardless of whether an exception was raised or not. It is typically used for cleanup operations.

try: file = open("example.txt", "r") content = file.read() except FileNotFoundError as e: print(f"Error: {e}") finally: print("Closing the file.") if 'file' in locals() and not file.closed: file.close() # Output: Error: [Errno 2] No such file or directory: 'example.txt' # Closing the file.

Raising Exceptions: - You can raise exceptions explicitly using the raise keyword.

def check_positive(num): if num < 0: raise ValueError("Number must be positive") return num try: check_positive(-5) except ValueError as e: print(f"Error: {e}") # Output: Error: Number must be positive

Custom Exceptions: - You can define your own exceptions by creating a custom class that inherits from the Exception class.

class CustomError(Exception): pass try: raise CustomError("This is a custom error") except CustomError as e: print(f"Error: {e}") # Output: Error: This is a custom error