レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

コンピュテーショナルシンキングについての学習ルート

最近ずっと僕が取り憑かれているコンピュテーショナルシンキングとは、コンピュータサイエンティストの思考法という解釈がしっくり来ます。

Google for Educationでも重要な指針として認められている考え方です。

 

edu.google.com

 

主なコンセプトは、以下です。(Google for Educationより)

抽象化

主要なアイデアを定義するために関連情報を特定して抽出する

アルゴリズム設計

類似の問題を解決するため、またはタスクを実行するための一連の命令を作成する

自動化

コンピュータや機械に繰り返しの作業をさせる

データ分析

パターンを見つけたり洞察を深めたりしてデータを理解する

データ収集

情報の収集

データ表現

適切なグラフ、図表、言葉、または画像でデータを描き、整理する

分解

データ、プロセス、または問題を小さく管理しやすい部分に分割する

並列化

より大きなタスクからより効率的に共通の目標に到達するための小規模なタスクの同時処理

パターンの一般化

予測された結果をテストするために、モデル、ルール、原則、または観察パターンの理論を作成する

パターン認識

データのパターン、傾向、規則性を見出す

シミュレーション

実世界のプロセスを模倣するモデルをつくる

 

プログラミングというよりも、システム設計の分野で使われている考え方とした方が良いかもしれません。

 

 

 今後は、システム設計の学習方法について考えます。

 

コンピュテーショナルシンキングをSEの世界で考える

コンピュテーショナルシンキングを習得する授業を高校向けにやっていきましょうという話をしていて、コンピュテーショナルシンキングについてシステムエンジニアではない人にどうやって説明するかについて気づきを得たのでメモしていきます。

 

コンピュテーショナルな考え方とは、「システムの設計」的な思考だと言い換えるとわかりやすいと感じました。

 

システムとは、以下のようなものです。

多くの物事や一連の働きを秩序立てた全体的なまとまり。体系。もっと狭くは、組織や制度。

by Goolge 

「体系化」の思考方法と考えるとコンピュテーショナルシンキングも身近になります。

 

システムの設計を教えるときに、入り口のモチーフにしているのは、みんなで使う共有サーバーの「フォルダ構成」を考えることです。

 

学校でいうと、国語、理科、数学などの教科をトップフォルダに並べるのか、

先生の名前で並べるのか、年次で並べるのか、など用途によって使いやすい分類が変わって来ます。

このフォルダ構造の設計には、誰がどのようにどのぐらいの頻度でどのフォルダを利用するのかを分析すると、最適解が見つかりますが、はじめにどのように設計するかは、分析を待たずに論理的に実践する必要があります。

 

詳しい実践の方法はまた別で考えるとしましょう。

 

とにかく、システム化は、ソフトウェアシステムだけではなく、組織・ルールづくり、ひいてはビジネスモデル構築など、応用が大変聞く範囲ですし、高校生でいうと教科横断的な効果があると感じられます。

 

 

 

 

 

 

Javaオブジェクト指向以降の練習問題

研修やってるので覚書

 

課題1 配列

 パッケージ ex_arrayを作成。

 クラス UserSide を作成し、public static void main メソッドで以下を作成

 String配列を作成 String member = new String[3];

 member[0] = "山田花子";

 member[1] = "10";

 member[2] = "90";

「社員番号10番山田花子スコア90点」と表示。

 

課題2 インスタンス

 パッケージex_instanceを作成

 クラス Memberを作成

 フィールド String name;

 フィールド int member_no;

 フィールド int score;

を持たせる。

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

Member型の変数memberを作成して、インスタンスを代入。

member.name = "山田花子";

member.member_no = 10;

member.score = 90;

 

各フィールドからデータを取得して

「社員番号10番山田花子スコア90点」

と表示。

 

 課題3 複数のインスタンス

パッケージex_instance

(課題2のクラスMemberを利用する)

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

Member型の変数member1を作成して、インスタンスを代入。

member1.name = "山田花子";

member1.member_no = 10;

member1.score = 90;

 

Member型の変数member2を作成して、インスタンスを代入。

member2.name = "鈴木一郎";

member2.member_no = 9;

member2.score = 100;

 

Member型の変数member3を作成して、インスタンスを代入。

member3.name = "田中三郎";

member3.member_no = 15;

member3.score = 10;

 

各フィールドからデータを取得して

「社員番号10番山田花子スコア90点」

「社員番号9番鈴木一郎スコア100点」

「社員番号15番田中三郎スコア10点」

と表示。

 

課題4 メソッド

パッケージex_instance

(課題2のクラスMemberを利用する)

 フィールド String name;

 フィールド int member_no;

 フィールド int score;

を持たせる。

 

