文字のグレードを数値範囲に割り当てるシェルスクリプトを記述する方法


19

0〜100の数字を入力するように促し、その数字に基づいて成績を表示するスクリプトを作成します。

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

回答:


20

簡潔さと読みやすさ:中間点

これまで見てきたように、この問題は、適度に長くある程度反復的で読みやすいソリューションterdonABの bashの回答)、および非常に短いが直感的ではなく、自己文書化がはるかに少ないソリューション(Timのpythonそして、bashの回答やグレン・ジャックマンのperlの答え)。これらのアプローチはすべて貴重です。

また、コンパクトさと読みやすさの連続体の途中でコードを使用してこの問題を解決することもできます。このアプローチは、より長いソリューションとほぼ同じくらい読みやすく、長さが小さな難解なソリューションに近いものです。

#!/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."

このbashソリューションでは、読みやすくするためにいくつかの空白行を含めましたが、さらに短くしたい場合は削除できます。

空白行が含まれています。これは実際には、ABのbashソリューションのコンパクト化された、まだかなり読みやすいバリアントよりもわずかに短いだけです。その方法に対する主な利点は次のとおりです。

  • より直感的です。
  • グレード間の境界を変更する(または追加のグレードを追加する)のは簡単です。
  • 先頭と末尾のスペースを含む入力を自動的に受け入れます((( ))動作の説明については以下を参照)。

これらの3つの利点はすべて、この方法が構成数字を手動で調べるのではなく、数値データとしてユーザーの入力を使用するために発生します。

使い方

  1. ユーザーからの入力を読み取ります。矢印キーを使用して、入力したテキスト内を移動できるようにし(-e\、エスケープ文字として解釈しないようにします(-r)。
    このスクリプトは、機能が豊富なソリューションではありません(詳細については以下を参照してください)。しかし、これらの便利な機能により、2文字だけ長くなります。ユーザーにエスケープを提供する必要があることがわかっていない限り、常に-rwith を使用することをお勧めしreadます\
  2. ユーザーが書き込みqまたはQを終了した場合。
  3. 連想 配列declare -A)を作成します。各文字のグレードに関連付けられた最高の数値グレードを入力します。
  4. 文字の等級を最低から最高までループし、ユーザーが指定した数値が各文字の等級の数値範囲に入るのに十分かどうかを確認します。算術評価、変数名を使って拡張する必要はありません(他のほとんどの状況では、名前の代わりに変数の値を使用する場合、これを行う必要があります。)
    (( ))$
  5. 範囲内に収まる場合は、グレードを出力して終了します。
    簡潔にするために、- ではなく、短絡および演算子(&&)を使用します。ifthen
  6. ループが終了し、一致する範囲がない場合は、入力された数値が大きすぎる(100を超える)と想定し、範囲外であるとユーザーに伝えます。

奇妙な入力でこれがどのように動作するか

投稿された他の短いソリューションのように、そのスクリプトは入力が数字であると仮定する前に入力をチェックしません。算術評価((( )))は先頭と末尾の空白を自動的に削除するため問題はありませんが、

  • 数字のように見えない入力は0として解釈されます。
  • 入力が数字のように見える場合(つまり、数字で始まる場合)、無効な文字が含まれている場合、スクリプトはエラーを出力します。
  • で始まる複数桁の入力は8進数である0解釈されます。たとえば、スクリプトでは77がCであり、077がDであることが示されます。一部のユーザーはこれを必要とする場合がありますが、ほとんどの場合はそうではなく、混乱を引き起こす可能性があります。
  • プラス面では、算術式が与えられると、このスクリプトはそれを自動的に単純化し、関連する文字のグレードを決定します。たとえば、320/4がBであることがわかります。

拡張された完全機能版

これらの理由により、この拡張スクリプトのようなものを使用したい場合があります。このスクリプトは、入力が適切であることを確認し、他のいくつかの機能強化を含みます。

#!/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

これはまだ非常にコンパクトなソリューションです。

これはどの機能を追加しますか?

