Python 101 : The Ultimate Python Tutorial For Beginners
Published: 2022-04-22 23:55:17

## Knowing Python
Python is a *high-level*, *general-purpose programming language*. Its design philosophy emphasizes code readability with the use of significant indentation. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small- and large-scale projects.

## More about Python
Python is *dynamically-typed and garbage-collected*. It supports multiple programming paradigms, including structured (particularly procedural), object-oriented and functional programming. It is often described as a "batteries included" language due to its comprehensive standard library.

## Who invented Python? 
Python was conceived in the late 1980s by **Guido van Rossum at Centrum Wiskunde & Informatica (CWI) in the Netherlands*. Van Rossum shouldered sole responsibility for the project, as the lead developer, until 12 July 2018, when he announced his "permanent vacation" from his responsibilities as Python's "benevolent dictator for life", a title the Python community bestowed upon him to reflect his long-term commitment as the project's chief decision-maker. In January 2019, active Python core developers elected a five-member Steering Council to lead the project.

## Python's Evolution
**Guido van Rossum** began working on Python in the late 1980s as a successor to the ABC programming language and first released it in 1991 as Python 0.9.0. Python 2.0 was released in 2000 and introduced new features such as list comprehensions, cycle-detecting garbage collection, reference counting, and Unicode support. Python 3.0, released in 2008, was a major revision that is not completely backward-compatible with earlier versions. Python 2 was discontinued with version 2.7.18 in 2020. Right now in April 2022 the latest version is 3.10.4.

## Why is Python so popular nowadays?
* Python consistently ranks as one of the most popular programming languages. 
* Python is a programming language that lets you work quickly and integrate systems more effectively. It's very easy to learn 

### Programming examples
Hello world program:
`print('Hello, world!')`

Program to calculate the factorial of a positive integer:
```
n = int(input('Type a number, and its factorial will be printed: '))

if n < 0:
    raise ValueError('You must enter a non-negative integer')

factorial = 1
for i in range(2, n + 1):
    factorial *= i

print(factorial)
```
## Libraries
Python's large standard library, commonly cited as one of its greatest strengths, provides tools suited to many tasks. For Internet-facing applications, many standard formats and protocols such as MIME and HTTP are supported. It includes modules for creating graphical user interfaces, connecting to relational databases, generating pseudorandom numbers, arithmetic with arbitrary-precision decimals, manipulating regular expressions, and unit testing.

Some parts of the standard library are covered by specifications—for example, the Web Server Gateway Interface (WSGI) implementation wsgiref follows PEP 333 but most are specified by their code, internal documentation, and test suites. However, because most of the standard library is cross-platform Python code, only a few modules need altering or rewriting for variant implementations.

## Python uses and applications
1. Automation
2. Data analytics
3. Databases
4. Documentation
5. Graphical user interfaces
6. Image processing
7. Machine learning
8. Mobile apps
9. Multimedia
10. Computer networking
11. Scientific computing
12. System administration
13. Test frameworks
14. Text processing
15. Web frameworks
16. Web scraping

## Python Keywords
Python has 35 keywords or reserved words; they cannot be used as identifiers.

* and
* as
* assert
* async
* await
* break
* class
* continue
* def
* del
* elif
* else
* except
* False
* finally
* for
* from
* global
* if
* import
* in
* is
* lambda
* None
* nonlocal
* not
* or
* pass
* raise
* return
* True
* try
* while
* with
* yield

## Indentation
Python uses whitespace to delimit control flow blocks (following the off-side rule). Python borrows this feature from its predecessor ABC: instead of punctuation or keywords, it uses indentation to indicate the run of a block.

In so-called "free-format" languages—that use the block structure derived from ALGOL—blocks of code are set off with braces ({ }) or keywords. In most coding conventions for these languages, programmers conventionally indent the code within a block, to visually set it apart from the surrounding code.

A recursive function named foo, which is passed a single parameter, x, and if the parameter is 0 will call a different function named bar and otherwise will call baz, passing x, and also call itself recursively, passing x-1 as the parameter, could be implemented like this in Python:

```
def foo(x):
    if x == 0:
        bar()
    else:
        baz(x)
        foo(x - 1)
```
and could be written like this in C with K&R indent style:
```
void foo(int x)
{
    if (x == 0) {
        bar();
    } else {
        baz(x);
        foo(x - 1);
    }
}
```
Incorrectly indented code could be misread by a human reader differently than it would be interpreted by a compiler or interpreter. For example, if the function call foo(x - 1) on the last line in the example above was erroneously indented to be outside the if/else block:
```
def foo(x):
    if x == 0:
        bar()
    else:
        baz(x)
    foo(x - 1)
```
## Data structures
Since Python is a dynamically typed language, Python values, not variables, carry type information. All variables in Python hold references to objects, and these references are passed to functions. Some people (including Guido van Rossum himself) have called this parameter-passing scheme "call by object reference". An object reference means a name, and the passed reference is an "alias", i.e. a copy of the reference to the same object, just as in C/C++. The object's value may be changed in the called function with the "alias", for example:
```
>>> alist = ['a', 'b', 'c']
>>> def my_func(al):
...     al.append('x')
...     print(al)
...
>>> my_func(alist)
['a', 'b', 'c', 'x']
>>> alist
['a', 'b', 'c', 'x']
```
Function my_func changes the value of alist with the formal argument al, which is an alias of alist. However, any attempt to operate (assign a new object reference to) on the alias itself will have no effect on the original object.[clarification needed]

