Lab 1

De la WikiLabs
Versiunea din 14 septembrie 2026 05:51, autor: Andrei.ulmamei (discuție | contribuții) (→‎Lab 1 — Python for C/C++ Programmers)
(dif) ← Versiunea anterioară | Versiunea curentă (dif) | Versiunea următoare → (dif)
Jump to navigationJump to search

Lab 1 — Python for C/C++ Programmers

Objectives

The purpose of this laboratory is to introduce Python to students who already have experience with procedural programming in C and object-oriented programming in C++.

The focus is therefore not on learning programming concepts from scratch, but on understanding how concepts already familiar from C/C++ are expressed in Python.

After completing this laboratory, you should be able to:

  • understand the basic syntax of Python;
  • recognize the main differences between Python and C/C++;
  • work with Python's fundamental data types;
  • use conditional statements and loops;
  • work with lists, dictionaries, sets and tuples;
  • define and call functions;
  • understand basic Python object/reference semantics;
  • recognize several common Python idioms;
  • create and execute a simple Python project.

Throughout this laboratory, equivalent or similar C/C++ and Python code will be presented side by side.

1. Running a Python program

A C/C++ program normally has to be compiled before it is executed. Python programs are usually executed directly by the Python interpreter.

C/C++ Python
#include <iostream>

int main()
{
std::cout << "Hello, world!\n";
return 0;
}
print("Hello, world!")

A Python source file normally uses the extension:

.py

For example:

hello.py

It can be executed using:

python3 hello.py

Unlike C/C++, Python does not require a special main() function.

However, larger Python programs commonly use:

C/C++ Python
#include <iostream>

int main()
{
std::cout << "Program started\n";


return 0;

}
def main():
    print("Program started")


if __name__ == "__main__":
    main()

The Python version is not mandatory, but this pattern will become useful when programs are split into multiple modules.

2. Blocks and indentation

In C and C++, braces delimit blocks of code.

Python uses indentation instead.

C/C++ Python
if (x > 10) {
    std::cout << "Large\n";
    std::cout << "Value: " << x << "\n";
}
if x > 10:
    print("Large")
    print("Value:", x)

Indentation in Python is part of the language syntax.

The standard convention is 4 spaces per indentation level.

For example, the following code is incorrect:

if x > 10:
    print("Large")

Python will report an IndentationError.

3. Variables and types

C/C++ variables have a declared static type.

Python variables do not require explicit type declarations.

C/C++ Python
int count = 10;
double temperature = 23.5;
bool enabled = true;
std::string name = "Alice";
count = 10
temperature = 23.5
enabled = True
name = "Alice"

Python is dynamically typed.

This means that a variable name can later refer to an object of another type.

C/C++ Python
int value = 10;

// Not allowed:
// value = "hello";
value = 10
value = "hello"

This does not mean that Python has no types.

Objects still have types:

C/C++ Python
#include <iostream>
#include <typeinfo>

int value = 10;

std::cout << typeid(value).name();
value = 10

print(type(value))

Python will produce:

<class 'int'>

Common basic types

C/C++ type Python equivalent Example
int int 42
float / double float 3.14
bool bool True, False
char No separate character type "A"
std::string str "Hello"
nullptr None None

4. Constants

C++ can enforce that a value cannot be modified using const.

Python does not enforce constants at language level.

C/C++ Python
const double PI = 3.1415926535;
const int MAX_USERS = 100;
PI = 3.1415926535
MAX_USERS = 100

By convention, Python names that should be treated as constants are written using uppercase letters.

Nothing prevents the programmer from changing them.

5. Arithmetic operators

Most arithmetic operators are identical.

C/C++ Python
int a = 10;
int b = 3;

int sum  = a + b;
int diff = a - b;
int prod = a * b;
int div  = a / b;
int rem  = a % b;
a = 10
b = 3

sum_ = a + b
diff = a - b
prod = a * b
div = a // b
rem = a % b

There is an important difference between / and //.

C/C++ Python
int a = 10;
int b = 3;

std::cout << a / b;   // 3
a = 10
b = 3