この拡張スクリプトの重要なポイントは次のとおりです。

  • 入力検証。terdonのスクリプトはを使用して入力チェックするため、簡潔さを犠牲にしてより堅牢な別の方法を示します。ユーザーは先頭と末尾のスペースを入力でき、8進数として意図されているかどうかを表す表現を許可しません(ゼロでない限り) 。if [[ ! $response =~ ^[0-9]*$ ]] ...
  • 正規表現の一致演算子ではなく、拡張グロブを使用caseしました(terdonの回答のように)。私はそれをして、その方法でもできることを示しました。グロブと正規表現は、テキストに一致するパターンを指定する2つの方法であり、どちらの方法でもこのアプリケーションに適しています。[[=~
  • ABのbashスクリプトのように、全体を外側のループで囲みました(cutoffs配列の最初の作成を除く)。端末入力が利用可能で、ユーザーが終了するように指示していない限り、数字を要求し、対応する文字のグレードを与えます。判断するとdo... doneあなたがそれを望むようなコードの周りにあなたの質問に、それが見えます。
  • 終了を簡単にするために、qまたはの大文字と小文字を区別しないバリアントを受け入れますquit

このスクリプトは、初心者には馴染みのないかもしれないいくつかの構造を使用します。以下に詳しく説明します。

説明:の使用 continue

外側のwhileループの本体の残りの部分をスキップしたい場合は、continueコマンドを使用します。これにより、ループの先頭に戻り、より多くの入力を読み取り、別の反復を実行します。

初めてこれを行うとき、私がいる唯一のループは外側のwhileループなのでcontinue、引数なしで呼び出すことができます。(私は中だcase構造、それの動作には影響しませんbreakかをcontinue。)

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

ただし、2回目forは、それ自体が外側のwhileループの内側にネストされている内側のループにいます。continue引数なしで使用した場合、これは外側のループではなくcontinue 1内側のforループと同等になり、継続しwhileます。

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

そのため、その場合は、continue 2代わりにbashが2番目のループを見つけて続行するようにします。

説明:caseグローブ付きのラベル

ABのbash answerのように)数字がcaseどの文字グレードのビンに入るかを判断するために使用しません。しかし、ユーザーの入力を考慮する必要があるかどうかを判断するために使用しています。case

  • 有効な番号、 *( )@([1-9]*([0-9])|+(0))*( )
  • 終了コマンド、 *( )[qQ]?([uU][iI][tT])*( )
  • その他(および無効な入力)、 *

これらはシェルグロブです。

  • それぞれが続いている)任意の開口部により一致しないこと(で、caseそれが一致したときに実行されるコマンドからパターンを分離するための構文。
  • ;;case、特定の大文字と小文字を一致させるために実行するコマンドの終了を示すための構文です(実行後に後続のケースをテストしないでください)。

通常のシェルグロビングでは*、0個以上の文字、?1つの文字、および[ ]括弧内の文字クラス/範囲に一致します。しかし、私は拡張グロビングを使用していますが、それはそれを超えています。拡張グロビングはbash、対話的に使用する場合はデフォルトで有効になりますが、スクリプトを実行する場合はデフォルトで無効になります。shopt -s extglobスクリプトの先頭にコマンドがそれをオンにします。

説明:拡張グロビング

*( )@([1-9]*([0-9])|+(0))*( )、数値入力をチェックし、次のシーケンスに一致します。

  • 0個以上のスペース(*( ))。*( )構築物は、ここだけのスペースである、括弧内のパターンのゼロまたはそれ以上に一致します。
    実際には、2種類の水平空白、スペースとタブがあり、多くの場合、タブも一致させることが望ましいです。ただし、このスクリプトは手動の対話型入力とGNU readline -eread有効にするフラグ用に記述されているため、ここでは心配していません。これは、ユーザーが左右の矢印キーを使用してテキスト内を前後に移動できるようにするためですが、通常、タブが文字どおりに入力されないという副作用があります。
  • @( )いずれか(|)の1つの出現():
    • ゼロ以外の数字([1-9])の後*( )に任意の数字のゼロ以上()が続きます([0-9])。
    • 1つ以上の(+( )0
  • ゼロ個以上のスペース(*( ))、再び。

*( )[qQ]?([uU][iI][tT])*( )quitコマンドをチェックし、次のシーケンスに一致します:

  • 0個以上のスペース(*( ))。
  • qまたはQ[qQ])。
  • オプション?( ):ゼロまたは1つのオカレンス():
    • uまたはU[uU])に続くior I[iI])に続くtor T[tT])。
  • ゼロ個以上のスペース(*( ))、再び。