メソッド showNameAndScore()を作成

「社員番号 + member_no + 番 + name + スコア + score + 点」

と表示するように作成

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

Member型の変数member1を作成して、インスタンスを代入。

member1.name = "山田花子";

member1.member_no = 10;

member1.score = 90;

member1.showNameAndScore()を呼び出し

 

課題5 メソッド パターン1(引数なし・戻り値なし)

パッケージex_method

クラス Light

メソッド lightOn を作成。(引数なし、戻り値なし)

 このメソッドでは「ライトをつけました。」と表示する。

メソッド lightOff を作成。(引数なし、戻り値なし)

 このメソッドでは「ライトを消しました。」と表示する。

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

Light型の変数lightを作成して、インスタンスを代入。

lightOnメソッドを呼び出し

lightOffメソッドを呼び出し

 

課題6 メソッド パターン2(引数あり・戻り値なし)

パッケージex_method

課題5のクラス Lightを利用

 Lightにフィールド boolean 型のisLightOn を持つ

 

 Lightにboolean型の引数 isTurnOn を渡すメソッド、戻り値のないメソッドとして、lightSwitchを作成。

 trueを渡して呼び出すと「ライトをつけました。」と表示。

   フィールド isLightOn をtrueにする。

 falseを渡して呼び出すと「ライトを消しました」と表示する。

   フィールド isLightOn をfalseにする。

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

 Light型の変数lightを作成して、インスタンスを代入。

 lightのlightSwitchメソッドにtrueを渡して呼び出す

 lightのlightSwitchメソッドにfalseを渡して呼び出す

 

課題7 メソッド パターン3(引数なし・戻り値あり)

パッケージex_method 

課題6のクラスを利用

 Lightにメソッド reportLightStatus を作成。引数なし、戻り値Stringとする。

 このメソッドを呼び出すと、

 isLightOnのフィールドがtrueなら「現在のライトの状況はONです」と返し

 isLightOnのフィールドがfalseなら「現在のライトの状況はOFFです」と返す。

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

 Light型の変数lightを作成して、インスタンスを代入

 lightのlightSwitchメソッドにtrueを渡して呼び出す

 lightのreportLightStatusメソッドを呼び出す

 lightのlightSwitchメソッドにfalseを渡して呼び出す

 lightのreportLightStatusメソッドを呼び出す

 

課題8 メソッド パターン4(引数あり・戻り値あり)

パッケージex_method

 課題7のクラス Lightを利用

 Lightにフィールド int型の lightness を作成5で初期化

 Lightにメソッド lightnessUpTo を作成

 引数 int型 upを引き渡す。

 引き渡されたupをlightness変数に+した数字でlightnessを更新

 戻り値 更新後のlightnessの数字

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

 Light型の変数lightを作成して、インスタンスを代入

 lightnessUpToメソッドに、3を渡す。

 戻り値を変数 currentLightness に受け取る

 「明るさをあげました。現在の明るさは + currentLightness + です」と表示

 

課題9 コンストラクタ

パッケージex_constructor

 パッケージ「ex_instance」のクラスMemberをコピーする

 

コンストラクタ

 Member(String n, int no, int s)

 を作成。

 name = n

 member_no = no

 score = s

 を処理

 

クラス UserSide を作成し、public static void main メソッドで以下を作成

Member型の変数memberを作成して、コンストラクタによりインスタンス生成。

Member( "山田花子", 10, 90)

「社員番号10番山田花子スコア90点」

と表示。

 

課題10 総合

パッケージ ex_move

クラス MiniRobot

 フィールド String sprite = "A" <-文字はなんでもいいです。

 メソッド

  display():引数なし/戻り値なし

   System.out.print()メソッドを使ってspriteを表示する

クラス Start

 public static void main メソッドで以下を作成

 MiniRobot型の変数roboを作成して、インスタンスを代入。

 roboのdisplay()メソッドを呼び出す

 

課題11総合

課題10のMiniRobotとStartを利用

MiniRobotに以下を追加

 フィールド int x 初期値10;

 フィールド int y 初期値0;

メソッド

 display()を改造

  spriteを表示している行の前に

  x個分のスペースをSystem.out.print()メソッドを使って表示

  

 

課題12総合

課題11のMiniRobotとStartを利用

MiniRobotに以下を追加

 フィールド int windowHight 初期値100;

 フィールド int windowWidth 初期値100;

メソッド

  display()を改造

  x個分のスペースをSystem.out.print()メソッドを使って表示したコードの前に

  windowHeight ぶんの改行コードを出力するコードを追記

 (改行コードの出力はSystem.out.println()を引数なしで呼び出す)

 

課題13総合

課題12のMiniRobotとStartを利用