print(a / b)   # 3.3333333333333335
print(a // b)  # 3

In C/C++, dividing two integers performs integer division.

In Python, the / operator always performs floating-point division, while // performs floor division.

Python also provides an exponentiation operator:

C/C++ Python
#include <cmath>

double result = std::pow(2, 8);
result = 2 ** 8

6. Printing values

Output using std::cout is replaced by the built-in print() function.

C/C++ Python
std::string name = "Alice";
int age = 21;

std::cout << name
<< " is "
<< age
<< " years old\n";
name = "Alice"
age = 21

print(name, "is", age, "years old")

Python also provides formatted string literals, commonly called f-strings.

C/C++ Python
std::cout << "Temperature: "
<< temperature
<< " C\n";
print(f"Temperature: {temperature} C")

Expressions can appear directly inside an f-string:

C/C++ Python
std::cout << "Result: "
<< a + b
<< "\n";
print(f"Result: {a + b}")

7. Reading input

Console input is performed using input().

An important difference is that input() always returns a string.

C/C++ Python
int age;

std::cout << "Age: ";
std::cin >> age;
age = int(input("Age: "))

Without the conversion:

age = input("Age: ")

age is a string.

Conversions are explicit:

C/C++ Python
int a = std::stoi(text);
double b = std::stod(text);
a = int(text)
b = float(text)

8. Conditional statements

The overall structure is similar, but Python does not use parentheses or braces.

C/C++ Python
if (temperature > 30) {
std::cout << "Hot\n";
}
else if (temperature > 20) {
std::cout << "Warm\n";
}
else {
std::cout << "Cold\n";
}
if temperature > 30:
    print("Hot")
elif temperature > 20:
    print("Warm")
else:
    print("Cold")

Notice that Python uses:

elif

instead of:

else if

9. Boolean operators

Python uses words instead of the C/C++ symbolic logical operators.

C/C++ Python
&& and
|| or
! not

For example:

C/C++ Python
if (age >= 18 && enabled) {
    ...
}

if (!enabled) {
    ...
}
if age >= 18 and enabled:
    ...

if not enabled:
    ...

10. Comparison operators

Most comparison operators are identical.

Operation C/C++ Python
equality == ==
inequality != !=
less than < <
greater than > >
less than or equal <= <=
greater than or equal >= >=

Python also allows chained comparisons.

C/C++ Python
if (0 <= x && x < 100) {
    ...
}
if 0 <= x < 100:
    ...

11. The ternary operator

Both languages support conditional expressions.

C/C++ Python
int maximum = (a > b) ? a : b;
maximum = a if a > b else b

Notice that Python's order is different:

value_if_true if condition else value_if_false

12. While loops

A while loop is very similar.

C/C++ Python
int i = 0;

while (i < 5) {
std::cout << i << "\n";
i++;
}
i = 0

while i < 5:
    print(i)
    i += 1

Python does not have ++ or -- operators.

Therefore:

i += 1

is used instead.

13. For loops

This is one of the first important conceptual differences.

In C/C++, a for statement commonly controls a numeric index.

Python's for statement iterates over objects.

C/C++ Python
for (int i = 0; i < 5; i++) {
    std::cout << i << "\n";
}
for i in range(5):
    print(i)

range(5) generates values conceptually equivalent to:

0, 1, 2, 3, 4

A different starting value can be specified:

C/C++ Python
for (int i = 2; i < 10; i++) {
    std::cout << i << "\n";
}
for i in range(2, 10):
    print(i)

A step can also be specified:

C/C++ Python
for (int i = 0; i < 10; i += 2) {
    std::cout << i << "\n";
}
for i in range(0, 10, 2):
    print(i)

14. Iterating over containers

Suppose we want to print every element of a vector/list.

An index-based implementation is possible:

C/C++ Python
std::vector<int> values = {10, 20, 30};

for (size_t i = 0; i < values.size(); i++) {
std::cout << values[i] << "\n";
}
values = [10, 20, 30]

for i in range(len(values)):
    print(values[i])

However, this is generally not the preferred Python style.

If the index is not required, iterate directly over the elements.

C++ Python
std::vector<int> values = {10, 20, 30};

for (const auto& value : values) {
std::cout << value << "\n";
}
values = [10, 20, 30]

for value in values:
    print(value)

The second Python version should normally be preferred.

15. When both index and value are required

C/C++ programmers frequently use an explicit index.

Python provides enumerate().

C/C++ Python
std::vector<std::string> names = {
    "Ana",
    "Bob",
    "Carol"
};

for (size_t i = 0; i < names.size(); i++) {
std::cout << i
<< ": "
<< names[i]
<< "\n";
}
names = ["Ana", "Bob", "Carol"]

for i, name in enumerate(names):
    print(i, ":", name)

This introduces another frequently used Python feature: unpacking.

16. Lists

The closest commonly used Python equivalent to std::vector is list.

C++ Python
std::vector<int> values = {
    10, 20, 30
};

values.push_back(40);

std::cout << values[0];
std::cout << values.size();
values = [10, 20, 30]

values.append(40)

print(values[0])
print(len(values))

Python lists can contain objects of different types:

C++ Python
// A normal std::vector cannot
// contain unrelated types.

std::vector<int> values = {
10, 20, 30
};
values = [
10,
3.14,
"hello",
True
]

Although Python allows this, homogeneous collections are generally easier to understand and maintain when the elements conceptually represent the same kind of data.

17. Negative indexing

Python allows indexing from the end of a sequence.

C++ Python
std::vector<int> v = {10, 20, 30, 40};

std::cout << v[v.size() - 1]; // 40
std::cout << v[v.size() - 2]; // 30
v = [10, 20, 30, 40]

print(v[-1])  # 40
print(v[-2])  # 30

18. Slicing

Python sequences support slicing directly.

C++ Python
std::vector<int> v = {
    10, 20, 30, 40, 50
};

std::vector<int> part(
v.begin() + 1,
v.begin() + 4
);
v = [10, 20, 30, 40, 50]

part = v[1:4]

The result is:

[20, 30, 40]

General syntax:

sequence[start:stop:step]

For example:

C/C++ Python
// Requires an explicit loop or
// another algorithm.
v = [0, 1, 2, 3, 4, 5]

print(v[1:4])   # [1, 2, 3]
print(v[:3])    # [0, 1, 2]
print(v[3:])    # [3, 4, 5]
print(v[::2])   # [0, 2, 4]
print(v[::-1])  # [5, 4, 3, 2, 1, 0]

19. Membership testing

Checking whether an element exists in a container is commonly performed using in.

C++ Python
std::vector<int> values = {10, 20, 30};

if (std::find(
values.begin(),
values.end(),
20
) != values.end()) {
std::cout << "Found\n";
}
values = [10, 20, 30]

if 20 in values:
    print("Found")

The opposite test uses not in:

if 100 not in values:
    print("Not found")

20. Dictionaries

A Python dict is similar to a C++ associative container such as std::unordered_map.

C++ Python
std::unordered_map<std::string, int> grades;

grades["Ana"] = 10;
grades["Bob"] = 8;

std::cout << grades["Ana"];
grades = {}

grades["Ana"] = 10
grades["Bob"] = 8

print(grades["Ana"])

A dictionary can also be initialized directly:

C++ Python
std::unordered_map<std::string, int> grades = {
    {"Ana", 10},
    {"Bob", 8},
    {"Carol", 9}
};
grades = {
    "Ana": 10,
    "Bob": 8,
    "Carol": 9,
}

Iterating over keys and values:

C++ Python
for (const auto& [name, grade] : grades) {
    std::cout << name
              << ": "
              << grade
              << "\n";
}
for name, grade in grades.items():
    print(name, ":", grade)

21. Sets

A Python set represents a collection containing unique values.

C++ Python
std::unordered_set<int> values = {
    10, 20, 30
};

values.insert(40);

if (20 != values.end()) {
// conceptually test membership
}
values = {10, 20, 30}

values.add(40)

if 20 in values:
    print("Found")

A more correct C++ membership test would be:

if (values.find(20) != values.end()) {
    std::cout << "Found\n";
}

Sets are particularly useful when:

  • duplicate values should be removed;
  • fast membership tests are required;
  • mathematical set operations are useful.

22. Tuples

Tuples are similar to lists, but they are immutable.

C++ Python
std::tuple<int, double, std::string> data {
    10,
    3.14,
    "test"
};
data = (10, 3.14, "test")

Python uses tuples extensively for returning or unpacking multiple values.

23. Functions

Functions are declared using def.

C/C++ Python
int add(int a, int b)
{
    return a + b;
}

int result = add(2, 3);
def add(a, b):
    return a + b


result = add(2, 3)

Python does not require parameter or return types to be declared.

However, Python supports optional type hints.

C++ Python
double average(
    double a,
    double b
) {
    return (a + b) / 2.0;
}
def average(
    a: float,
    b: float
) -> float:
    return (a + b) / 2

Type hints do not normally enforce types at runtime.

They provide information for:

  • the programmer;
  • IDEs;
  • static analysis tools;
  • documentation.

24. Default parameters

Both C++ and Python support default parameter values.

C++ Python
void greet(
    const std::string& name = "World"
) {
    std::cout << "Hello, "
              << name
              << "\n";
}

greet();
greet("Alice");
def greet(name="World"):
    print(f"Hello, {name}")


greet()
greet("Alice")

25. Named arguments

Python allows function arguments to be specified by name.

C++ Python
void connect(
    std::string host,
    int port,
    bool secure
);

connect("server.local", 443, true);
def connect(host, port, secure):
    ...


connect(
    host="server.local",
    port=443,
    secure=True
)

This can make calls with several parameters easier to understand.

26. Returning multiple values

In C++, multiple return values typically require a structure, tuple, pair or output parameters.

Python commonly uses tuples.

C++ Python
std::pair<int, int> minmax(int a, int b)
{
    if (a < b)
        return {a, b};


return {b, a};

}

auto [minimum, maximum] = minmax(10, 3);
def minmax(a, b):
    if a < b:
        return a, b

    return b, a


minimum, maximum = minmax(10, 3)

This is another example of tuple unpacking.

27. Swapping variables

A temporary variable is normally used in C.

Python supports unpacking directly.

C/C++ Python
int temp = a;
a = b;
b = temp;
a, b = b, a

28. Strings

Python strings behave more like C++ std::string objects than traditional C character arrays.

C++ Python
std::string text = "Hello";

std::cout << text.size();
std::cout << text[0];
text = "Hello"

print(len(text))
print(text[0])

String concatenation:

C++ Python
std::string first = "Hello";
std::string second = "World";

std::string result =
first + " " + second;
first = "Hello"
second = "World"

result = first + " " + second

Python strings provide many built-in operations:

C++ Python
std::string text = "hello";

// Usually requires algorithms,
// explicit transformations,
// or utility functions.
text = "hello"

print(text.upper())
print(text.lower())
print(text.startswith("he"))
print(text.endswith("lo"))
print(text.replace("l", "x"))

29. Lists versus arrays: important semantic difference

Consider assigning one collection to another.

With normal C++ value semantics, copying a vector produces another vector.

Python assignment behaves differently.

C++ Python
std::vector<int> a = {1, 2, 3};

std::vector<int> b = a;

b[0] = 100;

std::cout << a[0];  // 1
std::cout << b[0];  // 100
a = [1, 2, 3]

b = a

b[0] = 100

print(a[0])  # 100
print(b[0])  # 100

This happens because:

b = a

does not copy the list.

Both names refer to the same list object.

Conceptually:

       +-------------+
a ---> | [1, 2, 3]   |
       +-------------+
          ^
          |
b --------+

To explicitly create a shallow copy:

C++ Python
std::vector<int> b = a;
b = a.copy()

or:

b = list(a)

This distinction is extremely important when using Python.

30. Equality versus identity

Python distinguishes between:

  • whether two objects contain equal values;
  • whether two names refer to the exact same object.
C++ Python
std::vector<int> a = {1, 2, 3};
std::vector<int> b = {1, 2, 3};

std::cout << (a == b);  // true

// Address comparison would be needed
// to determine object identity.
a = [1, 2, 3]
b = [1, 2, 3]

print(a == b)  # True
print(a is b)  # False

In Python:

==  tests value equality
is  tests object identity

Do not use is when you intend to compare values.

A common correct use is:

if value is None:
    ...

31. None and nullptr

Python's None represents the absence of a value.

C++ Python
Object* ptr = nullptr;

if (ptr == nullptr) {
...
}
value = None

if value is None:
    ...

32. Exceptions

Exception handling is conceptually similar.

C++ Python
try {
    int value = std::stoi(text);
}
catch (const std::exception& e) {
    std::cout << "Invalid value\n";
}
try:
    value = int(text)
except ValueError:
    print("Invalid value")

Python generally uses exceptions rather than special error return values for many failure conditions.

33. A first Pythonic transformation

Consider creating a vector/list containing the squares of the numbers from 0 to 9.

A direct translation from C++ could look like this:

C++ Python — direct translation
std::vector<int> squares;

for (int i = 0; i < 10; i++) {
squares.push_back(i * i);
}
squares = []

for i in range(10):
    squares.append(i * i)

The Python code is correct.

However, Python provides a concise construct called a list comprehension.

C++ Python — idiomatic
std::vector<int> squares;

for (int i = 0; i < 10; i++) {
squares.push_back(i * i);
}
squares = [
i * i
for i in range(10)
]

A condition can also be included.

C++ Python
std::vector<int> squares;

for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
squares.push_back(i * i);
}
}
squares = [
i * i
for i in range(10)
if i % 2 == 0
]

