Python Core Concepts

Python 3 programming fundamentals

Iniziamo. È gratuito!
o registrati con il tuo indirizzo email
Python Core Concepts da Mind Map: Python Core Concepts

1. Python functions

1.1. Python function positional arguments

1.2. Python function keyword arguments

1.2.1. if you mix keyword and positional arguments when invoking a function, all positional arguments must precede keyword, otherwise an exception will raise

1.3. Python function invocation

1.4. Python print() function

1.4.1. takes multi type arguments

1.4.2. converts all output to string type

1.5. Python built-in functions

1.6. Python input() function

1.6.1. take user input

1.6.2. optional string argument for prompt

1.6.3. must assign to variable

1.6.4. type returned is always string

1.6.4.1. but you can cast by enclosing input() in a cast function such as int()

1.7. Python range() function

1.7.1. often used with for loops

1.7.2. takes 3 args, all integers: start, stop, step

1.7.2.1. only stop is mandatory

1.7.2.1.1. last value produced is stop -1

1.7.2.2. start defaults to 0

1.7.2.3. step defaults to 1

1.7.3. example

1.7.3.1. range(10)

1.7.3.1.1. produces integers 0 to 9

1.7.3.2. range(2,8)

1.7.3.2.1. produces: 2 to 7

1.7.3.3. range(3,9,2)

1.7.3.3.1. produces: 3,5,7

1.8. Python len() function

1.8.1. often used with lists

1.8.2. takes object as argument and returns number of elements in that object

1.9. Python user-defined functions

1.9.1. syntax

1.9.1.1. def name_of_function(<optional params>): <function body>

1.9.2. functions are invoked

1.9.2.1. definition must precede invocation

1.9.2.2. after function body is executed, interpreter returns to line after invocation

1.9.3. function names must be unique and must not clash with variable names

1.9.4. if you invoke a function and pass any argument that is not matched to a parameter in the function definition, this will generate an exception

1.9.5. parameters exist inside functions, arguments exist outside functions

1.9.5.1. parameter values are set at moment of function invocation

1.9.5.2. parameters can only be declared between the parentheses ( ) of function definition

1.9.5.3. arguments can be passed two ways

1.9.5.3.1. positional arguments

1.9.5.3.2. keyword argument passing

1.9.5.3.3. you can mix styles but positional args must precede keyword args

1.9.5.3.4. beware passing arg as both positional and keyword, as it throws exception

1.9.5.4. parameters can be defined with default values, which kick in if the associated argument is omitted during invocation

1.9.5.4.1. def myFunction(firstName, lastName = "Smith"): print("Hello", firstName, lastName)

1.9.5.4.2. beware that you must place all pre-defined parameters at end, as you will get an exception if you mix them with mandatory parameters

1.9.5.5. parameters can be mapped to any valid Python type, including lists

1.9.6. parameter names can be same as variable names that are declared outside function

1.9.6.1. invokes shadowing

1.9.6.1.1. parameter takes temporary control of variable, then previous assignment returns

1.9.7. functions can produce effects and produce results

1.9.7.1. return

1.9.7.1.1. keyword

1.9.7.1.2. causes immediate termination of function body

1.9.7.1.3. without expression

1.9.7.1.4. with expression

1.9.7.1.5. functions can return any valid Python data type

1.10. Python tuple() function

1.10.1. convert an iterable type like a list or string to a tuple

1.11. Python list() function

1.11.1. convert an iterable type like a tuple or string to a list

1.12. Python dict() function

1.12.1. covert an iterable type in the right "key-value" structure to a dictionary

1.12.1.1. example of "right" structure (a tuple of tuples in this case)

1.12.1.1.1. colors = (("green", "#008000"), ("blue", "#0000FF")) colDict = {} for t in colors: colDict.update(dict([t])) print(colDict)

1.12.2. dict() supports 3 ways to create dictionary objects via its parameters: 1) keyword arguments (known as kwargs), 2) mapping, 3) iterable

