1) Python Basics. First steps in programming and introduction to IPython

4 May 2025 13 minutes Author: Lady Liberty

Python is one of the simplest and at the same time powerful programming languages, which is a convenient way to start your development journey. This section of the course introduces key concepts without which it is impossible to write code confidently. It covers basic Python syntax, working with the IPython interactive interpreter, basic commands, and creating variables. Thanks to this block, beginners get a practical idea of ​​the language structure, the principles of executing commands in real time, and the basic logic of working with data. This section forms the foundation on which all further learning is based, opening the way to confident and effective programming.

Python syntax

The first thing that usually catches your eye when talking about Python syntax is that indentation matters:

  • they determine what code goes into a block;

  • when a block of code begins and ends.

Example Python code:

a = 10
b = 5

if a > b:
    print("A більше B")
    print(a - b)
else:
    print("B більше або дорівнює A")
    print(b - a)

print("Кінець")

def open_file(filename):
    print("Читання файлу", filename)
    with open(filename) as f:
        return f.read()
        print("Готово")

This code is shown to demonstrate the syntax. And even though we haven’t looked at the if/else construct yet, the gist of the code will likely be clear.

Python understands which lines belong to the if based on indentation. The block ends when it encounters a line with the same indentation as the line itself. Similarly, with the else block. Another Python feature: some expressions must be followed by a colon (for example, after and after). if a > bif a > bif a > belse

A few rules and recommendations regarding indentations:

  • Tabs or spaces can be used as indents (it is better to use spaces, or rather, configure the editor so that a tab equals 4 spaces – then when using the tab key, 4 spaces will be inserted, instead of 1 tab character).

  • The number of spaces should be the same in one block (it is better that the number of spaces is the same throughout the code – a popular option is to use 2-4 spaces, for example, 4 spaces are used in this book).

Another feature of the code above is the use of empty lines. They format the code to make it easier to read. Other syntax features will be shown as we get to know Python data structures.

Python has a special document that describes how to better write Python code, PEP 8 – Style Guide for Python Code.

Comments

When writing code, it is often necessary to leave a comment, for example, to describe the features of the code.

Comments in Python can be single-line:

# Дуже важливий коментар
a = 10
b = 5 # Дуже важливий коментар

Single-line comments begin with a parenthesis. Note that a comment can be on the same line as the code or on a separate line.

If you need to write multiple lines of comments, you can use a multi-line comment to avoid having to put a parenthesis before each comment:

"""
Дуже важливий та довгий коментар
"""
a = 10
b = 5

For a multi-line comment, you can use three double quotes or three single quotes. Comments can be used both to comment out what is happening in the code, and to prevent a specific line or block of code from being executed (i.e., to comment them out)..

Python interpreter. IPython

The interpreter allows you to get instant feedback on the actions performed. You can say that the interpreter works like the CLI (Command Line Interface) of network devices: each command will be executed immediately after pressing Enter. However, there is an exception – more complex objects (for example, loops or functions) are executed only after pressing Enter twice.

In the previous section, the standard interpreter was called to check the Python installation. In addition to it, there is an improved IPython interpreter. IPython allows much more than the standard interpreter, which is called by the python command. A few examples (IPython’s capabilities are much wider):

  • auto-completion of commands by Tab or a hint if there are several command options;

  • more structured and understandable command output;

  • automatic indentation in loops and other objects;

  • you can navigate through the command execution history, or view it with the “magic” command “%history”.

You can install IPython using pip (the installation will be done in a virtual environment if one is configured):

pip install ipython

After that, you can switch to IPython like this:

$ ipython
Python 3.7.3 (default, May 13 2019, 15:44:23)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

To exit, use the quit command. The following describes how to use IPython.

To get familiar with the interpreter, you can try using it as a calculator:

In [1]: 1 + 2
Out[1]: 3

In [2]: 22*45
Out[2]: 990

In [3]: 2**3
Out[3]: 8

In IPython, input and output are labeled:

  • In – user input

  • Out – the result returned by the command (if any)

  • the numbers after In or Out are the sequence numbers of the commands executed in the current IPython session

Example of outputting a string using the print() function:

In [4]: print('Hello!')
Hello!

When, for example, a loop is created in the interpreter, the prompt inside the loop changes to a period. To execute the loop and exit this submode, you must press Enter twice:

In [5]: for i in range(5):
   ...:     print(i)
   ...:
0
1
2
3
4

help()

In IPython, it is possible to view help for any object, function, or method using help():

In [1]: help(str)
Help on class str in module builtins:

