アプリケーション開発
プログラミングの他にコーディングという言葉がある。
メカ的アナロジーでいうと、プログラミングはメカ設計全般の仕事であり、コーディングは3Dモデリング・製図作業のみを指すものである。
非ソフトウェアエンジニアは、フィクションでハッカーがPCのキーボードをカタカタやっているイメージがあるが、あれがコーディングであるといって良い。
プログラミングには、プログラムの設計やテストなんかも含まれる。むしろコーディング期間とテスト期間は大体同じくらいかかる。しらんけど。
言語問わず、コーディングに必要なものは概ね以下のようなものである。
これらをなんとなく理解できれば、プログラミングの下準備は整ったと言っても良い。
1.文字コードと全角のスペース
古くはASCII(アスキー)が文字コードの代表で、アスキーアートやASCII.jp/月間アスキーの元ネタにもなっている。ASCIIの対応表はこちら。CR+LFは古い人ほど知っているかもしれない(由来はタイプライターでプリンターにもこの概念が使用されている:参考リンク)。
文字コードとはコンピュータに文字を認識させるために、文字に割り当てられる数字の組み合わせのようなものである。
ASCIIでは、英数字記号を16進数で0x00から0x7f(2の7乗)までの数字で表している。例えば、0x30を割り当てられている文字は”0″だったり、0x4bを割り当てられている文字は”0″だったりする。
では日本語は?英数字記号だけなら128通りで済むかもしれないが、英語以外の文字も含むとなると桁数の多い、もっと別の数列を文字と紐付けなければ、まともにコンピュータに日本語を認識させることなどできない。
そこで各国・言語ごとにASCIIのような文字への数値の割り当てを行う規格が必要となる。その規格こそが文字コードである。
日本では2020年まではShift-JISが主流であったといえるが、windows10でデフォルトの(メモ帳の)文字コードがUTF-8となったことで、様々な記号・広範囲の言語文字に対応できるようになった。
また、文字化けというものがるが、これは異なる文字コードを無理やり別の文字コードで表示させた結果、本来の数値と文字の対応から崩れてしまうことで起こるものである。
プログラミングではこのように汎用的な文字コードを使用することでバグを発生しづらくする必要がある。
したがって、今後は文字コードはUTF-8を厳とする。
また、多くの文字コードの英数字部分はACSIIと互換性をもたせているため、後述するコメント文でも極力日本語を使用しないことでバグ対策を行うことも効果的である。
ちなみにこのような背景もあってか、基本的にほぼすべてのプログラミング言語は半角英数字記号限定でのコーディングしかできない仕様になっている。
そのため、コードの途中に全角の英語等使用した場合、プログラムはもれなくバグる。というか、そもそも動かない。
ここで気をつけたいのが全角のスペースの存在である。全角のスペースは見えないので、文末や半角のスペースに紛れ込もうものなら、プログラマーはデスマーチをすることになるだろう(最近はエディタが全角のスペースを見つけてくれることが多いので実際にはそんなことではエラーにならないが)。
2.main関数
main関数とは、特別にプログラミング言語から割り当てられたプログラムの主となる関数のことである。
基本的にmain関数の中にコードを記載する。
そしてプログラムはmain関数内のコードが上から順に実行される(参考:エントリポイント)。
Pythonにおいては、色々なmain()の書き方がある(詳細:#019_色々なmain())。
Pythonでは
if __name__ == "__main__":
print(r"Hello World!")
Cでは
#inculde <stdio.h>
void main(void){
printf("Hello World!");
}
ちなみに…
ちなみに、環境構築の最後にもターミナルに”Hello World!”と表示させたが、これはプログラミング界隈では一般的な慣習であり、最も単純なコードを実行することによって、開発環境の構築が成功したことを確認するための手順である。これはプログラミング言語によらず、デファクトスタンダードになっている。ちなみにちなみに、ファーム(組み込み系プログラム)では、動作がパソコン上ではなく、マイコンなどのIC上の動作となるので、ターミナルへの文字出力は基本的にはできないため、”Hello World!”ではなく、ごく単純な動作としてLEDをチカチカ点滅させるプログラム動作(通称”Lチカ”)を実行することで開発環境が整ったことを確かめることが慣習となっている。
3.言語と文法
上記2は、PythonとC言語のmain関数の実例を示したが、このように言語ごとに記法が異なる。
特に、Pythonはインデントで関数1まとまりのブロックを表しているが、Cでは中括弧”{}”でブロックを形成している。
それぞれターミナルに”Hello World!”という文字列を表示させるプログラムであるが、次のような書き方も可能である。
Pythonでは
print(r"Hello World!") # mainを消してインデントを下げる。
Cでは
#inculde <stdio.h>
void main(void){ printf("Hello World!"); } // 中括弧の位置をずらす。
このように言語ごとに様々な特徴・違いがある。一方で、print()/printf()のように非常に似た名前・機能の関数もある。
したがって、1つの言語をある程度マスターすると、他の言語の習得は比較的楽である。
一般には、C言語が原始的かつ最難関なので大学では基本Cをメインに教えている場合が多い。
4.変数と代入
以下、混乱を避けるため、Pythonベースで話を進める。
プログラミング言語には変数と代入という概念がある。数学で習ったこの言葉はプログラミングにおいては性質が異なる点に注意したい。
数学では(左辺)=(右辺)ならば(右辺)=(左辺)が成り立つが、ことプログラミングにおいてはそうではない。以下に例を示す。
ある変数を定めて初めて代入することを初期化という。
変数の命名について、よく知られているのは下記の4通り。エラー用のフラグの命名例で紹介する。
- アッパーキャメルケース:FlagError
- ローワーキャメルケース:flagError
- スネークケース: flag_error
- ケバブケース: flag-error
>>> ooo_xxx のような形式で変数名を決めるとき、ooo には、 data/val/value/str/string/line/char/matrix/list/name/path など、機能が分かるものにする。xxx には、input/output/np/01/save/init/initialize/gui/click などその機能を修飾するような名称をつける。また、ローマ字を使用しないこと。
Python:
a = 1 # 変数aを初期化
b = 2 # 変数bを初期化
a = b + a
>>> a # 数学的には以上の計算でaの数値が変わることはないが
>>> 3 # プログラミングにおいては左辺に今入っている値を使って上書きする機能が代入である
# 例を増やすと、
a = 1
a = a + a + a # >>> aは1+1+1=3
a = a + a + 1 # >>> aは3+3+1=7
a = 1
a = a # >>> aは1
5.コメントとコメントアウト
しれっと、上記4に記載しているが、Pythonにおいては”#”マークの後に記載されたものは、プログラムとして認識されない機能がある。
このようなのものをコメント文という。コメント文には全角を使用することができる。
ただし、”表”や”能”といった文字は行末にあると、文字コードとして割り当てられている数値が文字コードを変更しなくても別の文字として認識されて文字化けが発生する事がある。
また、通常プログラムとして機能するコードの行頭に”#”マークを意図的に付加してコメント化することができるが、これをコメントアウトという。
コメントアウトすることでコードの実装順序を調整したり、バグの原因となっていそうな箇所をコメントアウトしてバグの発見をしたりすることが可能である。
print(r"Hello World!") # これはコメント
# print(r"Hello World!") # これはコメントアウトされたコード
"""
Pythonではこれもコメントとして扱われる。
数行にまたがる文章を書くのに便利。
"""
'''
シングルクォーテーション3つでもコメントになる。
シングルとダブルとを混在させないが吉。
'''
VScodeではコードにカーソルをあわせた状態で Ctrl + / を押すと、その行がコメントアウトされる。これは複数行選択でも有効である。
コメントアウトさせたコードを復帰させたい場合、該当行で再度 Ctrl + / を押すことでコメントアウトが解除できる。
6.型と表示
プログラミング言語では型という概念が存在する。これは主に変数の性質を示すもので、変数が整数なのか小数なのか、あるいは文字列なのかなどを明示的に示す機能である。
文字列として定義された変数には整数値を代入できないなどの制限がつけられることで、ソースコードの保守性・可読性を高める効果がある。
なお、型が存在しないプログラミング言語も存在する。特にPythonには実装されていなかった。Python 3.5以上のバージョンから型は使用可能である。
Python の過去のバージョンでは型が存在していなかったため、2021.12時点で最新のPython 3.10でも型を使用せずにコーディング可能である。ただし、この時点で異なる型に異なる型のデータを入力してもエラーとならずに、上書きされるっぽい。
a = 1 # 型を宣言せずに変数に数値を初期化できる。
b = "パイソン"
# 変数名: 型 = (値)
name_a: str = "unknown" # str型は文字列(string)を示す。
value1: int = 0 # int型は整数(integer)を示す。
このように定義された変数をターミナル上で表示するためにはprint()が使用できる。※print関数と呼ばずにprint()のように表記する場合がしばしばある。
# コード # 実行結果
print(a) # 1
print(b) # パイソン
print(name_a) # unknown
print(value1) # 0
また、変数の型が知りたい場合、type()を使用できる。
# コード # 実行結果
print(type(a)) # int ※ 正確には <class 'int'> のように表示される。
print(type(b)) # str
型を変換することも可能である。
# コード # 実行結果
val_x: float = 3.14
val_y: int = 0
val_y = (int)(val_x)
print(type(val_y)) # int
print(val_y) # 3 ※ 小数点から整数への変換では小数点以下は切り捨てられる。
表示に関して、変数の値を文字列に組み込んで表示させたい場合、f文字列というものが使用できる。
f文字列のfとはformat(フォーマット)である。f stringとか言ったりする。
# コード
cla_y = type(val_y)
print(f"val_y is {val_y} (this type is {cla_y})") # f"{(変数)}"で埋め込み可。
# 実行結果
# val_y is 3 (this type is <class 'int'>)
他に主な型としては 真偽を示すbool型、日付・時間のみを示すdatetime型などがある。
7.ライブラリ
プログラミング言語によって呼び方がもしかしたから異なるかもしれないが、ある一定の機能・関数がまとまったソースコードをライブラリという。Pythonではモジュールと呼ぶ(特にGUIのためのライブラリのことをフレームワークなどと読んだりする)。例えば、行列計算が可能なNumPyや画像解析が可能なOpenCV、グラフ作成が可能なMatplotlibなどがある。ライブラリに存在する関数を使用する場合には、Pythonでは import を使用して読み込む必要がある。例えば、行列を扱いたい場合、次のような関数を使用できる。※このような行列をプログラミングの用語で配列という。
ただし、初回の利用にはパッケージのインストールが必要である。インストールについてはこちら。
# コード
import numpy
array1 = numpy.array([ [11, 12, 13], [21, 22, 23], [31, 32, 33] ], dtype = 'int')
print(array1)
print("1行1列目の要素:")
print(array1[0][0])
# 実行結果
# [[11 12 13]
# [21 22 23]
# [31 32 33]]
# 11
また、numpyのようによく使用する名前は短いほうが良いので、次のように名前を代用することができる。
# コード
import numpy as np
array2 = np.array(["neko","cat"], dtype="U4") # dtypeは型の指定を行う。
array3 = np.array(["neko","cat"], dtype="U2") # dtypeは型の指定を行う。
print(array2) # "Un"のnは要素の最大文字数を示す。
print(array3)
print("1行1列目の要素:")
print(array2[0])
print("1行2列目の要素:")
print(array2[1])
# 実行結果
# ['neko' 'cat']
# ['ne' 'ca']
8.条件文:if文
エクセルなどを使用している人はしばしばある測定値が判定基準より下ならNG,判定基準以上ならOKと表示させる条件文を作ることもあるだろうが、Pythonでは下記のように実現できる。
# コード
val_a: float = 0.38 # 測定値a
val_b: float = 0.44 # 測定値b
judge: float = 0.4 # 判定基準
val_x = val_a
if val_x < judge:
print("NG")
elif val_x >= judge:
print("OK")
else:
pass # なにもしないという処理を行うコード
# 実行結果
# NG
ifに続く条件式には下記のようなものが使用可能である。
なお、変数名として True や and などのみの文字列を定義できない(予約語:言語側があらかじめ用意している変数・定数・文字列・関数名など)。
# コード
val_x = val_b
flag_j: bool = True
if (val_x == judge) and (flag_j == True): # == 等しい, and 2つの条件どちらも成り立つなら
print("NG")
elif (val_x != judge) or (flag_j == False):# != 異なる, or どちらかが成り立つなら
print("OK")
else:
pass # なにもしないという処理を行うコード
# 実行結果
# OK
9.ループ文:while文、for文
同じ処理を繰り返し行うループ文というものが2種類ある。コードから下記のような設計思想が読み取れるし、そのような設計思想だということを示せる。
- while: 基本的に無限に処理を行い、ある条件が成り立つときに終了(break)する。
- for: 指定回数のみ処理を行う。
while文は条件式が成り立っている間実行される。基本的には1やTrueを入れておく。
ループさせるよりはインデントを忘れずに入れるようにする。
VScodeでは改行した段階でインデントが自動入力されるので、これを活用すること。
print("1を入力したら終了します")
flag_w = -1
flag_w = (int)(input(">>> "))
# while (条件式):
while True:
if flag_w == 1:
break # ループを終了させる。
else:
print("ループ中") # ターミナル上で Ctrl + C を入力すると終了する。
for文はカウントが上限値以下の間実行される。
色々な記法があるが、他のプログラミング言語に類似する記法を紹介する。
下記の(変数) in range(k,n+1) はkからnまでの数値をkから順に変数に代入する関数である。
# コード
n: int = 5
for i in range(0, n+1):
print(i)
# 実行結果
# 0
# 1
# 2
# 3
# 4
# 5
※ループのカウント方法には色々な物がある。例えばリストから要素を1つずつ取り出してなくなるまでループさせるなどの特別な方法が存在したりするが、基本的に可読性が低下する恐れがあるので、上記のような形で使用するのが良い。
※for文とwhile文は互いに同じことができるので、どちらを使用しても良い。