1.12.2.1. **kwargs

1.12.2.1.1. print(dict(m=8, n=9))

1.12.2.1.2. kwargs can combine with mapping or iterable

1.12.2.1.3. ** means an arbitrary number of kwargs

1.12.2.2. mapping

1.12.2.2.1. print(dict({"m":8, "n":9}))

1.12.2.3. iterable

1.12.2.3.1. print(dict([("m",9),("n",10)]))

1.12.2.4. all arguments optional

1.12.2.4.1. dict()

2. Python data types

2.1. Python literal values

2.1.1. Python octal numbers

2.1.1.1. 0o prefix

2.1.2. Python hexadecimal numbers

2.1.2.1. 0x prefix

2.1.3. Python floating point numbers

2.1.3.1. Python number scientific notation

2.1.3.1.1. For very big or small numbers

2.1.3.1.2. exponent + 'E' + base

2.1.4. Python Booleans

2.2. Python strings

2.2.1. Python string escape characters

2.2.1.1. starts with \

2.2.1.1.1. example

2.2.2. Python multiline strings

2.2.2.1. """line 1 line 2"""

2.3. Python integers

3. Python operators

3.1. Python exponentiation

3.1.1. if either base or exponent is float vs int, float trumps and result is given in float

3.1.1.1. same applies to multiplication

3.1.2. **

3.2. Python division

3.2.1. /

3.2.2. result is always float even if dividend and divisor are int and result is whole number

3.3. Python floor division

3.3.1. //

3.3.2. aka integer division

