Come scrivere uno script di shell per assegnare i voti delle lettere a intervalli numerici?

19

Voglio creare uno script che ti suggerisca un numero compreso tra 0 e 100 e quindi darti il ​​voto in base al numero.

Mi piacerebbe farlo in bash.

PS3='Please enter your choice: '
(Something here)

do
case $
    "0-59")
        echo "F"
        ;;
    "60-69")
        echo "D"
        ;;
    "70-79")
        echo "C"
        ;;
    "Quit")
        break
        ;;
    *) echo invalid option;;
esac
done
    
posta Temple Pate 09.05.2015 - 13:46

9 risposte

20

Brevità vs. leggibilità: una via di mezzo

Come hai visto, questo problema ammette soluzioni moderatamente lunghe e in qualche modo ripetitive ma altamente leggibili ( terdon's e risposte bash di AB), nonché quelle che sono molto brevi ma non intuitive e molto meno auto-documentante (Tim's python e bash risposte e glenn jackman's risposta perl ). Tutti questi approcci sono preziosi.

Puoi anche risolvere questo problema con il codice nel mezzo del continuum tra compattezza e leggibilità. Questo approccio è quasi leggibile quanto le soluzioni più lunghe, con una lunghezza più vicina alle piccole soluzioni esoteriche.

#!/usr/bin/env bash

read -erp 'Enter numeric grade (q to quit): '
case $REPLY in [qQ]) exit;; esac

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

for letter in F D C B A; do
    ((REPLY <= cutoffs[$letter])) && { echo $letter; exit; }
done
echo "Grade out of range."

In questa soluzione bash, ho incluso alcune righe vuote per migliorare la leggibilità, ma potresti rimuoverle se lo volessi ancora più breve.

Righe vuote incluse, questo è in realtà solo leggermente più corto di una variante compatta, ancora abbastanza leggibile di La soluzione bash di AB . I suoi principali vantaggi rispetto a questo metodo sono:

  • È più intuitivo.
  • È più facile cambiare i confini tra i voti (o aggiungere altri voti).
  • Accetta automaticamente l'input con spazi iniziali e finali (vedi sotto per una spiegazione di come (( )) funziona).

Tutti e tre questi vantaggi si presentano perché questo metodo utilizza l'input dell'utente come dati numerici anziché esaminare manualmente le sue cifre costituenti.

Come funziona

  1. Leggi l'input dell'utente. Permetti loro di usare i tasti freccia per spostarti nel testo sono stati inseriti ( -e ) e non interpretano \ come carattere di escape ( -r ).
    Questo script non è una soluzione ricca di funzionalità - vedi sotto per un raffinamento- -ma quelle funzioni utili rendono solo due caratteri più lunghi. Ti consiglio di utilizzare sempre -r con read , a meno che tu non sappia che devi consentire all'utente di fornire \ di escape.
  2. Se l'utente ha scritto q o Q , esci.
  3. Crea un associativo array ( declare -A ). Compilalo con il voto numerico più alto associato al voto di ogni lettera.
  4. Passa attraverso i voti delle lettere dal più basso al più alto, controllando se il numero fornito dall'utente è abbastanza basso da rientrare nell'intervallo numerico del grado di ogni lettera.
    Con (( )) valutazione aritmetica, i nomi delle variabili non devono essere espansi con $ . (Nella maggior parte delle altre situazioni, se si desidera utilizzare il valore di una variabile al posto del suo nome, devi farlo .)
  5. Se rientra nell'intervallo, stampa il voto e esci .
    Per brevità, utilizzo l'operatore e ( && ) di cortocircuito piuttosto che if - then .
  6. Se il ciclo finisce e nessun intervallo è stato abbinato, supponi che il numero inserito sia troppo alto (oltre 100) e dica all'utente che era fuori portata.

Come funziona Behaves, con Weird Input

Come le altre soluzioni brevi pubblicate, quello script non controlla l'input prima di supporre che sia un numero. La valutazione aritmetica ( (( )) ) elimina automaticamente gli spazi bianchi iniziali e finali, quindi questo nessun problema, ma:

  • L'input che non assomiglia ad un numero è interpretato come 0.
  • Con un input che assomiglia a un numero (ad esempio, se inizia con una cifra) ma contiene caratteri non validi, lo script emette errori.
  • L'input a più cifre che inizia con 0 è interpretato come in ottale . Ad esempio, lo script ti dirà che 77 è un C, mentre 077 è un D. Anche se alcuni utenti potrebbero volerlo, molto probabilmente non lo fanno e possono causare confusione.
  • Sul lato positivo, quando viene fornita un'espressione aritmetica, questo script lo semplifica automaticamente e determina il grado di lettera associato. Ad esempio, ti dirà che 320/4 è un B.

