/*""" Esercizio1_Suggerimenti per la soluzione di Padding_numbers Autore: jthi Data di creazione: 2024-01-05 Creazione Versione JMP: JMP Pro 17.2 Descrizione: Scopri come aggiungere padding ai numeri utilizzando la presentazione dei caratteri in modo che i numeri siano sempre lunghi tre caratteri. Prova con valori compresi tra 0 e 999. Nota: lo scopo non è creare una funzione per eseguire questa attività. Ovviamente puoi creare una funzione o utilizzare espressioni, ma non le abbiamo ancora trattate in questo corso. Esempi: Input Output 1 "001" 10 "010" 100 "100" Bonus 1: se il valore è inferiore a 0 o superiore a 999, imposta il valore come stringa vuota Bonus 2: scopri almeno un metodo aggiuntivo per eseguire la stessa attività Extra: esegui un calcolo simile su una tabella dati e crea una nuova colonna """*/ //============================================================ // Input //================================================================== I nomi predefiniti sono qui(1); input_list = {1, 10, 100}; // puoi creare i tuoi esempi //============================================================= // Soluzione passo dopo passo //=============================================================== // Nota: tutti i valori sono compresi tra 0 e 999 (non devi preoccuparti di valori mancanti O valori pari o superiori a 1000) // Inizia con piccoli pezzi molto semplici // in questa soluzione passo dopo passo presupponiamo che la quantità massima di zeri che aggiungiamo sia 2 val = 1; val_str = Char(val); // trasforma in stringa res1 = "00" || val_str; // "001" -> OK -> nessuno zero da rimuovere val2 = 10; val_str2 = Char(val2); // cambia in stringa res2 = "00" || val_str2; // "0010" -> NOK -> Dobbiamo rimuovere UNO zero val3 = 100; val_str3 = Char(val3); // cambia in stringa res3 = "00" || val_str3; // "00010" -> NOK -> Dobbiamo rimuovere DUE zeri // Crea un ciclo di base per semplificare i test For Each({val}, input_list, val_str = Char(val); res = "00" || val_str; Print(Eval Insert("Input: ¤val¤, Result: ¤res¤", "¤")); ); // come possiamo aggiungere la giusta quantità di zeri? // potremmo basare la quantità di zeri sulla lunghezza di val_str // lunghezza 1 -> aggiungi 2 // lunghezza 2 -> aggiungi 1 // lunghezza 3 -> aggiungi 0 len_val = Length(val_str); // potremmo usare If, Match o Choose zeros_to_add = If(len_val == 1, 2 , len_val == 2, 1 , len_val == 3, // potremmo anche usare else per questo 0 ); zeros_to_add = Match(len_val, 1, 2, 2, 1, 3, 0 ); zeros_to_add = Choose(len_val, 2, 1, 0 ); // o una soluzione più generica // quando la lunghezza aumenta di 1 gli zeri aggiunti diminuiscono di 1 A PARTIRE da 2 zeros_to_add = 3 - len_val; // la lunghezza minima è 1 -> inizia dall'addizione da 3 // possiamo testarli con un ciclo (nella prossima lezione possiamo trasformarlo in una funzione per renderlo ancora più semplice) For Each({val}, input_list, val_str = Char(val); zeros_to_add = 3 - Length(val_str); show(zeros_to_add); ); // ora sappiamo quanti zeri aggiungere. Come crearli? // La ripetizione è una buona opzione val = 1; val_str = Char(val); len_val = Length(val_str); zeros_to_add = 3 - len_val; zero_str = Repeat("0", zeros_to_add); // e ora creiamo la nostra stringa finale val_output = zero_str || val_str; // test con ciclo For Each({val}, input_list, val_str = Char(val); len_val = Length(val_str); zeros_to_add = 3 - len_val; zero_str = Repeat("0", zeros_to_add); val_output = zero_str || val_str; show(val_output); ); // trasforma in soluzione (elenco di stringhe) result = {}; For Each({val}, input_list, val_str = Char(val); len_val = Length(val_str); zeros_to_add = 3 - len_val; zero_str = Repeat("0", zeros_to_add); val_output = zero_str || val_str; Insert Into(result, val_output); ); show(result); //============================================================ // Soluzioni non passo passo //=============================================================== //==================================================================== // Opzione 1 - Aggiungi zeri e usa la trasformazione di ciascuno //============================================================= input_list = {1, 10, 100}; MAX_STRING_LENGTH = 3; result = Transform Each({val}, input_list, val_str = Char(val); zeros_to_add = MAX_STRING_LENGTH - Length(val_str); Repeat("0", zeros_to_add) || val_str; // l'ultima riga verrà restituita da Transform Each ); show(result); //============================================================= // Opzione 2 - Rimuovi gli zeri usando Right //================================================================ input_list = {1, 10, 100}; // sappiamo che il numero massimo di zeri che possiamo avere è 2 -> possiamo creare la nostra stringa in anticipo MAX_STR_LENGTH = 3; zero_str = Repeat("0", MAX_STR_LENGTH - 1); // -1 per lasciare spazio al nostro numero result = Transform Each({val}, input_list, val_str = Char(val); Right(zero_str || val_str, MAX_STR_LENGTH); ); show(result); //============================================================ // Opzione 3 - Rimuovi gli zeri usando Substr //============================================================= input_list = {1, 10, 100}; MAX_ZERO_STR = "00"; risultato = Trasforma Ciascuno({val}, input_list, val_str = Char(val); res_str = MAX_ZERO_STR || val_str; start_idx = Length(res_str) - 2; Substr(res_str, start_idx); // Substr(res_str, start_idx, Length(res_str)); // Substr(res_str, -3); // dovrebbe funzionare anche ); show(risultato); //============================================================= // Opzione 4 - Regex (non consigliata in casi semplici come questo) //=================================================================== input_list = {1, 10, 100}; MAX_ZERO_STR = "00"; result = Transform Each({val}, input_list, val_str = Char(val); res_str = MAX_ZERO_STR || val_str; Regex(res_str, "\d{3}$"); // prendi gli ultimi tre numeri ); show(result); //============================================================= // Opzione 5 - Non fare questo //================================================================== input_list = {1, 10, 100}; result = Transform Each({val}, input_list, str = Char(val, 4, 3); // la larghezza della stringa è 4 per tenere conto del separatore decimale str_l = Words(str, ".,"); Concat Items(Reverse(str_l), ""); ); show(result); //============================================================= // Bonus 1 - Utilizzo dell'opzione 1 //============================================================== input_list = {1, 10, 100, -1, 1000, 0, ., 99, 10, 999, 9}; MAX_STRING_LENGTH = 3; risultato = Transform Each({val}, input_list, If(!IsMissing(val) & 0 < val < 1000, val_str = Char(val); zeros_to_add = MAX_STRING_LENGTH - Length(val_str); Repeat("0", zeros_to_add) || val_str; // l'ultima riga verrà restituita da Transform Each , // altrimenti ""; ); ); show(result); //============================================================ // Bonus 1 (soluzione non funzionante) - Script di debug tramite Try-Catch //============================================================== input_list = {1, 10, 100, -1, 1000, 0, .}; MAX_STRING_LENGTH = 3; risultato = Transform Each({val}, input_list, Try( If(!IsMissing(val) | 0 < val < 1000, val_str = Char(val); zeros_to_add = MAX_STRING_LENGTH - Length(val_str); Repeat("0", zeros_to_add) || val_str; // l'ultima riga verrà restituita da Transform Each , // altrimenti ""; ); , Show(val, exception_msg); // utile per stampare il valore in modo da poterlo testare ); ); show(result); //============================================================= // Bonus 1 - Aggiungere solo opzioni valide a un elenco e restituire un elenco di problemi //=================================================================== // passiamo a For Each perché in questo modo la gestione di ciò che viene restituito è molto più semplice input_list = {1, 10, 100, -1, 1000, 0, .}; MAX_STRING_LENGTH = 3; result = {}; issue_list = {}; // memorizza l'elenco di elenchi con indice e valore aa_issues = Associative Array(); // altra opzione (usa idx come chiave e value come valore) For Each({val, idx}, input_list, Try( If(!IsMissing(val) & 0 < val < 1000, val_str = Char(val); zeros_to_add = MAX_STRING_LENGTH - Length(val_str); res = Repeat("0", zeros_to_add) || val_str; // l'ultima riga verrà restituita da Transform Each Insert Into(result, res); , // else Insert Into(issue_list, Eval List({Eval List({idx, val})})); aa_issues[idx] = val; // altra opzione ); , // cattura Show(val, exception_msg); ); ); show(result, issue_list, aa_issues); //============================================================= // Inoltre, crea una formula per eseguire un'azione simile //=============================================================== dt_input = New Table("Exercise1_Padding_Solution", Add Rows(1000), Compress File When Saved(1), New Column("Input", Numeric, "Continuous", Set Values(0::999)) ); //============================================================ // Utilizzo di una formula semplice con valori codificati //============================================================== dt_input << Nuova colonna("Soluzione1", Carattere, Nominale, Formula( Right("00" || Char(:Input), 3); )); //============================================================= // Utilizzo di Local() e variabili //=============================================================== dt_input << Nuova colonna("Soluzione2", Carattere, Nominale, Formula( Local({ MAX_STR_LENGTH = 3, zero_str = Ripeti("0", MAX_STR_LENGTH - 1) }, Right(zero_str || Char(:Input), MAX_STR_LENGTH); ); )); //============================================================= // Utilizzo di As Constant() //=============================================================== // le variabili dovrebbero essere valutate solo sulla prima riga quando si utilizza questo dt_input << New Column("Solution3", Character, Nominal, Formula( As Constant( MAX_STR_LENGTH = 3; zero_str = Repeat("0", MAX_STR_LENGTH - 1); ); Right(zero_str || Char(:Input), MAX_STR_LENGTH); )); //============================================================== // Utilizzo della variabile tabella //================================================================= dt_input << New Table Variable("MAX_INPUT_LENGTH", 3); // Le variabili tabella sono memorizzate come stringhe, quindi le convertirei solo per essere sicuro // dt_input << Get Table Variable("MAX_INPUT_LENGTH"); dt_input << Nuova colonna("Soluzione4", Carattere, Nominale, Formula( Right(Ripeti("0", Num(:LENGTH_MAX_INPUT) - 1) || Char(:Input), Num(:LENGTH_MAX_INPUT)); )); // Nota, per assicurarti che le formule siano state valutate usa dt_ref << Esegui formule; NON wait(0); // Nota, quando usi le formule potrebbe essere una buona idea rimuoverle OPPURE sopprimere la loro valutazione // se non c'è bisogno che i valori vengano aggiornati dopo la creazione iniziale // col_ref << Elimina formula; // col_ref << Sopprime Eval(1); //============================================================ // Utilizzo di For Each Row al posto della formula //================================================================ // se puoi essere sicuro del nome della colonna dt_input << New Column("Solution5", Character, Nominal); For Each Row(dt_input, :Solution5 = Right("00" || Char(:Input), 3); ); // se non lo sei puoi usare il riferimento di colonna new_col = dt_input << New Column("Solution5.1", Character, Nominal); Per ogni riga(dt_input, new_col[Row()] = Right("00" || Char(:Input), 3); // potrebbe anche usare :Solution5 ); // o con il nome della colonna new_col = dt_input << New Column("Solution5.2", Character, Nominal); Per ogni riga(dt_input, As Column(dt_input, (new_col << get name)) = Right("00" || Char(:Input), 3); ); // o con il nome della colonna new_col = dt_input << New Column("Solution5.3", Character, Nominal); Per ogni riga(dt_input, Column(dt_input, (new_col << get name))[] = Right("00" || Char(:Input), 3); ); // nota come vengono utilizzati [] e [Row()] (sono la stessa cosa ma [Row()] è più esplicito) //=============================================================== // Utilizzo di << Imposta ogni valore (QUESTO NON È UN COMPORTAMENTO INTENZIONALE, QUINDI POTREBBE CAMBIARE) //
https://community.jmp.com/t5/JMP-Wish-List/Make-using-formula-expressions-in-Set-Each-Value-and-using/idi-p/666966 //=================================================================== dt_input << Nuova colonna("Soluzione6", Carattere, Nominale, << Imposta ciascun valore( Right("00" || Char(:Input), 3); )); Scrivi();