3.3.3. Integer divisional operator (//) with one float will produce float result but fractional part rounded down to zero

3.4. Python modulo division

3.4.1. %

3.5. Binary vs Unary operators

3.5.1. Binary operator requires two arguments, one to left, one to right

3.5.1.1. Example: 3+5

3.5.2. Unary operator requires one argument to right

3.5.2.1. Example: -3

3.6. Python operator precedence

3.6.1. Python operator binding

3.6.1.1. When precedence order of operators is same, left binding generally takes precedence

3.6.1.1.1. Example: 6 % 3 % 2 is same as (6 % 3) % 2

3.6.1.1.2. Exception is exponention operator (**)

3.7. Python comparison operators

3.7.1. equality

3.7.1.1. ==

3.7.1.2. can assess int as equal to float

3.7.1.2.1. e.g. 2 == 2.0 returns True

3.7.1.3. can assess int as equal to True/False

3.7.1.3.1. e.g. 1 == True returns True

3.7.1.3.2. e.g. 0 == True returns False

3.7.1.3.3. e.g. 0 == False returns True

3.7.1.3.4. True is equal to 1, False is equal to 0

3.7.2. inequality

3.7.2.1. !=

3.7.3. less/more than

3.7.3.1. >

3.7.3.2. >=

3.7.3.3. <

3.7.3.4. <=

3.7.4. Precedence is below + and i binary operators

3.7.4.1. less/more trumps equality/inequality

4. Python variables

4.1. Python variable naming rules

4.1.1. upper/lower case letters, digits and underscore (_)

4.1.2. must begin with letter or underscore (_)

4.1.3. Python is case sensitive

4.1.4. cannot conflict with Python reserved words

4.1.4.1. Python reserved keywords

4.1.5. letters from non Latin alphabets also allowed

4.1.6. same naming rules apply to functions

4.2. Python variable declaration and assignment

4.2.1. var = val

4.2.2. you can also make multiple assignments in single line

4.2.2.1. example

4.2.2.1.1. a, b, c = 1, 3, 7

4.2.3. you can reverse variable assignments in single line

4.2.3.1. example

4.2.3.1.1. var1, var2 = var2, var1

4.2.4. you can also assign two or more variables to a single value in one line

4.2.4.1. example

4.2.4.1.1. var1 = var2 = 1

4.3. Python assignments and shortcut operators

4.3.1. Examples: += and -=

4.4. Python is dynamically typed

4.4.1. no need to declare type

4.4.2. re-assignment to different types allowed

5. Python PEP 8 style guide

5.1. Recommended standards for Python code style

6. Python comments

6.1. #

7. Python type cast functions

7.1. Python int() function

7.2. Python float() function

7.3. Python str() function

8. Python string concatenation

8.1. string + string

9. Python string replication

9.1. string * 5

10. Python conditional statements

10.1. indentation important

10.1.1. must be consistent

10.1.2. cannot mix tabs and spaces

10.2. Python if statement

10.2.1. if <Boolean expression>: <instruction(s)> elif <Boolean expression>: <instruction(s)> else: <instruction(s)>

10.2.2. when branch is single instruction, Python permits it to be on same line

10.2.2.1. example

10.2.2.1.1. if a > b: x = a else: x = b

10.3. if-elif-else is known as cascade

10.3.1. else branch must always be last in cascade

10.3.2. else is optional in cascade

11. Python loops

11.1. Python while loop

11.1.1. while condition_expression: <instruction(s)>

11.1.2. if condition is false on first evaluation, loop body is not executed even once

11.1.3. loop body should include instruction(s) that eventually change while loop's condition expression to False

11.1.4. If loop body never alters condition expression from True to False, you get an endless loop

11.1.4.1. Ctrl + C usually breaks out of endless loop

11.2. instructions in loop are called loop's body

11.3. Python for loop

11.3.1. for <control variable> in <collection>: <instruction(s)>

11.3.2. number of elements in collection determines loop repetitions

11.3.3. control variable is fed next collection element on each loop

11.4. Python break and continue

11.4.1. break halts loop and exits it

11.4.2. continue halts loop body and jumps to next iteration

11.5. else clause supported for both while and for

11.5.1. always runs exactly once even when main loop body does not run at all

12. Python logical operators

12.1. binary operators

12.1.1. and

12.1.1.1. logical conjunction

12.1.2. or

12.1.2.1. lower priority than and

12.1.2.2. logical disjunction

12.1.3. lower priority than comparison operators

12.2. unary operator

12.2.1. not

12.2.1.1. very high priority

12.2.1.1.1. equivalent to unary + and -

12.2.1.2. logical negation

12.3. De Morgan's laws

12.3.1. not (p and q) == (not p) or (not q) not (p or q) == (not p) and (not q)

12.4. any non 0 bit in whole evaluates to True

12.4.1. examples

12.4.1.1. print(bool(2 + 3))

12.4.1.1.1. returns True

12.4.1.2. print(bool(2 - 2))

12.4.1.2.1. returns False

12.4.1.3. print(not bool(2))

12.4.1.3.1. returns False

13. Python bitwise operators

13.1. &

13.1.1. bitwise conjunction

13.1.2. requires exactly two 1s to return 1, else 0

13.2. |

13.2.1. bitwise disjunction

13.2.2. requires at least one 1 to return 1, else 0

13.3. ~

13.3.1. bitwise negation

13.3.2. turns 1 to 0 and 0 to 1

13.4. ^

13.4.1. bitwise exclusive or (xor)

13.4.2. requires exactly one 1 to return 1, else 0

13.5. & | ^ have higher precedence than assignment operators but lower than comparison operators

13.6. Python shift operators

13.6.1. <<

13.6.1.1. left shift

13.6.1.1.1. example

13.6.2. >>

13.6.2.1. right shift

13.6.2.1.1. example

13.6.3. higher precedence than comparison operators, lower than binary arithmetic operators

13.7. arguments must be integers, floats are disallowed

13.8. unlike logical operators, bitwise operators act on individual bits of arguments

13.9. assignments, long and abbreviated

13.9.1. x = x & y

13.9.1.1. x &= y

13.9.2. x = x | y

13.9.2.1. x |= y

13.9.3. x = x ^ y

13.9.3.1. x ^= y

13.10. lowest bit is named bit number 0, second bit is bit #1, etc

13.11. bitmasks to check, reset and set bits

13.11.1. check bit (is set to 1)

13.11.1.1. if flagRegister & theMask: # my bit is set else: # my bit is reset

13.11.2. reset bit (to zero)

13.11.2.1. flagRegister = flagRegister & ~theMask

13.11.3. set bit (to 1)

13.11.3.1. flagRegister = flagRegister | theMask

13.12. Binary manipulation

14. Python Collections

14.1. Python Lists

14.1.1. defined by elements inside square brackets [ ]

14.1.2. mutable (i.e. changeable)

14.1.3. assignment example

14.1.3.1. numbers = [1, 4, 8, 10, 19]

14.1.3.2. myList = []

14.1.3.2.1. creates an empty list

14.1.4. accessed by index

14.1.4.1. zero-based

14.1.4.2. example

14.1.4.2.1. print(numbers[0])

14.1.4.2.2. print(numbers[4])

14.1.4.3. negative indexes allowed

14.1.4.3.1. -1 means last in list, -2 second to last, etc

14.1.5. duplicate values allowed

14.1.6. remove elements with del instruction

14.1.6.1. example

14.1.6.1.1. del numbers[1]

14.1.6.2. del reduces length of list (i.e. len() function will return previous value minus 1)

14.1.6.3. del can also remove slices from a list

14.1.6.3.1. example

14.1.6.4. when using del with a variable pointed to a list but no reference to an element or slice, only pointer is deleted, not the underlying list

14.1.6.4.1. example

14.1.7. Python list object methods

14.1.7.1. list.append()

14.1.7.1.1. takes 1 arg

14.1.7.1.2. adds arg to end of list

14.1.7.1.3. increases length of list by 1

14.1.7.2. list.insert()

14.1.7.2.1. takes 2 args

14.1.7.2.2. shifts all list elements to right of insert index by 1

14.1.7.2.3. increases length of list by 1

14.1.7.3. list.sort()

14.1.7.3.1. takes 0 - 2 args (i.e. both args optional)

14.1.7.4. list.reverse()

14.1.7.4.1. no args

14.1.7.4.2. reverses element order in list

14.1.7.5. list.count()

14.1.7.5.1. counts number of occurrences of arg value in list

14.1.8. for loop can access all list elements without needing to specify length or use indexes

14.1.8.1. syntax: for i in aList: print(i)

14.1.8.1.1. prints element value without needing to access index

14.1.9. Lists can be nested (e.g. lists within lists within lists, etc.)

14.1.10. List elements can be of mixed types

14.1.11. Lists can be added together using the binary + operator

14.1.11.1. list1 = [1,2] list2 = [3,4] print(list1 + list2)

14.1.11.1.1. [1,2,3,4]

14.1.12. Lists can be multiplied using the * operator and an integer

14.1.12.1. list1 = [1,2] print(list1 * 3)

14.1.12.1.1. [1,2,1,2,1,2]

14.2. Complex data types are stored differently to simple scalar types

14.2.1. for ordinary variable assigned to scalar value think of it as the name of the content

14.2.2. for variables assigned to complex types like lists, think of it as a memory location where the data is stored

14.2.2.1. important implication by example

14.2.2.1.1. list1 = [1] list2 = list1 list1[0] = 2 print(list2)

14.2.2.2. Python slice

14.2.2.2.1. use this to make copy of types like list

14.2.2.2.2. syntax is [start:end]

14.2.2.2.3. you can also specify increment, which if omitted, defaults to 1

14.3. Python membership operators

14.3.1. in

14.3.2. not in

14.3.3. return True or False when element found/not found in sequence

14.3.4. example

14.3.4.1. list1 = ["Hello","World"] print("Hello" in list1) print("Hello" not in list1)

14.3.4.1.1. returns: True False

14.4. Python list comprehension

14.4.1. Provides a concise way to create lists

14.4.2. syntax

14.4.2.1. [expression for element in list if conditional]

14.4.2.1.1. equivalent to

14.4.2.1.2. if conditional is optional

14.4.2.1.3. expression resolves to something that is added to list via the for loop

14.4.3. examples

14.4.3.1. x = "hello world" y = [x for i in range(4)] print(y)

14.4.3.1.1. returns

14.4.3.1.2. x is data used to fill list

14.4.3.1.3. clause specifying how many times to repeat x in list is: for i in range(4)

14.4.3.2. wordList = ["hello","world","how","are","you"] myWords = [w for w in wordList if w[0] == "h"] #all words beginning with 'h' print(myWords)

14.4.3.2.1. returns

14.4.3.2.2. w represents the iterating element in the list (wordList) and the data being picked to fill the new list (myWords)

14.4.3.2.3. if statement enables a conditional filter to determine which instances of w get added to new list

14.4.4. 2D arrays

14.4.4.1. aka matrix

14.4.4.2. think "table"

14.4.4.3. example

14.4.4.3.1. e = 0 myArray = [[e for i in range(3)] for i in range(3)] print(myArray)

14.5. Python sequence unpacking

14.5.1. syntactic sugar for exploding lists and tuples into multiple variable assignments in one line of code

14.5.1.1. list example

14.5.1.1.1. myList = [1, 2, 3] a, b, c = myList print(a) print(b) print(c)

14.5.1.2. tuple example

14.5.1.2.1. myTuple = (4, 5, 6) a, b, c = myTuple print(a) print(b) print(c)

14.5.1.3. but if you specify more than one variable on left side but that number does not correspond to number of sequence elements, this will raise exception

14.5.1.3.1. myTuple = (4, 5, 6) a, b = myTuple print(a) print(b) print(c)

14.6. Python Tuples

14.6.1. A tuple is an immutable sequence type

14.6.2. syntax to create them uses parentheses ( ) rather than the brackets [ ] used for lists

14.6.2.1. example

14.6.2.1.1. tuple1 = (1, 2, 4, 8) tuple2 = 1., .5, .25, .125

14.6.2.2. you can also create a tuple with just a comma separated element assignment

14.6.2.3. empty tuple assignment allowed, requires empty parentheses ( )

14.6.2.3.1. emptyTuple = ()

14.6.2.4. To create a 1-element tuple, you must put a comma after the element value, otherwise (if you omit comma) the variable will be assigned a single value type, not a tuple

14.6.2.4.1. oneElementTuple1 = (1, ) oneElementTuple2 = 1.,

14.6.3. elements can be mix of any data type, including complex types

14.6.4. For read operations, all the same methods used for lists work the same with tuples

14.6.5. Any attempt to use a list write operation on a tuple will raise an exception

14.6.5.1. myTuple = 1, 2, 3 del myTuple[2] #throws exception myTuple[2] = 4 #throws exception

14.6.5.2. myList = [1, 2, 3] myList.append(4) print(myList) myTuple = (1, 2, 3) myTuple.append(4) #throws exception print(myTuple)

14.6.5.3. but tuples can be deleted as a whole

14.6.5.3.1. del myTuple

14.6.6. You can use the binary + and * operators with tuples and the behaviour is the same as for lists

14.6.6.1. myTuple = 1, 2, 3 myTuple += 4, print(myTuple)

14.6.6.1.1. returns

14.6.6.1.2. note: the += "addition to self" combines two tuples into a new tuple and re-assigns variable to that

14.6.7. You can use the in and not operators with tuples and the behaviour is the same as for lists

14.7. Python Dictionaries

14.7.1. A dictionary is mutable but not a sequence type

14.7.1.1. In Python 3.6x dictionaries have become ordered collections by default.

14.7.2. Elements are key-value pairs

14.7.2.1. key and value are separated by colon

14.7.2.2. key-value pairs are separated by commas

14.7.3. Every key must be unique

14.7.4. Keys can be numbers (int or float) or strings

14.7.5. syntax for assignment uses curly braces { }

14.7.5.1. myE2IDictionary = { "hi" : "ciao", "today" : "oggi", "kiss" : "bacio" }

14.7.6. When keys are string type, they are case-sensitive

14.7.7. Values are retrieved by using keys in same style as list and tuple elements are retrieved via indexes [ key ]

14.7.7.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict["dog"])