An important objective of this course is not only to write programs that work in Python, but to learn to write programs in a style appropriate for Python.

34. Example: processing student grades

Consider the following problem:

  • store the grades of several students;
  • compute the average;
  • print the students whose grade is greater than or equal to the average.
C++ Python
#include <iostream>
#include <string>
#include <unordered_map>

int main()
{
std::unordered_map<std::string, double> grades = {
{"Ana", 9.5},
{"Bob", 7.0},
{"Carol", 8.5},
{"Dan", 6.0}
};


double sum = 0.0;

for (const auto& [name, grade] : grades) {
    sum += grade;
}

double average = sum / grades.size();

std::cout << "Average: "
          << average
          << "\n";

for (const auto& [name, grade] : grades) {
    if (grade >= average) {
        std::cout << name
                  << ": "
                  << grade
                  << "\n";
    }
}

return 0;

}
grades = {
    "Ana": 9.5,
    "Bob": 7.0,
    "Carol": 8.5,
    "Dan": 6.0,
}

average = sum(grades.values()) / len(grades)

print(f"Average: {average:.2f}")

for name, grade in grades.items():
    if grade >= average:
        print(f"{name}: {grade}")

Notice that the Python version uses existing language functionality rather than manually reproducing every operation.

In particular:

sum(grades.values())

