Preambolo
Poiché stiamo vettorializzando la nostra API di colore, stiamo modificando i tipi di input accettati per la maggior parte delle nostre funzioni. Ci teniamo a mantenere la compatibilità con il codice esistente.
Definiamo le seguenti variabili di input:
numerico
R
shape: ()
Ad esempio, un valore R di pixel di una tripletta RGB.
1d
[R, G, B]
shape: (3)
Ad esempio una tripletta di valori RGB pixel
2d
[[R, G, B],
[R, G, B],
[R, G, B],
[R, G, B],
[R, G, B],
[R, G, B]]
shape: (6, 3)
Una linea di valori tripletti RGB, per esempio.
3D
[[[R, G, B],
[R, G, B],
[R, G, B]],
[[R, G, B],
[R, G, B],
[R, G, B]]]
shape: (2, 3, 3)
Un'immagine della terzina dei valori RGB, per esempio.
Aspettative
Una funzione che in precedenza accettava un numerico come input ora può accettare una matrice numerica o 1d . Una funzione che in precedenza accetta una matrice 1d come input può ora accettare una matrice 1d , 2d o 3d .
La maggior parte della vettorizzazione del codebase è ora prototipata. In particolare, per supportare gli array 1d , 2d o 3d con funzioni che inizialmente utilizzano un array 1d come input, convertiamo la matrice di input in una 2d . Gli algoritmi interni ora funzionano con gli array 2d , quindi la loro implementazione è semplice e prevedibile.
Per una data funzione, quando modifichiamo le dimensioni dell'array di input per il suo scopo algoritmo, le dimensioni dell'array output risultanti vengono alterate (se non facciamo nulla al riguardo).
Vorremmo sapere quanto segue:
Sta cercando di mantenere le dimensioni dell'array un comportamento comunemente previsto?
Un percorso che sembra logico è quello di mantenere le dimensioni dell'array di input: ad esempio, supponiamo che qualcuno inserisca un'immagine (con una forma 3d ) alla nostra% la funzione diRGB_to_XYZ
probabilmente si aspetterebbe di ottenere un'immagine con una forma 3d , se qualcuno immettesse un pixel RGB 1d con quella stessa funzione probabilmente si aspetterebbe di ottenere 1d XYZ pixel in risposta e non una 2d array.
Un percorso alternativo sarebbe quello di far rispettare le dimensioni di array di input / output previsti per ciascuna funzione (che interromperà la compatibilità con le versioni precedenti).
Implementazioni
Il percorso alternativo non presenta alcuna difficoltà nella sua implementazione.
Il percorso logico è comunque più complicato: dato che abbiamo prototipato il codice a tale riguardo, abbiamo un sacco di codice ridondante della piastra della caldaia all'inizio e alla fine di ogni funzione al fine di recuperare le dimensioni della matrice di input, cambiare le sue dimensioni e rimodellare la matrice di output. Questo non è molto elegante e confuso per qualcuno che legge il codice mentre contribuisce a una manutenibilità più difficile.
Esiste un modo elegante per implementare il comportamento del percorso "logico"?
Stiamo pensando a una funzione wrapper (decoratore mentre stiamo usando Python) che potrebbe essere responsabile della gestione di tutte le dimensioni / risagoma delle magie, le funzioni stesse potrebbero quindi avere aspettative fisse sull'input / output come in percorso alternativo.