14.7.7.1.1. returns

14.7.7.2. you can also use dictionary get() method

14.7.7.2.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict.get("dog"))

14.7.8. Key must exist, else exception is thrown

14.7.8.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} print(dict["Dog"])

14.7.8.1.1. throws exception

14.7.8.2. avoid this exception using in or not in operations

14.7.8.2.1. if "horse" in dict: print(dict["horse"]) else: print("horse not in dictionary")

14.7.9. dictionaries can be iterated using for loops, and there are various dictionary methods that can be useful

14.7.9.1. keys()

14.7.9.1.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} for key in dict.keys(): print(key,"->",dict[key])

14.7.9.2. sorted()

14.7.9.2.1. to get a sorted key list, you can use the built in sorted() function

14.7.9.3. items()

14.7.9.3.1. you can also iterate using the items() method, which returns all the key-value pairs as a list of tuples

14.7.9.4. values()

14.7.9.4.1. you can also iterate using the values() method, which returns all the values as a list

14.7.9.5. you can also iterate a dictionary without using any of these methods, as a for loop will naturally iterate all the keys

14.7.9.5.1. dict = {"cat" : "chat", "dog" : "chien", "horse" : "cheval"} for key in dict: print(key,"->",dict[key])

14.7.9.6. when for loop specifies two or more dictionaries to iterate, the loop variable references the whole dictionary rather than the keys