```
>>> alist = ['a', 'b', 'c']
>>> def my_func(al):
...     # al.append('x')
...     al = al + ['x'] # a new list created and assigned to al means al is no more alias for alist
...     print(al)
...
>>> my_func(alist)
['a', 'b', 'c', 'x']
>>> alist
['a', 'b', 'c']
```
## Variables
Variables are used to store information to be referenced and manipulated in a computer program. They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by the reader and ourselves. It is helpful to think of variables as containers that hold information. Their sole purpose is to label and store data in memory. This data can then be used throughout your program.
```
favourite_food = "Rösti"
print(favourite_food)
```
Note:

Variables do not need to be declared. Their data types are inferred from their assignment statement, which makes Python a dynamically typed language. This means that different data types can be assigned to the same variable throughout the code.
```
favourite_food = "Rösti"
print(favourite_food)
favourite_food = 26
print(favourite_food)
favourite_food = False
print(favourite_food)
```

## Operators
###Arithmetic
Python includes the +, -, *, / ("true division"), // (floor division), % (modulus), and ** (exponentiation) operators, with their usual mathematical precedence.

In Python 3, x / y performs "true division", meaning that it always returns a float, even if both x and y are integers that divide evenly.

```
>>> 4 / 2
2.0
```
and // performs integer division or floor division, returning the floor of the quotient as an integer.

In Python 2 (and most other programming languages), unless explicitly requested, x / y performed integer division, returning a float only if either input was a float. However, because Python is a dynamically typed language, it was not always possible to tell which operation was being performed, which often led to subtle bugs, thus prompting the introduction of the // operator and the change in semantics of the / operator in Python 3.

###Comparison operators
The comparison operators, i.e. ==, !=, <, >, <=, >=, is, is not, in and not in[16] are used on all manner of values. Numbers, strings, sequences, and mappings can all be compared. In Python 3, disparate types (such as a str and an int) do not have a consistent relative ordering. While it was possible to compare whether some string was greater-than or less-than some integer in Python 2, this was considered a historical design quirk and was ultimately removed in Python 3.

Chained comparison expressions such as a < b < c have roughly the meaning that they have in mathematics, rather than the unusual meaning found in C and similar languages. The terms are evaluated and compared in order. The operation has short-circuit semantics, meaning that evaluation is guaranteed to stop as soon as a verdict is clear: if a < b is false, c is never evaluated as the expression cannot possibly be true anymore.

For expressions without side effects, a < b < c is equivalent to a < b and b < c. However, there is a substantial difference when the expressions have side effects. 'a < f(x) < b will evaluate f(x)' exactly once, whereas 'a < f(x) and f(x) < b' will evaluate it twice if the value of a is less than f(x) and once otherwise.

### Logical operators
In all versions of Python, boolean operators treat zero values or empty values such as "", 0, None, 0.0, [], and {} as false, while in general treating non-empty, non-zero values as true. The boolean values True and False were added to the language in Python 2.2.1 as constants (subclassed from 1 and 0) and were changed to be full blown keywords in Python 3. The binary comparison operators such as == and > return either True or False.

The boolean operators and and or use minimal evaluation. For example, `y == 0 or x/y > 100` will never raise a divide-by-zero exception. These operators return the value of the last operand evaluated, rather than True or False. Thus the expression (4 and 5) evaluates to 5, and (4 or 5) evaluates to 4.



## Literals

### Strings

Python has various kinds of string literals.

###Normal string literals
Either single or double quotes can be used to quote strings. Unlike in Unix shell languages, Perl or Perl-influenced languages such as Ruby or Groovy, single quotes and double quotes function identically, i.e. there is no string interpolation of $foo expressions. However, interpolation can be done in various ways: with "f-strings" (since Python 3.6[12]), using the format method or the old % string-format operator.

For instance, all of these Python statements:
```
print(f"I just printed {num} pages to the printer {printer}")

print("I just printed {} pages to the printer {}".format(num, printer))
print("I just printed {0} pages to the printer {1}".format(num, printer))
print("I just printed {num} pages to the printer {printer}".format(num=num, printer=printer))

print("I just printed %s pages to the printer %s" % (num, printer))
print("I just printed %(num)s pages to the printer %(printer)s" % {"num": num, "printer": printer})
are equivalent to the Perl statement:

print "I just printed $num pages to the printer $printer\n"
They build a string using the variables num and printer.

Multi-line string literals
There are also multi-line strings, which begin and end with a series of three single or double quotes and function like here documents in Perl and Ruby.

A simple example with variable interpolation (using the format method) is:

print("""Dear {recipient},

I wish you to leave Sunnydale and never return.

Not Quite Love,
{sender}
""".format(sender="Buffy the Vampire Slayer", recipient="Spike"))
```
###Raw strings
Finally, all of the previously mentioned string types come in "raw" varieties (denoted by placing a literal r before the opening quote), which do no backslash-interpolation and hence are very useful for regular expressions; compare "@-quoting" in C#. Raw strings were originally included specifically for regular expressions. Due to limitations of the tokenizer, raw strings may not have a trailing backslash.[13] Creating a raw string holding a Windows path ending with a backslash requires some variety of workaround (commonly, using forward slashes instead of backslashes, since Windows accepts both).