MiniRobotに以下を追加

メソッド

 moveRight() :戻り値なし/引数なし

   処理:xを+1して、xを上書きする

 inputMoveString(String input):戻り値なし/ 引数 String型のinput

   処理:

   input が"d"だったら、this.moveRight()を呼び出す

 

クラス Start

インポート文 import java.util.Scanner; を追加

 

mainメソッドの処理を以下にする。

 

import java.util.Scanner;

public class Start {
  public static void main(String args) throws Exception{
    Scanner sc = new Scanner(System.in);
    Man m = new Man();
    while(true){
      m.display();
      m.inputMoveString(sc.next());
    }
  }
}

 

 *コンパイルして実行 d + Enter で移動します

 *ストップ  Ctrl + c

 

課題14総合

課題13のMiniRobotとStartを利用

MiniRobotに以下を追加

メソッド

 moveLeft() :戻り値なし/引数なし

   処理:xを-1して、xを上書きする

 

 inputMoveString(String input):戻り値なし/ 引数 String型のinput を修正

   処理:

   input が"d"だったら、this.moveRight()を呼び出す

   input が"a"だったら、this.moveLeft()を呼び出す

 

課題15総合

課題14のMiniRobotとStartを利用

MiniRobotに以下を追加

メソッド

 moveUp() :戻り値なし/引数なし

   処理:yを+1して、yを上書きする

 moveDown() :戻り値なし/引数なし

   処理:yを-1して、yを上書きする 

 

 display()メソッドを改造

  spriteを表示しているコードの後に、

  y個分の改行コードを出力するコードを追記

 (改行コードの出力はSystem.out.println()を引数なしで呼び出す)

 

 inputMoveString(String input):戻り値なし/ 引数 String型のinput を修正

   処理:

   input が"d"だったら、this.moveRight()を呼び出す

   input が"a"だったら、this.moveLeft()を呼び出す

   input が"w"だったら、this.moveUp()を呼び出す

   input が"s"だったら、this.moveDown()を呼び出す

 

 

 

 

 

 

初心者にプログラミングを教える時の例集

 

do while

 テストと追試

  →40点以下再試験。

  テスト1回目は、全員必ず受けるが、40点以下なら再試験。

  再試験でまだ40点以下なら再再試験。40点を超えるまで繰り返し。

 

多次元配列:

 表や立方体を例えに出すと、4次元で詰むので

 リストの中にリストが入っている例として「新幹線の座席」を使う

 ABCDEの列が20列ならんでいることと、そういった配列が

 1−16号車まで並んでいる。

 そういった車両が、のぞみxxxなどと番号づけされている。

 

インスタンス・オブジェクト

 同一型のデータ集合である配列と比較して、

 各データに名前付き・型付きのデータ項目が持てる。

 おまけに、そのデータを専門に扱う処理が書ける。

 

参照型

 フォルダの実体とショートカット。ショートカットで開いて操作したら、

 サーバーの実体が更新される。

 

抽象クラス・インターフェイス

 人事部や学校の先生から配られる、日報フォーマットやテストの回答用紙。

 抽象メソッド部分が記入欄で、配られた側は記入欄のみを記載する。

 抽象メソッドを実装することが強制され、使う側はルールに乗っ取っていることを

 インターフェイスは、抽象メソッドのみの集まり、ルールセット。劣化しにくい

 抽象クラスは、式やマクロ入りのテンプレート。

 マクロ入りや式入りは経年劣化やバグの可能性あり、取扱注意。

 

メソッド

 なんどもやる仕事を名前をつけて定型化

 例えば、日直の仕事の定型化

 ホワイトボードを消す、終業後消灯する。帰宅後チェックリストによるチェック。

 掃除して()

  ぬいぐるみをタンスにしまう。

  ブロックを箱にしまう。

  拭き掃除をする。

 

メソッド引数なし、戻り値なし。

 →消灯する。(メソッド名のみ)

 

定義側

class DayDuty{

  void lightsOff(){

     // 消灯処理

  }

}

 

 

呼び出し側

 DayDuty dd = new DayDuty();

 dd.lightsOff();

 

 

メソッド引数あり、戻り値なし。

 →テスト配って()

class DayDuty{

  void passOut(Test[] tests ){

     // テスト問題を配る

  }  

}

 

メソッド引数なし、戻り値あり。

 →昨日のチェック結果を報告して()

 →テスト答案回収して()

 

メソッド引数あり、戻り値あり

 →300円で、パン買ってきて()

 →テストを配って、回収して()

 

オーバーロード

 コピーしろと命令、渡すものが紙なのかパソコンなのかで、

 仕事をする側は動きが異なる。紙ならコピー機でコピーする

 パソコンならハードディスクをコピーする。

 

