- Questo topic ha 10 risposte, 3 partecipanti ed è stato aggiornato l'ultima volta 16 anni, 4 mesi fa da
strolego.
-
CreatoreTopic
-
26 Aprile 2010 alle 15:25 #44721::
A pagina 94 degli “Appunti di programmazione” di Enrico, vengono introdotte alcune macro per la manipolazione di liste, ma l’autore avverte cheSi noti che le nostre manipolazioni permettono solo di stampare gli
elementi della lista, non di passarli ad altre macro come argomentiC’è un modo per ottenere questa seconda cosa?
Il mio problema è avere qualcosa del tipo (usando quelle macro e un comando del pacchetto geometry)
`
\buildlist{opzioni}{}
\appendtolist{opzioni}{left=3cm}
\appendtolist{opzioni}{right=2cm}
…..
\newgeometry{\opzioni} -> o qualcosa di simile…`
Grazie
Flavio
-
CreatoreTopic
-
AutoreRisposte
-
-
26 Aprile 2010 alle 15:51 #44722::
A pagina 94 degli “Appunti di programmazione” di Enrico, vengono introdotte alcune macro per la manipolazione di liste, ma l’autore avverte che
Si noti che le nostre manipolazioni permettono solo di stampare gli
elementi della lista, non di passarli ad altre macro come argomentiC’è un modo per ottenere questa seconda cosa?
Il mio problema è avere qualcosa del tipo (usando quelle macro e un comando del pacchetto geometry)
`
\buildlist{opzioni}{}
\appendtolist{opzioni}{left=3cm}
\appendtolist{opzioni}{right=2cm}
…..
\newgeometry{\opzioni} -> o qualcosa di simile…`
Grazie
FlavioPer manipolare le liste io utilizzo il pacchetto etextools di Florent Chervet (pacchetto abbastanza recente che a sua volta estende il pacchetto di Lehman etoolbox, e nella fretta non riesco mai a non confondere il loro nome).
Bye
-
26 Aprile 2010 alle 16:24 #44723::
A pagina 94 degli “Appunti di programmazione” di Enrico, vengono introdotte alcune macro per la manipolazione di liste, ma l’autore avverte che
Si noti che le nostre manipolazioni permettono solo di stampare gli
elementi della lista, non di passarli ad altre macro come argomentiC’è un modo per ottenere questa seconda cosa?
Il mio problema è avere qualcosa del tipo (usando quelle macro e un comando del pacchetto geometry)
`
\buildlist{opzioni}{}
\appendtolist{opzioni}{left=3cm}
\appendtolist{opzioni}{right=2cm}
…..
\newgeometry{\opzioni} -> o qualcosa di simile…`
Grazie
Flavio`\expandafter\newgeometry\expandafter{\opzioni}`
Ciao
Enrico
-
26 Aprile 2010 alle 20:05 #44724::
`\expandafter\newgeometry\expandafter{\opzioni}`
e se invece di \newgeometry avessi un comando con argomenti come (scusa la “bestemmia sul comando)
\newgeomerty[arg1]{arg2}{arg3}[\lista]
Non riesco a vedere dove vanno gli \expandafter
🙁Proverò a guardare etextools e etoolbox anche se dai miei ricordi la documentazione non brillava per chiarezza e ricchezza di esempi
Grazie
Flavio
-
26 Aprile 2010 alle 20:33 #44725::
`\expandafter\newgeometry\expandafter{\opzioni}`
e se invece di \newgeometry avessi un comando con argomenti come (scusa la “bestemmia sul comando)
\newgeomerty[arg1]{arg2}{arg3}[\lista]
Non riesco a vedere dove vanno gli \expandafter
🙁Proverò a guardare etextools e etoolbox anche se dai miei ricordi la documentazione non brillava per chiarezza e ricchezza di esempi
Perché non dire con chiarezza che ti serve?
Se ti serve semplicemente un’interfaccia a \newgeometry (ma non saprei perché), puoi fare così:
`\makeatletter
\newtoks\st@collecttoks
\newcommand*{\collectoption}[1]{%
\st@collecttoks=\expandafter{\the\st@collecttoks,#1}}
\newcommand*{\applynewgeometry}{%
\expandafter\newgeometry\expandafter{\expandafter\@gobble\the\st@collecttoks}%
\st@resettoks={}}
\makeatother`
A questo punto puoi dire
`\collectoption{right=3cm}
\collectoption{left=2cm}
\applynewgeometry`
che sarebbe equivalente a
`\newgeometry{right=3cm,left=2cm}`
Ciao
Enrico
-
26 Aprile 2010 alle 21:05 #44726
-
26 Aprile 2010 alle 22:07 #44727::
Scusami ho usato quel comando di geometry perché è stato il primo che mi è venuto in mente che operasse su una lista.
Il mio problema è questo: devo scegliere casualmente da una lista di m oggetti (m diciamo 15) una lista di n (
Qualcosa del genere?
`\documentclass[a4paper]{article}
\usepackage{lcg}\makeatletter
\g@addto@macro\r@nd{\global\cr@nd\cr@nd}\newcommand{\rchoice}[4][]{\begingroup\def\excl@list{#4}%
\ifx\relax#1\relax
\reinitrand[first=#2,last=#3]%
\else
\reinitrand[seed=#1,first=#2,last=#3]%
\fi
\def\xyz@{}%
\@for\next:=\excl@list\do{\@namedef{xyz@\romannumeral\next}{}}%
\count\z@=\z@
\@rchoice\endgroup}
\def\@rchoice{%
\ifnum\count\z@=10 \else
\expandafter\@dochoice
\fi}
\def\@dochoice{\rand
\@ifundefined{xyz@\romannumeral\c@rand}{\@goodchoice}{\@rchoice}}
\def\@goodchoice{\@namedef{xyz@\romannumeral\c@rand}{}%
\advance\count\z@\@ne\number\c@rand\relax\space\@rchoice}
\makeatother\begin{document}
\rchoice[1]{1}{15}{2,3}
\rchoice[1]{1}{15}{2,3}
\rchoice{1}{15}{1,2,3,4,5}
\end{document}`
Ciao
Enrico
-
26 Aprile 2010 alle 23:12 #44728::
Qualcosa del genere?
…Spiegazione.
`\g@addto@macro\r@nd{\global\cr@nd\cr@nd}`
Per motivi di implementazione, il comando \rand non funziona se chiamato dentro un gruppo. Così si risolve.`\newcommand{\rchoice}[4][]{\begingroup
\ifx\relax#1\relax
\reinitrand[first=#2,last=#3]%
\else
\reinitrand[seed=#1,first=#2,last=#3]%
\fi`
Il comando \rchoice ha tre argomenti obbligatori: il minimo, il massimo e la lista dei numeri da escludere. Per prima cosa inizializziamo il contatore dei numeri casuali; l’argomento opzionale è il seme. Ci mettiamo in un gruppo.` \def\xyz@{}%
\def\excl@list{#4}%
\@for\next:=\excl@list\do{\@namedef{xyz@\romannumeral\next}{}}%`
Per ogni elemento della lista di esclusione, che deve essere un numero, definiamo il comando \xyz@xii (se il numero è 12). Così possiamo sapere se il numero è fra gli esclusi o fra quelli già estratti, esaminando se \xyz@xii (o quello che è) è definito.` \count\z@=\z@
\@rchoice\endgroup}`
Avviamo la ricorsione, tenendo conto di quanti numeri abbiamo estratto nel contatore 0 (tanto siamo in un gruppo).`\def\@rchoice{%
\ifnum\count\z@=10 \else
\expandafter\@dochoice
\fi}`
La macro \@rchoice è quella responsabile della ricorsione. Se abbiamo già raggiunto il numero di 10 estrazioni buone, abbiamo finito, altrimenti eseguiamo \@dochoice.`\def\@dochoice{\rand
\@ifundefined{xyz@\romannumeral\c@rand}{\@goodchoice}{\@rchoice}}`
La macro \@dochoice estrae un numero; se il numero è fra quelli esclusi o già estratti, eseguiamo ancora \@rchoice. Altrimenti eseguiamo \@goodchoice.`\def\@goodchoice{\@namedef{xyz@\romannumeral\c@rand}{}%
\advance\count\z@\@ne\number\c@rand\relax\space\@rchoice}`
La macro \@goodchoice definisce \xyz@xii (se il numero estratto è 12) o il comando opportuno. Poi avanza il contatore della ricorsione, stampa il numero estratto ed esegue di nuovo \@rchoice.Ciao
Enrico
-
27 Aprile 2010 alle 9:39 #44729::
Grazie del codice (ma come fai a produrlo così di getto?)Ho trovato un’altra soluzione usando random (che uso già in altri punti). Così come è non permette la scelta del seme, ma la cosa mi interessa poco (e posso sempre aggiungerlo con \randomi=). La parte principale (\getitems) è un adattamento di un vecchio codice TeX trovato tempo fa in rete.
Mi piacerebbe avere un tuo parere
`
\documentclass[a4paper]{article}
\usepackage{ifthen}
\input{random}
\makeatletter
\newcount\i@sh
\newcount\j@sh
\newcount\sh@max
\newcounter{shuf@tot}
\newcounter{shuf@lop}
\newcommand\shuf@ch{}
\renewcommand{\theshuf@lop}{\roman{shuf@lop}}%%% costruisco la lista
\newcommand\shuf@ifch[2]{%
\ifthenelse{\not\equal{\shuf@ch}{#1}}{\stepcounter{shuf@lop}\expandafter\edef\csname item\theshuf@lop \endcsname{#2}}{}%
}\newcommand\es@item[1]{%
\edef\es@Lista{\zap@space#1 \@empty}%
\@for\shuf@ch:=\es@Lista\do{%
\shuf@ifch{}{\shuf@ch}%
}
}\newcommand{\sh@chex}[1]{
\setcounter{shuf@lop}{0}
\renewcommand{\theshuf@lop}{\roman{shuf@lop}}
\es@item{#1}
\renewcommand{\theshuf@lop}{\arabic{shuf@lop}}
\setcounter{shuf@tot}{\theshuf@lop}
}\def\printitem#1{\csname item\romannumeral#1\endcsname}
%%% la funzione di scelta nella lista #2 escludendo #1 elementi
\newcommand{\scegli}[2][0]{\sh@max=#1\sh@chex{#2}\getitems}\def\getitems{%
\i@sh=\theshuf@tot
\loop
\expandafter\let \csname flag\number\i@sh \endcsname a%
\advance\i@sh by-1
\ifnum\i@sh > 0 \repeat
\i@sh=\theshuf@tot
\loop
\setrannum{\j@sh}{1}{\theshuf@tot}%
\expandafter\ifx \csname flag\number\j@sh \endcsname a%
\expandafter\let \csname flag\number\j@sh \endcsname b% Controllo se è già stato scelto
\expandafter\edef\csname file\romannumeral\j@sh\endcsname{\csname item\romannumeral\i@sh\endcsname}
\printitem\j@sh
\advance\i@sh by-1
\fi
\ifnum\i@sh > \sh@max \repeat
}\makeatother
\begin{document}
\scegli{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}\scegli[3]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}
\scegli[16]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}
\end{document}
`
-
27 Aprile 2010 alle 11:04 #44730::
Grazie del codice (ma come fai a produrlo così di getto?)
Ho trovato un’altra soluzione usando random (che uso già in altri punti). Così come è non permette la scelta del seme, ma la cosa mi interessa poco (e posso sempre aggiungerlo con \randomi=). La parte principale (\getitems) è un adattamento di un vecchio codice TeX trovato tempo fa in rete.
Mi piacerebbe avere un tuo parere
`
\documentclass[a4paper]{article}
\usepackage{ifthen}
\input{random}
\makeatletter
\newcount\i@sh
\newcount\j@sh
\newcount\sh@max
\newcounter{shuf@tot}
\newcounter{shuf@lop}
\newcommand\shuf@ch{}
\renewcommand{\theshuf@lop}{\roman{shuf@lop}}%%% costruisco la lista
\newcommand\shuf@ifch[2]{%
\ifthenelse{\not\equal{\shuf@ch}{#1}}{\stepcounter{shuf@lop}\expandafter\edef\csname item\theshuf@lop \endcsname{#2}}{}%
}\newcommand\es@item[1]{%
\edef\es@Lista{\zap@space#1 \@empty}%
\@for\shuf@ch:=\es@Lista\do{%
\shuf@ifch{}{\shuf@ch}%
}
}\newcommand{\sh@chex}[1]{
\setcounter{shuf@lop}{0}
\renewcommand{\theshuf@lop}{\roman{shuf@lop}}
\es@item{#1}
\renewcommand{\theshuf@lop}{\arabic{shuf@lop}}
\setcounter{shuf@tot}{\theshuf@lop}
}\def\printitem#1{\csname item\romannumeral#1\endcsname}
%%% la funzione di scelta nella lista #2 escludendo #1 elementi
\newcommand{\scegli}[2][0]{\sh@max=#1\sh@chex{#2}\getitems}\def\getitems{%
\i@sh=\theshuf@tot
\loop
\expandafter\let \csname flag\number\i@sh \endcsname a%
\advance\i@sh by-1
\ifnum\i@sh > 0 \repeat
\i@sh=\theshuf@tot
\loop
\setrannum{\j@sh}{1}{\theshuf@tot}%
\expandafter\ifx \csname flag\number\j@sh \endcsname a%
\expandafter\let \csname flag\number\j@sh \endcsname b% Controllo se è già stato scelto
\expandafter\edef\csname file\romannumeral\j@sh\endcsname{\csname item\romannumeral\i@sh\endcsname}
\printitem\j@sh
\advance\i@sh by-1
\fi
\ifnum\i@sh > \sh@max \repeat
}\makeatother
\begin{document}
\scegli{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}\scegli[3]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}
\scegli[16]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,a,b,c}
\end{document}
`Mi pare che sia più o meno come il mio; c’è una parte davvero brutta:
`\newcommand{\sh@chex}[1]{
\setcounter{shuf@lop}{0}
\renewcommand{\theshuf@lop}{\roman{shuf@lop}}
\es@item{#1}
\renewcommand{\theshuf@lop}{\arabic{shuf@lop}}
\setcounter{shuf@tot}{\theshuf@lop}
}`
che, a parte la notevole quantità di spazi spuri, è inutilmente complicata:
`\newcommand{\sh@chex}[1]{%
\setcounter{shuf@lop}{0}%
\es@item{#1}%
\setcounter{shuf@tot}{\value{shuf@lop}}%
}`
Non occorre certo rappresentare numericamente un contatore per accedere al suo valore. 🙂Sinceramente preferisco il mio; si tratta solo di aggiungere una corrispondenza tra gli oggetti eterogenei del tuo insieme e un insieme numerico “fisso”, diciamo {1,2,…,n}, dove n è il numero totale di oggetti.
Nella macro \@goodchoice invece di \number\c@rand che semplicemente stampa il risultato numerico, si può mettere una qualsiasi macro. Il modo più semplice è usare \csname per avere una “associative array”.
`\def\make@list#1{%
\count@=\z@ \def\temp{#1}
\@for\next:=\temp\do{\advance\count@\@ne
\expandafter\def\csname lista@\romannumeral\count@\expandafter\endcsname
\expandafter{\next}}
\chardef\listlength=\count@}
%%% ridefinizione di \@goodchoice
def\@goodchoice{\@namedef{xyz@\romannumeral\c@rand}{}%
\advance\count\z@\@ne\do@something\@rchoice}
%%% definizione dell'azione finale da eseguire con l'elemento estratto
\def\do@something{\@nameuse{lista@\romannumeral\c@rand}\space}`
Potresti adesso definire
`\newcommand\scegli[1]{\make@list{#1}%
\rchoice{1}{\list@length}{}}`
Non sono ben sicuro di aver capito a che serve l’argomento opzionale di \scegliCiao
Enrico
-
27 Aprile 2010 alle 21:34 #44731
-
-
AutoreRisposte
- Devi essere connesso per rispondere a questo topic.