计算具有不同加权百分比的成绩,并以bash输出最终成绩

时间:2019-04-02 22:23:30

标签: linux bash

我需要编写一个bash shell脚本,询问用户的姓名和4个分数不同的测试分数,然后计算他们的总成绩并输出他们的字母成绩。

值如下:

Assignments 30%
Midterm 30%
quiz 10%
Final 30%

在读取变量后,我尝试将变量乘以(30/100),但我无法接受bash接受多行算术运算。到目前为止,我只能将它们全部加起来并除以4。在这一点上我不知所措,感谢任何帮助

echo "What is your name?"
read name 
echo "What is your score on the Assignment?"
read s1 
echo "What is your score on the Quiz?"
read s2 
echo "What is your score on the Midterm Exam?"
read s3 
echo "What is your score on the Final Exam?"
read s4 


total=$(expr $s1 + $s2 + $s3 + $s4) 
avg=$(expr $total / 4) 


 if [ $avg -ge 80 ] 
 then 
  echo "$name's grade is an A"
 elif [ $avg -ge 70 ] 
 then 
         echo "$name's grade is a B" 
 elif [ $avg -ge 60 ] 
 then 
         echo "$name's grade is a C"
 elif [ $avg -ge 50 ] 
 then 
         echo "$names's grade is a D"
 else 
 echo "$name's grade is an F" 
 fi

1 个答案:

答案 0 :(得分:0)

根据我上面的评论,您可以做几件事。首先使用POSIX算术运算符(( ... ))代替古老的expr。接下来,由于bash仅提供整数数学,为了使用百分比,必须将百分比乘以100,然后除以100,以获得{{1 }}。您无需除以total,您的百分比已经占到了权重分数的100%。此外,在bash中,然后您必须依靠4之类的浮点实用程序来处理所有浮点计算,包括除法以得出bc

但是,当您在avg语句中比较avg时(例如,将if then elif ... else视为79.9),仅凭这一点并不能消除舍入错误。使用79获得bc,您仍然需要一种方法来正确处理舍入,以便从79.9(或更优)和{{1 }}小于80但大于或等于79.5的任何内容。

感谢79提供了一种方便的方法来将转换结果存储为变量并处理舍入,因为它使用了C-print转换逻辑。例如,要保存由79.5转换后的78.5的结果,然后正确舍入(保存在变量名printf -v中),可以执行以下操作:

avg

完全将其放入您可以做的事情:

bc

要确认正确处理了四舍五入,您可以在保存rounded之后添加一个简单的total=$((s1 * 30 + s2 * 30 + s3 * 10 + s4 * 30)) avg=$((total / 100)) ## not used but saved for output demonstration below printf -v rounded "%.0f" $(printf "scale=2; $total/100\n" | bc) ,例如添加:

#!/bin/bash

echo "What is your name?"
read name 
echo "What is your score on the Assignment?"
read s1 
echo "What is your score on the Quiz?"
read s2 
echo "What is your score on the Midterm Exam?"
read s3 
echo "What is your score on the Final Exam?"
read s4 

total=$((s1 * 30 + s2 * 30 + s3 * 10 + s4 * 30))
avg=$((total / 100)) 
printf -v rounded "%.0f" $(printf "scale=2; $total/100\n" | bc)

if [ "$rounded" -ge 80 ] 
then 
    echo "$name's grade is an A"
elif [ "$rounded" -ge 70 ] 
then 
    echo "$name's grade is a B" 
elif [ "$rounded" -ge 60 ] 
then 
    echo "$name's grade is a C"
elif [ "$rounded" -ge 50 ] 
then 
    echo "$names's grade is a D"
else 
    echo "$name's grade is an F" 
fi

然后确认,输入分数,如果没有正确舍入,分数将得到printf而不是rounded(您自由给出的分数为{{1} }),例如

使用/输出示例

printf "\ntotal: %d\navg  : %d\nrounded avg: %d\n\n" \
        "$total" "$avg" "$rounded"

使用"B"语句

您可能还想考虑使用简单的"A"语句消除80语句的长链,这将大大清除内容。例如,您可以将整个$ bash student.sh What is your name? John What is your score on the Assignment? 78 What is your score on the Quiz? 80 What is your score on the Midterm Exam? 81 What is your score on the Final Exam? 81 total: 7980 avg : 79 rounded avg: 80 John's grade is an A 替换为

case

if then elif then elif then ...一起使用/输出的示例

case ... esac

仔细研究一下,如果您有任何疑问,请告诉我。