class str(object)
 |  str(object='') -> str
 |  str(bytes_or_buffer[, encoding[, errors]]) -> str
 |
 |  Create a new string object from the given object. If encoding or
 |  errors is specified, then the object must expose a data buffer
 |  that will be decoded using the given encoding and error handler.
...

In [2]: help(str.strip)
Help on method_descriptor:

strip(...)
    S.strip([chars]) -> str

    Return a copy of the string S with leading and trailing
    whitespace removed.
    If chars is given and not None, remove characters in chars instead.

Second option:

In [3]: ?str
Init signature: str(self, /, *args, **kwargs)
Docstring:
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
Type:           type

In [4]: ?str.strip
Docstring:
S.strip([chars]) -> str

Return a copy of the string S with leading and trailing
whitespace removed.
If chars is given and not None, remove characters in chars instead.
Type:      method_descriptor

print()

The print() function allows you to output information to the standard output stream (the current terminal screen). If you need to output a string, you must enclose it in quotes (double or single). If you need to output, for example, the result of a calculation or just a number, then quotes are not needed:

In [6]: print('Hello!')
Hello!

In [7]: print(5*5)
25

If you need to display several values ​​in a row separated by a space, you need to list them with commas:

In [8]: print(1*5, 2*5, 3*5, 4*5)
5 10 15 20

In [9]: print('one', 'two', 'three')
one two three

By default, there will be a line break at the end of each expression passed to print(). If you want to avoid line breaks after each expression, you can specify an additional argument end as the last expression in print().

dir()

The dir() function can be used to see what attributes (variables bound to an object) and methods (functions bound to an object) are.

For example, for a number the output would be like this (note the different methods that allow arithmetic operations):

In [10]: dir(5)
Out[10]:
['__abs__',
 '__add__',
 '__and__',
 ...
 'bit_length',
 'conjugate',
 'denominator',
 'imag',
 'numerator',
 'real']

Similarly for the line:

In [11]: dir('hello')
Out[11]:
['__add__',
 '__class__',
 '__contains__',
 ...
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

If you execute dir() without passing a value, it shows the existing methods, attributes, and variables defined in the current interpreter session:

In [12]: dir()
Out[12]:
[ '__builtin__',
 '__builtins__',
 '__doc__',
 '__name__',
 '_dh',
 ...
 '_oh',
 '_sh',
 'exit',
 'get_ipython',
 'i',
 'quit']

For example, after creating the variable a and test():

In [13]: a = 'hello'

In [14]: def test():
   ....:     print('test')
   ....:

In [15]: dir()
Out[15]:
 ...
 'a',
 'exit',
 'get_ipython',
 'i',
 'quit',
 'test']

Special ipython commands

IPython has special commands that make it easier to work with the interpreter. They all start with a percent sign.

%history

For example, the %history command allows you to view the history of commands entered by the user in the current IPython session:

In [1]: a = 10

In [2]: b = 5

In [3]: if a > b:
   ...:     print("A is bigger")
   ...:
A is bigger

In [4]: %history
a = 10
b = 5
if a > b:
    print("A is bigger")
%history

Using %history you can copy the desired block of code.

%time

The %time command shows how many seconds the expression was executed:

In [5]: import subprocess

In [6]: def ping_ip(ip_address):
    ..:     reply = subprocess.run(['ping', '-c', '3', '-n', ip_address],
    ..:                            stdout=subprocess.PIPE,
    ..:                            stderr=subprocess.PIPE,
    ..:                            encoding='utf-8')
    ..:     if reply.returncode == 0:
    ..:         return True
    ..:     else:
    ..:         return False
    ..:

In [7]: %time ping_ip('8.8.8.8')
CPU times: user 0 ns, sys: 4 ms, total: 4 ms
Wall time: 2.03 s
Out[7]: True

In [8]: %time ping_ip('8.8.8')
CPU times: user 0 ns, sys: 8 ms, total: 8 ms
Wall time: 12 s
Out[8]: False

In [9]: items = [1, 3, 5, 7, 9, 1, 2, 3, 55, 77, 33]

In [10]: %time sorted(items)
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 8.11 µs
Out[10]: [1, 1, 2, 3, 3, 5, 7, 9, 33, 55, 77]

You can read more about IPython in the IPython documentation.

You can view the information briefly in IPython itself with the %quickref command:

IPython -- An enhanced Interactive Python - Quick Reference Card
===========================================================

obj?, obj??      : Get help, or more help for object (also works as
                   ?obj, ??obj).
?foo.*abc*       : List names in 'foo' containing 'abc' in them.
%magic           : Information about IPython's 'magic' % functions.

Magic functions are prefixed by % or %%, and typically take their arguments
without parentheses, quotes or even commas for convenience.  Line magics take a
single % and cell magics are prefixed with two %%.