14.7.9.6.1. for example, this code combines two dictionaries together in a third one (d3)

14.7.10. modifying dictionaries

14.7.10.1. update values

14.7.10.1.1. dict['cat'] = "miccio"

14.7.10.1.2. dict.update({'dog' : 'canelino'})

14.7.10.2. add key-value pairs

14.7.10.2.1. dict['snake'] = 'serpente'

14.7.10.2.2. dict.update({'cow' : 'mucca'})

14.7.10.3. delete key-value pairs

14.7.10.3.1. del dict["snake"]

14.7.10.3.2. dict.popitem()

14.7.10.3.3. del dict

14.7.10.3.4. dict.clear()

14.7.11. copying dictionaries with the copy() method

14.7.11.1. copyDict = dict.copy()

15. Python methods

15.1. like function but dependent on class (object)

15.2. invocation differs to function

15.2.1. object.method()

15.3. can alter internal state of object

16. Python modules

17. Python None value

17.1. None is a reserved keyword

17.2. you can assign to a variable or return it from an invoked function

17.3. assigning a variable to a function that doesn't include a return will assign None to that variable

18. Python global keyword and variable scope

18.1. when preceding variable name in a function (or other structure with local scope), enables function to change value of variable that persists outside function body

18.2. for multiple variables, separate each by comma after global password

