infomisc -ITエンジニア雑記-

某ITエンジニアの雑記および備忘録です。プログラミング教育についても触れていければと思っています。

プログラミング的思考#3

f:id:rmatsush:20200112005344j:plain

www.infomisc.net の続きです。

「レゴで家を作りたい」⇒「家を作るには組み立ての説明書が必要」⇒???

についてもう少し考えてみました。

「レゴで家を作る」ための説明書を作るにはどういった考え方が必要になるでしょうか。

自分の場合は、まずは以下のように課題を分解します。 この分解の仕方も正解はありませんので、あくまで私個人の方法です。

まずは課題の分解と前提条件の整理

レゴで家を作るために、それぞれの特性を理解していないといけません。 レゴで遊ぶときは意識していないと思いますが、無意識の意識化をしてあげる必要があります。

レゴの特性の理解すること

  • 1ブロックは1メートルx1メートルの立方体と想定する
  • ブロックをブロックの上に積み上げられる
  • ブロックを配置するには他のブロックと接している必要がある

家の構造を理解すること

  • 出入口(玄関)がある
  • 窓がある
  • 床がある
  • 壁がある
  • 天井がある
  • 屋根がある
  • 床は家の一番下にある
  • 床の上に出入口、窓、壁がある
  • 壁の上に天井がある
  • 天井の上に屋根がある

細かくしたらキリがないのでこのくらいにしましょうか。

最初の段階として、家の一番下となる床をブロックでどう作るかに着目できたら、 レゴの特性も家の特性も分かっていることになりますよね。 小さい子には、まずは身近にあるもモノやコトを分解させてみるのもいいのかなと思います。

組み立ての流れ

レゴの特性上、基本的には下からブロックを積み上げていきますので、家を作成するためには、

  • 床をつくる
  • 窓、出入口、壁をつくる
  • 天井をつくる
  • 屋根をつくる

という順番でブロックを組み立てる必要があります。 実際のブロックを使わなくても説明書を作ることはできると思うのですが、 経験がないと小さい子には想像もできない思いますので、 実際に手を動かして試行錯誤してもらう方が理解は断然早そうです。

組み立て

まず、床をつくる工程では、どんなブロックを使ってどのくらいの大きさにするかを決めます。 単純な四角形とするのか、より複雑なかたちにするのかを考えます。

さらにその上に窓、出入口、壁をつくります。 ここでも窓や玄関の大きさなどを想定する必要があります。 レゴを使う場合は、何個のブロックで表現するかを考えます。 この工程は必要な高さになるまで繰り返し行います。 高さが1ブロック(1メートル)では、人が生活できない家になりますので、 高さも考える必要があります。

さらに天井とその上に屋根をつくります。 屋根もフラットにするのか、三角屋根にするのかなどを考えます。

この手順をまとめたものが組み立ての説明書になります。が、、これだけでも相当大変ですよね。。 最初から説明書はできませんので、まずは試行錯誤を繰り返して、ブロックの積み方やアンチパターン(例えば、出入口や窓がない家など)を学んで行く必要があります。 これこそがプログラミング的思考を経験できる場になるのかなと思います。

というわけでウチは引き続きレゴで一緒に遊びたいと思います^^=

正規表現を使った文字列検索

f:id:rmatsush:20200120013705p:plain

正規表現

正規表現」という用語があります。 Wikipediaでは、

正規表現(せいきひょうげん、英: regular expression)とは、文字列の集合を一つの文字列で表現する方法の一つである。正則表現(せいそくひょうげん)とも呼ばれ、形式言語理論の分野では比較的こちらの訳語の方が使われる。まれに正規式と呼ばれることもある。

と定義されています。

が、、これだとちょっと分かりづらいのでもう少し簡単な例を。

例えば「aaa」という文字列は、「a」が3回繰り返されているので「a{3}」と表現します。という約束事を決めているとご理解ください。この約束事の集まりを正規表現と呼んでいます。 他にも「a」または「aa」または「aaa」という文字列は、「a+」(+は1回以上現れるという意味)と表現できますので、「aがたくさん並んでいる」という内容を明確に定義することができます。

正規表現を使った文字列検索

