継続的に値を確認する - Bashスクリプト

継続的に値を確認する - Bashスクリプト

標準入力からパラメータ(1日の学習時間)を取得し、学生が定期的に勉強していることを確認するスクリプトを作成したいと思います。正規学習とは、連続7日間で少なくとも1日4時間、この7日間で少なくとも2日間は、少なくとも1日6時間(連続する必要はありません)を意味します。私はこれを試しました:

four_h=0
six_h=0
for i in $@ ; do
        if [ $i -ge 6 ]; then let six_h=six_h+1 
        elif [ $i -ge 4 ]; then let four_h=four_h+1 
    else :
    fi
done

if [ $four_h -ge 7 ] && [ $six_h -ge 2 ];
    then echo "you are regularly studying"
else echo "you are not regularly studying"
fi

しかし、うまくいきません。繰り返すことはできませんが、理由を理解していないようです。そして、学生が4時間以上「持続的に」勉強しているかどうかを確認する方法がわかりません。

答え1

2つの条件が満たされていることを確認する必要があるようです。

  1. 7つの連続した値のうち、すべての数字は4以上でなければなりません。
  2. 連続する7つの数字のうち2つは6以上でなければなりません。

したがって、数値の配列を維持する必要があるように見え、配列に正確に7つの数字が含まれている場合から、両方の条件を確認する必要があります。

その後、始めることができます変えるループから配列の数字を読み、それぞれの新しい数字の条件を再確認します。

以下のスクリプトがbashまさにそのことをします。ただこんな感じ現れる宿題の問題でコードの注釈に記載されている以上は言いません。考えてみてください。コードが何であるかもしれず、宿題に対する答えとしてコードを使用するなら、自分自身に害を及ぼすでしょう。コードの品質があなたやあなたの同僚が見るものと異なる場合、不正行為で起訴されることがあります。

#!/bin/bash

has_studied () {
        # Tests the integers (given as arguments) and returns true if
        # 1. All numbers are 4 or larger, and
        # 2. There are at least two numbers that are 6 or greater

        local enough large

        enough=0 large=0
        for number do
                [ "$number" -ge 4 ] && enough=$(( enough + 1 ))
                [ "$number" -ge 6 ] && large=$(( large + 1 ))
        done

        # Just some debug output:
        printf 'Number of sufficient study days: %d\n' "$enough" >&2
        printf 'Number of long study days (out of those): %d\n' "$large" >&2

        [ "$enough" -eq 7 ] && [ "$large" -ge 2 ]
}


# Array holding the read integers
ints=()

echo 'Please enter hours of study, one integer per line' >&2
echo 'End by pressing Ctrl+D' >&2

# Loop over standard input, expecting to read an integer at as time.
# No input validation is done to check whether we are actually reading
# integers.

while read integer; do
        # Add the integer to the array in a cyclic manner.
        ints[i%7]=$integer
        i=$(( i + 1 ))

        # If the array now holds 7 integers, call our function.
        # If the function returns true, continue, otherwise terminate
        # with an error.
        if [ "${#ints[@]}" -eq 7 ]; then
                if ! has_studied "${ints[@]}"; then
                        echo 'Has not studied!'
                        exit 1
                fi
        fi
done

# If the script hasn't terminated inside the loop, then all input has
# been read and the student appears to have studied enough.

echo 'Appears to have studied'

答え2

awkバージョンを読むstdin

awk 'BEGIN{print "Enter study hours and finish input with ctrl+d:"}
        {if ($0 >=0) {count++; print $0" hours on day "count}
        if ($0 >= 4 && $0 < 6) hrs[4]++;
        if ($0 >= 6) hrs[6]++}
    END{print "\nStudy scheme over "count" days:";
        for (d in hrs) print d" hours studied on "hrs[d]" days";
        if (hrs[4]+hrs[6] < 7 || hrs[6] < 2) not=" not";
        print "You are"not" studying regularly"
    }' -

関連情報