[Risolto] Bash - chiarimento operatori logici e negazione

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

[Risolto] Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Ciao, sono alle prese con questo script:

Codice: Seleziona tutto

#!/bin/bash
read -s -n1 -p "1, 2, o 3?" scelta
if [ "$scelta" != "1" -a "$scelta" != "2" -a "$scelta" != "3" ]
 then
  echo "Tasto non valido."
fi
exit
però non capisco una cosa circa gli operatori logici AND e OR. In questo script mi funzionano al contrario (a causa della negazione), in pratica se voglio che l'if mi funzioni in modalità: 1 OR 2 OR 3, devo invece scrivere 1 AND 2 AND 3 (e viceversa).
Non mi è chiara la logica di questo "ragionamento", io nego l'uguaglianza della variabile con 1, 2 o 3, non l'operatore logico e in ogni caso, sempre che non mi stia sbagliando, la negazione di AND non è OR (e viceversa).

Chi riesce a illuminarmi? :-\
Grazie.
Ultima modifica di sanzo87 il lunedì 1 agosto 2011, 22:43, modificato 1 volta in totale.
Linux user #495182 Ubuntu user #28554
pier_IP
Prode Principiante
Messaggi: 51
Iscrizione: sabato 17 ottobre 2009, 10:34
Contatti:

Re: Bash - chiarimento operatori logici e negazione

Messaggio da pier_IP »

Si parla di algebra booleana. Provo a chiarirti le idee.
Abbiamo a e b due espressioni booleane
a and b : vero se e solo se sono entrambe vere
a or b : vero se una delle due (o tutte e due) sono vere; quindi falsa se e solo se tutte e due sono false

Nel tuo caso le espressioni sono
$scelta != 1 che chiamiamo a
$scelta != 2 che chiamiamo b
$scelta != 3 che chiamiamo c
Quindi "a and b and c" e' vera se tutte e tre sono vere, quindi se $scelta non e' ne' 1, ne' 2 e ne' 3

Se invece di != mettiamo = allora invece degli and abbiamo gli or
a or b or c e' false se sono false tutte e 3, quindi se $scelta non e' ne' 1, ne' 2 e ne' 3. Negandola abbiamo il risultato di prima.
Aiuto utenti linux, esercizi svolti di matematica e teoria (statistica e analisi), strumenti matematici vari (scomposizione fattori primi, permutazioni, ...), progetti software didattici con documentazioni. Tutto qui : http://pierprogramm.altervista.org/wordpress
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Scusa, ma non mi è chiarissima la tua risposta :S
Si, so che si tratta di logica booleana e infatti lo script non la rispetta.
Prova ad eseguirlo e vedrai che non corrisponde alle tavole di verità qui di seguito, infatti se tu premi (nello script, mettendo OR al posto di AND) 1, 2 o 3 la risposta che otterrai sarà: tasto non valido, mentre se lasci l'and funziona nel modo in cui vorrei io ovvero con un OR. Non so se mi sono spiegato.


ABCA AND B AND C


0000


0010


0100


0110


1000


1010


1100


1111




ABCA OR B OR C


0000


0011


0101


0111


1001


1011


1101


1111
Linux user #495182 Ubuntu user #28554
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Codice: Seleziona tutto

[ "$scelta" != "1" -a "$scelta" != "2" -a "$scelta" != "3" ]
Il fatto è che questo codice sarà sempre vero perché la variabile è una proposizione che non potrà mai assumere più di un valore alla volta, per questo motivo non sarà mai falsa. Ok, nello script funziona ma è un ragionamento sbagliato.

Io voglio che la variabile sia uguale ad a, b o c; se è diversa da uno di questi valori allora la proposizione è vera e deve eseguire l'if. L'operatore logico da usare è quindi OR, ma se tu fai

Codice: Seleziona tutto

[ "$scelta" != "1" -o "$scelta" != "2" -o "$scelta" != "3" ]
Otterrai sempre che la proposizione è vera anche quando la variabile è uguale ad a (che poi sarebbe 1).
Se la variabile assume il valore "a", la proposizione dovrebbe essere falsa e non eseguire l'if, ma se provi ti accorgi subito che non funziona...
Ultima modifica di sanzo87 il lunedì 1 agosto 2011, 21:49, modificato 1 volta in totale.
Linux user #495182 Ubuntu user #28554
pier_IP
Prode Principiante
Messaggi: 51
Iscrizione: sabato 17 ottobre 2009, 10:34
Contatti:

Re: Bash - chiarimento operatori logici e negazione

Messaggio da pier_IP »

Codice: Seleziona tutto

#!/bin/bash
read -p "1, 2, o 3?" scelta
if [ $scelta != "1" -a $scelta != "2" -a $scelta != "3" ]
 then
  echo "Tasto non valido."