Example magic function calls:

%alias d ls -F   : 'd' is now an alias for 'ls -F'
alias d ls -F    : Works if 'alias' not a python name
alist = %alias   : Get list of aliases to 'alist'
cd /usr/share    : Obvious. cd -<tab> to choose from visited dirs.
%cd??            : See help AND source for magic %cd
%timeit x=10     : time the 'x=10' statement with high precision.
%%timeit x=2**100
x**100           : time 'x**100' with a setup of 'x=2**100'; setup code is not
                   counted.  This is an example of a cell magic.

System commands:

!cp a.txt b/     : System command escape, calls os.system()
cp a.txt b/      : after %rehashx, most system commands work without !
cp ${f}.txt $bar : Variable expansion in magics and system commands
files = !ls /usr : Capture sytem command output
files.s, files.l, files.n: "a b c", ['a','b','c'], 'a\nb\nc'

History:

_i, _ii, _iii    : Previous, next previous, next next previous input
_i4, _ih[2:5]    : Input history line 4, lines 2-4
exec _i81        : Execute input history line #81 again
%rep 81          : Edit input history line #81
_, __, ___       : previous, next previous, next next previous output
_dh              : Directory history
_oh              : Output history
%hist            : Command history of current session.
%hist -g foo     : Search command history of (almost) all sessions for 'foo'.
%hist -g         : Command history of (almost) all sessions.
%hist 1/2-8      : Command history containing lines 2-8 of session 1.
%hist 1/ ~2/     : Command history of session 1 and 2 sessions before current.

Variables

Variables in Python do not require a variable type declaration (since Python is a dynamically typed language) and are references to a memory area. Variable naming rules:

  • the variable name can only consist of letters, numbers, and the underscore;

  • the name cannot start with a number;

  • the name cannot contain the special characters @, $, %.

Example of creating variables in Python

In [1]: a = 3

In [2]: b = 'Hello'

In [3]: c, d = 9, 'Test'

In [4]: print(a,b,c,d)
3 Hello 9 Test

Note that in Python, you don’t need to specify that a is a number and b is a string.

Variables are references to a memory location. This can be demonstrated using id(), which returns the object’s identifier:

In [5]: a = b = c = 33

In [6]: id(a)
Out[6]: 31671480

In [7]: id(b)
Out[7]: 31671480

In [8]: id(c)
Out[8]: 31671480

In this example, you can see that all three names refer to the same identifier, meaning that it is the same object that is pointed to by the three references – “a”, “b” and “c”. There is one thing about numbers in Python that can be a bit confusing: the numbers from -5 to 256 are created in advance and stored in an array (list). Therefore, when you create a number from this range, you are actually creating a reference to the number in the created array.

This feature is specific to the CPython implementation discussed in the book.

This can be checked like this:

In [9]: a = 3

In [10]: b = 3

In [11]: id(a)
Out[11]: 4400936168

In [12]: id(b)
Out[12]: 4400936168

In [13]: id(3)
Out[13]: 4400936168

Notice that a, b, and the number 3 have the same identifiers. They are all references to an existing number in the list.

If you do the same with a number greater than 256, they will all have different identifiers:

In [14]: a = 500

In [15]: b = 500

In [16]: id(a)
Out[16]: 140239990503056

In [17]: id(b)
Out[17]: 140239990503032

In [18]: id(500)
Out[18]: 140239990502960

At the same time, if you assign variables to each other, the identifiers will all be the same (in this case, a and b refer to the same object):

In [19]: a = b = c = 500

In [20]: id(a)
Out[20]: 140239990503080

In [21]: id(b)
Out[21]: 140239990503080

In [22]: id(c)
Out[22]: 140239990503080

Variable names

Variable names should not overlap with operator and module names or other reserved words. Python has recommendations for naming functions, classes, and variables:

  • variable names are usually written either in all uppercase or lowercase (e.g. DB_NAME, db_name);

  • function names are written in lowercase, with underscores between words (e.g. get_names);

  • class names are written in all uppercase words without spaces, this is called CamelCase (e.g. CiscoSwitch).

Conclusion

Mastering Python syntax, the principles of the IPython interpreter, basic commands, and the correct use of variables are fundamental skills for anyone starting to learn programming. The third section of the course introduces the key features of the language that make Python understandable and convenient for beginners. Thanks to a clear structure, interactive environment, and flexible syntax, users can quickly move from theory to practice. This is a solid foundation for further development, allowing you to confidently move forward and create your own projects from the very first lessons.

Other related articles
Found an error?
If you find an error, take a screenshot and send it to the bot.
OSZAR »