プログラミング言語を使う際に処理をまとめて暑かったほうが扱いやすいので関数を使うことになります。この関数の市kj味は、高校の関数に似ているので、高校の数学の合成かんすうを学習した後だとそれほど難しくない構造になっています。そこで、今回は関数について書こうと思います。

 関数は単体で使用しますが、合成関数では複数の関数を使用することになります。高校の数学では、括弧を使って複数の式をまとめて扱うものが登場しますが、複数の関数を使用すると様々な処理が出来るようになります。


 例えば、

関数1
関数2

がある場合、個別に実行することもできますが、関数は 【 計算結果 】 を出力するので、解を変数の値として使用することができます。その為、

 f(x)=x+1
 g(x)=x^2+2x+1・・・(x+1)^2

のような一次式と二次式が存在した場合、

   ■ f(x)+g(x)
   ■ f(x)-g(x)
   ■ g(x)-f(x)
   ■ f(x)*g(x)
   ■ g(x)/f(x)
   ■ g(x)/f(x)
  
のような四則演算や
  
   ■ f(x)**g(x)
   ■ g(x)**f(x)
   ■ f(x)**(1/g(x))
   ■ g(x)**(1/f(x))

のような冪乗の処理や

   ■ f(x)%g(x)
   ■ g(x)%f(x)

のような 【 剰余(割り算の余り) 】 を算出することもできますし、

   ■ f(x)//g(x)
   ■ g(x)//f(x)

のように 【 割った後の整数部 】 を求めることもできます。

 数学では、数値のみを使用しますから、関数も 【 関数の解 】 の部分を使用する場合には、関数自体を変数のように使用することが出来ますが、プログラミング言語を使用してコードを書く場合にも同様のことができます。上記の内容は、

  a=f(x)
  b=g(x)

のように 【 変数に関数を格納した状態 】 で考えると、中学校一年生の数学の項のカリキュラムで登場する変数項を用いた式と同じ方法で処理を考えることが出来ます。

 この状態にすると、 【 変数aと変数bの関係性 】 で式を構築できるので、項のカリキュラムの基本である

 【 加算以外は、変数に付与できるオプション 】
 
のようなものと考えることができます。中学校の数学では、変数項が登城するので、値が代入できるものはアルファベットで表記する変数項で示すことが出来るようになりますが、この際に 【 加算以外の要素は項に付与する 】 という形で 【 一つの処理の塊 】 として扱うようになっています。その為、

 【 変数xという任意の値を格納できる箱のようなもの 】

を用意した場合、この変数に対して追加できる要素が数値の推移の方向性を決める要素になります。この付与された要素によって発生する法則性を示したものが 【 関数 】 になりますが、中学校では次数と係数を付与したものを扱うようになっています。

  ■ 一次関数 : 次数が1 
  ■ 二次関数 : 次数が2

なので、

  ■ 一次関数 : y=x
  ■ 二次関数 : y=x^2・・・(y=x*x)

になりますが、これに指数を追加することで、

  ■ 一次関数 : y=ax
  ■ 分数関数 : y=1/x

のような形にすることができます。これは、

  ■ 一次関数 : 正比例
  ■ 分数関数 : 反比例

のグラフになりますが、これが次数と係数による推移の変化を示したものになります。関数を扱う場合、

 【 数値の推移をグラフにしたほうがわかりやすい 】

ので、中学校の数学では、座標軸と同じ物を変数の名称に使用しています。その為、

  ■ x : 式の中の変数の推移
  ■ y : 関数の解

となっているので、【 y=変数xを使用した関数 】 の形になっています。その基本形が、 【 y=x 】 になりますが、この構造に対して、変数項に追加できる要素を付与することで様々な数値の変化を実装できるようになっています。


 

 

  数の構造

 


 数字の構造として、
  
  ■ A+0=A
  ■ Aー0=A
  ■ A×1=A
  ■ A÷1=A

のようになりますが、この内容は変数xにも適応できます。これを踏まえて、関数の式を見てみると、

  ■ 一次関数 : y=x
  ■ 二次関数 : y=x^2
  ■ 分数関数 : y=1/x

