この記事を読むことで、PythonとGASで10進数から任意の進数(M進数)に基数変換するコードの書き方を学べます。 whileループでMで割った余りをリスト(配列)に格納し、Pythonではスライスを使ってForループでリストの逆順から表示させます。
別解として2進数に変換した結果を数値に格納するコードも記述しました。 GASではこの別解に基づいてコードを書いています。
基本的なループの書き方にスライスを使った書き方、剰余演算子、リスト(配列の追加)など、プログラミングの基幹となる文法の習得を強化できます。
このコーナーでは、学習コンテンツpaizaラーニング のレベルアップ問題集 をPythonとGASの両方で解いて全コードの解説をしています。 PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。 GASはスプレッドシートを使っています。 GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。
サイトマップはこちらから
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る メインメニューに戻る Python自作サンプル GASサンプル 基本情報技術者試験
paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。
10 進数から M 進数に変換 (paizaランク C 相当)
問題: 10 進数で表された整数 N, M が与えられます。 N を M 進数に変換して出力してください。
この記事では、下記の入力例2の場合に、10進数N=10と基数変換するM進数M=8が与えられた時に、8進数でどのような計算結果になるのかを求めて行きます。
入力例2 10 8
出力例2 12
ではまず、Pythonで解いてみます。
今回は、paiza.io を使って解きます。paiza.ioの使い方はこちら から。
■ Pythonでの解き方 ■
下準備として、paiza.ioにこの様に入力します。 (入力例1をそのままioにコピーしただけ。)
手順として、
1:10進数の数値N=10とM進数のM=8を取得する 2:余りを格納する整数arrayを宣言する 3:whileループでN>=1の間、Mで割り続けて余りをarrayに格納する 4:Forループでスライスを使ってarrayを逆順に取り出す
で、行います。
まずは、プログラムの各変数の動きを追いやすいように、トレースのio出力結果と、トレースのコードを添えます。
10進数の10を8進数に変換すると12になり、計算過程はこちらの画像をご覧下さい。
この計算をwhileループを使って行います。 では、Whileループのトレースをします。
1回目の除算
2回目の除算
以上を踏まえて、トレースの部分を表示したコードを掲載します。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
print ( '<<<ループに入る>>>' )
while N>= 1 :
print ( '除算実行前のNの値:' + str ( N) )
print ( '除算実行前のリストarray:' + str ( array) )
array. append( N% M)
print ( 'リストに追加した余り【' + str ( N% M) + '】' )
N/= M
N= int ( N)
print ( '除算実行後のNの値:' + str ( N) )
print ( '除算実行後のリストarray:' + str ( array) )
print ( '-----------------------' )
print ( '<<<ループを抜けた>>>' )
print ( array)
for num in array[ : : - 1 ] :
print ( num, end= "" )
print ( )
このままでは、出力結果である出力例3に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
while N>= 1 :
array. append( N% M)
N/= M
N= int ( N)
for num in array[ : : - 1 ] :
print ( num, end= "" )
print ( )
更に、コードがスッキリするように、コメントアウトした部分を省いたコードです。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
while N>= 1 :
array. append( N% M)
N/= M
N= int ( N)
for num in array[ : : - 1 ] :
print ( num, end= "" )
print ( )
ioの出力結果です。
上の書き方ではスライスを使ってリストをForループで逆から取り出していましたが、リストを反転させて、[1,2]を12と表記させる方法のコードを掲載します。
別解のコードでは、Forループのトレースと、コメントアウトをしたコード、コメントアウトを取り除いたコードを掲載します。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
while N>= 1 :
array. append( N% M)
N/= M
N= int ( N)
print ( array)
array= list ( reversed ( array) )
print ( array)
ans= 0
print ( )
print ( '<<<Forループに入る>>>' )
for num in array:
print ( '計算前のansの値:' + str ( ans) )
ans*= 10
print ( '10倍したansの値:' + str ( ans) )
print ( str ( ans) + 'に' + str ( num) + 'を加える' )
ans+= num
print ( '計算後のansの値' + str ( ans) )
print ( '-----------------' )
print ( '<<<Forループを抜けた>>>' )
print ( )
print ( ans)
For文に入る前に、リストを反転させます。
では、For文のループでの変数の動きを見て行きます。
1回目のansの計算
2回目のansの計算
このコードを出力形式に合わせてコメントアウトしたコードです。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
while N>= 1 :
array. append( N% M)
N/= M
N= int ( N)
array= list ( reversed ( array) )
ans= 0
for num in array:
ans*= 10
ans+= num
print ( ans)
更に、コメント部分を取り除いた、スッキリとしたコードです。
N, M= map ( int , input ( ) . rstrip( ) . split( ' ' ) )
array= [ ]
while N>= 1 :
array. append( N% M)
N/= M
N= int ( N)
array= list ( reversed ( array) )
ans= 0
for num in array:
ans*= 10
ans+= num
print ( ans)
別解でも無事正解しました。
■ GASでの解き方 ■
では、同じ問題をGASで解いてみます。 まず、スプレッドシートにこの様に配置しました。
スプレッドシートの黄色いセルの所に「10進数N(=10)をM(=8)進数に基数変換をした結果12」を出力します。
基数変換の計算結果はansに格納します。 また、ansを二次元配列ans2に追加して、スプレッドシートに出力します。
※スプレッドシートに表示する場合は、ループを使って一次元配列ではなく、二次元配列としてからの配列に追加をして作成します※
手順はこのようになります。
1:スプレッドシートからアクティブシートをアクセスする 2:スプレッドシートの緑色のセルから10進数の整数N(この例では「10」)を取得する 3:スプレッドシートの灰色のセルからM進数のM(この例では「8」)を取得する 4:8で割った余りを格納する配列を宣言する 5:whileループを使って余りを配列に格納する 6:配列を表示 7:配列を反転させる 8:反転した配列を表示 9:M進数を変数ansに格納する為、ansを0で初期化する 10:Forループで8進数を計算する 11:ansを表示 12:スプレッドシートに格納する二次元配列ans2を宣言 13:ansをans2に二次元配列として格納 14:スプレッドシートに出力前にans2を出力して確認する 15:スプレッドシートの黄色い所に8進数に基数変換した結果を格納する
手順1: スプレッドシートからアクティブシートをアクセスする
const ss=SpreadsheetApp.getActiveSheet();
ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。
手順2:スプレッドシートの緑色のセルから10進数の整数N(この例では「10」)を取得する
let N=ss.getRange(1,2).getValue();
※Nを割っていくので、Nの値が変わる、すなわち変数なので定数のconstではなく変数のletで宣言をします※
手順3:スプレッドシートの緑色のセルから10進数の整数N(この例では「10」)を取得する
let N=ss.getRange(1,2).getValue();
手順4:2で割った余りを格納する配列を宣言する
let array=[]
手順5:whileループを使って余りを配列に格納する
1回目の除算
2回目の除算
whileループの部分のコードです。
console. log ( '<<<whileループに入りました>>>' ) ;
while ( N >= 1 ) {
console. log ( `計算前のNの値: ${ N } ` ) ;
console. log ( `計算前の配列array:[ ${ array} ]` ) ;
console. log ( `配列に追加する余り【 ${ N % M } 】` ) ;
array. push ( N % M ) ;
N /= M ;
N = Math. floor ( N ) ;
console. log ( `計算後のNの値: ${ N } ` ) ;
console. log ( `計算後の配列array:[ ${ array} ]` ) ;
console. log ( '------------------------' ) ;
}
console. log ( '<<<whileループを抜けました。>>>' ) ;
手順6:配列を表示
console.log(array);
手順7:配列を反転させる
array=array.reverse();
手順8:反転した配列を表示
console.log(array);
配列を反転させる前と後の画像です。
手順9:2進数を変数ansに格納する為、ansを0で初期化する
let ans=0;
手順10:Forループでリストから2進数に基数変換する
1回目のansの計算
2回目のansの計算
Forループのコードです。
console. log ( '<<<Forループに入りました>>>' ) ;
for ( let i= 0 ; i<= array. length- 1 ; i++ ) {
console. log ( `計算前のansの値: ${ ans} ` ) ;
ans*= 10 ;
console. log ( `ansを10倍にした値: ${ ans} ` ) ;
ans+= array[ i] ;
console. log ( `計算後のansの値: ${ ans} ` ) ;
console. log ( '------------------------' ) ;
}
console. log ( '<<<Forループを抜けました。>>>' ) ;
手順11:ansを表示
console.log(ans);
手順12:スプレッドシートに格納する二次元配列ans2を宣言
let ans2=[];
手順13:ansをans2に二次元配列として格納
ans2.push([ans]);
手順14:スプレッドシートに出力前にans2を出力して確認する
console.log(ans2);
手順15:スプレッドシートの黄色い所に8進数に基数変換した結果を格納する
ss.getRange(3,2).setValue(ans2);
実行した後のスプレッドシートです。
GASでの全コードはこちらになります。
function loop2no11 ( ) {
const ss = SpreadsheetApp. getActiveSheet ( ) ;
let N = ss. getRange ( 1 , 2 ) . getValue ( ) ;
const M = ss. getRange ( 2 , 2 ) . getValue ( ) ;
let array = [ ] ;
console. log ( '<<<whileループに入りました>>>' ) ;
while ( N >= 1 ) {
console. log ( `計算前のNの値: ${ N } ` ) ;
console. log ( `計算前の配列array:[ ${ array} ]` ) ;
console. log ( `配列に追加する余り【 ${ N % M } 】` ) ;
array. push ( N % M ) ;
N /= M ;
N = Math. floor ( N ) ;
console. log ( `計算後のNの値: ${ N } ` ) ;
console. log ( `計算後の配列array:[ ${ array} ]` ) ;
console. log ( '------------------------' ) ;
}
console. log ( '<<<whileループを抜けました。>>>' ) ;
console. log ( array) ;
array = array. reverse ( ) ;
console. log ( array) ;
let ans = 0 ;
console. log ( '<<<Forループに入りました>>>' ) ;
for ( let i = 0 ; i <= array. length - 1 ; i++ ) {
console. log ( `計算前のansの値: ${ ans} ` ) ;
ans *= 10 ;
console. log ( `ansを10倍にした値: ${ ans} ` ) ;
ans += array[ i] ;
console. log ( `計算後のansの値: ${ ans} ` ) ;
console. log ( '------------------------' ) ;
}
console. log ( '<<<Forループを抜けました。>>>' ) ;
console. log ( ans) ;
let ans2 = [ ] ;
ans2. push ( [ ans] ) ;
console. log ( ans2) ;
ss. getRange ( 4 , 2 ) . setValue ( ans2) ;
}
宜しかったらコピペしてアレンジして見て下さい。 お疲れ様でした、ブレイクタイムフォトはこちらになります。
神奈川県川崎市、工場地帯の工場萌え写真。
■ 参考文献の紹介■
じっくり丁寧にPythonを学びたい方向け。 まずはpaizaラーニング などの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。
初めてGASを学ぶ方向け。 スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。
GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。
サイトマップはこちらから
paizaレベルアップ問題集でPythonとGASを解いて見たに戻る メインメニューに戻る Python自作サンプル GASサンプル 基本情報技術者試験
←前の問題へ 次の問題へ→