Google ClassroomGoogle Classroom
GeoGebraGeoGebra Classroom

日常1(プロフィールの追加アプリ)

このページはマス旅の一部です。 今回は、「プログラミングで脳トレ」の初回です。 身近なネタを使って、数学にも関係のある小物をプログラミングしてみよう。 数学もプログラミングも、ちょっとした脳トレの道具にできたらいいね。

1.BMIとか干支って話題に上ることってありませんか?

ということで、お題は次の通り。 課題:プロフィール追加アプリ 詳細: 「身長(cm)、体重(kg)、和暦の生年月日(M/T/S/H/R yy/mm/dd)」 を入力すると、 「BMIと体型(低体重、標準、肥満度)、西暦の生まれ年、干支」 を表示してくれる。

2.使う数学外の知識

#BMI BMI=W(kg)/(H(m))^2 #体型 BMIから判定基準(日本肥満学会) 18.5未満:低体重(やせ) 18.5〜25未満:普通体重(標準) 25〜30未満:肥満(1度) 30〜35未満:肥満(2度) 35〜40未満:肥満(3度) 40以上:肥満(4度) #西暦ADの生まれ年 M,T,S,H,R ==>明治,大正,昭和,平成,令和 元年{1868,1912,1926,1989,2019 末   45 15 64 31 末年 1912 1926 1989 2019 #干支 子(ね)、丑(うし)、寅(とら)、卯(う)、 辰(たつ)、巳(み)、午(うま)、未(ひつじ)、 申(さる)、酉(とり)、戌(いぬ)、亥(い) 西暦から3を引いて12で割った余りが1が子という人がいます。 以下が子になる西暦 1876年(明治9年) 1888年(明治21年) 1900年(明治33年) .....

3.数学・言語・プログラミングの知識

#BMI計算 身長の入力が㎝なので、100で割ってから2乗して、体重を割る。 見やすくするために、四捨五入して小数第1の数にします。 xの小数第2位を四捨五入した値は、floor(10x+0.5)/10で求められるね。 #体型判断 Case文がないと、if-elseを入れ子にするのが普通の発想ですね。 しかし、判定基準の仕切りが 18.5以外は25,30、35、40と5刻みになっていることを活用したい。 5の倍数の判定境界値を5で割ると 5,6,7,8となる。 この特殊性に目をつけて、「リスト的な発想」で取り組む。 体型ランクのリストを作る。 ランクに入れるためにはBMI値を5で割って切り捨てると、 たとえば、BMI=25.5ならfloor(BMI/5)=5となり、インデックス5を指せる。 だから、最初から判定語(体型ランク)を9個作り、それが1から9の番号で指せるようにしよう。 もし、低体重なら無条件にインデックスは1で、 floor(BMI/5)が9を超えないように最大値が9となるようにしたい。 そのため、9と比べて小さい方をインデックスにする。 「ガードの発想」ですね。 #西暦の生まれ年 和暦文字はM,T,S,H,Rを入れる。 X={"M","T","S","H","R"}を作っておけば、インデックスIdをみつけられます。 Idの和暦ごとのゼロ年の西暦Cがわかれば、 Cにyyをたせば生まれ年の西暦が出ます。 C1={1868,1912,1926,1989,2019} 元年リストC1から1引いた0年リストC0を作れたら楽ですね。 #干支 西暦から3を引いて12で割った余りが1が子という人がいます。 というのは面倒ですね。 (X-3)=1 mod 12 が子(1) X=4 mod 12 のときのXが子(1) Xを9増やすと巡回シフトする。 X=4+8≡0 mod 12 のときのXは申さる(9) 干支を申さる(9)スタートひつじ未(0)終わりにすると、 X(mod 12)で0スタート11エンドの繰り返しになります。 こうすれば、Xを12の倍数をスタートの周期にできますね。 (脱線) 12=3×4で、下4桁が4の倍数で各位の和が3の倍数です。 西暦は18YY,19YY,20YYの3通りしかありません。 申年だけを知りたいとしましょう。 1+8=9は3の倍数だから、18YYのYYは12の倍数です。1896が最後の申年。 19YYのYYは4の倍数で3の倍数ー1。1992が最後の申年 20YYのYYは4の倍数で3の倍数ー2です。2004が最初の申年。

4.コード化

<geogebraのアプレット> 「要素を追加>geogebra>作成>関数グラフ」 数式ビューの入力...に 1行づつ貼り付けてEnter #入力ボックスの挿入で、見出し、コントロール名を選びます。 それをInputBox(見出し、コントロール名)と表示しています。 (InputBoxコマンドから入力するときは、コントロール名だけを引数にとるので、 見出しは設定の変更が必要になります。) H=180 W=70 Era="H" YY=20 InputBox("身長(cm)",H) InputBox("体重(kg)",W) InputBox("和暦",Era) InputBox("年YY",YY) text0="「和暦」は明治はM,大正はT,昭和はS,平成はH、令和はRで、" text1="「年YY」は、5年生まれならば05と入力してください。" #計算部分 BMI=((floor(10*((W)/((((H)/(100)))^(2)))+0.5))/(10)) BodyTypes={"低体重","標準","標準","標準","肥満1","肥満2","肥満3","肥満4","肥満4"} BodyTypeIndex = if(BMI<18.5, 1,floor(BMI/5)) BodyType=Element(BodyTypes, min(BodyTypeIndex,9)) Eras={"M","T","S","H","R"} base1={1868,1912,1926,1989,2019} base0=base1-1 eraBase=Element(base0,IndexOf(Era,Eras)) YearAD=eraBase+YY etos={"申(さる)","酉(とり)","戌(いぬ)","亥(い)", "子(ね)","丑(うし)","寅(とら)","卯(う)", "辰(たつ)","巳(み)","午(うま)","未(ひつじ)"} etoId=Mod(YearAD,12)+1 eto=Element(etos,etoId) #結果表示 text2="あなたのBMI: "+BMI text3="あなたの体型判定: "+BodyType text4="西暦の生まれ年: "+YearAD text5="干支: "+eto

プロフィール追加アプリ

<Pythonへの移植コード> jupyter notebook のセルにまるごと貼り付けて、Run。 # 入力ラインが表示される H = float(input("身長(cm): ")) W = float(input("体重(kg): ")) Era = input("和暦(M/T/S/H/R): ").upper() YY = int(input("年YY: ")) # 計算部分 BMI = round(W / ((H / 100) ** 2), 1) BodyTypes = ["低体重", "標準", "標準", "標準", "肥満1", "肥満2", "肥満3", "肥満4", "肥満4"] if BMI < 18.5: BodyTypeIndex = 0 # Pythonは0-indexed else: BodyTypeIndex = int(BMI // 5)-1 BodyType = BodyTypes[min(BodyTypeIndex, len(BodyTypes) - 1)] Eras = ["M", "T", "S", "H", "R"] base1 = [1868, 1912, 1926, 1989, 2019] base0 = [b - 1 for b in base1] eraBase = base0[Eras.index(Era)] YearAD = eraBase + YY etos = ["申(さる)", "酉(とり)", "戌(いぬ)", "亥(い)", "子(ね)", "丑(うし)", "寅(とら)", "卯(う)", "辰(たつ)", "巳(み)", "午(うま)", "未(ひつじ)"] eto = etos[YearAD % 12] # 結果表示 print(f"\nあなたのBMI: {BMI}") print(f"あなたの体型判定: {BodyType}") print(f"西暦の生まれ年: {YearAD}") print(f"干支: {eto}")