の構造は、

  ■ 一次関数 : y=(x+0)
  ■ 二次関数 : y=(x+0)^2
  ■ 分数関数 : y=1/(x+0)

と考えることができます。この状態を見ると、一次関数だけ

  ■ 一次関数 : y=x+0

の形になっていますから、この加算部分は異なる関数の追加と同じ状態になっています。その為、一次関数については、

   ■ f(x)+g(x)

の形になっていますが、一次関数では、

  ■ 関数のグラフ
  ■ 定数のグラフ(増加分)

を追加したものが登城しますから、

  ■ 関数の法則性
  ■ 切片

を組み合わせた構造になっています。この切片は、

【 y切片 】

   原点座標の変化を追加したもの

なので、 【 x=0の時の値がy切片 】 になります。

 一次関数は傾きを持っているので、y切片があれば、X軸と交わる点も生じますが、この時に出来る切片を 【 x切片 】 と言います。x切片は、

【 x切片 】

   値が0になる地点

ですから、 【 y=0の時の状態がx切片の値 】 になります。その為、

 【 y=ax+bの関数の場合 】
 
    ■ x切片 : yに0を代入する
    ■ y切片 : xに0を代入する

と算出できるようになっています。このように一次関数では、 【 y切片 】 が登場しますが、これは、 【 関数に定数のグラフを足した構造体 】 なので、y切片の値によって、グラフが上下動します。

 これと比較した際に、

  ■ 分数関数   : y=1/(x+0)
  ■ 二次関数   : y=(x+0)^2
  ■ 平方根の関数 : y=(x+0)^1/2

は、【 x+0 】 の部分が【 項の推移の変化 】として作用しています。その為、この式を、【 x+p 】 のような形に置き換えて変数pの変化を与えてみると、関数のグラフは 【 x軸方向に移動する 】 ようになります。

 この処理については、高校の数学で登場しますが、関数のグラフも

  ■ x軸の移動 : (x+p)で制御
  ■ y軸の移動 : 定数のグラフの加算

で行えるようになっています。数学の場合、

  ■ 1=1
  
のように同じ数字は同じになりますが、

  ■ a=a

のようにその法則紫衣を変数で示すことができます。また、

  ■ 1+1=2

のように

  ■ 数式=解

の形で示すことが出来るので、

  ■ x=(x+0)

のような形で示すことができます。0は定数項なので、これを変数に置き換えて0を代入すれば同じ結果になるので、

  ■ x=(x+p)

のように変数項を用いた形にすると、変数xの値に自由度をもたせることができます。ただし、この時の解の推移を使用したい場合だと、xの値の変化をプログラミング言語のコードのように示すのではなく関数の形にする必要がありますから、

  ■ y=(x+p)
  ■ f(x)=(x+p)

の形になります。この形は、

  ■ y = x+p
  ■ f(x)= x+p

と同じなので、

  ■ y = x+b
  ■ f(x)= x+b

に置き換えることができます。その為、加算した値はy切片となるわけですが、この構造は、【 2項の多項式 】 であり、次数が1なので 【 一次式 】 ということになりますが、変数項には、数値の変化を与える要素を付与できるので係数の追加ができますから、係数として使用できる値として変数aを付与すると

  ■ y = ax+b
  ■ f(x)= ax+b

と言うふうになります。これが中学校一年生の数学で登場する一次関数の仕組みになります。

 

 中学校の項のカリキュラムで、

  ■ 乗算 : 係数
  ■ 累乗 : 指数

で制御できることを学習しますが、基本的に累乗は 【 n進数の桁の変化 】 になりますから、定数項に対して指数を付与すると 【 n進数 】 になります。その為、

【 桁の変化 】
  
  ■ 指数が正の数 : 桁が増える
  ■ 指数が負の数 : 桁が減る

ので、

   整数方向と小数点方向の桁の移動を
   指数だけでコントロールすることが
   出来る

