Python
Data Model

Hash Functions

(Racapitulando ED2...)

Problema

Como separar a platéia em 2 grupos

± do mesmo tamanho?

Idéia 1

Conte 1 2 1 2 ... para cada pessoa e cada um estará num grupo

Idéia 1

Conte 1 2 1 2 ... para cada pessoa e cada um estará num grupo

Mas se quisermos voltar no próximo meetup e ainda ter 2 grupos razoavelmente iguais (em tamanho)?

Problema v2

Como separar a platéia em 2 grupos ± do mesmo tamanho, tal que nos próximos meetups eu consiga saber qual grupo estava, e novas pessoas também possam entrar, mantendo os tamanhos dos grupos equilibrados?

Problema v2

Como separar a platéia em 2 grupos ± do mesmo tamanho, tal que nos próximos meetups eu consiga saber qual grupo estava, e novas pessoas também possam entrar?

Requisito 1

Determinismo

Determinismo

 

Dado uma pessoa, o número dela será sempre o mesmo

Idéia 2

Determine o grupo a partir da data de aniversário da pessoa

Dia do aniversario:

      Par   →   Grupo 0

Impar   →   Grupo 1

Idéia 3

Determine o grupo a partir da data de aniversário da pessoa

1º Algarismo do Mes da pessoa

0   →   Grupo 0

1   →   Grupo 1

Jan 01 , Ago 08, Maio 05 → 0

Outubro 10 , Dezembro 12 → 1

Distribuição de Nascimentos nos meses: Uniforme

P(mes = M) = 1/12
P(mes=M)=1/12P(mes = M) = 1/12

Distribuição de Nascimentos nos dias: Uniforme

P(dia = N) = 1/30
P(dia=N)=1/30P(dia = N) = 1/30

Idéia 2

P ( dia | PAR) = \sum_{i=1}^{15} P(i) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(diaPAR)=i=115P(i)=i=1151/30=15/30=0.5=50%P ( dia | PAR) = \sum_{i=1}^{15} P(i) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(dia | IMPAR) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(diaIMPAR)=i=1151/30=15/30=0.5=50%P(dia | IMPAR) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}

Idéia 3

P ( mes | 0X ) = P(01) + P(02) + P(03) + P(04) + P(05) + P(06) + P(07) + P(08) + P(09) =
P(mes0X)=P(01)+P(02)+P(03)+P(04)+P(05)+P(06)+P(07)+P(08)+P(09)=P ( mes | 0X ) = P(01) + P(02) + P(03) + P(04) + P(05) + P(06) + P(07) + P(08) + P(09) =
P ( mes | 0X ) = \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} = \frac{9}{12} = 0.75 = \mathbf{75\%}
P(mes0X)=112+112+112+112+112+112+112+112+112=912=0.75=75%P ( mes | 0X ) = \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} = \frac{9}{12} = 0.75 = \mathbf{75\%}
P ( mes | 1X ) = P(10) + P(11) + P(12) = \frac{1}{12} + \frac{1}{12} = \frac{3}{12} = 0.25 = \mathbf{25\%}
P(mes1X)=P(10)+P(11)+P(12)=112+112=312=0.25=25%P ( mes | 1X ) = P(10) + P(11) + P(12) = \frac{1}{12} + \frac{1}{12} = \frac{3}{12} = 0.25 = \mathbf{25\%}

Idéia 2

P ( dia | PAR) = \sum_{i=1}^{15} P(i) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(diaPAR)=i=115P(i)=i=1151/30=15/30=0.5=50%P ( dia | PAR) = \sum_{i=1}^{15} P(i) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(dia | IMPAR) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}
P(diaIMPAR)=i=1151/30=15/30=0.5=50%P(dia | IMPAR) = \sum_{i=1}^{15}1/30 = 15/30 = 0.5 = \mathbf{50\%}

Idéia 3

P ( mes | 0X ) = P(01) + P(02) + P(03) + P(04) + P(05) + P(06) + P(07) + P(08) + P(09) =
P(mes0X)=P(01)+P(02)+P(03)+P(04)+P(05)+P(06)+P(07)+P(08)+P(09)=P ( mes | 0X ) = P(01) + P(02) + P(03) + P(04) + P(05) + P(06) + P(07) + P(08) + P(09) =
P ( mes | 0X ) = \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} = \frac{9}{12} = 0.75 = \mathbf{75\%}
P(mes0X)=112+112+112+112+112+112+112+112+112=912=0.75=75%P ( mes | 0X ) = \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} + \frac{1}{12} = \frac{9}{12} = 0.75 = \mathbf{75\%}
P ( mes | 1X ) = P(10) + P(11) + P(12) = \frac{1}{12} + \frac{1}{12} = \frac{3}{12} = 0.25 = \mathbf{25\%}
P(mes1X)=P(10)+P(11)+P(12)=112+112=312=0.25=25%P ( mes | 1X ) = P(10) + P(11) + P(12) = \frac{1}{12} + \frac{1}{12} = \frac{3}{12} = 0.25 = \mathbf{25\%}