Una versione espansa e completamente in evidenza

Per questi motivi, ti consigliamo di utilizzare qualcosa come questo script espanso, che verifica che l'input sia valido e include altri miglioramenti.

#!/usr/bin/env bash
shopt -s extglob

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

while read -erp 'Enter numeric grade (q to quit): '; do
    case $REPLY in  # allow leading/trailing spaces, but not octal (e.g. "03") 
        *( )@([1-9]*([0-9])|+(0))*( )) ;;
        *( )[qQ]?([uU][iI][tT])*( )) exit;;
        *) echo "I don't understand that number."; continue;;
    esac

    for letter in F D C B A; do
        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }
    done
    echo "Grade out of range."
done

Questa è ancora una soluzione piuttosto compatta.

Quali funzionalità aggiunge?

I punti chiave di questo script espanso sono:

  • Convalida dell'input. lo script di terdon controlla l'input con if [[ ! $response =~ ^[0-9]*$ ]] ... , quindi mostro un altro modo, che sacrifica un po 'di brevità ma è più robusto, permettendo utente per inserire spazi iniziali e finali e rifiutando di consentire un'espressione che potrebbe o non potrebbe essere intesa come ottale (a meno che non sia zero).
  • Ho utilizzato case con globbing esteso anziché [[ con =~ corrispondenza di espressioni regolari operatore (come nella risposta di terdon ). L'ho fatto per dimostrare che (e come) può anche essere fatto in questo modo. Glob e regex sono due modi per specificare i pattern che corrispondono al testo, e entrambi i metodi vanno bene per questa applicazione.
  • Come script bash di AB , ho racchiuso il tutto in un ciclo esterno (tranne la creazione iniziale della matrice cutoffs ). Richiede numeri e assegna i voti delle lettere corrispondenti finché l'input del terminale è disponibile e l'utente non gli ha detto di uscire. Giudicando dal do ... done attorno al codice nella tua domanda, sembra che tu lo voglia.
  • Per facilitare l'uscita, accetto qualsiasi variante non sensibile alle maiuscole / minuscole di q o quit .

Questo script usa alcuni costrutti che potrebbero non essere familiari ai novizi; sono dettagliati di seguito.

Spiegazione: uso di continue

Quando voglio saltare il resto del corpo del ciclo while esterno, utilizzo il comando continue . Questo lo riporta in cima al ciclo, per leggere più input ed eseguire un'altra iterazione.

La prima volta che faccio questo, l'unico loop in cui mi trovo è il% outer co_de% loop, quindi posso chiamare while senza argomenti. (Sono in un costrutto continue , ma questo non influenza l'operazione di case o break .)

        *) echo "I don't understand that number."; continue;;

La seconda volta, tuttavia, mi trovo in un ciclo interno continue che è a sua volta annidato all'interno del ciclo for esterno. Se ho usato while senza argomenti, questo sarebbe equivalente a continue e continuerebbe il ciclo interno continue 1 invece del ciclo for esterno.

        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }

Quindi in questo caso, utilizzo while per fare in modo che bash trovi e continui il secondo loop out.

Spiegazione: continue 2 Etichette con Globs

Non uso case per capire quale tipo di lettera bin ricade in un numero (come in < a href="https://askubuntu.com/a/621471/22949"> risposta bash di AB ). Ma io uso case per decidere se l'input dell'utente deve essere considerato:

  • un numero valido, case
  • il comando quit, *( )@([1-9]*([0-9])|+(0))*( )
  • qualsiasi altra cosa (e quindi input non valido), *( )[qQ]?([uU][iI][tT])*( )