正規表現の特性を文字列検索に応用すると、欲しい文字列のみを取り出すことができます。 どのような時に使えるかというと、例えば特定の文章から日付だけを抜き取りたい場合などに便利です。 決まった文字列の検索でしたら、正規表現を使う必要はありませんが、形式は決まっている(例えば4桁の西暦の後に月と日付けが現れるという決まりがある場合など)ものの、その内容が都度変わる場合に威力を発揮します。

「abcdefg 2020/1/24 abcdefg 2020/1/1 abcdefg」という文字列のなかから、日付のみを取り出すには以下のように書きます。

>>> import re
>>> str = 'abcdefg 2020/1/24 abcdefg 2020/1/1 abcdefg'
>>> re.findall(r'(\d{4}/\d{1,2}/\d{1,2})', str)
['2020/1/24', '2020/1/1']

検索対象の文字列(str)のなかから、正規表現の条件に合致する文字列のみを抽出します。re.findall関数でマッチしたすべての文字列をリストで返しています。

\d{4}/\d{1,2}/\d{1,2}

この表現は、

  • 「\d」(0~9までの任意の数字)が4回現れ({4}で表現されます)、
  • その後に「/」が現れ、
  • 「\d」(0~9までの任意の数字)が1回か2回現れ({1,2}で表現されます)、
  • その後に「/」が現れ、
  • 「\d」(0~9までの任意の数字)が1回か2回現れる({1,2}で表現されます)

という文字列がマッチするかを探します。 ですので、例にある「2020/1/24」や「2020/1/1」はマッチします。ですが、「999/1/1」という文字列はマッチしません(999は4つの数字ではないため)。

厳密に日付を検索する場合は、形式などを改めて精査す必要がありますが、現実にはなかなか999年といった日付を目にすることもありませんので、困ることはありません。

少し応用

re.search関数(最初の1回のみマッチ)とgroup関数を使った例です。取り出した日付文字列をdatetimeオブジェクトに変換して、、などで使うことが多いです。とりあえずメモとして。

>>> import re
>>> str = 'abcdefg2020/1/24abcdefg2020/1/1abcdefg'
>>> m = re.search(r'(?P<dstr>(\d{4}/\d{1,2}/\d{1,2}))', str)
>>> print m.group(dstr)
2020/1/24

自分が使っているWindowsアプリ

f:id:rmatsush:20200124175655p:plain 2020年になりましたし、誕生日も迎えたこともあり、心機一転ということで、久しぶりに自分のPCを初期化しました。

何か重要なファイルをバックアップしきれていない不安も若干ありますが、今は問題ないので大丈夫でしょう。 気づいたときに考えることにします^^; 起動時間を含めて、かなり快適になりました。

備忘もかねて自分がインストールしているソフトウェア一覧を纏めておきます。


Ctrl2Cap v2.0 docs.microsoft.com

Caps LockキーとCtrlキーを入れ替えるソフトです。Microsoft純正。 Emacs派なのでCtrlキーの位置が重要なのです。


GNU Emacs www.gnu.org

Unix系で有名なエディタ。学生の頃からお世話になっています。有志の方が日本語化してくれているので、Windowsでも問題なく日本語を利用可能です。

Emacsは、いかに「.emacs」を充実させられるかで効率がかなり変わります。個人的には howm がおススメ。


7-Zip sevenzip.osdn.jp

圧縮/解凍ソフト。幅広いファイル形式に対応。 右クリックから「7-Zip」->「ここに展開」がかなり便利です。


Firefox www.mozilla.org

有名なブラウザ。アドオンが豊富。


Clibor www.vector.co.jp

クリップボード管理。 Ctrlキー2回押しで簡単にクリップボードの履歴を呼び出せます。Emacsとの相性も悪くない。


サクラエディタ sakura-editor.github.io

2つ目のエディタ。 こちらはメモ帳感覚でガンガンウィンドウを開いてログなどを見ていく場合に使います。Emacsは文章を書いたりとかをメインにして使い分けています。


Tera Term ttssh2.osdn.jp

有名なSSH接続クライアント。


WinSCP winscp.net

SCPクライアント。 エクスプローラライクな見た目でファイルのやり取りができます。


VirtualBox www.virtualbox.org