expresses the intention directly.

35. Exercise 1 — Translation

Translate the following C++ program into Python.

C++ Python
#include <iostream>
#include <vector>

int main()
{
std::vector<int> values = {
12, 7, 18, 3, 24, 11
};


int sum = 0;
int count = 0;

for (int value : values) {
    if (value % 2 == 0) {
        sum += value;
        count++;
    }
}

std::cout << "Count: "
          << count
          << "\n";

std::cout << "Sum: "
          << sum
          << "\n";

return 0;

}

Your implementation:

# TODO

After implementing a direct translation, try to simplify the Python implementation.

36. Exercise 2 — Statistics

Write a Python program that:

  1. reads a sequence of integer values;
  2. stores them in a list;
  3. prints the minimum value;
  4. prints the maximum value;
  5. prints the average;
  6. prints how many values are above the average.

The equivalent C++ structure might begin as follows:

C++ Python
std::vector<int> values;

// Read / initialize values.

int minimum = ...;
int maximum = ...;
double average = ...;
values = []

# Read / initialize values.

minimum = ...
maximum = ...
average = ...

Useful Python functions include:

len(...)
sum(...)
min(...)
max(...)

37. Exercise 3 — Word frequency

Given a sentence, count how many times each word occurs.

For example:

python is simple and python is powerful