Questi sono globuli di shell .

  • Ognuno è seguito da un * a cui non corrisponde alcuna apertura ) , che è la sintassi di ( per separare un modello dai comandi che vengono eseguiti quando è abbinato.
  • case è la sintassi di ;; per indicare la fine dei comandi da eseguire per una corrispondenza caso-caso (e che nessun caso successivo deve essere testato dopo averli eseguiti).

Il globbing della shell ordinaria fornisce case per corrispondere a zero o più caratteri, * per corrispondere esattamente a un carattere e classi / intervalli di caratteri in ? [ parentesi. Ma sto usando globbing esteso , che va oltre. Il globbing esteso è abilitato per impostazione predefinita quando si utilizza ] in modo interattivo, ma è disabilitato per impostazione predefinita quando si esegue uno script. Il comando bash nella parte superiore dello script lo attiva.

Spiegazione: Globbing esteso

shopt -s extglob , che controlla l'input numerico , corrisponde a una sequenza di:

  • Zero o più spazi ( *( )@([1-9]*([0-9])|+(0))*( ) ). Il costrutto *( ) *( corrisponde a zero o più del modello tra parentesi, che qui è solo uno spazio.
    Esistono in realtà due tipi di spazi, spazi e tabulazioni orizzontali e spesso è desiderabile schede di corrispondenza anche. Ma non mi preoccupo di questo qui, perché questo script è scritto per l'input manuale e interattivo e il flag ) su -e abilita la lettura GNU. In questo modo l'utente può spostarsi avanti e indietro nel testo con i tasti freccia sinistra e destra, ma ha l'effetto collaterale di impedire in genere l'inserimento letterale delle schede.
  • Una ricorrenza ( read @( ) di entrambi ( ) ):
    • Una cifra diversa da zero ( | ) seguita da zero o più ( [1-9] *( ) di qualsiasi cifra ( ) ).
    • Uno o più ( [0-9] +( ) di ) .
  • Zero o più spazi ( 0 ), ancora.

*( ) , che controlla il comando quit , corrisponde a una sequenza di:

  • Zero o più spazi ( *( )[qQ]?([uU][iI][tT])*( ) ).
  • *( ) o q ( Q ).
  • Facoltativamente - cioè, zero o una occorrenza ( [qQ] ?( ) - di:
    • ) o u ( U ) seguito da [uU] o i ( I ) seguito da [iI] o t ( T ).
  • Zero o più spazi ( [tT] ), ancora.

Variante: convalida dell'input con un'espressione regolare estesa

Se preferisci testare l'input dell'utente con un'espressione regolare piuttosto che con una shell glob, potresti preferire usare questa versione, che funziona allo stesso modo ma usa *( ) e [[ (come in terdon's's risposta ) anziché =~ e globbing esteso.

#!/usr/bin/env bash
shopt -s nocasematch

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

while read -erp 'Enter numeric grade (q to quit): '; do
    # allow leading/trailing spaces, but not octal (e.g., "03")
    if [[ ! $REPLY =~ ^\ *([1-9][0-9]*|0+)\ *$ ]]; then
        [[ $REPLY =~ ^\ *q(uit)?\ *$ ]] && exit
        echo "I don't understand that number."; continue
    fi

    for letter in F D C B A; do
        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }
    done
    echo "Grade out of range."
done

I possibili vantaggi di questo approccio sono:

  • In questo caso particolare, la sintassi è un po 'più semplice, almeno nel secondo schema, in cui controllo il comando quit. Questo perché sono stato in grado di impostare l'opzione di shell case , quindi tutte le varianti di case di nocasematch e q sono state coperte automaticamente.

    Questo è ciò che fa il comando quit . Il comando shopt -s nocasematch viene omesso poiché il globbing non viene utilizzato in questa versione.

  • Le abilità di espressione regolare sono più comuni rispetto alla competenza in extglobs di bash.

Spiegazione: espressioni regolari

Come per i pattern specificati a destra dell'operatore shopt -s extglob , ecco come funzionano quelle espressioni regolari.

=~ , che controlla l'input numerico , corrisponde a una sequenza di:

  • L'inizio - cioè, il bordo sinistro - della linea ( ^\ *([1-9][0-9]*|0+)\ *$ ).
  • Zero o più ( ^ , applicati postfix) spazi. Normalmente uno spazio non ha bisogno di essere * -escaped in un'espressione regolare, ma è necessario con \ per evitare un errore di sintassi.
  • Una sottostringa ( [[ ( ) che è una o l'altra ( ) ) di:
    • | : una cifra diversa da zero ( [1-9][0-9]* ) seguita da zero o più ( [1-9] , applicata postfix) di qualsiasi cifra ( * ).
    • [0-9] : uno o più ( 0+ , applicato postfix) di + .
  • Zero o più spazi ( 0 ), come prima.
  • La fine - cioè, il margine destro - della linea ( \ * ).

A differenza delle etichette $ , che corrispondono all'intera espressione testata, case restituisce true se qualsiasi parte della sua espressione a sinistra corrisponde al modello dato come espressione a destra. Questo è il motivo per cui le =~ e ^ ancore, che specificano l'inizio e la fine della linea, sono qui necessarie e non corrispondono sintatticamente a qualsiasi cosa appaia nel metodo con $ ed extglobs.

Le parentesi sono necessarie per rendere case e ^ associate alla disgiunzione di $ e [1-9][0-9]* . Altrimenti sarebbe la disgiunzione di 0+ e ^[1-9][0-9]* , e corrisponde a qualsiasi input che inizia con una cifra diversa da zero o che termina con una 0+$ (o entrambe, che potrebbero ancora includere non digit in tra).

0 , che controlla il comando quit , corrisponde a una sequenza di:

  • L'inizio della riga ( ^\ *q(uit)?\ *$ ).
  • Zero o più spazi ( ^ , vedi la spiegazione sopra).
  • La lettera \ * . O q , poiché Q è abilitato.
  • Facoltativamente - vale a dire, zero o una occorrenza (postfix shopt nocasematch ) - della sottostringa ( ? ( ):
    • ) , seguito da u , seguito da i . Oppure, poiché t è abilitato shopt nocasematch può essere u ; indipendentemente, U può essere i ; e indipendentemente, I può essere t . (Cioè, le possibilità sono non limitate a T e uit .)
  • Ancora zero o più spazi ( UIT ).
  • La fine della riga ( \ * ).
risposta data Eliah Kagan 09.05.2015 - 20:31
23

Hai già l'idea di base. Se vuoi codificarlo in bash (che è una scelta ragionevole dato che è la shell predefinita su Ubuntu e molti altri Linux), non puoi usare case perché non comprende gli intervalli. Invece, potresti utilizzare if / else :

#!/usr/bin/env bash

read -p "Please enter your choice: " response

## If the response given did not consist entirely of digits
if [[ ! $response =~ ^[0-9]*$ ]]
then
    ## If it was Quit or quit, exit
    [[ $response =~ [Qq]uit ]] && exit
    ## If it wasn't quit or Quit but wasn't a number either,
    ## print an error message and quit.
    echo "Please enter a number between 0 and 100 or \"quit\" to exit" && exit
fi
## Process the other choices
if [ $response -le 59 ]
then
    echo "F"
elif [ $response -le 69 ]
then
    echo "D"
elif  [ $response -le 79 ]
then
    echo "C"
elif  [ $response -le 89 ]
then
    echo "B"
elif [ $response -le 100 ]
then
    echo "A"
elif [ $response -gt 100 ]
then
    echo "Please enter a number between 0 and 100"
     exit
fi
    
risposta data terdon 09.05.2015 - 14:04
12
#!/bin/bash

while true
do
  read -p "Please enter your choice: " choice

  case "$choice"
   in
      [0-9]|[1-5][0-9])
          echo "F"
          ;;
      6[0-9])
          echo "D"
          ;;
      7[0-9])
          echo "C"
          ;;
      8[0-9])
          echo "B"
          ;;
      9[0-9]|100)
          echo "A"
          ;;
      [Qq])
          exit 0
          ;;
      *) echo "Only numbers between 0..100, q for quit"
          ;;
  esac
