Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions Workbook/Dictionaries/Dicts_1/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,42 @@ Copyright (C) 2019- Andrea Sterbini <sterbini@di.uniroma1.it>,
Angelo Monti <monti@di.uniroma1.it>,
Matteo Neri <matteo2794@outlook.com>

Tutti i programmi ed i file contenuti in questo archivio/directory sono rilasciati sotto licenza GPL v.3
All programs and files contained in this archive / directory are released under the GPL v.3 license
(https://www.gnu.org/licenses/gpl-3.0.en.html)

ISTRUZIONI
INSTRUCTIONS
==========
Per svolgere l'esercizio editate il file program.py usando un editor di testi, meglio ancora un IDE.
Vanno bene Notepad++, Atom, Spyder, PyCharm ed altri editor di testo.
NON usate Notepad, Word, Wordpad o altri editor di documenti.
To carry out the exercise, edit the program.py file using a text editor, better still an IDE.
Notepad ++, Atom, Spyder, PyCharm and other text editors are fine.
DO NOT use Notepad, Word, Wordpad or other document editors.

TEST
====
Questa directory contiene i file necessari a verificare, su almeno 3 esempi di input, che il vostro programma sia corretto.
Prima di eseguire i test se necessario installate Python e le librerie necessarie (vedi sotto).
This directory contains the files necessary to verify, on at least 3 input examples, that your program is correct.
Before running the tests, if necessary, install Python and the necessary libraries (see below).

Per controllare se il vostro programma funziona bene sui dati di esempio:
- aprite una finestra Anaconda Prompt e posizionatevi nella directory dell'esercizio (usando il comando cd)
- eseguite il comando:
To check if your program works fine on the sample data:
- open an Anaconda Prompt window and go to the exercise directory (using the cd command)
- execute the command:
python test.py
- oppure
- otherwise
pytest test.py

Per ottenere informazioni più dettagliate sull'esecuzione (con una analisi dei tempi spesi nelle diverse parti del programma)
- eseguite invece il comando
To obtain more detailed information on the execution (with an analysis of the time spent in the different parts of the program)
- run the command instead
pytest -v -rA --profile test.py

SOLUZIONE
SOLUTION
=========
Nella directory è inclusa una nostra soluzione dell'esercizio.
Vi consigliamo di esaminarla SOLO DOPO AVER PROVATO A RISOLVERE L'ESERCIZIO DA SOLI.
A solution of our exercise is included in the directory.
We advise you to examine it ONLY AFTER TRYING TO SOLVE THE EXERCISE BY YOURSELF.

INSTALLAZIONE
INSTALLATION
=============
Per poter eseguire questi test o quelli di un altro esercizio installate (va fatto una sola volta):
- la distribuzione Anaconda nella versione che contiene Python 3.x (da https://www.anaconda.com/distribution/)
- i moduli Python seguenti
Aprite un Anaconda Prompt ed eseguite i comandi
To be able to perform these tests or those of another exercise, install (must be done only once):
- the Anaconda distribution in the version that contains Python 3.x (from https://www.anaconda.com/distribution/)
- the following Python modules
Open an Anaconda Prompt and execute the commands
conda install -c conda-forge pytest
conda install -c conda-forge ddt
conda install -c conda-forge pytest-timeout
Expand Down
14 changes: 7 additions & 7 deletions Workbook/Dictionaries/Dicts_1/exercise.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"id": 26,
"description": "Dati una tabella e il nome di una colonna della tabella, si ordinano le righe della tabella secondo i valori contenuti nella colonna, si ritorna il numero di colonne della tabella.",
"text": " \n Si implementi la funzione es26(tabella,colonna) che presi in input\n - una tabella rappresentata tramite lista di dizionari\n - una stringa con il nome di una delle colonne della tabella\n modifica distruttivamente la tabella riordinandone le righe in ordine decrescente rispetto \n ai valori contenuti nella colonna indicata. La funzione deve restituire il numero di colonne della tabella.\n Ad esempio con tabella = [{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]\n al termine di es26(dati, 'anno') la tabella sara' stata modificata in \n [{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]\n e restituisce il numero di colonne 3.\n ",
"algorithm": "Ordina la lista passando come chiave di ordinamento la colonna della tabella\nritorna la lunghezza della prima riga della tabella",
"description": "Given a table and the name of a column in the table, the rows of the table are ordered according to the values ​​contained in the column, and the number of columns in the table is returned.",
"text": " \n Implement the function es26 (table, column) that I took as input\n - a table represented by a list of dictionaries\n - a string with the name of one of the columns of the table\n destructively modifies the table by reordering its rows in descending order \n to the values contained in the indicated column. The function must return the number of columns in the table.\n For example with table = [{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]\n at the end of es26(dati, 'anno') the table will have been changed to \n [{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]\n and returns the number of columns 3.\n ",
"algorithm": "Sort the list by passing the table column as the sort key \ nreturns the length of the first row of the table",
"tags": [
"Dizionari",
"Ordinamento",
"Liste"
"Dictionaries",
"Sorting",
"List"
],
"effort": 2,
"clues": [],
"from": "recupero-15-2-18"
}
}
43 changes: 21 additions & 22 deletions Workbook/Dictionaries/Dicts_1/program.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
"""
Un modo comune di memorizzare tabelle e' come liste di dizionari.
Ogni riga della tabella corrisponde ad un dizionario le cui chiavi sono i nomi delle colonne della tabella.
Questa collezione di dizionari e' poi memorizzata in una lista.
Ad esempio la tabella
A common way of storing tables is as dictionary lists.
Each row of the table corresponds to a dictionary whose keys are the names of the columns of the table.
This collection of dictionaries is then stored in a list. 5 For example the table

nome | anno | tel
name | year | tel
--------|------|---------
Sofia | 1973 | 5553546
Bruno | 1981 | 5558432

puo' essere memorizzata come
[{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546},{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432}]
can be stored as
[{'name': 'Sofia', 'year': 1973 ,'tel': 5553546},{'name': 'Bruno', 'year': 1981 ,'tel': 5558432}]

"""


def es26(tabella, colonna):
def es26(table, column):
"""
Si implementi la funzione es26(tabella,colonna) che presi in input
- una tabella rappresentata tramite lista di dizionari
- una stringa con il nome di una delle colonne della tabella
modifica distruttivamente la tabella riordinandone le righe in ordine decrescente rispetto
ai valori contenuti nella colonna indicata. La funzione deve restituire il numero di colonne della tabella.
Ad esempio con tabella = [{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},
{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]
al termine di es26(dati, 'anno') la tabella sara' stata modificata in
[{'nome': 'Bruno', 'anno': 1981 ,'tel': 5558432},{'nome': 'Sofia', 'anno': 1973 ,'tel': 5553546}]
e restituisce il numero di colonne 3.
Implement the function es26 (table, column) that I took as input
- a table represented by a list of dictionaries
- a string with the name of one of the columns of the table
destructively modifies the table by reordering its rows in descending order
to the values ​​contained in the indicated column. The function must return the number of columns in the table.
For example with table = [{'name': 'Bruno', 'year': 1981 ,'tel': 5558432},
{'name': 'Sofia', 'year': 1973 ,'tel': 5553546}]
at the end of es26(dati, 'anno') the table will have been changed to
[{'name': 'Bruno', 'year': 1981 ,'tel': 5558432},{'name': 'Sofia', 'year': 1973 ,'tel': 5553546}]
and returns the number of columns 3.
"""
tabe = sorted(tabella, reverse=True, key=lambda x: x[colonna])
tabella.clear()
tabella.extend(tabe)
return len(tabella[0])
tabe = sorted(table, reverse=True, key=lambda x: x[column])
table.clear()
table.extend(tabe)
return len(table[0])
26 changes: 13 additions & 13 deletions Workbook/Dictionaries/Dicts_1/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@

@ddt
class Test(testlib.TestCase):
def do_test(self, tabella, colonna, expected, expectedTab):
"""Implementazione del test
- tabella : tabella sotto forma di lista di dizionari
- colonna : nome della colonna della tabella
- expected : numero di colonne atteso
- expectedTab : tabella modificata attesa
def do_test(self, tabella, column, expected, expectedTab):
"""Test implementation
- table : table in the form of a list of dictionaries
- column : table column name
- expected : expected number of columns
- expectedTab : modified waiting table
"""
with self.ignored_function("builtins.print"), self.forbidden_function(
"os.walk"
), self.timer(2):
result = program.es26(tabella, colonna)
result = program.es26(table, column)
self.assertEqual(
result, expected, f"Il risultato deve essere {expected} invece che {result}"
result, expected, f "The result must be {expected} instead of {result}"
)
self.assertEqual(
tabella,
table,
expectedTab,
f"Il risultato deve essere {expectedTab} invece che {tabella}",
f "The result must be {expectedTab} instead of {table}",
)

@data(
Expand Down Expand Up @@ -64,10 +64,10 @@ def do_test(self, tabella, colonna, expected, expectedTab):
),
)
@unpack
def test(self, tabella, colonna, expected, expectedTab):
return self.do_test(tabella, colonna, expected, expectedTab)
def test(self, tabella, column, expected, expectedTab):
return self.do_test(table, column, expected, expectedTab)


# I TEST VENGONO ESEGUITI SIA ESEGUENDO program.py che chiamando pytest nella directory
# TESTS ARE PERFORMED BOTH BY RUNNING program.py and by calling pytest in the directory
if __name__ == "__main__":
Test.main()
28 changes: 14 additions & 14 deletions Workbook/Dictionaries/Dicts_1/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@ def __exit__(self, *args):
class TestCase(unittest.TestCase):
def _raise_forbidden(self, forbidden):
# lancia una eccezione
raise ForbiddenError(f"E' proibito usare la funzione/metodo {forbidden}")
raise ForbiddenError(f "It is forbidden to use the function / method {forbidden}")

def forbidden_function(self, target="builtins.print"):
# torna un contesto che fa proibire l'uso della funzione target: per default 'builtins.print'
#returns a context that prohibits the use of the target function: by default 'builtins.print'
return unittest.mock.patch(
target, new=lambda *x, **y: self._raise_forbidden(target)
)

def ignored_function(self, target="builtins.print"):
# torna un contesto che fa ignorare la funzione target: per default 'builtins.print'
# returns a context that causes the target function to be ignored: by default 'builtins.print
return unittest.mock.patch(target, new=lambda *x, **y: None)

def timer(self, sec):
"""torna un contesto di cui viene misurato il tempo di esecuzione e se necessario lanciata una eccezione per timeout"""
"""returns a context whose execution time is measured and if necessary an exception for timeout is thrown"""
return Timer(sec)

def check(self, value, expected, params=None, explanation=""):
Expand All @@ -60,27 +60,27 @@ def check_text_file(self, a, b):
txt_b = f.read()
lines_a = [l.strip() for l in txt_a.splitlines()]
lines_b = [l.strip() for l in txt_b.splitlines()]
# todo: usare una diff
# todo: use a diff
msg = "text differ: " + a + " " + b
self.assertEqual(lines_a, lines_b, msg)

def __image_load(self, filename):
"""Carica l'immagine in formato PNG dal file
filename, la converte nel formato a matrice
di tuple e la ritorna"""
"""Upload the image in PNG format from the file
filename, converts it to the matrix format
of tuples and returns it"""
import png

with open(filename, "rb") as f:
# legge l'immagine come RGB a 256 valori
# reads the image as RGB with 256 values
r = png.Reader(file=f)
iw, ih, png_img, _ = r.asRGB8()
# converte in lista di liste di tuple
# convert to list of tuple lists
img = []
for png_row in png_img:
row = []
# l'immagine PNG ha i colori in
# un'unico array quindi li leggiamo
# tre alla volta in una tupla
# the PNG image has the colors in
# a single array so we read them
# three at a time in a tuple
for i in range(0, len(png_row), 3):
row.append((png_row[i + 0], png_row[i + 1], png_row[i + 2]))
img.append(row)
Expand All @@ -103,7 +103,7 @@ def check_img_file(self, a, b):
)
self.assertEqual(ca, cb, msg)

def check_json_file(self, a, b, msg="I due file JSON contengono strutture diverse"):
def check_json_file(self, a, b, msg="The two JSON files contain different structures"):
import json

with open(a, "r", encoding="utf8") as f1:
Expand Down