should produce information equivalent to:

python -> 2
is -> 2
simple -> 1
and -> 1
powerful -> 1

A possible C++ data structure and its Python equivalent are:

C++ Python
std::unordered_map<std::string, int>
    frequencies;
frequencies = {}

Use:

sentence.split()

to separate the sentence into words.

38. Exercise 4 — Remove duplicates

Given:

values = [4, 2, 7, 4, 2, 9, 7, 1]

create a collection containing every distinct value.

Think about the following C++ and Python data structures:

C++ Python
std::unordered_set<int> unique_values;
unique_values = set()

Try to solve the problem both:

  1. using an explicit loop;
  2. using Python's built-in functionality.

39. Exercise 5 — Small problem

Write a program that receives a list of students and their grades and determines:

  • the class average;
  • the student with the highest grade;
  • all students who passed;
  • all students whose grade is above the class average.

Suggested representation:

C++ Python
std::unordered_map<std::string, double>
    grades;
grades = {
    "Ana": 9.5,
    "Bob": 7.0,
    "Carol": 8.5,
    "Dan": 4.0,
}

Avoid using numeric indices unless an index is actually required.

40. Creating a project environment

Python applications commonly use a virtual environment to isolate project dependencies.

Create a directory for the project:

mkdir python-project
cd python-project