done

e una versione più compatta (Thx @EliahKagan ):

#!/usr/bin/env bash

while read -erp 'Enter numeric grade (q to quit): '; do
    case $REPLY in
        [0-9]|[1-5][0-9])   echo F ;;
        6[0-9])             echo D ;;
        7[0-9])             echo C ;;
        8[0-9])             echo B ;;
        9[0-9]|100)         echo A ;;

        [Qq])               exit ;;
        *)                  echo 'Only numbers between 0..100, q for quit' ;;
    esac
done
    
risposta data A.B. 09.05.2015 - 13:58
9

Tutte le installazioni di Ubuntu hanno Python, quindi ecco uno script di python. Se hai bisogno che sia in bash, ho anche scritto l'equivalente come script di shell .

print (chr(75-max(5,int('0'+raw_input('Enter the number: ')[:-1]))))

Per eseguirlo, salvalo in un file (ad esempio grade.py ), quindi eseguilo nel terminale con questo:

python grade.py

Questo è ciò che vedrai:

Enter the number: 65
E

Come funziona?

  1. Accetta input - 65 .
  2. Aggiungi uno 0 all'inizio - 065 .
  3. Rimuovi l'ultimo carattere - 06 .
  4. 75 sottrarre quel numero - 70 .
  5. Converti in una lettera (A è 65, B è 66) - E .
  6. Stampa fuori - E .
