[L3] Salvare valori proprietà

  • Creatore
    Topic
  • #80878
    robitex
    Amministratore del forum
      Up
      0
      Down
      ::


      Ciao,
      una delle nuove possibilità offerte dal kernel di LaTeX3 è quella delle liste di proprietà, esempio:
      `
      % nuova lista di proprietà
      \prop_new:N \g_val_prop

      % inserimento valori
      \prop_put:Nnn \g_val_prop { numsal } { 3 }
      \prop_put:Nnn \g_val_prop { implav } { 12819.01 }
      \prop_put:Nnn \g_val_prop { impsic } { 0.00 }
      \prop_put:Nnn \g_val_prop { rib } { 25.151 }

      \NewDocumentCommand{ \getdata }{ m }
      {
      \prop_get:Nn \g_val_prop { #1 }
      }
      `

      Cercando tra le funzioni non ne ho trovato una che a partire da una lista chiave=valore inserisse i dati.
      Per capirci un comando tipo questo, per ottenere lo stesso risultato del codice precedente:
      `
      \setdata{numsal = 3,
      implav = 12819.01,
      impsic = 0.00,
      rib = 25.151,}
      `

      Come si potrebbe fare?
      Lo scopo è quello di eseguire calcoli con l3fp con i valori salvati nella proprietà.
      Grazie
      R.

    Visualizzazione 8 filoni di risposte
    • Autore
      Risposte
      • #80879
        Up
        0
        Down
        ::

        robitex” post=80088Ciao,
        una delle nuove possibilità offerte dal kernel di LaTeX3 è quella delle liste di proprietà, esempio:
        `
        % nuova lista di proprietà
        \prop_new:N \g_val_prop

        % inserimento valori
        \prop_put:Nnn \g_val_prop { numsal } { 3 }
        \prop_put:Nnn \g_val_prop { implav } { 12819.01 }
        \prop_put:Nnn \g_val_prop { impsic } { 0.00 }
        \prop_put:Nnn \g_val_prop { rib } { 25.151 }

        \NewDocumentCommand{ \getdata }{ m }
        {
        \prop_get:Nn \g_val_prop { #1 }
        }
        `

        Cercando tra le funzioni non ne ho trovato una che a partire da una lista chiave=valore inserisse i dati.
        Per capirci un comando tipo questo, per ottenere lo stesso risultato del codice precedente:
        `
        \setdata{numsal = 3,
        implav = 12819.01,
        impsic = 0.00,
        rib = 25.151,}
        `

        Come si potrebbe fare?
        Lo scopo è quello di eseguire calcoli con l3fp con i valori salvati nella proprietà.
        Grazie
        R.

        Dipende molto da che tipo di applicazione hai in mente. Se ti serve solo una lista con solo quelle quattro proprietà, meglio usare direttamente quattro token list o addirittura variabili fp:
        `\keys_define:nn { robitex }
        {
        numsal .fp_set:N = \g_robitex_numsal_fp,
        implav .fp_set:N = \g_robitex_implav_fp,
        impsic .fp_set:N = \g_robitex_impsic_fp,
        rib .fp_set:N = \g_robitex_rb_fp,
        }
        \NewDocumentCommand{\setdata}{ m } { \keys_set:nn { robitex } { #1 } }`

        Ciao
        Enrico

      • #80880
        robitex
        Amministratore del forum
          Up
          0
          Down
          ::


          L’idea è quella di inserire con la sintassi chiave valore una serie di dati, elaborarne numericamente alcuni e rendere disponibili i risultati con un altrettanto semplice comando \getdata{}.

          Per il primo passo ci pensa l3keys, per il secondo l3fp e per il terzo l3prop:
          `\documentclass{article}

          \usepackage[T1]{fontenc}
          \usepackage[utf8]{inputenc}
          \usepackage[italian]{babel}

          \usepackage{siunitx}
          \usepackage{eurosym}
          \usepackage{booktabs}

          \sisetup{output-decimal-marker={,}}

          \ExplSyntaxOn
          \fp_new:N \g_impsal_fp
          \fp_new:N \g_implavnetto_fp
          \fp_new:N \g_impsalnetto_fp

          \cs_new:Nn \my_process_values:
          {
          \fp_set:Nn \g_impsal_fp
          {
          \fp_use:N \g_implav_fp + \fp_use:N \g_impsic_fp
          }
          \fp_set:Nn \g_implavnetto_fp
          {
          ( 1 – \fp_use:N \g_rib_fp/100 ) * \fp_use:N \g_implav_fp
          }
          \fp_set:Nn \g_impsalnetto_fp
          {
          \fp_use:N \g_implavnetto_fp + \fp_use:N \g_impsic_fp
          }
          }

          \prop_new:N \g_salval_prop

          \cs_new:Nn \my_save_values:
          {
          \prop_put:NnV \g_salval_prop { numsal } \g_numsal_tl
          \prop_put:Nnn \g_salval_prop { impsal }
          {
          \fp_use:N \g_impsal_fp
          }
          \prop_put:Nnn \g_salval_prop { implav }
          {
          \SI[ round-mode = places ,
          round-precision = 2 ]
          { \fp_use:N \g_implav_fp }{ \euro }
          }
          \prop_put:Nnn \g_salval_prop { impsalnetto }
          {
          \SI[ round-mode = places ,
          round-precision = 2 ]
          { \fp_use:N \g_impsalnetto_fp }{ \euro }
          }
          \prop_put:Nnn \g_salval_prop { implavnetto }
          {
          \SI[ round-mode = places ,
          round-precision = 2 ]
          { \fp_use:N \g_implavnetto_fp }{ \euro }
          }
          \prop_put:Nnn \g_salval_prop { impsic }
          {
          \SI[ round-mode = places ,
          round-precision = 2 ]
          { \fp_use:N \g_impsic_fp }{ \euro }
          }
          \prop_put:Nnn \g_salval_prop { rib }
          {
          \SI{ \fp_use:N \g_rib_fp }{ \percent }
          }

          }

          \keys_define:nn { salValues }
          {
          numsal .tl_set:N = \g_numsal_tl,
          numsal .default:n = x,

          implav .fp_set:N = \g_implav_fp,
          impsic .fp_set:N = \g_impsic_fp,
          rib .fp_set:N = \g_rib_fp,
          }

          \NewDocumentCommand { \setdata } { m }
          {
          \keys_set:nn { salValues }
          { #1 }
          \my_process_values:
          \my_save_values:
          }
          \NewDocumentCommand { \getdata } { m }
          {
          \prop_get:NnN \g_salval_prop { #1 } \l_tmpa_tl
          \tl_use:N \l_tmpa_tl
          }
          \ExplSyntaxOff

          \setdata{
          numsal = 3,
          implav = 12819.01,
          impsic = 1.00,
          rib = 25.151,
          }

          \begin{document}

          % ok
          Il numero del sal è \getdata{numsal}.

          % ok
          Il valore netto dei lavori è \getdata{implavnetto}.

          % ok
          L'importo del sal numero \getdata{numsal} è \getdata{impsal}~\euro.

          % error
          %L'importo del sal numero \getdata{numsal} è \SI{\getdata{impsal}}{\euro}.

          \end{document}`

          Come vedete dal codice che segue la strategia descritta e che funziona abbastanza bene, ci sono un po’ di guai.
          Non riesco ad espandere correttamente il numero nel comando \SI (funziona solo se memorizzo nella proprietà l’intera formattazione con siunitx.
          Se per caso digito una chiave dalla sintassi sbagliata la compilazione si blocca indefinitivamente (per esempio un \getdata{nonesisto}).
          Ho un po’ troppa ridondanza nei nomi tra funzioni e variabili, come si può notare dal codice delle funzioni \my_process_values: e \my_save_values: (la leggibilità non è il massimo)

          Ho implementato il tutto anche in LuaTeX incontrando meno problemi. Non ho ancora risolto del tutto l’argomento con LuaTeX perciò non vi riporterò qui il codice.
          Grazie per aver seguito fino a qui.
          R.

        • #80881
          Up
          0
          Down
          ::

          robitex” post=80110L’idea è quella di inserire con la sintassi chiave valore una serie di dati, elaborarne numericamente alcuni e rendere disponibili i risultati con un altrettanto semplice comando \getdata{}.

          Per il primo passo ci pensa l3keys, per il secondo l3fp e per il terzo l3prop:
          `\documentclass{article}
          […]
          `

          Come vedete dal codice che segue la strategia descritta e che funziona abbastanza bene, ci sono un po’ di guai.
          Non riesco ad espandere correttamente il numero nel comando \SI (funziona solo se memorizzo nella proprietà l’intera formattazione con siunitx.
          Se per caso digito una chiave dalla sintassi sbagliata la compilazione si blocca indefinitivamente (per esempio un \getdata{nonesisto}).
          Ho un po’ troppa ridondanza nei nomi tra funzioni e variabili, come si può notare dal codice delle funzioni \my_process_values: e \my_save_values: (la leggibilità non è il massimo)

          Ho implementato il tutto anche in LuaTeX incontrando meno problemi. Non ho ancora risolto del tutto l’argomento con LuaTeX perciò non vi riporterò qui il codice.
          Grazie per aver seguito fino a qui.
          R.

          Una tirata di orecchie: devi usare un prefisso per le tue funzioni e variabili.

          Per inserire il valore espanso, puoi fare così:
          `\cs_new:Nn \my_save_values:
          {
          \prop_gput:NnV \g_salval_prop { numsal } \g_numsal_tl
          \prop_gput:Nnx \g_salval_prop { impsal }
          {
          \fp_use:N \g_impsal_fp
          }
          \prop_gput:Nnx \g_salval_prop { implav }
          {
          \exp_not:N \SI[ round-mode = places ,
          round-precision = 2 ]
          { \fp_use:N \g_implav_fp }{ \exp_not:N \euro }
          }

          }`
          Naturalmente correggerai con il prefisso. Nota [tt]\prop_gput:Nnx[/tt]; le variabili globali vanno sempre modificate globalmente.

          Per l’ultimo problema:
          `\DeclareExpandableDocumentCommand { \getdata } { m }
          {
          \prop_get:Nn \g_salval_prop { #1 }
          }`
          oppure, direttamente
          `\cs_new:Npn \getdata #1 { \prop_get:Nn \g_salval_prop { #1 } }`

          Ciao
          Enrico

        • #80882
          robitex
          Amministratore del forum
            Up
            0
            Down
            ::


            Eccomi.
            Ho sistemato il prefisso. Grazie. Ed ecco il codice completo compilabile e funzionante.
            Quando serve solo il numero uso \num{\getdata{}} come nella tabella, e quando serve anche l’unità di misura uso \SI, come nel testo:
            `\documentclass{article}

            \usepackage[T1]{fontenc}
            \usepackage[utf8]{inputenc}
            \usepackage[italian]{babel}

            \usepackage{siunitx}
            \usepackage{eurosym}
            \usepackage{booktabs}

            \sisetup{output-decimal-marker={,},
            round-mode = places,
            round-precision = 2,
            round-integer-to-decimal}

            % prefix name
            % gds := gestione dati sal

            \ExplSyntaxOn
            \fp_new:N \g_gds_impsal_fp
            \fp_new:N \g_gds_implavnetto_fp
            \fp_new:N \g_gds_impsalnetto_fp

            \cs_new:Nn \gds_process_values:
            {
            \fp_set:Nn \g_gds_impsal_fp
            {
            \fp_use:N \g_gds_implav_fp + \fp_use:N \g_gds_impsic_fp
            }
            \fp_set:Nn \g_gds_implavnetto_fp
            {
            ( 1 – \fp_use:N \g_gds_rib_fp/100 ) * \fp_use:N \g_gds_implav_fp
            }
            \fp_set:Nn \g_gds_impsalnetto_fp
            {
            \fp_use:N \g_gds_implavnetto_fp + \fp_use:N \g_gds_impsic_fp
            }
            }

            \prop_new:N \g_gds_salval_prop

            \cs_new:Nn \gds_save_values:
            {
            \prop_gput:NnV \g_gds_salval_prop { numsal } \g_gds_numsal_tl
            \prop_gput:Nnx \g_gds_salval_prop { impsal }
            {
            \fp_use:N \g_gds_impsal_fp
            }
            \prop_gput:Nnx \g_gds_salval_prop { implav }
            {
            \fp_use:N \g_gds_implav_fp
            }
            \prop_gput:Nnx \g_gds_salval_prop { impsalnetto }
            {
            \fp_use:N \g_gds_impsalnetto_fp
            }
            \prop_gput:Nnx \g_gds_salval_prop { implavnetto }
            {
            \fp_use:N \g_gds_implavnetto_fp
            }
            \prop_gput:Nnx \g_gds_salval_prop { impsic }
            {
            \fp_use:N \g_gds_impsic_fp
            }
            \prop_gput:Nnx \g_gds_salval_prop { rib }
            {
            \fp_use:N \g_gds_rib_fp
            }
            }

            \keys_define:nn { gdsfamily }
            {
            numsal .tl_set:N = \g_gds_numsal_tl,
            numsal .default:n = x,

            implav .fp_set:N = \g_gds_implav_fp,
            impsic .fp_set:N = \g_gds_impsic_fp,
            rib .fp_set:N = \g_gds_rib_fp,
            }

            \NewDocumentCommand { \setdata } { m }
            {
            \keys_set:nn { gdsfamily }
            { #1 }
            \gds_process_values:
            \gds_save_values:
            }
            \DeclareExpandableDocumentCommand { \getdata } { m }
            {
            \prop_get:Nn \g_gds_salval_prop { #1 }
            }
            \ExplSyntaxOff

            \setdata{
            numsal = 3,
            implav = 12819.01,
            impsic = 1000,
            rib = 25.151,
            }

            \begin{document}

            % ok
            Il numero del sal è \getdata{numsal} per un valore di \SI{\getdata{impsal}}{\euro}, di cui \SI{\getdata{impsic}}{\euro} sono oneri di sicurezza. Il valore netto in euro dei lavori è \num{\getdata{implavnetto}}.

            % ok
            \bigskip
            \begin{tabular}{cccc}
            \toprule
            Lavori & Sicurezza & Totale SAL & Totale netto\\
            \euro & \euro & \euro & \euro \\
            \midrule
            \num{\getdata{implav}} & \num{\getdata{impsic}} & \num{\getdata{impsal}} & \num{\getdata{impsalnetto}}\\
            \bottomrule
            \end{tabular}

            \end{document}`

            Per aumentare la leggibilità del codice (cosa che con TeX penso sia molto più difficile), si può anche creare la seguente funzione di servizio:
            `\cs_new:Nn \gds_savein_fpval:n
            {
            \prop_gput:Nnx \g_gds_salval_prop { #1 }
            {
            \fp_use:c { g_gds_#1_fp }
            }
            }`

            Da usare poi così:
            `\cs_new:Nn \gds_save_values:
            {
            \prop_gput:NnV \g_gds_salval_prop { numsal } \g_gds_numsal_tl
            \gds_savein_fpval:n { impsal }
            \gds_savein_fpval:n { implav }
            \gds_savein_fpval:n { impsalnetto }
            \gds_savein_fpval:n { implavnetto }
            \gds_savein_fpval:n { impsic }
            \gds_savein_fpval:n { rib }
            }`

            Probabilmente si può fare ancora meglio…
            Un saluto e buon weekend3!
            R.

          • #80883
            robitex
            Amministratore del forum
              Up
              0
              Down
              ::


              Ecco un miglioramento per la funzione interna che salva in una variabile proprietà un valore in virgola mobile. Invece di chiamarla tante volte quante sono le variabili in virgola mobile, è possibile passare l’elenco delle variabili una sola volta come lista di valori.
              La funzione diventerebbe quindi questa:
              `\cs_new:Nn \gds_save_values:
              {
              \prop_gput:NnV \g_gds_salval_prop { numsal } \g_gds_numsal_tl
              \gds_savein_fpval:n { impsal,
              implav,
              impsalnetto,
              implavnetto,
              impsic,
              rib
              }
              }`
              mentre la funzione di servizio verrebbe modificata molto poco in questa:
              `\cs_new:Nn \gds_savein_fpval:n
              {
              \clist_set:Nn \l_tmpa_clist { #1 }
              \clist_map_inline:Nn \l_tmpa_clist
              {
              \prop_gput:Nnx \g_gds_salval_prop { ##1 }
              {
              \fp_use:c { g_gds_##1_fp }
              }
              }
              }`
              Buona domenica!
              R.

            • #80884
              Up
              0
              Down
              ::

              robitex” post=80178[…]
              mentre la funzione di servizio verrebbe modificata molto poco in questa:
              `\cs_new:Nn \gds_savein_fpval:n
              {
              \clist_set:Nn \l_tmpa_clist { #1 }
              \clist_map_inline:Nn \l_tmpa_clist
              {
              \prop_gput:Nnx \g_gds_salval_prop { ##1 }
              {
              \fp_use:c { g_gds_##1_fp }
              }
              }
              }`

              Più semplice:
              `\cs_new:Nn \gds_savein_fpval:n
              {
              \clist_map_inline:nn { #1 }
              {
              \prop_gput:Nnx \g_gds_salval_prop { ##1 }
              {
              \fp_use:c { g_gds_##1_fp }
              }
              }
              }`
              Ciao
              Enrico

            • #80885
              robitex
              Amministratore del forum
                Up
                0
                Down
                ::


                A ecco.
                Cercavo una funzione del genere nella documentazione interface3 e non ero accorto della funzione alternativa \clist_map_inline:nn.
                Questa funzione accetta una lista esplicita come primo argomento ed applica a tutti gli elementi della lista la funzione esplicita del secondo argomento.
                L’elemento della lista è rappresentato da ##1 poiché siamo all’interno di un’altra funzione.

                Grazie.
                R.

              • #80886
                franen
                Partecipante
                  Up
                  0
                  Down
                  ::

                  robitex” post=80182Cercavo una funzione del genere nella documentazione interface3 e non ero accorto della funzione alternativa \clist_map_inline:nn.

                  Ma se non esistesse si potrebbe sempre(?) creare con [tt]\cs_generate_variant:Nn[/tt]. O no?

                  Fran

                • #80887
                  Up
                  0
                  Down
                  ::

                  franen” post=80187

                  Cercavo una funzione del genere nella documentazione interface3 e non ero accorto della funzione alternativa \clist_map_inline:nn.

                  Ma se non esistesse si potrebbe sempre(?) creare con [tt]\cs_generate_variant:Nn[/tt]. O no?

                  Più o meno sì. Ma [tt]\clist_map_inline:nn[/tt] e [tt]\tl_map_inline:nn[/tt] sono certamente predefinite perché è normale pensare di dover elaborare liste date come argomenti [tt]n[/tt]. Questo non avrebbe senso per [tt]\seq_map_inline:Nn[/tt] e [tt]\prop_map_inline:Nn[/tt], ovviamente.

                  Ciao
                  Enrico

              Visualizzazione 8 filoni di risposte
              • Devi essere connesso per rispondere a questo topic.

              Go to top