Create a virtual environment:

python3 -m venv .venv

Activate it on Linux/macOS:

source .venv/bin/activate

Activate it on Windows PowerShell:

.venv\Scripts\Activate.ps1

The command prompt will normally indicate that the environment is active.

For example:

(.venv) student@computer:~/python-project$

Packages installed using pip will now be installed inside this environment.

For example:

pip install requests

To inspect installed packages:

pip list

41. Recommended initial project structure

For the first laboratories, the following structure is sufficient:

python-project/
├── .venv/
├── main.py
├── README.md
└── .gitignore

A basic .gitignore should contain:

.venv/
__pycache__/
*.pyc

Do not commit the virtual environment to Git.

42. C/C++ habits to reconsider in Python

When transitioning from C/C++ to Python, the following patterns should generally be reconsidered.

C/C++ habit Typical Python approach
Iterate using an integer index Iterate directly over the objects
Manually maintain counters Consider enumerate()
Search manually through a container Use in
Manually calculate container size Use len()
Explicit temporary variable for swapping Use tuple unpacking
Explicit loop for simple transformations Consider a comprehension
Long output expressions Use f-strings
Copy assumed after assignment Remember that names refer to objects
Check null using equality Use is None

The objective is not simply to translate C/C++ syntax into Python syntax.

Consider:

C++ style translated literally More idiomatic Python
for i in range(len(values)):
    print(values[i])
for value in values:
    print(value)

Both programs are correct.

The second expresses the programmer's intention more directly.

43. Summary

The main mappings introduced in this laboratory are:

C/C++ Python
{ ... } indentation
true, false True, False
&& and
|| or
! not
nullptr None
std::vector list
std::unordered_map dict
std::unordered_set set
std::tuple tuple
std::cout print()
std::cin input()
indexed iteration direct iteration / enumerate()
manual search in
std::pow(a, b) a ** b
integer division //

The central idea to retain from this laboratory is:

Python should not be treated merely as C++ with different syntax. Python provides its own abstractions and idioms, and using them generally produces simpler and more readable programs.

44. Preparation for Lab 2

Before the next laboratory:

  1. complete all exercises from this laboratory;
  2. ensure Python 3 is installed;
  3. create a virtual environment successfully;
  4. create a Git repository for the semester project;
  5. become familiar with lists, dictionaries, tuples and sets;
  6. review the concepts of classes, objects, inheritance and composition from C++.

In Lab 2, these concepts will be revisited from the perspective of Python's object model and Pythonic object-oriented programming.