20171030 - TNUI-UB/grupA-sessions GitHub Wiki
Parcial dimecres 8 de novembre
-
Consistirà en teoria i pràctiques. Molt probablement, sereu tota l'estona (màx 3 h) en una aula d'informàtica i allà fareu la teoria i la pràctica.
-
Part pràctica
- reviseu el que hem fet fins ara. Entra pràctica 0 i 1.
- no heu de memoritzar res, els algorismes s'explicaran.
-
Dubtes?
Pràctica 1: Apriori
- Revisem alguna funció:
filter_by_support()
,naive()
igenerate_next()
.
def filter_by_support(df, all_sets, min_support):
"""
Donades totes les combinacions i el suport mínim, retorna un altre
DataFrame amb solament aquelles combinacions que tenen un suport
major al mínim
:param df: DataFrame de dades
:param all_sets: DataFrame de combinacions, amb `order_id` i `products`
:param min_support: Suport mínim de les combinacions
:return: DataFrame amb estructura igual que `all_sets` però filtrat segons el
suport mínim
"""
counts = all_sets['products'].value_counts()
return all_sets[all_sets['products'].isin(counts[counts >= min_support].index)]
def naive(df, target_n, min_support):
"""
Donat el conjunt original, la $n$ objectiu i el suport mínim,
calcula aquelles combinacions freqüents de forma Naive, utilitzant
les funcions programades adalt.
:param df: DataFrame de dades
:param target_n: $n$ objectiu
:param min_support: Suport mínim de les combinacions
:return: DataFrame de combinacions, amb `order_id` i `products`, amb
combinacions de tamany $n$ i filtrat pel suport mínim
"""
all_sets = get_all_n_sets(df, target_n)
filtered = filter_by_support(df, all_sets, min_support)
return filtered
def generate_next(previous, n_prev):
"""
Donades les combinacions de tamany $n-1$ genera les de tamany $n$. Ho fa
seguint les regles d'Apriori (ie. si anteriorment en l'ordre 1 i tamany 2 teníem solament
(1,2),(1,4),(4,5) i ara volem generar les de tamany 3, la combinació (1,4,5) no és vàlida,
doncs no teníem originalment la (1,5)!
:param previous: DataFrame de combinacions del tamany previ, amb `order_id` i `products`
:param n_prev: Tamany previ de les combinacions present en el DataFrame `previous`
:return: DataFrame de combinacions de tamany $n$, amb `order_id` i `products`
"""
def wrapped():
unique = set(previous['products'])
for order_id in previous['order_id'].unique():
prods = previous[previous['order_id'] == order_id]['products']
for prod_1 in prods:
for prod_2 in prods:
comb = sorted(set(itertools.chain(prod_1, prod_2)))
if len(comb) == n_prev + 1:
if all(c in unique for c in itertools.combinations(comb, n_prev)):
yield order_id, tuple(comb)
data = pd.DataFrame(wrapped())
data.columns = ['order_id', 'products']
data = data.drop_duplicates(keep='first')
return data
Pràctica 2: Chatbot
Chatbot de Telegram. A lliurar abans del 13 de novembre. Ull! La setmana anterior és la de parcials, així que tindrem dues sessions per a treballar-hi. Avui és la darrera
En aquesta pràctica aprendrem a treballar amb una API i de forma asíncrona mitjançant Python 3.5.
- Idea: per treballar amb parelles amb un token cadascú, poseu el vostre token al fitxer
TOKEN
i afegiu-lo a.gitignore
. Així, quan pugeu codi al repositori no sobreescriureu el de l'altre.
1. Persistència de sessions
Aquesta part l'implementem desacoblada del bot.
Informació guardada a:
{
'id': 1234,
'status': 'FLAGGING',
'messages': ['/start', 'llet', 'ous 6', '/done'],
'products': [
{
'id': 'llet',
'status': 'PENDING',
'qty': 1
},
{
'id': 'ous',
'status': 'PENDING',
'qty': 6
},
]
}
Per afegir un nou element llet
, el que hem de fer és veure si a contingut[user_id]['products']
existeix un element amb id == "llet"
.
Casuístiques:
/start => usuari en estat 'ADDING'
llet 3 => afegim llet->3
llet 4 => llet->7
ous 2 => ous->2
/list => retornem llet->7, ous->2
ous 1 => ous->3
/done => envia el mateix que /list
usuari en estat 'FLAGGING'
a partir d'aquí els productes es marcaran com a "BOUGHT".
poma 3 => ERROR! ja no es poden afegir productes
ous => marquem el producte 'ous' com a comprat: ous.status = 'BOUGHT'
ous => ERROR! ja havíem comprat el producte 'ous'
formatge => ERROR! 'formatge' no és a la llista de productes
/start => eliminem tota la info de l'usuari
- El missatge
/start
el podeu guardar o no. En l'enunciat diem ambdues coses, així que ho deixem a la vostra elecció.