ようになっています。二進数だとこの桁の推移を 【 シフト 】 の処理で行えるようになっていますが、この挙動と二進数の乗除算の変化が同じなので、二進数の場合だと、双方向シフトレジスター回路を使うことで乗除算の処理を行うことが出来るようになっています。

 ちなみに、二進数の場合、人が計算する場合には減算ができますが、機械は加算しかできないので、補数を算出して最後の1桁に+1をして加算を行い値を求めるようになっています。この時に桁溢れ(オーバーフロー)した値はカウントせず、有効桁数の範囲内だけ使用することで減算の結果を出すことが出来るようになっています。この場合、真逆の数値を代入すればいいので、

  ■ 加算 : バッファー
  ■ 減算 : インバーター(論理否定:NOT)

を使用すれば計算できるので、桁数の多い加算器を用意して、値を取得する際に入力の切り替えを行うだけで減算も行えるようになっています。その為、加算と減算を行う装置については、【 加減算器 】 の構造にして構築することになりますが、マイクラのように計算器を作るとひたすら巨大になるようなものであっても、補数をNOT回路を用いたものを使用すると小型にすることができます。

 と言っても、計算機の場合だと、
  
  ■ 入力 : 十進数 〜▶ 二進数
  ■ 出力 : 二進数 〜▶ 十進数

が必要になるので、

  ■ 入力装置
  ■ 出力装置
  ■ デコーダー

が必要になるので、シーケンサー部分よりも巨大な回路や装置が必要になりますから、結果的に巨大な装置を作ることになります。

 話を戻して、

 二次式などの場合、

  ■ 分数関数   : y=1/(x+p)
  ■ 二次関数   : y=(x+p)^2
  ■ 平方根の関数 : y=(x+p)^1/2

のように 【 項の構成要素 】 として使用できるので、(x+p)の構造を一つの項目の構成要素として包含できる条件については、 【 x軸方向の移動 】 が出来るようになります。

 これが、高校のカリキュラムで登場する 【 関数の原点座標の制御 】 になります。

 その為、数学では、

  ■ 単項式 : x
  ■ 多項式 : x+p

のような構造を 【 部品 】 として使用することになりますが、

  ■ y軸の移動 : 項の加算
  ■ x軸の移動 : x+p

を行うことで、グラフの原点座標を座標平面状の任意の場所に指定できるようになっています。
 

 

 

  項の仕組みとプログラミング



 中学校の項のカリキュラムでは、

  【 項 + 項 + 項 + ... 】 

のような処理が出来ることを学習しますが、この変数項の状態も

  【 変数項 】 = 【 数式 】

の形に置き換えることが出来るので、項の加算を行う形で表記してある構造物は、

  ■ 数値
  ■ 方程式

の形にできるので、回が決まった状態だとその状態で運用することができます。ただし、方程式は 【 関数の変数に対して定数項を代入した状態 】 ですから、この部分を方程式のように決まった値が出るものではなく、変数xの値で解が変化する関数に置き換えることもできます。その為、

  ■ 関数を項として使用した四則演算
  ■ 関数を項の要素として付与する

と言った処理にしようできるようになっています。この考え方が合成関数や関数を使った特殊な挙動の実装で使用できるのですが、プログラミング言語の場合、

  変数 = 関数I(引数)
  関数II(変数)

のようなことが極当たり前に行えるので、

  f(x) = 2x+3
  a = f(x)
  g(a)=2a

  f(5)

の時にg(a)を求めるような処理を作ることができます。この場合、

  ■ x=5

  ■ f(x)=2×5+3
        =13

  ■ a=13

  ■ g(a)=2×13
        =26
  

のような処理ができますが、流石に、この状態だとわかりにくいので、コードを書く場合だと、

  x=5 ・・・f(5)

  f=2*x+3 ・・・f(x) = 2x+3
  a=f ・・・a = f(x)
  g=2*a ・・・g(a)=2a

  
のようにします。そうすると、g(a)と同じ値がメモリー内に記録されるので、これをコンソールに表示して客員するために

  print(g)