カプセル化

 携帯電話の電波の3本線表示を勝手に操作できたとしても意味がない。

 内部処理を反映した結果だから意味がある。

 →操作させないことも大事。

 

インターフェイス(ルールブック)

 日直の仕事とは(ルールブック)

 人事部は、誰が日直だとしてもルールを教えたはずの前提なので、

 ルール通りに命令する。

 → 朝会仕切れ()など

  

インターフェイスの役割

 コンポーネント(再利用可能な独立部品)のつなぎ目。

  つなぎ目を規格化するもの

 

インターフェイスを複数持つ意味

 パソコンだと、USBやHDMIVGAなど複数のインターフェイスの実装を持つことができるようなもの。

 

 ポリモフィズム

 屋台街でくれと言ってまわる

 

 

 

Computational Thinking

プログラミングを学ぶことの上位目的としてComputational ThinkingCT/計算論的思考)という言葉が使われることがあります。

 

CTとは、問題解決や問題分析の手法だと捉えたほうがよく、プログラミングそのものとは切り離してあらゆるシーンで使うことができる考え方です。

プログラミングを子供達に教えることの意義は、色々と言われますがこのCTをしっかり身につけることが良いと考えています。

 

CTの分類は諸説あるながら、以下のブログで解説されている分類がとてもしっくりくるので引用させていただきます。

Computational Thinkingとは何か - 小さなごちそう

 

1. Decomposition(問題の分解)

 複雑な問題を解決可能なレベルまで分解すること。

 

2. Pattern Recognition(パターンの発見)

 周期性や法則性を見抜くこと。

 

3. Abstraction(抽象化)

 枝葉を切り落として重要な要素だけを抜き出すこと。

 

4. Algorithm Design(手順化)

 ステップバイステップで、問題解決の手順を明らかにすること。

 

 

話は少し変わって、コンピューターはちょうど、4歳の子供とそっくりだなと思います。

4歳の子供は「掃除」をしなさいと言われても、何をするべきかピンと来なかったりします。

「木のおもちゃは木箱に入れて、人形はプラスチックケースに入れて」と具体的に分解すること(Decomposition)をやってあげると、理解してきちんと動けるようになります。

 

 

私と仕事どっちが大事なの問題

「仕事と家族」(または若い人にとっては「仕事と恋人」)という2つの優先順位の違う世界をいかに上手く過ごすかという問題はとても大事だ。

 

しかし難しいことに、この2つの価値基準はまったく異なっている。

 

仕事は、利己的。

仕事は、自分の生きがいとして重要。つまり自己実現や承認やらといった、自己肯定のために重要。世のため人のためと言うのは勝手だけれど、家族や恋人と比較すると、どうしても利己的なのだ。それぐらい家族が人にとって重いとも言える。

 

家族や恋人は、社交的。

家族や恋人は、一番近くの社会であり重要。人間は人と関わるからこそ人間であり、その最重要な要素は家族や恋人。

 

これらのバランスをとるために、最も大事なのはバランスを取ろうとすることだと思う。でも完全な50:50は難しいから、51:49ぐらいの比率をもってみるのが良い。

どっちが51かを決めるのは自分。

 

いずれにしても、このバランスを取ろうとすることは両方を高みに登らせる唯一の手段だと思う。

 

バランスというのは、多分それを見ようとすることから始まると思う。

 

自分たちらしい入社誓約書

入社誓約書って、結構会社のカラーが出ると思います。そこで自分たちらしい誓約書を作ってみようかと思います。

まずは僕だけの意見で作ってみて、社員さんたちと相談して更新しながら実際に使っていこうと思います。

 

【入社誓約書】

  1. 上機嫌で仕事をすることを心がけます。機嫌が悪いところを同僚や部下に見せないようにします。
  2. 育てることを仕事にします。対象はお客さんも仲間も自分もです。
  3. 任されたら責任を持ってやり抜きます。仲間には信頼して任せます。
  4. 責任を追求せず、問題を解決します。
  5. 怒ったり叱ったりしません。一緒に問題を解決します。
  6. 失敗をチェンスと考えます。失敗した人にも必ずもう一度チャンスを与えます。
  7. 自分で判断します。
  8. やばかったら助けを求めます。やばそうなら助けます。
  9. 時間や約束は守ります。
  10. 自分と家族と仲間の健康を何より大事にします。
  11. 依頼を受けて仕事をするのではなく、提案して仕事を作ります。
  12. 常に学びます。仕事とは関係ないことを学びます。
  13. 独立心を持ちます。会社に依存せず起業も視野にいれます。
  14. タバコは吸いません。
  15. 退職してからも仲良くします。

それでは。