Most programming languages require a way of representing types (numbers especially) in memory.
Interpreters as Python crucially rely on type representation to instrument calculations: +, -, *, /, …
Rule(s)
- Python views common numbers (integers, floating point numbers…) as
constructed types instead of primitive types. For example, integers are unbounded in Python.
Example
import math
import sys
# Integers are unbounded in Python 3.x
my_int = int()
print('my_int', my_int) # '0'
print('Size of \'int\'',
sys.getsizeof(int())) # Size (in bytes) of an *instance* of the 'int' class, namely size of '0'...
# Disappeared from Python 3.x:
# print('long', sys.getsizeof(long())) # Size of an *instance* of the 'long' class
one_bit_set = [False, False, False, False, False, False, False, True] # 8 bits...
one = int()
for value in one_bit_set:
one = one << 1
one = one | 1 if value else one
print(bin(one)) # '0b1'
two_bit_set = [False, False, False, False, False, False, True, False]
two = int()
for value in two_bit_set:
two = two << 1
two = two | 1 if value else two
print(bin(two)) # '0b10'
three = int('00000011', 2)
print(three)
minus_nine = ~(9 - 1)
print(minus_nine, bin(minus_nine))
minus_ten = ~(10 - 1)
print(minus_ten, bin(minus_ten))
print(type(math.pi)) # '<class 'float'>'
# https://docs.python.org/3/library/stdtypes.html#float.hex ->
print(float.hex(math.pi)) # [sign] ['0x'] integer ['.' fraction] ['p' exponent] -> '0x1.921fb54442d18p+1'
print(float.fromhex('0x1.921fb54442d18p+1'))
Numerical stability
Rule(s)
sys.float_info
provides information on
memory representation constraints
about floating point numbers.
Example
# https://docs.python.org/3/library/sys.html#sys.float_info
print('Max float: ', sys.float_info.max)
print('Epsilon such that there is *no* \'x\' such that \'1 < x < 1 + sys.float_info.epsilon\': ',
sys.float_info.epsilon)
# Floating point numbers are not primitive:
my_float = float()
my_other_float = float()
my_yet_another_float = my_float
print(my_float == my_other_float) # 'True' is displayed since both are qual to '0'
assert (not my_float is my_other_float) # 'is' and 'id()' are *totally* equivalent
assert (my_float is my_yet_another_float)
assert (not id(my_float) == id(my_other_float))
assert (id(my_float) == id(my_yet_another_float))
Accessing to bytes…
Rule(s)
- In a more generic way,
bytearray
is
a relevant class to deal with byte sets as internal representation of objects: strings, etc.
Example
b = bytearray('ABC', 'utf-8')
print(b, 'size:', len(b))
for character in b:
print(bin(character)) # Display: '0b1000001' '0b1000010' '0b1000011'
print('**')
print(bytearray([65, 66, 67]).decode('utf-8')) # Display: 'ABC'
Resource(s)
- Numbers.py.zip
See also
Although dictionaries (a.k.a. hash tables, hash maps, associative containers, etc.) are fully fledged collections,
choosing a dictionary as underlying data representation structure hotly is a question of fluent data processing.
More details on Python collections are
here…
Example
from collections import OrderedDict
class Polynomial:
def __init__(self, *elements):
self.__representation = {} # Python common dictionary...
for e in elements:
# print(e)
self.__representation[e[1]] = e[0] # Powers are keys...
# sorted(self.__representation) # Sort on keys (ascending)... returns a list...
# Required for Horner eval.:
self.__representation = OrderedDict(sorted(self.__representation.items(), key=lambda pair: pair[0],
reverse=True)) # Sort on keys (descending)...
# print(type(self.__representation)) # '<class 'collections.OrderedDict'>' is displayed
# print(self.__representation)
def eval(self, x):
result = 0
for key, value in self.__representation.items():
# print(key)
result += pow(x, key) * value
return result
# https://en.wikipedia.org/wiki/Horner%27s_method
def eval_Horner(self, x): # Horner method that required less multiplication stuff...
prior_key = None
result = 0
for key in self.__representation:
if prior_key is not None:
assert key < prior_key # Imposed by sorting in '__init__'
# print(key)
result += self.__representation.get(prior_key)
for i in range(prior_key, key, -1):
# print(i, end='-')
result *= x
prior_key = key
result += self.__representation.get(prior_key)
for i in range(prior_key, 0, -1):
# print(i, end='-')
result *= x
return result
p1 = Polynomial((5, 2), (-3, 1), (8, 0))
print('eval p1:', p1.eval(2)) # '22' is displayed
print('eval_Horner:', p1.eval_Horner(2))
p2 = Polynomial((-12, 10), (8, 39))
print('eval p2:', p2.eval(1)) # '-4' is displayed
print('eval_Horner:', p2.eval_Horner(1))
p3 = Polynomial((3, 11), (-8, 7), (-7, 1), (-43, 0))
print('eval p3:', p3.eval(5)) # '145859297' is displayed
print('eval_Horner:', p3.eval_Horner(5))
Resource(s)
- Polynomial.py.zip
Hash method overriding
Rule(s)
- For homemade built types acting as the type of keys in dictionaries, the overriding of the
__hash__
function is mandatory along with that of the __eq__
function.
- As in many other programming languages, the crucial rule to be respected is:
x == y ⇒ hash(x) == hash(y)
.
Example (homemade built type)
import re
class N_INSEE:
# Similar to 'static initializer' in Java:
_Expression_reguliere_N_INSEE = re.compile("^\d{13}$",
re.ASCII) # 're.ASCII' only allows [0-9] in excluding UNICODE digits
# Improve regular expression as follows (https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France):
# One digit sex between '1' and '2'
# 2 digits birth year between '01' and '99'
# 2 digits birth month between '01' and '12'
# Etc
@staticmethod
def Format_N_INSEE():
return N_INSEE._Expression_reguliere_N_INSEE
def __init__(self, valeur, clef):
assert clef >= 1 and clef <= 97 # Pre-condition
# print(re.findall('^\d{13}$', valeur))
self._valeur = None
if N_INSEE.Format_N_INSEE().match(valeur) is not None:
self._valeur = int(valeur)
def __eq__(self, n_insee): # Python 3 *IMPLICITELY* implements '__ne__(self, n_insee)' while Python 2 *DOESN'T*!
return self.__class__ == n_insee.__class__ and self._valeur == n_insee._valeur
def __hash__(self):
return hash(self._valeur)
def clef(self):
if self._valeur is None:
raise Exception("Le N°INSEE n'est pas conforme au format " + '"^\d{13}$"')
return 97 - self._valeur % 97
Example (homemade built type as type of keys in ordinary dictionaries)
from N_INSEE import N_INSEE
class University:
def __init__(self, *students):
self.__students = {} # Python common dictionary...
for s in students:
# print(s)
self.__students[s.get_n_insee()] = s # Danger: index is based on a *HOMEMADE* built type!
def count(self):
return len(self.__students)
def search(self, s):
if s.get_n_insee() in self.__students:
return True
return False
class Student:
def __init__(self, surname, given_name, student_id, n_insee, photo=None):
self._surname = surname
self._given_name = given_name
self._student_id = student_id
self._n_insee = n_insee # Type is 'N_INSEE'
# Etc.
def get_n_insee(self):
return self._n_insee
fb1 = Student('Barbier', 'Franck', '?', N_INSEE('1630125388055', 29))
fb2 = Student('Barbier', 'Franck', '?', N_INSEE('1630125388055', 29))
u = University(fb1, fb2)
print(u.count()) # '2' is displayed '__eq__(self, n_insee)' '__hash__(self)' are *NOT* overridden!
Resource(s)
- N_INSEE.Python.zip
See also
pip is the most famous Python library (package)
manager as Maven Repository
for Java or npm for JavaScript.
Example (Operating System (OS) level)
# 'Carrefour_Items_requirements.txt' file
beautifulsoup4
Pillow
requests
…
# Test access and version:
pip -V
pip install -r Carrefour_Items_requirements.txt
Example (library access and use)
from bs4 import BeautifulSoup # https://pypi.org/project/beautifulsoup4/
import os # built-in package
import requests # https://pypi.org/project/requests/
…
def request_Carrefour_Items(search_text):
headers = {
'accept': "application/json",
'content-type': "application/json",
'x-ibm-client-id': Carrefour_Items.Get_X_ibm_client_id(),
'x-ibm-client-secret': Carrefour_Items.Get_X_ibm_client_secret()
}
query = "{\"queries\":[{\"query\":\"" + search_text + "\",\"field\":\"barcodeDescription\"}]}"
return requests.post("https://api.fr.carrefour.io/v1/openapi/items", data=query, headers=headers).json()
Resource(s)
- Carrefour_Items.Python.zip