を追加して、結果を確認することが出来るようになっています。手順で考えるとこうなりますが、定数で処理を刷る場合だと、方程式なのa=fの部分が不要なので、

  x=5
  f=2*x+3
  g=2*f
  print(g)

で回を求めることもできます。もう少し式を変更して、最初に乱数を取得する場合だと、

  from random import randint
  a=randint(1,10)
  x=randint(1,10)
  
  y=2*x+3
  g=a*y

  print(g)

のような形になりますが、表示をもう少しくわかりやすくして、複数回行うようにすると



のようになりますが、これを実行すると、



のようになります。

 処理の結果だけを得る場合だと、
 
  x=5
  f=2*(2*x+3)
  print(f)
 
で済むので、乱数を使う場合も

  from random import randint
  a=randint(1,10)
  x=randint(1,10)
  
  f=a*(2*x+3)

  print(f)

で済みますが、状態を表示する場合だと表示部分の記述は必要になるのでその部分だけ処理が増えます。ちなみに

【 データ 】

  from random import randint
  a=randint(1,10)
  x=randint(1,10)


【 処理 】
  
  f=a*(2*x+3)


【 出力(表示) 】

  print(f)


のようになっていますが、自動で動くものだとこうした物を用意することになります。変数の部分は、乱数を使用していますが、これは、【 乱数の代入 】 なので、任意の値を入力していることになるので、

  ■ 入力
  ■ 処理
  ■ 出力

と分けて考えることもできます。その為、この入力部分には、

  ■ 定数 
  ■ 変数

が使用できるので、

  ■ 変数の初期化
  ■ input関数による入力
  ■ 乱数の代入

などを使用することができます。これとは別に、処理をこおなった結果も代入できますが、これが

 【 関数の解を関数で使用している変数として使用する 】

と言う考え方と同じになります。こうした自由度についても高校でも学習することになりますが、この代表的なものが合成関数になります。

 また、出力についても、標準ライブラリには

  ■ 表示
  ■ 音声出力

が用意されているので、

  ■ 標準入力
  ■ 標準出力
  ■ 標準エラー出力

のように入出力とエラー処理を行う機能はどのプログラミング言語でも実装されているので、JavaScriptをコンソールで使用する際にもこの3つを使った処理が出来るので、コードを書くことでPythonのinput関数ような処理を実装することもできますが、こうした機能とは別にマルチメディア関連の機能もあるので、

  ■ 音声の利用
  ■ グラフィックの利用
  ■ ウィジェットの利用

なども出来るようになっています。その為、現在のプログラミング言語だと

  ■ JAVA
  ■ C#

などが、インストール直後からウィジェットを使ったデスクトップアプリを作れるものになっていますが、Pythonもtkを追加すれば、TkinterやTurtleを使用できるので、標準ライブラリの機能だけでもデスクトップアプリを作ることが出来るようになっています。

 このように 

  ■ 入力
  ■ 出力

には色々な選択がありますが、数値の結果を見るだけだとGUIを使う必要はないので、ターミナルで動作するコンソールアプリを作って確認することになります。

 デスクトップアプリの場合だと、この値をウィジェットのプロパティに対して使用することになりますから、 

  ■ 処理の実装
  ■ 連携

で変数の変化をウィジェット側に渡すことが出来るようになっています。この際にウィジェットの作成が必要になりますから、その仕組みをWYSWYGな作業が出来るソフトウェアを使用したり、コードで指定して記述することになります。

 その為、 【 数値の制御部分はコンソールアプリと同じ 】 なので動かす方法を学ぶ際には 【 基礎となるコンソールアプリの作成 】 を行いながら処理の方法を学習することになります。
 

 

 

  関数



 関数は 【 処理 】 を実装したものになりますが、変数に値を代入することで結果となる解を求めることが出来る仕組みになっています。高校の数学では、

  ■ 法則 : f(x)=x
  ■ 処理 : f(1)

のような方法で、

  ■ 関数の指定
  ■ 変数への値の代入

