プログラミング初心者で、pythonを勉強しています。生徒の成績を付けるプログラムを書いていて、それぞれ50点満点で「技能」「考え方」「知識」の項目の点数を入力し、それぞれをパーセンテージによってA、B,Cで三段階評価し、
さらにA=3、B=2、C=1とし、その合計を3で割った値を5段階評価し、それを総合評価として出力したいです。
しかし、以下のコードを実行すると、各項目の結果が2回ずつ表示されます。
<コード>counter = 0
ginou = 0
kangae = 0
chishiki = 0
while True:
ginou = ginou + int (input ("技能"))
kangae = kangae + int (input ("考え方"))
chishiki = chishiki + int (input("知識"))
counter += 1
ask = int(input ("continue?(y=1,n=0)"))
if ask == 1:
continue
elif ask == 0:
def hyotei(tensuu):
if tensuu /counter /50 *100 >= 90:
print ("A",tensuu /counter /50 *100,"%")
return 3
elif tensuu / counter /50 *100 >=60:
print ("B",tensuu /counter /50 *100,"%")
return 2
elif tensuu / counter / 50 *100 <60:
print ("C",tensuu /counter /50 *100,"%")
return 1
hyotei(ginou)
eva = hyotei(ginou)
hyotei(kangae)
eva2 = hyotei (kangae)
hyotei(chishiki)
eva3= hyotei (chishiki)
if (eva + eva2+eva3)/3>=2.9:
print("総合評価:5")
elif (eva + eva2+eva3)/3>=2.6:
print("総合評価:4")
elif (eva + eva2+eva3)/3>=1.8:
print("総合評価:3")
elif (eva + eva2+eva3)/3>=1.3:
print("総合評価:2")
elif (eva + eva2+eva3)/3<1.3:
print("総合評価:1")
break
<技能50、考え方40、知識20の場合の実行結果>
A 100.0 %
A 100.0 %
B 80.0 %
B 80.0 %
C 40.0 %
C 40.0 %
総合評価:3
おそらくeva = hyoutei(ginou) のところの書き方が悪いのではと思っていますが、どうすれば結果を一回ずつ表示することができるでしょうか。
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
> 例えば出力はまったくせずに、returnで帰ってくる数値だけを参照して計算したりするばあいはどうしたらいいでしょうか。
基本的には返り値は、
1. 変数に代入するように持っていく
2. 別の関数の引数にツッコむ
の二種類の使い方をします。どっちでも好きなようにして構いません。
> eva=3 のとき
> print(hyotei(ginou)+5)
> だと、計算結果の8以外に、A 100.0 %という出力結果が出てしまいます。
それはhyoutei内にprintを仕込んでるからですね。hyoutei内からprintを外した方が良いでしょう。
ええと、「綺麗なプログラミングをしたい」と言う場合、入力、出力を「計算のキモ」となる関数から外した方が良いです。まあ、プログラミング書法的な考え方ですが、「入力は入力だけでまとめる」「出力は出力だけでまとめる」のが見通しが良いです。
ちょっと専門的な話になりますが、「関数は返り値を返し」ますが、その為に(現代の高級言語的には)「計算の結果を返す」場合は関数を作る、と言うセオリーを形作っています。
一方、実は入出力ってのは「計算」じゃないんですよ。こういう「計算と全く関係ない作用」を専門的には「副作用」と呼びます。
Python3では「printは関数」って事になってますが、実はこれは「副作用目的」の関数なんですね。
C言語やLispだとこういう「出力関数」ってのは印字と別に何かしらの返り値を持ってるんですが、Python3の場合、
>>> x = print("hello")
hello
>>> x
>>>
と、xには何も代入されません。Python3だと「Noneを返す関数」と言う表現を使いますが、実は一般的なプログラミング用語だとこれは関数ではないのです。こういう「返り値が何もない計算以外の目的(副作用目的)に使う何か」を手続き、あるいはプロシージャと呼びます。つまり、一般的にはPythonのprintは関数ではなくてプロシージャなんです。
注: これ、Pascal辺りだと厳密に関数とプロシージャが分かれてるんですが、高級言語もどんどん高級になるに従って境界線が曖昧になってきてて、Pythonの「Noneを返す関数」もそういう一例ですね。ちなみにC言語のvoid関数ってのも要するにプロシージャです。
まあ、ちょっと説明が難しいかもしれませんが、要するに、「綺麗なプログラムを書きたい」場合、「関数とプロシージャを混ぜ合わせない」ってのがコツで、プロシージャの何が一番頻出するのか、と言うと、やっぱ「入出力」なんですよ。こいつが関数内だと「邪魔」なんで、混ぜるな危険(笑)、ってワケで、切り分けるようにした方が見通しが良い、つまり「後々、修正が容易になる」って事ですね。
いずれにせよ、入出力を噛ませるのは「最後にプログラムをまとめる時」って覚えておいた方が後々良いのではないでしょうか。
なるほど、まだ勉強し始めて3週間ほどですが、綺麗なコードというのは今まで意識したことなかったですね。
丁寧に教えていただきありがとうございました!
No.1
- 回答日時:
うーん、正直言って・・・・。
酷いコードですね。
いや、初心者だって事は分かってるんだけど、教本が良くないのじゃないかしらん。
バッチ式プログラミングになっています。
しかも、期せずしてローカル関数定義になってるし・・・・・・。
まあ、「動けば良い」って考え方もあるんですが・・・・・。
どないすんねん、これ、ってカンジです。
平たく言うと、貴方の予想通り、
hyotei(ginou) <- これが要らない
eva = hyotei(ginou)
hyotei(kangae) <- これが要らない
eva2 = hyotei (kangae)
hyotei(chishiki) <- これが要らない
eva3= hyotei (chishiki)
です。
(期せずしてなった)ローカル関数には不幸な事に出力関数printが入っています。
つまり例えば、
hyotei(ginou) # ここで出力される
eva = hyotei(ginou) # ついでにここでも出力される
んで、「二回出力されてる」んですね。全く同じ結果が二回印字されるのはそのせいです。
ありがとうございます。
おっしゃる通り、まだグローバル関数なるものを習っておらず、とりあえず知ってる知識だけで書きました。
いらないところを消したら動きました。。。が、
例えば出力はまったくせずに、returnで帰ってくる数値だけを参照して計算したりするばあいはどうしたらいいでしょうか。
たとえば
eva=3 のとき
print(hyotei(ginou)+5)
だと、計算結果の8以外に、A 100.0 %という出力結果が出てしまいます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Ruby パイソンプログラミング 2 2022/12/03 18:44
- その他(プログラミング・Web制作) 【Python初学者】以下コードについて教えていただきたいです 4 2023/04/19 13:01
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Ruby プログラミング 3 2023/06/09 14:30
- その他(プログラミング・Web制作) atcoder python コードへの助言 2 2022/08/12 15:31
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
16進の10進変換について
-
pythonの*
-
perl言語について
-
perでメールが送信出来ない場合...
-
パイソン文法で(インデント)
-
前ゼロ補填
-
awkの正規表現での最左最短マッ...
-
pythonについての質問です。
-
Perl でワードファイルのヘッダ...
-
<python>数字あてゲーム
-
小数点付きの余分な桁を消すには
-
Application.ScreenUpdating = ...
-
セレクトメニューで選んだ値を...
-
ホームページビルダーのメール...
-
フォームの日本語が文字化け
-
セレクトボックスから別窓にジ...
-
FLASHとCGIでのデータの受け渡...
-
構造体の変数の値を、動的に取...
-
JSONで文字列が長い時
-
年令の計算方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
16進の10進変換について
-
【至急!!!】python言語で本を見...
-
pythonで演算子を変数に代入す...
-
数値かどうかの判定方法
-
pythonの*
-
UWSCのSELECT文の記述方法
-
int(input("○○"))の使い方
-
関数「exists」と「defined」の...
-
c言語 16進数の2進数への変換
-
Perlにおける<?phpinfo();?>の...
-
I2C接続のLCDディスプレイを使う
-
シェルスクリプトで、空白(ス...
-
「HSP」でキャラコードを使って...
-
switch文のエラーについて
-
Use of uninitialized value ---
-
変数の中は文字列か数値か調べ...
-
perでメールが送信出来ない場合...
-
画面上再読み込みをさせたいの...
-
awkの正規表現での最左最短マッ...
-
数値英単語変換
おすすめ情報