仮想エミュレータソフト。 VMwareもありますが、こちらの方が使いこなれているので。


とりあえずこんなところでしょうか。 他にあれば追記します。

プログラミングが必修化された背景について

f:id:rmatsush:20200125172148p:plain

www.infomisc.net と関連してます。

IT力が必須??

「小学校プログラミング教育必修化に向けて」パンフレット(未来の学びコンソーシアム作成)

「未来の学びコンソーシアム」にてプログラミングが必修化された背景が書かれているのですが、個人的にちょっと違和感があったので書いておきます。

我が国の競争力を左右するのは何か。それは「IT力」です。ヨーロッパでは、「IT力」が、若者が労働市場に入るために必要不可欠な要素であると認識されています。現に、90%の職業が、少なくとも基礎的なITスキルを必要としているといわれており、多くの国や地域が学校教育のカリキュラムの一環としてプログラミングを導入しています。

もし上記のように「IT力」が必須なら、プログラミング教育は算数や理科に含めるのでなく、新しい科目とした方がシンプルかなと思っています。

プログラミング教育を算数や理科に応用するという点では賛成ですが、プログラミング的思考がどこまで理解できたかをどうやって評価するのかはかなり難しいことと思っています。 だから新しい科目にできていないのかもしれませんが。。

本来の「プログラミング的思考」を育むという目標と、上記の背景がなんとなくずれているように感じたので残しておきます。

個人的には。。

IT技術」は手段の一つです。ですので、ITが必要になるなら、外部に依頼することも一つの解決策になります。「IT力」の不足が、国の競争力を左右するとはちょっと思えないんですよね。

もちろん、論理的思考力は必要なのでそれを鍛える必要があるというのは同意見です。

プログラミング教育の教科書はこんな感じに

f:id:rmatsush:20200124180447j:plain

miraino-manabi.jp

未来の学びコンソーシアム事務局」が運営するポータルサイトに教科書に関する内容が載っていました。

教科書発行者サイトのプログラミング教育関連ページのご紹介 | 小学校を中心としたプログラミング教育ポータル

対象科目は算数と理科となっています。
手を動かしてもらうためのプログラミング体験演習もあります。
そのなかの算数の一例はこんな感じ。

学校図書株式会社 f:id:rmatsush:20200121121942p:plain

新興出版社啓林館 f:id:rmatsush:20200121122031p:plain

大日本図書株式会社 f:id:rmatsush:20200121122039p:plain

東京書籍株式会社 f:id:rmatsush:20200121122051p:plain

出版社毎に色が出ていて面白いですね。
教材を選ぶ学校の先生たちはどうやって選ぶんでしょうかね^^;;


5歳からの「レゴ WeDo2.0 for home by アフレル」

python 2系 サポート終了

f:id:rmatsush:20200120013705p:plain

www.python.org

python 2系のサポートが2020/1/1をもって終了しました。 ということは、セキュリティ脆弱性のようなコードの不具合があっても、今後は修正されないということです。 というわけで、早々にpython 3系への移行が必要です。

いくつか方言や使い方が変わるので勉強し直さないと。。

関連記事

ファイル読み込み

f:id:rmatsush:20200120013705p:plain

Pythonに関するTipsを忘れないように書いておきます。 自分の場合、仕事上大量のテキストファイルを扱うことが多いので、ファイル読み込みとか、文字列操作に関するTipsが多くなりそうです。

ファイル読み込み#1

with open('/tmp/test.txt') as f:
     for line in f:
         print line

/tmp/test.txtを読み込んで、1行ずつ出力するプログラムです。 この方法は、ファイルを読み込んだ際にすべてのファイルの中身をメモリに乗せることはないらしいです。 物理メモリサイズに比べてファイルサイズが大きい場合は、この方法が有効になります。

ファイル読み込み#2

f = open('/tmp/test.txt')
for line in f.readlines():
     print line
f.close()

動作としては同じですが、一度ファイルの内容をメモリに展開します。 f.readlines()がすべての行を取得するので、その分の空きメモリが必要になります。

自分はファイル読み込み#2の方法を使っていたと思います。 処理速度といった点では、すべての内容をメモリに展開する#2の方が高速かもしれませんが、効率化といった意味では#1の方が優れてそうです。