を行っていますが、プログラミング言語も同様な仕組みになっているので、この構造を少し変形させたものを使用しています。Pythonだとdefで宣言しますが、この宣言はクラスでも使用するので、見かける頻度が高いと思います。関数の宣言は

【 関数の宣言 】

   def 関数名(引数):

     処理

のようになっているので、この構造を作ると、メモリー内に関数内の処理の内容を記録できます。この際に変数と同様に 【 関数名と処理が紐付けされている 】 ので、

【 関数の実行 】

   関数名(引数)

   return 戻り値 

で実行できます。その為、

   def f(x):

     y=x+2

     return y

のようにすると、引数x値を代入した際に内部の計算を行えるようになっています。

 関数内部の変数は外部参照ができないので、戻り値を出力することで値を得る構造になっています。この辺りが、数学の関数とは異なる仕様になりますが、数値を取得して外部で使用する際には、 【 戻り値 】 を使用することになります。

 これが、数学の関数部分と同じく 【 処理の内容 】 になりますが、実行する際には、関数と同様に値を代入する必要があります。上記の関数は、一次関数ですから、変数xに値が入ると計算結果が算出されるので、高校の関数と同じく

  f(2)

のように関数名(引数)の構造にして、値を代入することで処理ができます。ただし、この状態だと、 【 演算結果が加工脳されるだけ 】 ですから、これを使用する際には、変数に関数を代入する必要があります。この使い方は、input関数で登場しますが、

  変数 = 関数(引数)

と言う形の物を使用します。こうすることで、【 関数の実行家かを変数に代入する 】 ことができます。この内容は、

  a=f(x)

と同じ考え方になりますが、先程の関数を

  a=f(x)
 
のようにすると変数aに戻り値を格納できるので、

  ■ 変数aを使用した計算
  ■ 変数aの表示

などを行うことが出来るようになります。その為、

【 処理の実装 】

   def 関数名(引数):

     処理
     
     return 戻り値

   
【 処理 】

   変数名 = 関数名(引数)


のような形で行い、変数を使って関数の実行結果を使用する流れになっています。その為、


【 入力 】

  実行側の変数雨の引数の値


【 処理の結果 】
  
  関数側の戻り値


【 戻り値 】

  関数を格納した変数に格納


という流れになるので、関数の実行部分で、

  ■ 値の入力
  ■ 戻り値の取得

を行っており、実行された時に引数を代入した形で関数が実行される仕様になっています。

 コンパイル型言語の場合、

  ■ 処理に必要なライブラリの読み込み
  ■ 関数の実装
  ■ 処理の実装
  ■ returnによる戻り値の指定

を行うようになっていますが、関数内部に処理を実装することで動作するようになっています。JAVAのように最初から 【 クラス 】 を用意して仕組みを作ってから処理を実装するようなものも存在していますが、基本的な処理の実装部分は関数の部分になります。

 C言語でPCで動くアプリケーションを作る時には、main関数に処理を実装しますが、マイコンのスケッチを書く場合には、
  
  ■ setup() : 設定ファイル
  ■ loop()  : 処理

が用意されているので、その中に設定や処理を記述することになります。これらも関数なので、C言語のように

  型 関数名(引数)
 {

  }

のような仕組みになっていますが、return 0;が入らないコードも書けるようになっています。ただし、変数をsetupとloopで参照するときにはグローバル変数にする方法もありますから、

  ■ グローバル変数の宣言
  ■ setup() : ピンの設定と変数の初期化
  ■ loop()  : 処理の実装

のような記述でコードを書くことになります。また、デバイスによってはライブラリを追加する必要があります。ちなみに

 Arduinoを使用した場合だと、setup()内の記述は、
 
  ■ 電源が入った時
  ■ リセットボタンを押した時

に1回だけ実行される仕様になっており、loop()内の記述は、

 【 電源を切るまで繰り返して実行される 】

ので無限ループ処理になります。その為、

  ■ 初期化
  ■ メインループ

のような構造になっています。