バリアント:拡張正規表現を使用した入力の検証

あなたが正規表現ではなく、シェルグロブに対するユーザからの入力をテストする場合は、あなたは、このバージョンを使用することを好むが、同じ用途に働くかもしれない[[=~(のようterdonの答え)の代わりcaseとグロブ延長しました。

#!/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

このアプローチの利点は次のとおりです。

  • この特定の場合、少なくとも2番目のパターンでは、quitコマンドをチェックする構文が少し単純です。私が設定することができたので、これはあるnocasematchシェルオプションをし、すべてのケースでの変異体qquit、自動的に覆われていました。

    それがshopt -s nocasematchコマンドの機能です。shopt -s extglobコマンドは、このバージョンでは使用されませんグロブとして省略されています。

  • 正規表現スキルは、bashの拡張機能の習熟度よりも一般的です。

説明:正規表現

=~演算子の右側に指定されたパターンについては、これらの正規表現の仕組みを次に示します。

^\ *([1-9][0-9]*|0+)\ *$、数値入力をチェックし、次のシーケンスに一致します。

  • 行の先頭(つまり、左端^)()。
  • 0個以上の(*、適用された後置)スペース。通常\、正規表現でスペースをエスケープする必要はありませんが、これは[[構文エラーを防ぐために必要です。
  • ストリング(( )いずれか)または他の(|)の:
    • [1-9][0-9]*:ゼロ以外の数字([1-9])に続いて*、任意の数字([0-9])のゼロ以上(、適用された接尾辞)。
    • 0+:の1つ以上(+、適用される接尾辞)0
  • 前述のように、ゼロ個以上のスペース(\ *)。
  • 行の終わり(つまり、右端$)()。

caseテスト対象の式全体と一致するラベルとは異なり=~、左側の式の一部が右側の式として指定されたパターンと一致する場合、trueを返します。理由はここにあり^$アンカーは、ラインの開始と終了を指定し、ここで必要とされている、としてメソッドに表示されて何にも文法的に対応しないcaseとextglobs。

括弧を作るために必要とされる^$の論理和にバインド[1-9][0-9]*して0+。それ以外の場合は、およびの選言で^[1-9][0-9]*あり0+$、ゼロ以外の数字で始まる入力または aで終わる入力0(またはその両方に非数字が含まれている可能性があります)に一致します。

^\ *q(uit)?\ *$quitコマンドをチェックし、次のシーケンスに一致します:

  • 行の始まり(^)。
  • 0個以上のスペース(\ *、上記の説明を参照)。
  • 手紙q。またはQ、以来、shopt nocasematch有効になっています。
  • オプション?で、サブストリング(( ))のゼロまたは1つのオカレンス(ポストフィックス):
    • u、、、の順iに続きtます。または、shopt nocasematch有効になっている可能u性がありますU; 独立して、iであってもよいですI。そして独立して、tかもしれT。(すなわち、可能性はされないに限定uitし、UIT。)
  • 再びゼロ個以上のスペース(\ *)。
  • 行末($)。

3
真実を教えてください。どれくらい時間がかかりましたか?;)
heemayl

4
@heemayl私は1日中多くの小さな部分でそれを書いたので、完全にはわかりません(投稿の直前に完全な読み通しと編集が続きます)。私はそれがどれくらいかかるかについて考えていた場合、しかし、私が始めたときに思っていたよりも長い時間がかかったと確信しています。:)
エリアカガン

6
ますます書く、あなたの答えの本が必要です。
グリジェシュショーハン

TL; DRでも、とにかく笑わせてくれました!
ファビー

タイトルから説明まですべてが良いです。私は最初にそれを理解しましたが、私がしたかったのでもう一度読みました
スメエトデシュムフ

23

あなたはすでに基本的な考えを持っています。これをコーディングしたい場合bash(Ubuntuおよび他のほとんどのLinuxのデフォルトのシェルであるため、これは合理的な選択です)、case範囲を理解しないため使用できません。代わりに、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

4
-geおそらくあなたがを使用してelifいるので、これらのテストの束は削除できます。との愛はあり(( $response < X ))ませんか?
ムル

2
@muru true、ありがとう。私は数の範囲で考えて立ち往生したが、理由はなかった。(( $response < X ))必ず、私はこの明確見つけ、OPはbashのスクリプトに明らかに新しいです。
テルドン

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

よりコンパクトなバージョン(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

1
確かにそれらは文字の範囲ですか?つまり[0-59]、0、1、2、3、4、5または9などの任意の文字を意味します。数値に対してどのように機能するかわかりません。
スチールドライバー

3
常にFGITWである必要はありません。時間をかけて、良い答えを書いてください。terdonまたはEliah Kaganの仕組みをご覧ください。
ムル

@AB このソリューションは、主に文体の変更によって短縮できますが、非常に読みやすくなっています。簡潔さが最も重要な考慮事項になることはめったにないので、この方法で持っているものを変更する必要はないと思います。しかし、よりコンパクトなフォームはあまりスペースをとらないので、同じ方法で動作する短いスクリプトが必要な読者がいる場合は、それを表示することも検討してください。(必要に応じて、短縮版またはそのバリエーションを自由に使用してください。)
エリアケイガン

9

UbuntuのインストールにはすべてPythonが含まれているため、ここにPython スクリプト 1ライナーがあります。それをbashにする必要がある場合は、シェルスクリプトとして同等のもの作成しました。

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

実行するには、ファイル(例grade.py)に保存してから、ターミナルで次を実行します:

python grade.py

これが表示されます:

Enter the number: 65
E

これはどのように作動しますか?

  1. 入力してください- 65
  2. 先頭に0を追加します- 065
  3. 最後の文字-を削除し06ます。
  4. 75その数を引く- 70
  5. 文字に変換(Aは65、Bは66)- E
  6. 印刷してください- E

私の代名詞は彼/彼です


あなたのアイデアが好きです。+1
AB

使用しないでくださいinput()、それが呼び出されます、eval()使用、raw_input()あなたのグレーディングinstead..alsoが正しいようではない90+グレードに印刷されますB..useをchr(74 - max(4, num))....
heemayl

well..yourソリューションはいいですし、変更also..just python2で動作するinput()raw_input()python2..thatsため、それは...
heemayl

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

その後、としてのに間違っている、それが現在立っているとして、あなたの元のコードtoo..your modifedコードを変更する必要はpython3ありませんraw_input()..私は提案しraw_input()、使用してそれを実行するように言われているとして、あなたの最初の1のためにpython2...
heemayl

6

ここに私のだセミ 101個のエントリを持つ配列を移入し、それらに対するユーザの入力をチェックし-esoteric bashのソリューションは、。現実的な使用であっても合理的です。優れたパフォーマンスが必要な場合、bashを使用することはなく、100(またはそれ以上)の割り当ては依然として高速です。しかし、もっと広い範囲(100万など)に拡張すると、合理的ではなくなります。

#!/usr/bin/env bash
p(){ for i in `seq $2 $3`; do g[$i]=$1; 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

利点:

  • それほど難解ではありません。最短のソリューションよりも長く、長いソリューションほど自己文書化されていませんが... 合理的に自己文書化されています、まだ明らかに小さな側にいる間。
  • グレード範囲を変更したり、グレードを追加/削除するための簡単な変更が可能です。
  • これは、上のループして終了で動作しqquitまたは何が始まりますq/Q
  • あなたが肯定的に考えるのを助けるために、より高いグレードを最初にリストします。:)
  • うーん、これは仕事をして、あなたがそれを見ても意味を持ち続け、本質的な機能を持っています。これを実際に使用できます!

短所:

  • 数値以外の入力を行うと、Fが表示されますが、それはそれほど悪くありませんか?数値が必要な場所に非数値を指定した場合、おそらくF!
  • あいまいな、おそらく進入力は(以降オクタルとして扱われgている一次元インデックス付き配列)。古いことわざにあるように、「これはバグではなく、機能です!」まあ、多分。
  • 入力が範囲外であるか、数値ではない場合、空の行が出力されます。ただし、実際には何も問題はありません。どの文字のグレードが入力に対応しているかを示し、間違った入力の場合はありません。
  • 負の数を入力すると、それは...まあ、イースターエッグと呼びます
  • まだTimのpythonソリューションよりもかなり長い。ええ、私はそれをスピンしてアドバンテージのように思えません。

ちょっとカッコイイ?(まあ、そう思います。)

使い方

  1. p関数Pは、数値添字アレイopulates gGの 3番目の引数で指定(文字)の値と、最初の引数からその第二の範囲のインデックスで、RADESを。
  2. p 数値範囲を定義するために、各文字グレードに対して呼び出されます。
  3. 使用可能で、q(またはQ)で始まらない限り、ユーザー入力を読みg続け、文字グレードが入力された番号に対応する配列をチェックし、その文字を印刷します。

この条件はどうですか?[[ $n =~ ^(0|[1-9]+[0-9]*)$ ]]
ヘリオ

6

Python 2作成した後、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"

実行するには、ファイル(たとえばgrade.sh)に保存し、で実行可能にしchmod +x grade.shてから実行します./grade.shます。

これが表示されます:

Enter the number: 65
E

これはどのように作動しますか?

  1. 入力してください- 65
  2. 先頭に0を追加します065(そして10# 10を基数に保ちます)。
  3. 最後の文字を削除- 06ます。
  4. 75その数を引く- 70
  5. 文字に変換(Aは65、Bは66)- E
  6. 印刷してください- E

私の代名詞は彼/彼です


非常に賢い、よくやった
コス

@kosありがとう:)彼の範囲はおそらく彼が投稿したものではないので、OPでうまくいくとは思わない。これらは単純化のためだと思います。
ティム

5

そして、ここに私の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"
    }
}' -

またはワンライナーとして:

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"}}' -

4

ここにもう一つの「難解な」答えがあります

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
'

説明

  • perl -E:の-Eように-e、コマンドライン引数としてスクリプトを渡すことができます。これはperl one-linersを実行する方法です。とは異なり-e-Eすべてのオプション機能も有効にします(などsay、基本的にprint末尾に改行があります)。
  • print "number: "; :数字を入力するようユーザーに促します。
  • $n = <>;:その番号をとして保存し$nます。

次のビットを少し分解する必要があります。空白で区切ってqw/string/作成されたリストを評価stringします。だから、qw/A A B C D E F F F F F/実際にはこのリストです:

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

したがって、say qw/A A B C D E F F F F F/[11-($n+1)/10]と等価です

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

現在、Perlでは、負のインデックスを使用して、配列の末尾からカウントする要素を取得できます。例えば、$arrray[-1]、配列の最後の要素を出力します。さらに、浮動小数点配列のインデックス(10.7など)は、次に低い整数(10.7、10.3、またはすべて10になる整数)に自動的に切り捨てられます。

このすべての結果、インデックスは11-($n+1)/10常に配列の適切な要素(グレード)に評価されます。


4
難解な答えはすべて素晴らしいですが、説明を含めてください。
ムル

1

あなたはbashソリューションを求めましたが、私はPythonで、これはエレガントで短い方法で行うことができると思います。入力が間違っている場合の処理​​エラーと、0から100までの数字をAからF(またはその他)の文字に「変換」する場合の両方の処理をカバーします。

#!/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")

説明

  1. まず、ユーザーから番号を取得する必要があります。

    n = int(input("number: "))
  2. この番号がいくつかの条件で有効であるかどうかをテストします。

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

    これらの各テストの結果は、FalseまたはのいずれかになりますTrue。したがって(コードを少し圧縮する):

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

    から図を生成0します5

  3. その後、この図を文字列のインデックスとして使用して、出力として文字を生成できます。

    "ABCDEF"[3] 

    「D」を出力します(最初の文字が「A」であるため)

  4. 付加的な101リストには数が超えた場合に(Index-)エラーを生成することである100ので、"ABCDEF"[6]存在しません。同じことがにもn = n if n>=0 else ""当てはまります。0未満の数値が
    入力された場合、(Value-)エラーが作成されます。これらの場合、および入力が数字ではない場合、結果は次のようになります。

    invalid input

テスト:

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.