risposta data Tim 09.05.2015 - 14:56
6

Dopo facendolo in Python 2 , ho deciso di farlo in bash.

#! /bin/bash

read -p "Enter the number: " i
i=0$i
x=$((10#${i::-1}))
printf "\x$(printf %x $((11-($x>5?$x:5)+64)))\n"

Per eseguirlo, salvalo in un file (ad es. grade.sh), rendilo eseguibile con chmod +x grade.sh e poi esegui con ./grade.sh .

Questo è ciò che vedrai:

Enter the number: 65
E

Come funziona?

  1. Accetta input - 65 .
  2. Aggiungi uno 0 all'inizio - 065 (e 10# lo mantiene base 10).
  3. Rimuovi l'ultimo carattere - 06 .
  4. 75 sottrarre quel numero - 70 .
  5. Converti in una lettera (A è 65, B è 66) - E .
  6. Stampa fuori - E .
risposta data Tim 09.05.2015 - 15:33
6

Ecco la mia semi soluzione bash -esoterica, che popola un array con 101 voci e poi controlla l'input dell'utente contro di loro. Anche per l'uso nel mondo reale è ragionevole - se avessi bisogno di prestazioni eccellenti non avresti usato bash, e un centinaio di incarichi è ancora veloce. Ma smetterebbe di essere ragionevole se esteso a un raggio maggiore (come un milione).

#!/usr/bin/env bash
p(){ for i in 'seq  '; do g[$i]=; done; }
p A 90 100; p B 80 89; p C 70 79; p D 60 69; p F 0 59
while read -r n && [[ ! $n =~ ^[qQ] ]]; do echo ${g[$n]}; done

I vantaggi:

  • Non è proprio così esoterico. Sebbene sia più lungo delle soluzioni più brevi, e non è tanto auto-documentante quanto le soluzioni più lunghe ... è ragionevolmente autodocumentante , mentre è ancora decisamente sul lato minuscolo.
  • Permette facili modifiche per modificare intervalli di gradi o aggiungere / rimuovere voti.
  • Funziona in un ciclo e si chiude su q , quit o su qualsiasi cosa che inizia con q / Q .
  • Elenca prima i voti più alti, per aiutarti a pensare in positivo. :)
  • Hmm, questo fa il lavoro, continua a dare un senso anche dopo averlo guardato, e ha le caratteristiche essenziali. Potresti davvero usarlo!

Svantaggi:

  • Ti dà una F quando inserisci input non numerici ... ma non è poi così male, vero? Se dai un numero non numerico in cui è necessario un numero, forse ti meriti un F!
  • L'input ambiguo, eventualmente ottale, viene trattato come ottale (poiché g è un array indicizzato monodimensionale ). Come dice il vecchio proverbio, "Non è un bug, è una caratteristica!" Bene, forse.
  • L'input fuori dalla portata o non un numero causa la stampa di una linea vuota. Non c'è niente di veramente sbagliato in questo: ti dice quale voto di lettera corrisponde al tuo input, e per input sbagliato non ce n'è uno.
  • Inserisci un numero negativo e ... beh, chiamalo uovo di Pasqua .
  • Ancora significativamente più lungo della soluzione python di Tim . Sì, non posso davvero farlo sembrare un vantaggio.

Che bello, eh? (Beh, penso di si.)

Come funziona

  1. La funzione p p opula un array indicizzato numericamente g di g rades, in indici che vanno dal primo argomento al secondo, con il valore (lettera) dato nel terzo argomento.
  2. p viene chiamato per ogni grado di lettera, per definire il suo intervallo numerico.
  3. Continua a leggere l'input dell'utente finché è disponibile e non inizia con q (o Q ), controllando l'array g per il quale il grado di lettera corrisponde al numero inserito e stampando quella lettera.
risposta data Eliah Kagan 11.05.2015 - 07:13
5

Ed ecco la mia versione di awk:

awk '{
  if($_ <= 100 && $_ >= 0) {
      sub(/^([0-9]|[1-5][0-9])$/, "F", $_);
      sub(/^(6[0-9])$/, "D", $_);
      sub(/^(7[0-9])$/, "C", $_);
      sub(/^(8[0-9])$/, "B", $_);
      sub(/^(9[0-9]|100)$/, "A", $_);
      print
    }
    else {
      print "Only numbers between 0..100"
    }
}' -