Problema v2

Como separar a platéia em 2 grupos ± do mesmo tamanho, tal que nos próximos meetups eu consiga saber qual grupo estava, e novas pessoas também possam entrar?

Requisito 2

Uniformidade

Uniformidade

 

A função espalha de forma uniforme as entradas nas saídas

Distribuição Uniforme

Uniformidade

 

A função espalha de forma uniforme as entradas nas saídas

Distribuição Uniforme

Tamanho Fixo

 

A saída deve ter ter que estar dentro de uma faixa

=

A saída tem que ter número fixo de bits

>>> hash(10)
10
>>> hash(2**100)
68719476736
>>> hash("")
0
>>> hash("Ola")
3275334880683988321
>>> hash("Olá")
-3830807016388316699
>>> hash("Ola mundo")
7184885651759528628
>>> hash("Ola mundo! Como esta")
-4748936365567857139
>>> hash("Ola mundo! Como esta?")
-2371297093152996703

Hash Table

Hashmap

Listas

Listas

>>> l = [12, 99, 37]
>>> l[0]
12
>>> l[1]
99
>>> l[2]
37
>>> l[-1]
37
>>> l[0:1]
[12]
>>> l[0:2]
[12, 99]
>>> l[0] = 'string'
>>> l
['string', 99, 37]
>>> del l[2]
>>> l
['string', 99]

Hashtable

Colisão

Crescimento

Dictionary

dict()

Dictionary

dict()

Mapeia númeos e strings para algum objeto

Nome para Hashtables no Python!

>>> dicionario_vazio = dict()
>>> dicionario_vazio = {}
>>> d = { 1:1, 2:4, 3:9 }
>>> d
{1: 1, 2: 4, 3: 9}
>>> d.keys()
[1, 2, 3]
>>> d.values()
[1, 4, 9]
>>> d.items()
[(1, 1), (2, 4), (3, 9)]
>>> d[2]
4
>>> d[8]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 8
>>> d[10] = 100
>>> d
{1: 1, 2: 4, 3: 9, 10: 100}
>>> a = { 1:10, "python": "de mais", 100: "Cem", "Zero": 0}
>>> a
{'python': 'de mais', 1: 10, 'Zero': 0, 100: 'Cem'}
>>> a['python']
'de mais'
>>> a[100]
'Cem'
>>> a['python'] = "D+"
>>> del a[1]
>>> a
{'python': 'D+', 'Zero': 0, 100: 'Cem'}
>>> a.keys()
['python', 'Zero', 100]
>>> a.values()
['D+', 0, 'Cem']

Python Objects

object()
>>> class ClassName(object):
...     def __init__(self, arg):
...             self.arg = arg
...     def __del__(self):
...             print "good bye"
...     def method_name(self):
...             pass
...     def method_with_arg(self, arg1, arg2):
...             print arg1, arg2
... 
>>> o = ClassName(42)
>>> print o.arg
42
>>> o.method_with_arg("Hi", "There")
Hi There
>>> del o
good bye
cpython/Include/object.h:77-116

