この記事を読むことで、PythonとGASでwhileループを使って、変動する値を加算をしていく過程で、変数がどのように変化するのかを学べます。
毎日、所持金A円にA円の10%ずつ加算して行って、何日加算したら目標金額B円を超えるのかを求めます。
このコーナーでは、学習コンテンツpaizaラーニングのレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。
GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験
paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。
問題:
現在所持金を A 円持っています。
所持金が毎日 10% ずつ増えるとき、何日後に B 円を超えるか出力してください。
また、増加するお金は小数点以下切り捨てで考えることとします。
例として、所持金が 831 円 のとき、10% は 83.1円 ですが、増加するお金は 83 円 です。
この記事では、下記の入力例3の場合を例にして、A円の813円が10%ずつ増えると「何日後にB円の10000円を超えるか」を求めて行きます。
入力例3
813 10000
出力例3
27
ではまず、Pythonで解いてみます。
今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。
■ Pythonでの解き方 ■
下準備として、paiza.ioにこの様に入力します。
(入力例1をそのままioにコピーしただけ。)
手順として、
1:A,Bを標準入力で取り込む
2:ループの何日目でAの813円がBの10000を超えるかの日数を数える変数dayを0で初期化する
3:whileループでA<=Bの条件を満たす間、ループを回して加算する。dayをインクリメントする
4:dayを表示
で、行います。
まずは、プログラムの各変数の動きを追いやすいように、トレースのio出力結果と、トレースのコードを添えます。
Whileループのトレースをします。
27日間の増加の詳細です。
<1日〜3日目までのトレース>
<4日〜6日目までのトレース>
<7日〜9日目までのトレース>
<10日〜12日目までのトレース>
<13日〜15日目までのトレース>
<16日〜18日目までのトレース>
<19日〜21日目までのトレース>
<22日〜24日目までのトレース>
<25日〜27日目までのトレース>
元手のA円から目標金額B円までかかった日数dayはこちらです。
ここまでのwhileループによるトレースの部分のコードです。
#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))
#元手A円がB円を超える日数dayを0で初期化する
day=0
#whileループでA<=Bの間、お金を増やす
print('<<<whileループに入る>>>')
while A<=B:
print('計算前のAの金額:'+str(A)+'円')
#増加するお金
print('増加するお金は「'+str(int(A/10))+'円」です。')
#お金を増やす
A+=int(A/10)
print('計算後のAの金額:'+str(A)+'円')
#dayをインクリメント
day+=1
print('経過日数【'+str(day)+'】')
print(('---------------------------'))
print('<<<whileループを抜ける>>>')
print(day)
このままでは、出力結果である出力例3に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。
#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))
#元手A円がB円を超える日数dayを0で初期化する
day=0
#whileループでA<=Bの間、お金を増やす
#print('<<<whileループに入る>>>')
while A<=B:
#print('計算前のAの金額:'+str(A)+'円')
#増加するお金
#print('増加するお金は「'+str(int(A/10))+'円」です。')
#お金を増やす
A+=int(A/10)
#print('計算後のAの金額:'+str(A)+'円')
#dayをインクリメント
day+=1
#print('経過日数【'+str(day)+'】')
#print(('---------------------------'))
#print('<<<whileループを抜ける>>>')
print(day)
スッキリするように、コメントアウトした部分を省いたコードです。
#標準入力で元手の金額A円と基準の金額B円を取得する
A,B=map(int,input().rstrip().split(' '))
#元手A円がB円を超える日数dayを0で初期化する
day=0
#whileループでA<=Bの間、お金を増やす
while A<=B:
#お金を増やす
A+=int(A/10)
#dayをインクリメント
day+=1
print(day)
ioの出力結果です。
■ GASでの解き方 ■
では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。
スプレッドシートの黄色いセルの所に「加算される整数N(=1)、増加する数M(=3)、加算して超える基準値K(=8)」でKを超えるまでに加算した回数を出力します。
Whileループで加算する回数を変数countに格納します。
また、countを二次元配列count2に追加して、スプレッドシートに出力します。
※スプレッドシートに表示する場合は、ループを使って一次元配列ではなく、二次元配列としてからの配列に追加をして作成します※
手順はこのようになります。
1:スプレッドシートからアクティブシートをアクセスする
2:整数A,Bを取得する配列arrayを宣言する
3:スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する
4:arrayを出力して、各数が配列に格納されていることをログで確認する
5:A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。
6:それぞれの変数、定数が正しく代入されたことをログで確認する
7:Aに10%の金額ずつ足していく日数dayを0で初期化する
8:whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする
9:スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する
10:day2に二次元配列になるようにdayを追加
11:スプレッドシートに出力前のday2を出力して確認する
12:スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する
手順1: スプレッドシートからアクティブシートをアクセスする
const ss=SpreadsheetApp.getActiveSheet();
ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。
手順2:整数A,Bを取得する配列arrayを宣言する
let array=[];
手順3:スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する。
下のスプレッドシートより、セルB1つまり(1,2)から2行分を取得するので、getRangeの引数に(1,2,2)と書きます。
array=ss.getRange(1,2,2).getValues();
手順4:arrayを出力して、各数が配列に格納されていることをログで確認する
console.log(array);
手順5:A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。
let A=array[0][0];
const B=array[1][0];
※ Aは10%ずつ加算されていくので値が変わるから変数、それに対して基準値のBは値が変わらないので定数 ※
手順6:それぞれの変数、定数が正しく代入されたことをログで確認する
数値と文字を一緒に出力するときは、[Shiftキー]を押しながら「@」を押して「 ` 」で囲います。
console.log(`現在の所持金A:「${A}円」,目標金額B:「${B}円」`);
手順7:Aに10%の金額ずつ足していく日数dayを0で初期化する
let day=0;
手順8:whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする
<1日〜3日目までのトレース>
<4日〜6日目までのトレース>
<7日〜9日目までのトレース>
<10日〜12日目までのトレース>
<13日〜15日目までのトレース>
<16日〜18日目までのトレース>
<19日〜21日目までのトレース>
<22日〜24日目までのトレース>
<25日〜27日目までのトレース>
Whileループの部分のコードです。
//whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする
console.log('<<<ループに入ります。>>>');
while(A<=B){
console.log(`加算前の金額A:${A}円`);
console.log(`加算するAの10%の金額:${Math.floor(A/10)}円`);
//加算処理
A+=Math.floor(A/10);
console.log(`加算後の金額A:${A}円`);
//日数をインクリメント
day++;
console.log(`【${day}】日目`);
console.log('----------------------');
}
console.log('<<<ループを抜けました。>>>');
手順9:スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する
let day2=[];
手順10:day2に二次元配列になるようにdayを追加
day2.push([day]);
手順11:スプレッドシートに出力前のday2を出力して確認する
console.log(day2);
手順12:スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する
ss.getRange(5,2).setValue(day2);
実行後のスプレッドシートです。
GASでの全コードはこちらになります。
function loop2no13() {
//スプレッドシートからアクティブシートをアクセスする
const ss = SpreadsheetApp.getActiveSheet();
//整数A,Bを取得する配列arrayを宣言する
let array = [];
//スプレッドシートの緑色のセルにある金額A円(この例では「813」)と、灰色のセルにある目標金額B円(この例では10000)を2行1列の配列分取得して、arrayに格納する
array = ss.getRange(1, 2, 2).getValues();
//arrayを出力して、各数が配列に格納されていることをログで確認する
console.log(array);
//A=array[0][0]、B=array[1][0]として代入する。この時Aは変数で、Bは定数になる。
let A = array[0][0];
const B = array[1][0];
//それぞれの変数、定数が正しく代入されたことをログで確認する
console.log(`現在の所持金A:「${A}円」,目標金額B:「${B}円」`);
//Aに10%の金額ずつ足していく日数dayを0で初期化する
let day = 0;
//whileループを使ってAに現在のAの10%ずつ加算する「A+=Math.floor(A/10)」の計算をして、dayをインクリメントする
console.log('<<<ループに入ります。>>>');
while (A <= B) {
console.log(`加算前の金額A:${A}円`);
console.log(`加算するAの10%の金額:${Math.floor(A / 10)}円`);
//加算処理
A += Math.floor(A / 10);
console.log(`加算後の金額A:${A}円`);
//日数をインクリメント
day++;
console.log(`【${day}】日目`);
console.log('----------------------');
}
console.log('<<<ループを抜けました。>>>');
//スプレッドシートにdayに格納された日数を二次元配列として格納するday2を宣言する
let day2 = [];
//day2に二次元配列になるようにdayを追加
day2.push([day]);
//スプレッドシートに出力前のday2を出力して確認する
console.log(day2);
//スプレッドシートの黄色い所に日数を二次元配列として格納したday2を出力する
ss.getRange(5, 2).setValue(day2);
}
宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。
お食事中の方、ごめんなさい、浅草で有名な「うんこビル」です。
■ 参考文献の紹介■
じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。
GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験