o come one-liner:

awk '{if($_ <= 100 && $_ >= 0) { sub(/^([0-9]|[1-5][0-9])$/, "F", $_); sub(/^(6[0-9])$/, "D", $_); sub(/^(7[0-9])$/, "C", $_); sub(/^(8[0-9])$/, "B", $_);sub(/^(9[0-9]|100)$/, "A", $_);   print} else { print "Only numbers between 0..100"}}' -
    
risposta data A.B. 09.05.2015 - 21:13
4

Ecco un'altra risposta "esoterica" ​​

perl -E '
    print "number: "; 
    $n = <>; 
    say qw/A A B C D E F F F F F/[11-($n+1)/10]
       if $n=~/^\s*\d/ and 0<=$n and $n<=100
'

Spiegazione

  • perl -E : il -E , come -e , consente di passare uno script come argomento della riga di comando. Questo è un modo per lanciare perl one-liner. A differenza di -e , -E abilita anche tutte le funzioni opzionali (come say , che è fondamentalmente un print con una nuova riga finale.)
  • print "number: "; : richiede all'utente di inserire un numero.
  • $n = <>; : salva quel numero come $n .

Il prossimo bit deve essere scomposto un po '. qw/string/ valuta una lista creata rompendo string allo spazio bianco. Quindi, qw/A A B C D E F F F F F/ è in realtà questa lista:

0 : A
1 : A
2 : B
3 : C
4 : D
5 : E
6 : F
7 : F
8 : F
9 : F
10 : F

Pertanto, say qw/A A B C D E F F F F F/[11-($n+1)/10] è equivalente a

my @F=("A","A","B","C","D","E","F","F","F","F","F");
print "$F[11-($n+1)/10]\n"

Ora, Perl consente di utilizzare indici negativi per recuperare gli elementi contando dalla fine dell'array. Ad esempio, $arrray[-1] stamperà l'ultimo elemento dell'array. Inoltre, gli indici di array in virgola mobile (ad es. 10.7) vengono automaticamente troncati al numero intero inferiore successivo (10.7, o 10.3 o qualsiasi cosa diventino tutti 10).

Il risultato di tutto ciò è che l'indice 11-($n+1)/10 valuta sempre l'elemento appropriato (grado) dell'array.

    
risposta data glenn jackman 09.05.2015 - 16:03
1

Anche se hai chiesto una soluzione bash, penso che in Python, questo può essere fatto in modo elegante e breve. Coprendo entrambi gli errori di gestione in caso di input errato e la "conversione" di un numero compreso tra 0 e 100 in lettere da A a F (o qualsiasi altro):

#!/usr/bin/env python3
try:
    n = int(input("number: ")); n = n if n>0 else ""
    print("FEDCBA"[[n>=f for f in [50,60,70,80,90,101]].count(True)])
except:
    print("invalid input")

Spiegazione

  1. Per prima cosa dobbiamo ottenere il numero dall'utente:

    n = int(input("number: "))
    
  2. Testiamo questo numero per essere valido per una serie di condizioni:

    n>=50, n>=60, n>=70, n>=80, n>=90
    

    Per ciascuno di questi test, il risultato sarà False o True . Pertanto (comprimendo un po 'il codice):

    [n>=f for f in [50,60,70,80,90]].count(True)]
    

    produrrà una figura da 0 a 5

  3. Successivamente, possiamo usare questa figura come indice per una stringa, per produrre un carattere come output, ad es.

    "ABCDEF"[3] 
    

    genererà "D" (dal primo carattere="A")

  4. L'ulteriore 101 dell'elenco consiste nel generare un errore (Index-) nel caso in cui il numero superi 100 , poiché "ABCDEF"[6] non esiste. Lo stesso vale per n = n if n>=0 else "" , che creerà un errore (Valore) se viene inserito un numero inferiore a 0 In questi casi, così come se l'input non è una figura, il risultato sarà:

    invalid input
    

I test:

number: 10
F

number: 50
E

number: 60
D

number: 70
C

number: 80
B

number: 90
A

number: 110
invalid input

number: -10
invalid input

number: Monkey
invalid input
    
risposta data Jacob Vlijm 07.07.2015 - 15:05

Leggi altre domande sui tag