fi
exit 0
Funziona: se do in input 1, 2 o 3 non stampa nulla, se ne do' un altro stampa Tasto non valido.

Codice: Seleziona tutto

#!/bin/bash
read -p "1, 2, o 3?" scelta
if ! [ $scelta = "1" -o $scelta = "2" -o $scelta = "3" ]
 then
  echo "Tasto non valido."
fi
exit 0
To' funziona anche cosi'! Esattamente come ho scritto prima.
Auto-quote:
Se invece di != mettiamo = allora invece degli and abbiamo gli or
a or b or c e' false se sono false tutte e 3, quindi se $scelta non e' ne' 1, ne' 2 e ne' 3. Negandola abbiamo il risultato di prima.
Dai uno sguardo agli operatori booleani
http://it.wikipedia.org/wiki/Algebra_di ... i_booleani

EDIT: E non mettere le virgolette sulle variabili
Aiuto utenti linux, esercizi svolti di matematica e teoria (statistica e analisi), strumenti matematici vari (scomposizione fattori primi, permutazioni, ...), progetti software didattici con documentazioni. Tutto qui : http://pierprogramm.altervista.org/wordpress
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Lo so che funziona se nego l'and, o con l'or se non lo nego  è infatti quello che ho dovuto fare per far funzionare lo script ma è il metodo che sto contestando.
Conosco la logica booleana, come puoi vedere dal post precedente.

Il fatto è che io voglio che variabile sia uguale a 1, 2 o 3, nel caso contrario deve eseguirmi l'if (che infatti è la sua condizione) e darmi tasto errato.

Ma scusa, guarda la tavola di verità dell'OR che ho scritto prima, se la variabile assume valore 1, 2, o 3, quindi solo uno di questi, ottengo proposizione vera per cui, visto che il mio if è per quando la proposizione è falsa, non dovrebbe essere eseguito.
Insomma l'if deve essere eseguito quando la tavola ha valore di verità 0, come vedi l'and ha valore 0 anche quando uno dei tre valori è 1, ma se uno di questi ha valore 1, allora la variabile è 1, 2 o 3 quindi quello che voglio io cioè niente if, eppure lo esegue.

Non è che voglia darti contro a tutti i costi, ma o mi sfugge qualcosa che non riesco a capire, oppure c'è effettivamente un errore nella logica booleana di bash.

La seconda versione che hai scritto è quella che io userei (mi sembra quella giusta), ma tu la proponi come versione alternativa e logicamente uguale alla prima e per me non è così. Raccogliere a fattor comune una serie di negazioni dell'and sarebbe uguale al negare tutta una serie di or?
Linux user #495182 Ubuntu user #28554
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Alla fine ci sono arrivato, ho capito dove stava l'errore.
In pratica a me serve che la tavola di verità esca con valore 0, come dicevo all'inizio il problema è dovuto alla negazione; è un errore di logica per come l'ho impostata.
In un certo senso, pier, non penso ancora tu abbia ragione, ma solo che il metodo and funzioni proprio perché da quasi sempre 0 come valore di verità ovvero falso. Ma se, e qui grazie al tuo suggerimento, anzichè negare l'uguaglianza della variabile nego tutta l'espressione (quindi nego A OR B OR C), allora nego il valore di verità dell'or quindi tutti i suoi 1 diventano 0 nei casi che servono a me.
Questo però non vuol dire cambiare l'or in un and perché NOR != da AND.

Userò il secondo sistema che hai postato, quello del ! [..]
Grazie dell'aiuto!

P.S. Se poi vuoi continuare il discorso perché sei convinto delle tue idee e vuoi cercare di passarle a me, va bene, io ti girerò le mie ;)
Ultima modifica di sanzo87 il lunedì 1 agosto 2011, 22:46, modificato 1 volta in totale.
Linux user #495182 Ubuntu user #28554
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: Bash - chiarimento operatori logici e negazione

Messaggio da crap0101 »

sanzo87 ha scritto:

Codice: Seleziona tutto

[ "$scelta" != "1" -a "$scelta" != "2" -a "$scelta" != "3" ]
Il fatto è che questo codice sarà sempre vero perché la variabile è una proposizione che non potrà mai assumere più di un valore alla volta, per questo motivo non sarà mai falsa. Ok, nello script funziona ma è un ragionamento sbagliato.
questo non ha senso e comunque no, non sarà sempre vero.
Ma scusa, guarda la tavola di verità dell'OR che ho scritto prima, se la variabile assume valore 1, 2, o 3, quindi solo uno di questi, ottengo proposizione vera per cui, visto che il mio if è per quando la proposizione è falsa, non dovrebbe essere eseguito.
l' *if* viene eseguito solo se quello che deve valutare è vero, per cui o neghi il risultato come detto, oppure cambi i confronti.
Proprio guardando la tavola dovresti accorgerti che con -o al posto di -a la prima soluzione non funziona, cioè:

