Assertions¶
Definisce delle aspettative sui dati che possone essere verificate su una o più variabili generando report sulle violazioni trovate.
Importante
Se è attivo un filtro, l’elaborazione verrà limitata ai casi attivi.
assertions¶
assertions definisce la configurazione generale delle asserzioni.
Metodi:
- vars: varlist1, varlist2: definisce le variabili aggiuntive che devono comparire nelle liste
- list: true|false: attiva (default) o disattiva il listato dei casi
- ok: true|false: mostra (default) o nasconde le righe relative ai dati corretti
- fail: :continue|:stop|:abort: azione da intraprendere in caso di violazione: continue continua l’esecuzione, :stop interrompe lo script, :abort interrompe lo script senza listare i casi (default :continue)
- maxid: n: numero di id di riga da mostrare (default 0)
- save: filename: salva i report generati in un file xlsx (da utilizzare alla fine dopo il check dei dati). Ogni check verrà salvato in un foglio diverso.
- config: accetta un hash o un blocco per la definizione delle proprietà
1 2 3 4 5 6 7 8 9 10 11 12 13 | assertions.vars :ser_no, :mcr
assertions.fail :abort
assertions.config list: false, ok: false, maxid: 5
assertions.config do
list false
ok false
maxid 5
end
assertions.save "cleaning"
|
assert¶
assert viene usato per definire un gruppo di regole che costituisce un’asserzione e gli eventuali risolutori (solver) dei problemi. E’ anche possibile concatenare tutti i metodi e assegnare l’asserzione a una variabile.
Argomenti:
- :name: un simbolo con il nome dell’asserzione
- "description": la descrizione
- &block: il blocco di codice (do...end) che contiene le regole di validazione dei dati. In alternativa è possibile concatenare le istruzioni
1 2 3 4 5 6 | assert :check_valid_int, "Deve essere un numero tra 1 e 10 senza valori mancanti" do
between(1,10).solver :value, 0
not_null.solver :prop
end
r1 = assert(:id_rule, "L'ID deve essere un intero senza duplicati").integer.uniq
|
L’asserzione viene poi richiamata e utilizzata tramite l’istruzione assert(name) o direttamente attraverso la variabile a cui era stata assegnata.
check¶
Il metodo check verifica l’asserzione rispetto a una o più variabili.
Argomenti:
- var|varlist: la variabile o l’elenco di variabili da validare
- var1|[varlist1] => var2|[varlist2]: la variabile o l’elenco di variabili da validare e la variabile o l’elenco di variabili necessarie per la validazione dell’asserzione (per es. per le recole fzdep e expr)
1 2 3 | assert(:check_valid_int).check :d1, :d5
r1.check :ser_no
|
1 2 3 4 5 | assert(:check1, "Non deve avere blank e valori non etichettati") do
levels.solver :value, 9
not_null.solver :rnd
end
assert(:check1).check :d1, :d5
|
1 2 | assert(:chk1).expr("$0>$1+$2").check :v1 => [:v10, :v20]
assert(:chk2).fzdep.check [:city, :street] => :zip
|
Output testuale:
Output xlsx:
stop¶
Il metodo stop sostituisce il metodo check, provocando l’interruzione dello script in caso di violazione.
abort¶
Il metodo abort sostituisce il metodo check, provocando l’interruzione dello script in caso di violazione e omettendo la lista dei casi con violazioni.
flag¶
Il metodo flag crea per ciascuna variabile controllata, una nuova variabile che identifica i casi che contengono le violazioni.
Argomenti:
- :root|"name"|[namelist]: un simbolo con la radice dei nomi da creare (default flag_), il nome per una sola variabile o un elenco di nomi
1 2 3 4 5 6 7 | assert(:check_valid_int).check(:d1, :d5).flag # => "flag_d1", "flag_d5"
assert(:check_valid_int).check(:d1, :d5).flag [:err_d1, :err_d5] # => "err_d1", "err_d5"
assert(:check_valid_int).check(:d1, :d5).flag :fl_, 9 # => "fl_d1", "fl_d5"
assert(:check_valid_int).check(:d1).flag "x1" # => "x1"
|
solve¶
solve risolve i problemi evidenziati. Per almeno una regola deve essere stato definito un solver. I solver vengono eseguiti nella sequenza in cui sono stati dichiarati.
Argomenti:
- :seed => number permette ai solver basati su funzioni aleatorie di riprodurre, a parità di condizioni, gli stessi risultati
1 2 3 | assert(:check_valid_int).check(:d1, :d5).solve
assert(:check_valid_int).check(:d1, :d5).solve :seed => 1234
|
Regole¶
Ciascuna asserzione è composta da una o più regole.
base¶
La variabile deve avere come base i casi definiti dall’espressione specificata. Verifica sia i casi che dovrebbero avere un valore, ma sono blank, sia i casi che hanno un valore, ma dovrebbero esser blank.
Argomenti:
- expr: un’espressione filtro
1 | base :target => [1,2]
|
valid_when¶
La variabile deve essere valida quando è valida l’espressione specificata. Verifica i casi che dovrebbero avere un valore, ma sono blank.
Argomenti:
- expr: un’espressione filtro
1 | valid_when :target => [1,2]
|
not_null o notnull¶
La variabile non deve avere casi mancanti.
Argomenti:
- expr: (opzionale) un’espressione filtro
1 2 3 | not_null
not_null :target => [1,2]
|
null¶
La variabile non deve contere nessun valore.
Argomenti:
- expr: (opzionale) un’espressione filtro
1 2 3 | null
null :target => [3,4]
|
min¶
La variabile deve avere valori superiori o uguali al valore minimo indicato. I casi mancanti sono ignorati.
Argomenti:
- value: il valore minimo
1 | min 1
|
max¶
La variabile deve avere valori inferiori o uguali al valore massimo indicato. I casi mancanti sono ignorati.
Argomenti:
- value: il valore massimo
1 | max 15
|
values¶
La variabile deve avere uno dei valori indicati. I casi mancanti sono ignorati.
Argomenti:
- valuelist: la lista dei valori validi
- :ic => true|false: ignora maiuscolo/minuscolo (default false)
1 2 | values 1,2,6,8
values "va", "MI", :ic => true
|
between¶
La variabile deve avere valori compresi tra il valore minimo e il valore massimo indicati. I valori indicati devo essere interi. I casi mancanti sono ignorati.
Argomenti:
- min, max: il valore minimo e il valore massimo
1 | between 1,10
|
range¶
La variabile deve avere valori compresi tra il valore minimo e il valore massimo indicati. I valori indicati devo essere specificati come numeri decimali: 1.0, 2.9, 3.25. I casi mancanti sono ignorati.
Argomenti:
- min.0, max.0, ndec: il valore minimo (float), il valore massimo (float) e (opzionale) il numero di decimali
1 2 3 | range 2.5, 5.0
range 2.5, 5.0, 3
|
levels¶
La variabile deve avere valori corrispondenti ai codici dei livelli definiti della variabile. I casi mancanti sono ignorati.
type¶
La variabile deve contenere valori del tipo di dato indicato. I casi mancanti sono ignorati.
Argomenti:
- :type: un simbolo con il tipo di dato: :integer, :float, :string
1 | type :integer
|
uniq¶
La variabile deve contenere valori univoci. I casi mancanti sono ignorati.
sequence¶
La variabile deve contenere valori crescenti (o decrescenti). I casi mancanti sono ignorati.
Argomenti:
- :d: (opzionale) discendente
1 2 3 | sequence
sequence :d
|
upcase¶
La variabile deve avere tutti i caratteri in maiuscolo. I casi mancanti sono ignorati.
downcase¶
La variabile deve avere tutti i caratteri in minuscolo. I casi mancanti sono ignorati.
positive¶
La variabile deve avere tutti i valori positivi. I casi mancanti sono ignorati.
negative¶
La variabile deve avere tutti i valori negativi. I casi mancanti sono ignorati.
even¶
La variabile deve avere tutti i valori pari. I casi mancanti sono ignorati.
odd¶
La variabile deve avere tutti i valori dispari. I casi mancanti sono ignorati.
equal¶
Testa l’uguaglianza tra due variabili.
Nel metodo check devono essere forniti i due elenchi di variabili: var1|[varlist1] => var2|[varlist2].
1 2 | assert(:chk1).equal.check :x5 => :d5
assert(:chk2).equal.check :x5 => :d5, :r5 => :d5
|
fzdep¶
Testa la dipendenza funzionale tra due variabili o due gruppi di variabili: A -> B. Se due record hanno lo stesso valore per A, allora devono avere lo stesso valore per B. I casi con valore mancante in una delle variabili di sinistra sono ignorati.
Nel metodo check devono essere forniti i due elenchi di variabili: var1|[varlist1] => var2|[varlist2].
1 2 3 | assert(:chk1).fzdep.check :city => :prov
assert(:chk2).fzdep.check :zip => [:prov, :city]
assert(:chk3).fzdep.check [:city, :street] => :zip
|
expr¶
Testa l’espressione indicata.
All’interno dell’espressione è possibile utilizzare i segnaposti $# per le variabili che verranno inserite al momento del check. $0 è la variabile da validare, $1, $2, ecc. le restanti variabili.
All’interno dell’espressione è possibile utilizzare direttamente dei nomi di variabile.
Nel metodo check deve essere anche fornito l’elenco di variabili che costituiscono gli argomenti dell’espressione: var => var2|[varlist2].
1 2 3 4 5 6 7 8 | assert(:expr1).expr("$0>$1").check :v1 => :v10
assert(:expr2).expr("$0*2>$1").check :v1 => :v10
assert(:expr3).expr("$0*2>v10").check :v1
assert(:expr3).expr("$0+$1>$2").check :v1 => [:v10, :v20]
assert(:expr4).expr("$0>$1*$2").check :v2 => [:v11, :v12], :v3 => [:v21, :v22]
assert(:expr5).expr("$0=UPCASE($0)").check :name
|
Risolutori¶
Il metodo solver definisce il solver per ciascuna regola. E’ possibile definire un solver solo per alcune regole o non definirne affatto.
Argomenti:
- :solver_name: un simbolo con il nome del solver
- args: l’eventuale lista di argomenti specifici del solver
- :solver_name2: per alcune regole è possibile definire un secondo solver: un simbolo con il nome del secondo solver
- args2: l’eventuale lista di argomenti specifici del secondo solver
1 2 3 | levels.solver :value, 9
base(:gender => 2).solver :prop, :value, 9
|
value¶
Assegna il valore indicato alla variabile.
Argomenti:
- value: il valore
1 | between(1,10).solver :value, 0
|
rnd¶
Assegna un valore random tra quelli indicati.
Argomenti:
- :levels|list|range: (opzionale) i codici dei livelli (default) o un intervallo di valori o una lista di valori
- ndec: (opzionale) il numero di decimali
1 2 3 4 5 6 7 8 9 | between(1,10).solver :rnd # equivale a :levels
between(1,10).solver :rnd, :levels
between(1,10).solver :rnd, [3,5,7]
between(1,10).solver :rnd, 7..10
range(10.0,20.0).solver :rnd, 15.5..17.9, 3
|
prop¶
Assegna un valore secondo le proporzioni indicate. Se non è indicato alcun argomento, vengono utilizzatele distribuzioni di frequenze della variabile. Se è attivo un peso, vengono utilizzate le distribuzioni pesate.
Argomenti:
- {value1 => prob1, value2 => prob2,...}: (opzionale) un hash con i valori da imputare e le probabilità di assegnazione. Le probabilità vengono riproporzionate a uno.
1 2 3 4 5 6 7 | values(1,2).solver :prop
values(1,2).solver :prop, {1 => 0.33, 2 => 0.66}
values(1,2).solver :prop, {1 => 1, 2 => 2}
values(1,2).solver :prop, {1 => 33, 2 => 66}
|
abort¶
Interrompe l’esecuzione dello script in caso di violazione senza listare i casi con errori.
1 | between(1,10).solver :abort
|
Asserzioni predefinite¶
pTabs2 definisce alcune asserzioni di uso comune.
- :chk_notnull: Variable must have values
- rules: notnull
- solvers: prop
- :chk_uniq: Variable must have unique values
- rules: uniq
- solvers: drop
- :chk_notdup: Variable must be full and with unique values
- rules: notnull, uniq
- solvers: drop
- :chk_seq: Variable must be full and with ordinated values
- rules: notnull, sequence
- solvers: drop
- :chk_null: Variable must have no values
- rules: null
- solvers: nil
- :chk_dummy: It’s a dummy variable
- rules: values(0,1)
- :chk_equal: It’s equal to another variable
- rules: expr("$0=$1")
- :chk_levels: Variable must have code levels
- rules: levels
- solvers: prop
- :chk_notover: Overlapped variables
- rules: expr("NVALID($0,$1)<=1")
- :chk_any: Missing values in both variables
- rules: expr("NVALID($0,$1)>=1")
- :chk_int: Variable must contain integer values
- rules: type(:integer)
- :chk_flt: Variable must contain float values
- rules: type(:float)
- :chk_str: Variable must contain string values
- rules: type(:string)
1 2 3 4 5 6 7 | assert(:chk_dummy).check s(:d7_,10)
assert(:chk_seq).check :ser_no
assert(:chk_notdup).check(:ser_no).solve
assert(:chk_equal).check :x101 => :v101
|
check_base, check_all¶
Le funzioni check_all e check_base permetto di eseguire più sinteticamente due comuni operazioni di controllo sui dati:
- check_all varlist controlla che le variabili non contengano valori mancanti (utilizza la regola notnull)
- check_base varlist, expression controlla che la base delle variabili sia conforme all’espressione indicata (utilizza la regola base)
1 2 3 4 | check_all :v1, :v2
check_base s(:qv10_,1..7), :v11, :v12, :v100 => 1
check_base s(:qv10_,1..7), :v11, :v12, "v100=1"
|
if_not¶
if_not o ifnot è una variante di assert usata con i metodi stop e abort per interrompere, sollevando un errore,
l’esecuzione dello script al verificarsi della violazione di un’asserzione.
Non richiede l’inserimento di un nome per l’asserzione, ma è possibile utilizzarlo con le asserzioni predefinite.
abort non lista i casi con le violazioni.
1 2 3 4 5 6 7 8 9 10 11 | if_not.notnull.max(99).stop :price1, :price2
ifnot.values(2).abort :wave
if_not(:chk_notdup).stop :ser_no
if_not.equal.abort :x101 => :v101
if_not(:chk_notover).stop :v1 => :v2
if_not(:chk_any).stop :v1 => :v2
|