# 振り返り1

## 処理順序制御
```{figure} ./figs/control-flow.svg
:name: control-flow
処理順序
```

これまでで基本的なフロー制御である逐次処理、条件分岐、反復処理および関数定義を学び終えた。基本的にはすべてのプログラムはこれらの組み合わせで構築される。

```{tip}
教科書1章で軽く触れられている **{index}`万能チューリングマシン<ばんのうちゅーりんぐましん-万能チューリングマシン>`({index}`Universal Turing Machine`)** があれば、理論的には、【有限回の操作で計算できる処理】は全て記述することができる。万能チューリングマシンとは「無限長のテープ」と、そのテープを移動する命令と、テープへ読み書きする機能を有するマシンを指す。（参考: [チューリング・マシンとコンピュータ工学](https://www.slideshare.net/junpeitsuji/ss-57954980)）

これに対してプログラミング言語として用意されている逐次処理・条件分岐・ループ処理・関数定義、またstr型やlist型といった型は、これらがあると便利という意味で追加されている機能に過ぎない。例えばstr型なしに文字列を扱うプログラミング言語もある。

興味がある人はチューリングマシンについて調べてみよう。
```

```{note}
万能チューリングマシンの具体例が皆が使っている「コンピュータ」だ。問題を理解し、手順として整理したものを翻訳するという行為が【有限回の操作で計算できる処理】に変換していることに相当する。
```

---
## プログラミングへの取り組み方
```{figure} ./figs/programming-approarch.svg
:name: programming-approarch
プログラミングへの取り組み方
```

目標の達成方法、すなわち問題解決方法が思いつかない場合にはその **問題を分割** できないか考えてみよう。例えばプログラミングにおいては何をどのように実装すべきかがわからない場合、(1)どの部分は分かるのか、(2)どの部分が分からないのか、という視点で区別してみよう。その際に分からない部分が文法的なものであれば教科書等を遡って調べると解決できるはずだ。

文法ではなく **実装方法が不明瞭だという場合、紙に書き出す等して自分が分かりやすい方法で理解・整理** してみよう。いきなり翻訳するのでなく、理解・整理をする手順が抜けているはずだ。ここでいう整理とは料理における調理手順のように、1ステップずつ処理すべき内容を書き下すことを意味する。この手間を惜しんでいきなり翻訳しようとしても、より難しい問題に直面した際に翻訳へのプロセスを思いつかず、問題解決にたどり着けない。

手順として整理できたならばそれをコードに翻訳していくことになる。これも最初は100%の精度を考える必要はなく、**とりあえず動作するものを目指そう**。想定外が見つかるならばその都度[デバッグ](./debug)等を通して修正したら良いし、処理不足があるならば今取り組んでる小さな部品が完成した後で考えれば良い。各手順を動作できるコードに翻訳できたならば、それら全体として当初書き上げたかったプログラムになるはずだ。このように「理解・整理・翻訳」という考え方を練習していこう。この考え方はプログラミングを例に述べたものだが、より一般化すると「問題分割」や「構造化」という考え方になり、工学全般に共通したアプローチである。分割の練習は、紙など書き広げやすいものを使うとやりやすいだろう。

---
### 小さく作り、動作確認。
[デバッグ](./debug)を中心として、今書いているコードがどのように実行されるかを確認することはとても大切だ。「こう動くだろう」と想像するだけで、**最後にまとめて動作確認するというアプローチは絶対に避けよう**。取り組み方と一部重複するが、実装した部品がその時点で想定通りに動くことをまず確認しよう。想定通りに動かない場合、それを前提にしたコードは全て動作しないことになる。このような自体を避けるためにも、小さく作り、その都度動作確認しよう。

---
### 検討中は小さい例題で考えよう
コード側を小さくするだけではなく、小さな例題で考えてみるのも良いアプローチだ。例えば100個の数値を足し算するプログラムの前に、5個の数値で試してはどうだろう。5個なら手計算も簡単だし、サンプルデータを用意することも簡単だ。ループ処理を使わなくても実装できるし、一度ループ処理を使わずに書いたコードを元にそこからどのようにループ処理に発展させるかを検討することもできる。また、実現したいことの例題を考えることができないのであれば理解不足が生じていることもここで発見できる。このように例題を考えるのは様々なメリットがある。「**例示は理解の試金石**」だ。

小さな問題は取り扱いが容易なため、開発時点ではとっかかりやすくなる。このように問題をシンプルにすることを [toy problem（おもちゃのような問題）](https://eow.alc.co.jp/search?q=toy+problem) と呼ぶ。おもちゃらしく遊びつくそう。

```{tip}
「例示は理解の試金石」は[数学ガール](https://rentwi.hyuki.net/?985985934452649984s)作中で頻繁に出てくるアプローチです。
```

---
### コンピュータとの対話を大切に！
詰まっている状況の一つにエラー文を無視しているケースが非常に多い。ターミナルやインタプリタにて、何かこちらから命令を書いて実行した際にエラーが出た場合、それはコンピュータからの「応答」の一つである。一つずつ応答の意味を読み取れるうようにしよう。専門的な言い回しのため最初はわからないことだらけだが、「Not Found」とかは文字通りの意味だ。

- 「何故見つけられないのか？何を見つけられていないのか？」など、コンピュータの立場になって考えてみよう。
- それでも分からない場合には[デバッグ](./debug)したり、TA・先輩・担当教員らに相談してみよう。自分から行動するのが重要だ。

---
## 復習・予習
- 復習
  - 適宜過去資料及び教科書を参照しよう。
- 予習
  - 5.1 Tuples
  - 5.3 Lists and Mutability
  - 5.5 Strings, Tuples, Ranges and Lists