Codice: Seleziona tutto

usando: if [ "$scelta" != "1" -o "$scelta" != "2" -o "$scelta" != "3" ]
scelta = 1
    0 1 1 -> 1
scelta = 2
    1 0 1 -> 1
scelta = 3
    1 1 0 -> 1
scelta = 4
    1 1 1 -> 1
è questa che sarà sempre vera.
EDIT: E non mettere le virgolette sulle variabili
in genereale mi sembra invece una buona idea.
Ultima modifica di crap0101 il martedì 2 agosto 2011, 0:12, modificato 1 volta in totale.
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: [Risolto] Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Per la prima parte si, ho fatto un casino perché sono andato in palla e ho modificato quel post tipo 10 volte, può essere che alla fine non abbia tirato fuori nulla di buono.
Sulla seconda invece si, l'if parte se la sua condizione è vera, il problema è che le negazioni tirano scemi quindi capovolgiamo il problema, voglio che l'if venga eseguito quando la variabile assume o il valore 1, o il valore 2, o il valore 3.
Quindi quando è vero questo?
Facciamo le tavole di verità, quella dell'and mi dice che è vero solo quando la variabile è 1, 2 e 3, mentre quella dell'or mi dice che è vero quando la variabile assume almeno uno dei tre valori.
Traendo le conclusioni mi sembra sensato dire che l'operatore logico corretto da usare sia l'OR, visto che a me va bene che la variabile assuma anche solo 1 dei valori e non tutti (ma anche se fossero tutti, l'or va ancora bene).
Passo successivo, ora voglio invece che l'if venga eseguito quando la variabile assume un valore diverso da 1, 2 o 3.
Il problema mi sembra l'opposto del precedente quindi non cambio operatore logico, cambio solo il suo risultato negandolo.
Ecco perché dicevo che era un problema di logica, perché io negavo i valori anziché la tavola di verità.; devo negare tutta l'espressione (1 or 2 or 3) e non 1, 2 e 3 separatamente e poi metterli in OR, chiaro che così non funziona.
Il punto è che non bisogna ragionare in termini di "lo script funziona correttametne", "lo script non funziona correttamente", ma come va impostato il problema nel modo giusto, il risultato poi vien da se.
Linux user #495182 Ubuntu user #28554
pier_IP
Prode Principiante
Messaggi: 51
Iscrizione: sabato 17 ottobre 2009, 10:34
Contatti:

Re: [Risolto] Bash - chiarimento operatori logici e negazione

Messaggio da pier_IP »

Allora facciamo un po' di chiarezza.

[ $scelta != "1" -a $scelta != "2" -a $scelta != "3" ] : E' vera se $scelta non e' 1 e non e' 2 e non e' 3 (comportamento esatto)

[ $scelta = "1" -o $scelta = "2" -o $scelta = "3" ]  : E' vera se $scelta e' 1 oppure e' 2 oppure e' 3, quindi falsa quando $scelta non e' 1 o 2 o 3 (comportamento contrario a quello voluto, basta negarlo..)

! [ $scelta = "1" -o $scelta = "2" -o $scelta = "3" ]  : E' vera quando e' falsa quella di sopra, quindi quando $scelta non e' 1 o 2 o 3. (comportamento esatto)

Non e' una questione di idee o opinioni, e' solo una questione di giusto o sbagliato, io cerco solo di chiarirti le idee.

E poi nel linguaggio bash l'algebra booleana e' implementata correttamente (ci mancherebbe!), per questo dicevo "funziona", cioe' si comporta nel modo voluto (e non e' un caso, non parliamo di statistica ma di logica....)
Aiuto utenti linux, esercizi svolti di matematica e teoria (statistica e analisi), strumenti matematici vari (scomposizione fattori primi, permutazioni, ...), progetti software didattici con documentazioni. Tutto qui : http://pierprogramm.altervista.org/wordpress
sanzo87
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 357
Iscrizione: martedì 21 ottobre 2008, 13:16

Re: [Risolto] Bash - chiarimento operatori logici e negazione

Messaggio da sanzo87 »

Bene, allora vedi che alla fine mi dai ragione?
Ho sbagliato io a impostare il problema all'inizio, quindi il fatto era che usavo l'operatore giusto, ma nel modo sbagliato.
L'errore era nel modo in cui il codice era stato scritto, non nell'operatore.
Mi hai appena detto, in entrambi i casi, che l'operatore giusto (per i miei scopi) è l'or perché infatti quello che voglio io è il caso 3.

Siamo giunti quindi alla fine?
Se si, grazie ancora dell'aiuto, la soluzione arriva comunque dai tuoi messaggi!
Linux user #495182 Ubuntu user #28554
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 4 ospiti