Examples include:
```
>>> # A Windows path, even raw strings cannot end in a backslash
>>> r"C:\Foo\Bar\Baz\"
  File "<stdin>", line 1
    r"C:\Foo\Bar\Baz\"
                     ^
SyntaxError: EOL while scanning string literal

>>> dos_path = r"C:\Foo\Bar\Baz\ " # avoids the error by adding
>>> dos_path.rstrip()              # and removing trailing space
'C:\\Foo\\Bar\\Baz\\'

>>> quoted_dos_path = r'"{}"'.format(dos_path)
>>> quoted_dos_path
'"C:\\Foo\\Bar\\Baz\\ "'

>>> # A regular expression matching a quoted string with possible backslash quoting
>>> re.match(r'"(([^"\\]|\\.)*)"', quoted_dos_path).group(1).rstrip()
'C:\\Foo\\Bar\\Baz\\'

>>> code = 'foo(2, bar)'
>>> # Reverse the arguments in a two-arg function call
>>> re.sub(r'\(([^,]*?),([^ ,]*?)\)', r'(\2, \1)', code)
'foo(2, bar)'
>>> # Note that this won't work if either argument has parens or commas in it.
```

### Concatenation of adjacent string literals
String literals (using possibly different quote conventions) appearing contiguously and only separated by whitespace (including new lines), are allowed and are aggregated into a single longer string.[14] Thus
```
title = "One Good Turn: " \
        'A Natural History of the Screwdriver and the Screw'
is equivalent to

title = "One Good Turn: A Natural History of the Screwdriver and the Screw"
Unicode
```

Since Python 3.0, the default character set is UTF-8 both for source code and the interpreter. In UTF-8, unicode strings are handled like traditional byte strings. This example will work:
```
s = "Γειά" # Hello in Greek
print(s)
Numbers
Numeric literals in Python are of the normal sort, e.g. 0, -1, 3.4, 3.5e-8.
```
Python has arbitrary-length integers and automatically increases their storage size as necessary. Prior to Python 3, there were two kinds of integral numbers: traditional fixed size integers and "long" integers of arbitrary size. The conversion to "long" integers was performed automatically when required, and thus the programmer usually didn't have to be aware of the two integral types. In newer language versions the distinction is completely gone and all integers behave like arbitrary-length integers.

Python supports normal floating point numbers, which are created when a dot is used in a literal (e.g. 1.1), when an integer and a floating point number are used in an expression, or as a result of some mathematical operations ("true division" via the / operator, or exponentiation with a negative exponent).

Python also supports complex numbers natively. Complex numbers are indicated with the J or j suffix, e.g. 3 + 4j.

###Lists, tuples, sets, dictionaries
Python has syntactic support for the creation of container types.

Lists (class list) are mutable sequences of items of arbitrary types, and can be created either with the special syntax

`a_list = [1, 2, 3, "a dog"]`
or using normal object creation
```
a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)
```
Tuples (class tuple) are immutable sequences of items of arbitrary types. There is also a special syntax to create tuples
```
a_tuple = 1, 2, 3, "four"
a_tuple = (1, 2, 3, "four")
```
Although tuples are created by separating items with commas, the whole construct is usually wrapped in parentheses to increase readability. An empty tuple is denoted by (), while a tuple with a single value can be created with (1,).

Sets (class set) are mutable containers of hashable items[15] of arbitrary types, with no duplicates. The items are not ordered, but sets support iteration over the items. The syntax for set creation uses curly brackets

`some_set = {0, (), False}`

Python sets are very much like mathematical sets, and support operations like set intersection and union. Python also features a frozenset class for immutable sets, see Collection types.

Dictionaries (class dict) are mutable mappings tying keys and corresponding values. Python has special syntax to create dictionaries ({key: value})

`a_dictionary = {"key 1": "value 1", 2: 3, 4: []}`

The dictionary syntax is similar to the set syntax, the difference is the presence of colons. The empty literal {} results in an empty dictionary rather than an empty set, which is instead created using the non-literal constructor: set().




### Bibliography:
[Python Programming Language](https://en.wikipedia.org/wiki/Python_(programming_language))
[Python Organization](https://www.python.org/)
[Python Syntax and semantics](https://en.wikipedia.org/wiki/Python_syntax_and_semantics)

######*Note: This Technical article was written as an assignment for* **Python  Boot Camp by  @DSEAfrica  and  @lux_academy.**