typedef struct _object {
    long int ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;



typedef struct {
    long int ob_refcnt;
    struct _typeobject *ob_type;
    long int ob_size;
    /* Number of items in variable part */
} PyVarObject;
cpython/Include/typestruct.h
typedef struct _typeobject {
    PyObject_VAR_HEAD
    char *tp_name; /* For printing, in format "<module>.<name>" */
    int tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    printfunc tp_print;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    cmpfunc tp_compare;
    reprfunc tp_repr;

    /* Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* More standard operations (here for binary compatibility) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Functions to access object as input/output buffer */
    PyBufferProcs *tp_as_buffer;

    /* Flags to define presence of optional/expanded features */
    long tp_flags;

    char *tp_doc; /* Documentation string */

    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    long tp_weaklistoffset;

    /* Added in release 2.2 */
    /* Iterators */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Attribute descriptor and subclassing stuff */
    struct PyMethodDef *tp_methods;
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset;
    struct _typeobject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    long tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Low-level free-memory routine */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* method resolution order */
    PyObject *tp_cache;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;

} PyTypeObject;

References

variável   string que aponta pra um objeto

Font: https://www.safaribooksonline.com/library/view/learning-python-5th/9781449355722/ch06s02.html

dictionaries

{

    var1: obj1,

    var2: obj2,

    func1: obj3,

    module1: obj4

}
{

    var1: obj1,

    var2: obj2,

    func1: obj3,

    module1: {
        var_intern1: objn,
        (...)
    }

}

GC

Garbage Collector

GC

Garbage Collector


A = object()

if True:
    B = object()


del A

function()

print "END"

GC

Garbage Collector


A = object()

if True:
    B = object()
         # B disposable

del A    # A disposable

function()

print "END"

typedef struct _object {
    long int ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;
>>> class ClassName(object):
...     def __init__(self, arg):
...             self.arg = arg
...     def __del__(self):
...             print "good bye", self.arg
... 
>>> o = ClassName(42)
>>> del o
good bye 42
>>> if True:
...     n = ClassName("Jim")
... 
good bye Jim

Objects
Attributes

  • (Im)mutable
  • Callable
  • Hashable
  • Iterable
  • Descriptor
  • Container
    • Sequences
    • Mapping
  • ABC & Others

Objects Attributes

(Im) mutable

Immutable: may be reused

Mutable: Always different instances

>>> a=1
>>> b=1
>>> a is b
True
>>> a=[]
>>> b=[]
>>> a is b
False    # a is not b
>>> c = d = []
>>> c is d
True

callable

callable(object)
>>> callable(None)
False
>>> callable(10)
False
>>> callable(object)
True
>>> callable(pow)
True
/* Test whether an object can be called */
int
PyCallable_Check(PyObject *x)
{
	if (x == NULL)
		return 0;
	if (PyInstance_Check(x)) {
		PyObject *call = PyObject_GetAttrString(x, "__call__");
		if (call == NULL) {
			PyErr_Clear();
			return 0;
		}
		/* Could test recursively but don't, for fear of endless
		   recursion if some joker sets self.__call__ = self */
		Py_DECREF(call);
		return 1;
	}
	else {
		return x->ob_type->tp_call != NULL;
	}
}
cpython/Objects/object.c:1655
def callable(obj):
	return obj and hasattr(obj, '__call__')

Hashable

Immutable

 

__hash__()

__eq__() or __cmp__()

 

object.__hash__ == id

Iterable

__iter__() or __getitem__()

 

iter(obj)

next(iter)


StopIteration

Descriptor

__get__()
__set__()
__delete__()

property([fget[, fset[, fdel[, doc]]]])
class C(object):
    def __init__(self):
        self._x = None

    def getx(self):
        print "get x"
        return self._x

    def setx(self, value):
    	print "set x", value
        self._x = value

    def delx(self):
        print "del x"
        del self._x

    x = property(getx, setx, delx,
                 "I'm the 'x' property.")

property()

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        print "get x"
        return self._x

    @x.setter
    def x(self, value):
    	print "set x", value
        self._x = value

    @x.deleter
    def x(self):
        print "del x"
        del self._x

property()

>>> c = C()
>>> c.x
get x
>>> c.x = 10
set x 10
>>> c.x
get x
10
>>> del c.x
del x
>>> c.x
get x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 9, in x
AttributeError: 'C' object has no attribute '_x'
>>> c.x = 20
set x 20
>>> c.x
get x
20

property()

Container

Objects that references other objects

Sequence

__getitem__()
__len__()
  • tuple
  • list
  • str
  • unicode
  • bytes

A container

Mapping

lookups use arbitrary immutable keys rather than integers

  • dict
  • collections.defaultdict
  • collections.OrderedDict
  • collections.Counter

A container

Outros

Interfaces de Duck Typing

Arquivos

Bytes-like object

etc

ABC

Just easy as Do Re Mi

ABC

Abstract Base Classes 

Type Hierarchy

Type Hierarchy

  • None
  • NotImplemented
  • Ellipsis
  • numbers.Number
    • numbers.Integral
      • int
      • long
      • bool
    • numbers.Real:   float
    • numbers.Complex:   complex

Sequences

  • Immutable
    • String: str | bytes
    • Unicode: unicode | str
    • tuple
  • Mutable
    • list
    • bytearray
    • array (module)

Sets

  • set
  • frozenset

 

 

Mappings

  • dict

Type Hierarchy

Callable

  • User-defined function
  • User-defined methods | Instance Methods
  • Generator functions
  • | Coroutine functions
  • Built-in functions
  • Built-in methods
  • Class types
  • Classic Classes |
  • Class instances

Type Hierarchy

  • Modules
  • Classes | Custom Classes
  • Class Intances
  • Files | IO Objects
  • Internal Types
    • Code objects
    • Frame Objects
    • Traceback Objects
    • Slice Objects
    • Static method objects
    • Class method objects

Type Hierarchy

Data Model

Special Names

__somename__

_ _ duplos underscores _ _

Special Attributes

object.__dict__

Subtitle

Special Methods

Python Object Model

By Allan Daemon

Python Object Model

Lecture on Python Object Model for Python Triângulo

  • 737