Compendio Final Python-Certificacion
Compendio Final Python-Certificacion
Python
Exam block #1: Computer Programming
and Python Fundamentals
Study Pages
interpreting and the interpreter, compilation and the compiler, lexis, syntax and
semantics
PCEP 1.3 Introduce literals and variables into code and use different numeral systems
PCEP 1.4 Choose operators and data types adequate to the problem
11. The interpreter and its environment, created and distributed by the Python
Software Foundation (PSF) is written mostly in the C programming language. It
allows Python to be easily ported and migrated to all platforms providing the ability
to compile and run C language programs. This is also why the PSF implementation
is often referred to as CPython. CPython is the most widely used implementation of
Python.
Python basic types and literals
1. A literal is data whose value is determined by the literal itself. Different kinds of
data are coded in different ways, enabling Python (and the human reader of the
source code) to determine each literal's type. Knowing each argument's type is
crucial to understand what operations are legal, and what results can be returned.
2. Integer (int for short) is a type dedicated to storing integral numbers, that is,
numbers that lack fractional parts. For example, 1 is an integral number and 1.5 is
not.
3. Most used integer literals in Python consist of a sequence of decimal digits. Such a
sequence cannot include white spaces, but can contain any number of _
(underscore) characters. Note: there must not be more than one underscore between
two digits, and the underscore must be neither the last nor the first character of the
literal. Underscores don't change a literal's value, and their only role is to improve
literal readability. Integer literals can be preceded by any number of - (minus) or +
(plus) characters, which are applied to set the literal's sign.
7. Float literals are distinguished from integers by the fact that they contain a dot (.)
or the letter e (lower- or upper-case) or both. If the only digits which exist before or
after the dot are zeros, they can be omitted. Like integers, floats can be preceded by
any number of - and + characters, which determine the number's sign. White spaces
are not allowed, while underscores are.
8. If the float literal contains the letter e, it means that its value is scaled, that is, it's
multiplied by a power of 10 while the exponent (which must be an integer!) is
placed directly after the letter. A record like this:
mEn
m × 10n
This syntax is called scientific notation and is used to denote a number whose
absolute value is extremely large (close to infinity) or extremely small (close to
zero).
12. Boolean literals denote the only two possible values used by the Boolean algebra
– their only acceptable denotations are True and False.
13. The None literal denotes an empty value and can be used to indicate that a certain
item contains no usable value.
Operators
1. An operator is a symbol that determines an operation to perform. The operator along
with its arguments (operands) forms an expression that is subject to evaluation and
provides a result.
2. There are three basic groups of operators in Python:
o arithmetic, whose arguments are numbers;
o string, which operates on strings or strings and numbers;
o Boolean, which expects that their arguments are Boolean values.
always float
raises
/ Division 4 / 2 4÷2 2.0 ZeroDivisionError
when divider is zero
Lowest
int if both arguments are
Subtraction 2 - 1 2−1 1 ints
-
float otherwise
pairs of parentheses can be used to change the order of operations, for example:
o 2 + 3 * 4 evaluates to 14
o (2 + 3) * 4 evaluates to 20
when operators of the same priority (other than **)are placed side-by-side in the same
expression, they are evaluated from left to right: therefore, the expression:
1 / 2 * 2
when more than one ** operator is placed side-by-side in the same expression, they are
evaluated from right to left: therefore, the expression:
2 ** 2 ** 3
'a' * 3
Highest * Replication 3 * 'a'
'aaa' Always a string
Boolean operators demand Boolean arguments, and always result in a Boolean result. The
rules governing the use of operators and parentheses remain the same, including left-sided
binding.
Relational operators
Relational operators compare their arguments to diagnose the relationship between them,
and always return a Boolean value indicating the comparison result.
2 >= 1 True
>= greater or equal 1 >= 1 True
2 <= 1 False
<= less or equal 1 <= 1 True
Variables
1. A variable is a named container able to store data.
and must start with a letter (note: underscores count as letters). Upper- and lower-case
letters are treated as different.
3. Variable names which start with underscores play a specific role in Python – don't use
them unless you know what you're doing.
5. The name of the variable must not be any of Python's keywords (also known as reserved
words). The complete list of Python 3.8 keywords looks as follows:
* Note: Python 3.9 introduced a new keyword, __peg_parser__, which is an easter egg
related to the rollout of a new PEG parser for CPython. You can read more about this in
PEP 617. The keyword will most probably be removed in Python 3.10.
6. These are some legal, but not necessarily the best, Python variable names:
o i
o counter_2
o _
o Tax22
variable = expression
For example:
counter = 0
pi2 = 3.1415 ** 2
or – when more than one variable is assigned with the same value:
counter = stages = 0
8. A variable must be assigned (defined) before its first use – using a variable without prior
definition (assignment) raises the NameError exception.
9. Python is a dynamically typed language, which means that a variable can freely change its
type according to the last assignment it took part in.
10. There are some short-cut (compound) operators which simplify certain kinds of
assignments.
Compound operators
Compound Arithmetic Operators
11. A part of the code line which starts with hash (#), which is not a part of a string literal, is
considered a comment (a part of the code which is ignored by the interpreter)
Basic Input/Output
1. The input() function is used to interact with the user, allowing them to suspend
program execution and to enter a sequence (including an empty one) of characters,
which is the function's result.
2. If the user presses <Enter> while providing no other input, the input() function
returns an empty string as a result.
For example, the name variable is assigned with a string inputted by the user:
name = input()
3. The input() function accepts an optional argument which is a string; the argument
is printed on the screen before the actual input begins.
4. To convert the user's input into an integer number, the int() function can be used.
5. An operation during which the data changes its type is called type casting.
For example, the user is asked to input a year of birth. The input is converted into an
integer number and assigned to the b_year variable:
6. To convert the user's input into a float number, the float() function can be used.
For example, the user is asked to input a height measured in meters. The input is
converted into a float number and assigned to the m_stature variable:
7. If the int() or float() is not able to perform the conversion due to the incorrect
contents of the user's input, the ValueError exception is raised.
8. Unless otherwise specified, the printed values are separated by single spaces.
print(1, 2, 3)
9. If the invocation makes use of the sep keyword parameter, the parameter's value
(even when it's empty) is used to separate outputted values instead of spaces.
print(1, 2, 3, sep='*')
10. Unless otherwise specified, each print() function invocation sends the
newline character to the screen before its completion, therefore each print()
function's output starts on a new line.
For example, the following snippet produces two lines of output on the screen:
print('Alpha')
print('Bravo')
11. If the invocation makes use of the end keyword parameter, the parameter's
value is (even when it's empty) used to complete the output instead of the newline.
For example, the following snippet produces one line of output on the screen:
print('Alpha', end='')
print('Bravo')
For example, the following snippet produces one line of asterisk-separated letters:
print('C')
Exam block #2: Control Flow –
Conditional Blocks and Loops
Study Pages
PCEP 2.1 Make decisions and branch the flow with the if instruction
if condition:
instructions
5. When there is only one instruction that should be executed conditionally, the
instruction can be written in the following form:
if condition: instruction
counter = 1
if counter > 0:
print('TRUE')
7. The empty instruction denoted by the pass keyword can be used to indicate that no
action should be performed in the specific context. As the if instruction syntax
insists that there should be at least one statement after it, the following snippet does
not affect program execution:
if condition:
pass
8. It is suggested to use one tabulation character to make one indent level in Python
code, while the recommended tab size (settable in virtually all code editors) is 4.
9. The else branch can be used to specify a part of the code that should be executed
when the condition is not met:
if condition:
instructions
else:
instructions
10. For example, the following snippet prints TRUE when the counter variable is
greater than zero, and FALSE otherwise:
if counter > 0:
print('TRUE')
else:
print('FALSE')
11. To check more than one condition within one conditional block, the elif branch or
branches may be employed. In that case, not more than one if/elif branch can be
executed. The else branch is optional, and must be the last branch.
12. For example, the following snippet prints PLUS when the counter variable is
greater than zero, MINUS when it's less than zero, and ZERO when it's equal to zero:
if counter > 0:
print('PLUS')
print('MINUS')
else:
print('ZERO')
Loops
1. The while loop statement is a means allowing the programmer to repeat the
execution of the selected part of the code as long the specified condition is true.
The condition is checked before the loop's first turn, and therefore the loop's body
may not even be executed once.
while condition:
instructions
For example, the following snippet prints TRUE twice to the screen:
counter = 2
if counter > 0:
print('TRUE')
counter -= 1
5. The else branch can be used to specify a part of the code that should be executed
when the loop’s condition is not met:
while condition:
instructions
else:
instructions
For example, the following snippet prints TRUE FALSE to the screen:
counter = 1
counter -= 1
else:
print('FALSE')
6. If the condition is met at the beginning of the loop and there is no chance that the
condition value has changed inside the body of the loop, the execution enters an
infinite loop which cannot be broken without the user's intervention, for example
by pressing the Ctrl-C (Ctrl-Break) key combination.
For example, the following snippet infinitely prints TRUE to the screen:
while True:
print('TRUE', end=' ')
7. The for loop statement is a means allowing the programmer to repeat the
execution of the selected part of the code when the number of repetitions can be
determined in advance. The for statement uses a dedicated variable called a
control variable, whose subsequent values reflect the status of the iteration.
instructions
for i in range(3):
print(i, end=',')
12. The else branch can be used to specify a part of the code that should be
executed when the loop's body is not entered, which may happen when the range
being iterated is empty or when all the range's values have already been consumed.
for i in range(3):
else:
print('FINISHED')
for i in range(1,1):
else:
print('FINISHED')
13. The break statement can be used inside the loop's body only, and causes
immediate termination of the loop's code. If the loop is equipped with the else
branch, it is omitted.
for i in range(3):
if i == 2:
break
else:
print('FINISHED')
i = 1
while True:
i += 1
if i == 3:
break
else:
print('FINISHED')
14. The continue statement can be used inside the loop's body only, and
causes an immediate transition to the next iteration of the for loop, or to the while
loop's condition check.
for i in range(4):
if i % 2 == 1:
continue
print('FINISHED')
i = -1
while i < 3:
i += 1
if i % 2 != 0:
continue
else:
print('FINISHED')
Exam block #3: Data Collections – Tuples,
Dictionaries, Lists, and Strings
Study Pages
constructing vectors, indexing and slicing, the len() function, basic list methods
(append(), insert(), index()) and functions (len(), sorted(), etc.), the del instruction;
iterating through lists with the for loop, initializing loops; in and not in operators,
list comprehensions; copying and cloning, lists in lists: matrices and cubes.
tuples: indexing, slicing, building, immutability; tuples vs. lists: similarities and
differences, lists inside tuples and tuples inside lists.
2. Lists are sequences – they can be iterated, and the order of the elements is
established.
4. Lists can be initialized with list literals. For example, these two assignments
instantiate two lists – the former is empty, while the latter contains three elements:
empty_list = []
5. The number of elements contained in the list can be determined by the len()
function. For example, the following snippet prints 3 to the screen:
6. Any of the list's elements can be accessed using indexing. List elements are indexed
by integer numbers starting from zero. Therefore, the first list element's index is 0
while the last element's index is equal to the list length minus 1. Using indices that
are not integers raises the TypeError exception. For example, the following snippet
prints a b c 0 1 2 to the screen:
counter = 0
for ix in range(len(the_list)):
the_list[ix] = counter
counter += 1
for ix in range(len(the_list)):
7. The list elements can be indexed with negative numbers, too. In this case, -1
accesses the last element of the list, and -2 accesses the one before the last, and so
on. The alternative first list element's index is -len(list).
8. An attempt to access a non-existent list element (when the index goes out of the
permissible range) raises the IndexError exception.
9. A slice is a means by which the programmer can create a new list using a part of the
already existing list.
the_list[from:to:step]
and selects those elements whose indices start at from, don't exceed to, and change
with step. For example, the following snippet prints ['b', 'd'] to the screen:
print((1,2,3)[4:5])
the_list = [0, 1, 2, 3]
print(the_list[-3:-1])
2. Assigning a list to a list does not copy elements. Such an assignment results in a
situation when more than one name identifies the same data aggregate.
list_a = [1]
list_b = list_a
list_b[0] = 0
print(list_a[0] == list_b[0])
As the slice is a copy of the source list, the following snippet prints False to the
screen:
list_a = [1]
list_b = list_a[:]
list_b[0] = 0
print(list_a[0] == list_b[0])
3. The .append(element) method can be used to append an element to the end of an
existing list. For example, the following snippet outputs [1] to the screen:
the_list = []
the_list.append(1)
print(the_list)
the_list = [1]
the_list.insert(0, 2)
print(the_list)
5. The del the_list[index] instruction can be used to remove any of the existing
list elements. For example, the following snippet prints [] to the screen:
the_list = [1]
del the_list[0]
print(the_list)
6. The in and not in operators can check whether any value is contained inside the list
or not. For example, the following snippet prints True False to the screen:
the_list = [1,2,3]
print(the_list)
9. Strings, like lists, are sequences, and in many contexts they behave like lists,
especially when they are indexed and sliced or are arguments of the len() function.
10. The in and not in operators can be applied to strings to check if any string is a part
of another string. An empty string is considered a part of any string, including an
empty one.
Tuples
1. A tuple, like a list, is a data aggregate that contains a certain number (including
zero) of elements of any type. Tuples, like lists, are sequences, but they are
immutable. You're not allowed to change any of the tuple elements, or add a new
element, or remove an existing element. Attempting to break this rule will raise the
TypeError exception.
2. Tuples can be initialized with tuple literals. For example, these assignments
instantiate three tuples – one empty, one one-element, and one two-element:
3. The number of elements contained in the tuple can be determined by the len()
function. For example, the following snippet prints 4 to the screen:
Note the inner pair of parentheses – they cannot be omitted, as it will cause the
tuple to be replaced with four independent values and will cause an error.
4. Any of the tuple's elements can be accessed using indexing, which works in the
same manner as in lists, including slicing.
6. If any of the slice's indices exceeds the permissible range, no exception is raised,
and the non-existent elements are not taken into consideration. Therefore, the
resulting slice may be an empty tuple. For example, the following snippet outputs
() to the screen:
print((1,2,3)[4:5])
7. The in and not in operators can check whether or not any value is contained inside
the tuple.
8. Tuples can be iterated through (traversed) by the for loop, like lists.
Dictionaries
1. A dictionary is a data aggregate that gathers pairs of values. The first element
in each pair is called the key, and the second one is called the value. Both keys and
values can be of any type.
2. Dictionaries are mutable but are not sequences – the order of pairs is imposed by
the order in which the keys are entered into the dictionary.
empty_dictionary = {}
Dictionaries – continued
4. Accessing a dictionary's value requires the use of its key. For example, the
following line outputs 911 to the screen:
print(phone_directory['Emergency'])
5. An attempt to access an element whose key is absent in the dictionary raises the
KeyError exception.
6. The in and not in operators can be used to check whether a certain key exists in the
dictionary. For example, the following line prints True False to the screen:
7. The len() function returns the number of pairs contained in the directory. For
example, the following line outputs 0 to the screen:
print(len(empty_directory))
8. Changing a value of the existing key is done by an assignment. For example, the
following snippet outputs False to the screen:
attendance['Bob'] = False
print(attendance['Bob'])
9. Adding a new pair to the dictionary resembles a regular assignment. For example,
the following snippet outputs 2 to the screen:
domains['at'] = 'Austria'
print(len(domains))
10. Removing a pair from a dictionary is done with the del instruction. For
example, the following snippet outputs 0 to the screen:
del currencies['USD']
print(len(currencies))
11. When iterated through by the for loop, the dictionary displays only its keys.
For example, the following snippet outputs A B to the screen:
12. The .keys() method returns a list of keys contained in the dictionary. For
example, the following snippet outputs A B to the screen:
13. The .values() method returns a list of values contained in the dictionary.
For example, the following snippet outputs Alpha Bravo to the screen:
14. The .items() method returns a list of two-element tuples, each filled with
key:value pairs. For example, the following snippet outputs ('A', 'Alpha')
('B', 'Bravo') to the screen:
phonetic = {'A': 'Alpha', 'B': 'Bravo'}
defining and invoking user-defined functions and generators; the return keyword,
returning results, the None keyword, recursion.
PCEP 4.2 Organize interaction between the function and its environment
parameters vs. arguments; positional, keyword and mixed argument passing; default
parameter values, name scopes, name hiding (shadowing), the global keyword.
2. The simplest function, which does nothing and returns no result, can be defined in
the following way:
def lazy():
pass
lazy()
4. Function definition must precede its invocation. Breaking this rule raises the
NameError exception.
def function(parameter):
if parameter == False:
return True
print(function(False), function(True))
7. A function definition can declare default values for some or all of its parameters.
When the invocation does not provide arguments for these parameters, the default
values are taken into consideration. Note: parameters with default values must not
precede the ones without them. For example, the following snippet prints True
False to the screen:
return parameter
print(function(True), function())
print(a, b, c)
function(1, 2, 3)
print(a, b, c)
print(a, b, c)
11. Note that the following invocation is incorrect and will raise the TypeError
exception, because the a parameter is set twice (once with the positional passing and
once with the keyword passing) while the c parameter is not set at all.
12. A scope is the part of the code where a certain name is properly recognizable.
13. A variable existing outside a function has a scope which includes the function's
bodies.
14. A variable defined inside the function has a scope inside the function's body only.
15. If a certain variable is used inside a function and the variable’s name is listed
as an argument of the global keyword, it has global scope, and it is also
recognizable outside the function. For example, the following snippet outputs 2 to
the screen:
def function():
global variable
variable += 1
variable = 1
function()
print(variable)
Note: removing the line containing the global keyword will spoil the code and the
UnboundLocalError exception will be raised.
16. Changing the parameter's value doesn't propagate it outside the function.
For example, the following snippet outputs [1] to the screen:
def function(parameter):
parameter = [2]
the_list = [1]
function(the_list)
print(the_list)
def function(parameter):
parameter[0] = 2
the_list = [1]
function(the_list)
print(the_list)
18. Recursion is a programming technique in which the function invokes itself
to perform a complex task. For example, the following snippet contains a function
that evaluates the factorial of its argument and prints 120 to the screen:
def factorial(n):
if n < 2:
return n
else:
return n * factorial(n - 1)
print(factorial(5))
2. Python professes its philosophy expressed with the sentence: It's better to beg for
forgiveness than ask for permission. The recommendation hidden behind these
words says that the programmer should allow the exceptions to occur and handle
them properly instead of persistently avoiding problems and protecting the code
from all possible errors with all their might.
4. The try block encloses a part of the code that may cause an exception and when it
happens, the execution of the block is terminated and the control jumps into the
except block, which is dedicated to recognizing the problem and handling it. For
example, the following snippet prints PROCEEDING even though the code provokes
division by zero:
try:
x = 1 / 0
except:
x = None
print('PROCEEDING')
6. When more than one exception is expected inside the try block and these different
exceptions require different handling, another syntax is used where there is more
than one named except branch. The unnamed (anonymous) except branch is the
default one, and is responsible for servicing these exceptions which still need to be
handled.
try:
except ValueError:
print('NAN')
except ZeroDivisionError:
print('ZERO')
except:
print('ERR')
11. The process by which bugs are detected and removed from the code is called
debugging.
12. The tool which allows the programmer to run the code in a fully controllable
environment is called a debugger.
13. The 'print debugging' technique is a trivial debugging technique in which the
programmer adds some print() function invocations which help to trace execution
paths and output the values of selected critical variables.
14. The process in which the code is probed to ensure that it will behave correctly in a
production environment is called testing. The testing should prove that all
execution paths have been executed and caused no errors.
15. The programming technique in which the tests and test data are created before the
code is written or created in parallel with the code is called unit testing. It is
assumed that every code amendment (even the most trivial) is followed by the
execution of all previously defined tests.