18.3. example

18.3.1. def myFunction(): global x x = 4 print("x is set inside function") x = 3 myFunction() print(x)

18.3.1.1. returns

18.3.1.1.1. x is set inside function 4

18.4. as general rule, variable declared and assigned in main program has scope inside function body, but variables declared and set inside functions have local scope only

18.4.1. assigning new value to external variable will only affect value inside function unless you previously declare variable inside function body using global keyword

18.4.1.1. del with lists is exception

18.4.1.1.1. x = [5,10] def myFunction(y): print("inside, x =",x) del x[0] print("inside, x =",x) myFunction(x) print("outside, x =",x)

18.4.2. don't try to read external variable and then set it, as you will get exception (local variable referenced before assignment), but global declaration can fix that

18.4.2.1. bad example (throws exception)

18.4.2.1.1. x = 5 def myFunction(y): a = x x = y + 1 print("inside, x =",x) myFunction(x) print("outside, x =",x)

18.4.2.2. good example (no exception)

18.4.2.2.1. x = 5 def myFunction(y): global x a = x x = y + 1 print("inside, x =",x) myFunction(x) print("outside, x =",x)

18.5. you can declare variable inside function with same name as a variable declared outside function, but in this case local variable is treated as separate with local scope only

19. Python backslash \ to break long lines of code

19.1. example

19.1.1. print("This is a really long line \ but we can split it over multiple lines to improve readability")

20. Python function recursion

20.1. Function that invokes itself

20.1.1. example

20.1.1.1. def fib(n): if n < 1: return None if n < 3: return 1 return fib(n - 1) + fib(n - 2) for n in range(1, 10): print(n, "->", fib(n))

20.1.2. recursive invocation should involve reducing the problem towards a base case that solves the problem

20.1.2.1. adding print helps clarify

20.1.2.1.1. failure example (endless loop)

20.1.2.1.2. success example (base case)

20.1.2.2. you will need an if statement to ensure base case is satisfied and recursion ends

20.2. Beware that recursive function calls can consume a lot of memory and care must be taken to avoid endless loop conditions

21. Python sequences

21.1. collections that have a fixed ordering to their elements

21.2. can be iterated over by a for loop

22. Python mutable and immutable data types

22.1. mutable types allow element values to be changed after initial variable assignment, via index reference - immutable types do not

22.2. immutable types

22.2.1. in-built types like int, float, bool, string, unicode, tuple

22.2.1.1. example

22.2.1.1.1. myString = "Hello" myString[1] = "a"

22.3. mutable types

22.3.1. list, dict, set

22.4. Immutable objects are quicker to access and are expensive to change because it involves the creation of a copy. Whereas mutable objects are easy to change.

23. Multiple versions of Python

23.1. Python language was created by Guido van Rossum and first released in 1991

23.1.1. Guido is President of the Python Software Foundation (PSF)

23.1.1.1. PSF official website is python.org

23.2. Python 2 and Python 3 are two active versions that are not compatible with one another

23.2.1. Python 3 first released in 2008 is a major revision of the language

23.2.1.1. there are multiple dot releases for Python 3, which are fully backward compatible within the Python 3 family of versions

23.2.2. Python 2 development cycle ended quite some time ago, but continued to receive bug fixes, security enhancements, etc for many years

23.2.2.1. 1st Jan 2020 was Python 2 official sunset date, set by the PSF

23.2.2.1.1. Post sunset, Python 2 is officially no longer supported - no more bug fixes or security enhancements - users are urged to complete transition to Python 3

23.3. In addition to Python 2 and Python 3, there is more than one version of each

23.3.1. Pythons developed and maintained by people working under umbrella of PSF are known as canonical or reference versions - this is because Guido is President of PSF

23.3.1.1. these official versions of Python are also known as CPython

23.3.1.1.1. All versions of CPython are developed using the C language

23.3.1.1.2. Virtually all platforms have built in support for compiling and running C programs, which makes CPython highly portable across platforms

23.3.2. Cython is a Python superset that is intended to solve one of CPython's weaknesses, which is relatively slow performance (because CPython is an interpreted language)

23.3.2.1. Cython automatically translates Python code into C and in doing so makes the code significantly faster to execute

23.3.3. Jython is a version of Python developed in Java rather than C

23.3.3.1. useful for large & complex systems developed entirely with Java that need Python flexibility added

23.3.3.2. Java and C have little in common, which can make integrating CPython into Java environments difficult

23.3.3.3. Jython conforms to Python 2 standards, but does not yet support Python 3

23.3.4. PyPy is a version of Python developed in RPython

23.3.4.1. RPython stands for Restricted Python, which is a subset of CPython

23.3.4.2. Like Cython, PyPy translates Python code into C before execution, thereby making for faster code execution

23.3.4.3. PyPy is mostly used by developers that are developing the Python language itself

23.3.4.3.1. not really a choice for a regular developer like me!

23.3.4.4. PyPy supports both Python 2 and 3