よしたく blog

ほぼ週刊で記事を書いています

【再読】プログラマのためのDocker教科書を読んだ

業務ではdockerを使ってないけれど、業界で流行っていることは抑えていたほうがいいと思ったので読みました。簡単に環境構築もできるし、プライベートでの開発や技術技術調査で積極的に使っていきたいなー。

本としては、Dockerのことだけを語っているわけではなく、システム・インフラの基礎知識や仮想化についても章を設けられているので、自分みたいな初心者でも知識を習得・再整理しながら読むことができる。一定の知識がある人ならば、すっ飛ばしてDockerについてだけ読むことももちろんできる。

基本的なコマンドの説明からDockerイメージを作成できるDockefile、複数コンテナの一元管理できるDocker Composeも章として設けてある。 この本を一通り読めば、Dockerについて理解できるし、わからなくなったときの辞書としても使えそう。

以下は自分が読んでメモした部分

Dockerの基本操作

DockerでHello world

まずはDockerでHello worldをやってみる

docker run ubuntu:latest /bin/echo 'Hello world'

このコマンドは、ubuntuのDockerイメージを起動し、Docker内部でHello worldを表示している。 runコマンドは意味的にも実行するだけかと思いきや、ローカル環境にDockerコンテナのもとになるubuntuの Dockerイメージがあるか確認してくれて、なければダウンロードまでしてくれる便利なコマンド

ubuntu:latestは最新バージョンを取ってきて、という命令です。 あとはechoコマンドでHello worldを表示しろというそのままの意味です。

runコマンドにはオプションがあり、よく使うものをまとめておく。 -it コンテナの中にログインして操作ができる iはコンテナの標準入力を開く、tはtty(端末デバイス)を使うとなる。

yoshitakuMBA:~ yoshitaku$ docker run -it centos /bin/bash
[root@274130fac9fa /]# 

仮にオプションを外してbashしてみても、コンテナの中には入れない。

yoshitakuMBA:~ yoshitaku$ docker run centos /bin/bash
yoshitakuMBA:~ yoshitaku$ 

-d コンテナをバックグラウンドで実行できる -p コンテナのポート番号とホストOSのポート番号をマッピングすることができる

docker run -d --name nginx -p 8080:80 nginx

この場合、バックグラウンドでnginxを起動し、ポート番号8080と80をマッピングしている

コンテナの起動・停止

dockerコンテナを作成・起動・停止するためのコマンドを書いておく

docker start <コンテナの識別子>
docker stop <コンテナの識別子>

コンテナの識別子を確認するためのコマンドは docker ps -adocker statsがある。 docker ps -a-aオプションを付けることで、起動停止問わずすべてのコンテナを表示できる docker statsは起動中のコンテナだけを表示することができる

起動しているDockerコンテナの操作

docker attachdocker execがある

Docker内部にログインするという意味では、どちらも同じ だけどコマンドが別れているのにはちゃんと意味がある。

https://qiita.com/RyoMa_0923/items/9b5d2c4a97205692a560

docker attachは、プロセス1に接続させてもらうのに対して、 docker execは、新しくプロセスを作成して、それを利用してコンテナ内部に入るイメージ

docker ps -a #コンテナIDを調べる。起動していなければ、IDを覚えておく
docker start <コンテナ識別子> #コンテナを起動
docker attach <コンテナ識別子>
docker ps -a #コンテナIDを調べる。起動していなければ、IDを覚えておく
docker start <コンテナ識別子> #コンテナを起動
docker exec -it centos /bin/bash

Dockerfileの基本

DockerfileはDockerイメージを作るときに使われる。

Dockerfileからイメージを作成するときはdocker buildコマンドを使う。

docker build -t [イメージ名]:[タグ名] [dockerfileが置いてあるディレクトリ]

dockerファイルのビルドの注意

dockerfileを引数に指定していたら、unable to prepare contextが発生。 unable to prepare contextはファイル名まで書いてしまっているエラー。 dockerfileをビルドする際は、置いてあるディレクトリまでで大丈夫。

基本構成

命令 引数の基本構文で成り立っている。

FROM命令

FROM命令は必ず記述しなければいけない必須項目 ベースとなるOSのことを書くところ。 FROM ubuntu:latest

MAINTAINER命令

必須ではないけど、誰が作ったかとか連絡先を書いておく。 Docker Hubのように公開する場合は、書いておいたほうがいい MAINTAINER yoshitaku

FROM ubuntu:latest

MAINTAINER yoshitaku

RUN命令

FROM命令で指定したベースイメージに対して、「アプリケーション・ミドルウェアのインストールをする」「環境構築のためのコマンドを実行する」と言った、コマンドを実行するときにRUN命令を使う。

RUN命令はDockerイメージを生成するときに実行される。 RUN apt-get update RUN apt-get install -y apache2 RUN apt-get install -y mysql-server

Docker Composeについて

Docker Composeは複数のコンテナを一元管理したいときに使われる。 実際のwebシステムでは一つのサーバが一つの機能を持って使われることが多く、Dockerを使ってwebシステム環境を再現したいときなどに使うと便利。

ド定番のwordpressをDockerComposeでやってみる webサーバとDBサーバと、データを格納する専用コンテナを作成する。 データを格納する専用コンテナは、標準的なLinuxコマンドをまとめたBusyBoxと呼ばれるアプリケーションがあるのでコレを使って構築する。

FROM busybox

VOLUME /var/lib/mysql

イメージの作成 docker build -t dataonly .

データ専用コンテナの起動 docker run -it --name dataonly dataonly

Docker Composeは「docker-compose.yml」にシステム内で稼働するサーバの設定をまとめて定義する。 docker-compose.ymlの書き方はyamlの形式で書く。 portsのxx:xxの形式は文字列にしないと、時刻表期とみなされてしまうらしいので注意 ちゃんとダブルクォートで囲む

webserver:
    image: wordpress
        ports:
            - "80:80"
        links:
            - "dbserver:mysql"
dbserver:
    image: mysql
        volumes_from:
            - dataonly
    environment:
            MYSQL_ROOT_PASSWORD: password

docker-compose upで下のログが出れば成功

Starting test_dbserver_1 ... done
Starting test_webserver_1 ... done
Attaching to test_dbserver_1, test_webserver_1
dbserver_1   | 2018-03-23T16:18:37.321903Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
dbserver_1   | 2018-03-23T16:18:37.324429Z 0 [Note] mysqld (mysqld 5.7.21) starting as process 1 ...
dbserver_1   | 2018-03-23T16:18:37.330983Z 0 [Note] InnoDB: PUNCH HOLE support available
dbserver_1   | 2018-03-23T16:18:37.331048Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
dbserver_1   | 2018-03-23T16:18:37.331055Z 0 [Note] InnoDB: Uses event mutexes
dbserver_1   | 2018-03-23T16:18:37.331060Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
dbserver_1   | 2018-03-23T16:18:37.331065Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
dbserver_1   | 2018-03-23T16:18:37.331069Z 0 [Note] InnoDB: Using Linux native AIO
dbserver_1   | 2018-03-23T16:18:37.332053Z 0 [Note] InnoDB: Number of pools: 1
dbserver_1   | 2018-03-23T16:18:37.332300Z 0 [Note] InnoDB: Using CPU crc32 instructions
dbserver_1   | 2018-03-23T16:18:37.335841Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
dbserver_1   | 2018-03-23T16:18:37.355688Z 0 [Note] InnoDB: Completed initialization of buffer pool
dbserver_1   | 2018-03-23T16:18:37.359681Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
dbserver_1   | 2018-03-23T16:18:37.375230Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
dbserver_1   | 2018-03-23T16:18:37.410157Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
dbserver_1   | 2018-03-23T16:18:37.410289Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
dbserver_1   | 2018-03-23T16:18:37.516884Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
dbserver_1   | 2018-03-23T16:18:37.517994Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
dbserver_1   | 2018-03-23T16:18:37.518044Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
dbserver_1   | 2018-03-23T16:18:37.518586Z 0 [Note] InnoDB: Waiting for purge to start
dbserver_1   | 2018-03-23T16:18:37.568983Z 0 [Note] InnoDB: 5.7.21 started; log sequence number 12318893
dbserver_1   | 2018-03-23T16:18:37.569887Z 0 [Note] Plugin 'FEDERATED' is disabled.
dbserver_1   | 2018-03-23T16:18:37.578776Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
dbserver_1   | 2018-03-23T16:18:37.580825Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
dbserver_1   | 2018-03-23T16:18:37.593695Z 0 [Warning] CA certificate ca.pem is self signed.
dbserver_1   | 2018-03-23T16:18:37.596636Z 0 [Note] InnoDB: Buffer pool(s) load completed at 180323 16:18:37
dbserver_1   | 2018-03-23T16:18:37.597075Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
dbserver_1   | 2018-03-23T16:18:37.597149Z 0 [Note] IPv6 is available.
dbserver_1   | 2018-03-23T16:18:37.597182Z 0 [Note]   - '::' resolves to '::';
dbserver_1   | 2018-03-23T16:18:37.597221Z 0 [Note] Server socket created on IP: '::'.
dbserver_1   | 2018-03-23T16:18:37.611096Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.611244Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.611261Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.612975Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.613019Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.613050Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.658200Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.658279Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.740459Z 0 [Note] Event Scheduler: Loaded 0 events
dbserver_1   | 2018-03-23T16:18:37.741266Z 0 [Note] mysqld: ready for connections.
dbserver_1   | Version: '5.7.21'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
webserver_1  | [Fri Mar 23 16:18:38.341326 2018] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.2.3 configured -- resuming normal operations
webserver_1  | [Fri Mar 23 16:18:38.342818 2018] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

localhostにブラウザでアクセスすれば、いつもの画面が出てくる

まとめ

  • Dockerについて一通りのことが学べた
  • Dockerfileの書き方がわかった。
  • docker-composeを使ってwordpressを構築できた

これからは、社内で使うハンズオン資料をdockerで作ってみたいと思います。

画像処理ライブラリOpenCVを使って、画像からレシートを切り出してみた

Pythonの画像処理ライブラリであるOpenCVを使って、レシートをトリミングしてみました。 今回はその時のメモです。 手順通りにやればほぼほぼうまくいくと思います。

環境

準備

# 仮想環境を作成
python3 -m venv opencv-demo

#仮想環境の立ち上げ
cd opencv-demo
source bin/activate

# opencv-pythonのインストール
# 41.2MBほどあるので注意
pip install opencv-python

# Python3の起動
python3

opencv-demo配下にトリミングしたいreceipt.jpgを配置します。 今回はネットで拾ったこの画像がやりやすかったので、使わせていただきます。

下のソースコードを実行します。

import os
import numpy as np
import cv2

filename = "receipt"
imp_filename = "receipt.jpg"

def transform_by4(img, points):
    points = sorted(points, key=lambda x:x[1])
    top = sorted(points[:2], key=lambda x:x[0])
    bottom = sorted(points[2:], key=lambda x:x[0], reverse=True)
    points = np.array(top + bottom, dtype='float32')
    width = max(np.sqrt(((points[0][0]-points[2][0])**2)*2), np.sqrt(((points[1][0]-points[3][0])**2)*2))
    height = max(np.sqrt(((points[0][1]-points[2][1])**2)*2), np.sqrt(((points[1][1]-points[3][1])**2)*2))
    dst = np.array([
        np.array([0, 0]),
        np.array([width-1, 0]),
        np.array([width-1, height-1]),
        np.array([0, height-1]),
    ], np.float32)
    trans = cv2.getPerspectiveTransform(points, dst)
    return cv2.warpPerspective(img, trans, (int(width), int(height)))

im = cv2.imread(imp_filename)

im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite(filename+'_gray.jpg', im_gray)

im_blur = cv2.fastNlMeansDenoising(im_gray)
im_th = cv2.adaptiveThreshold(im_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 5)
cv2.imwrite(filename+'_th.jpg', im_th)

cnts = cv2.findContours(im_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
cnts.sort(key=cv2.contourArea, reverse=True)

im_line = im.copy()
warp = None

for c in cnts[1:]:
    arclen = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02*arclen, True)
    if len(approx) == 4:
        cv2.drawContours(im_line, [approx], -1, (0, 0, 255), 2)
        if warp is None:
            warp = approx.copy()
    else:
        cv2.drawContours(im_line, [approx], -1, (0, 255, 0), 2)
    for pos in approx:
        cv2.circle(im_line, tuple(pos[0]), 4, (255, 0, 0))

im_rect = transform_by4(im, warp[:,0,:])
cv2.imwrite(filename+'_rect.jpg', im_rect)

receipt_rect.jpgができあがって、 無事にレシートだけがトリミングできました!

今回は、OpenCVを使って、レシートをトリミングすることをやってみました 次回は、トリミングされた画像から、OCRをして文字を取得してみようと思います。

追記】 次回の記事です!!!

yoshitaku-jp.hatenablog.com

OSS Gateワークショップに参加して、RedashにPullRequestを出しました

はじめに

今回は2018/03/10にOSS Gateさんが主催している OSS Gateワークショップに参加してきたので参加レポです。

OSSに貢献していきたいなと思いつつなかなか手が出せなかったので、 今回のワークショップを通じて貢献していきたいと思い申し込みました!

OSS Gateとは

  • OSS Gateとは
    • OSS開発に参加していない人が参加する人に変わる「入り口」を提供する取り組み
    • 今回のワークショップはOSS開発参加者を増やす方法の1つとしておこなっている
  • 開催タイミング
    • 1月と4月と7月と10月は最終土曜日に10:30から17:00で開催している
    • 3月と6月と9月と12月は第2土曜日に13:00から19:00で開催している。ワークショップ後に希望者のみ参加の懇親会がある。
  • 想定の参加者
    • ビギナー
      • OSSの開発に参加したいけどまだ参加したことがない人
      • OSSの開発に参加したことはあるけどまだ自信がない人
    • サポーター
      • OSSの開発に参加している人
  • 詳しくはこちら
  • Doorkeeperで参加者を募集している

やること

  • OSSを動かす
    1. 対象のOSSを決める
    2. 作業メモを書く場所を用意
    3. 作業メモを書きながら、公式サイト・READMEを見て動かす
  • 気がついたことをフィードバックする

ビギナーとサポーターの1対1でワークショップはおこなっていきます。 今回担当してくださるサポーターの方はゴさん!

前半の部

対象のOSSを決める

今日はredashを扱ってみることにした。理由は、

  • Pythonで書かれていること
  • BIツールであること
  • 周りで使っている人が多くいること

という観点で選びました。

作業メモを作る

  • URLをメモする
  • 期待する効果をメモする
  • これがあったら良いなとおもったことをメモする
  • 躓いたところをメモする

今回の作業メモはここにあります

業務中にも作業を一つ一つメモすることはやりたいと思いつつ、 なかなか実践できないことである。やはり忘れてしまう… 今回はゆっくり進めて、サポーターの方々の「こういうふうなところをめもしたほうがいいよ」や「ここは躓かなかった?」といった突っ込みもありつつ、丁寧にメモをとることが出来たように思う。

作業メモを書きながら、公式サイト・READMEを見て動かす

今回はOSSの活動に慣れてもらうということで、 作業メモを書きながら、公式サイト・READMEを見ながら、インストールからはじめました。

黙々と作業している中で、躓いたことがありました。 今回はdockerを使ってredash環境を作ろうと思ったのですが、 このページの説明にはredashをローカル環境に落としてくることが明記されていませんでした。

2つ前のページには 「Make sure your current working directory is the root of this GitHub repository.」 と書いてあるのですが、手順としてgit cloneすることはどこにも書いていませんので、ここはコントリビュート出来るポイントかなと思いました。 作業メモに書いておきます。

無事にgit cloneしてdocker-compose upをおこない、redashにアクセスしたところでエラーが発生。 しかし、ここで前半の部が終了しました。

前半の振り返り・フィードバック

振り返りで - docker-compose upをするためのgit cloneが必要なことが明記されていないことがコントリビュート出来るポイント - New developer guideがあるので、そこに賛同するコメントをすることも良いこと

後半の部

気がついたことをフィードバックする

後半は気がついたことを実際に開発者たちへフィードバックすることでした フィードバックする上で大切なことは - 自分の伝えたいことを整理する - 開発者にとってわかりやすくなるように編集する - 適切な場所に報告する

自分の伝えたいことを整理する

docker-compose upをするためのgit cloneが必要なことが明記されていないことが 他の初心者も困ってしまうのかもしれないので、記述してほしい旨を伝えることにする。

開発者にとってわかりやすくなるように編集する

まずは日本語で

redashをクローンする

まずはredashをGitHubからクローンする
git clone git@github.com:getredash/redash.git
cd redash/

英語にしてみた

Git Clone Redash

At the beginning clone Redash from GitHub
git clone git@github.com:getredash/redash.git
cd redash/

サポーターの方がシャンハイ出身の方で、バリバリの英語の添削が入りました笑 - 一番上のところはコマンドを書くわけではないので、一旦やめてみる - 他の項目が動詞から始まっているので、動詞で初めてみる - Prepare The Source code とか - 説明文も、コマンドを繰り返す必要がなく、何をするのかを簡潔に説明する - Firstly, you need to setup the source code directory from the official repositoryとか

Prepare The Source code

Firstly, you need to setup the source code directory from the official repository.
git clone git@github.com:getredash/redash.git
cd redash/

適切な場所に報告する

今回どこに報告するべきか迷ったのですが、 サポーターのゴさんが、 redashのホームページがgithubで管理されていると教えてくれて、 こちらにプルリクエストを出すことにしました。

redashに対してpull requestをしてみた

https://github.com/getredash/website/pull/65

後半の振り返り・フィードバック

  • git プロトコルをあまり使うべきではない
    • httpsのほうがいい
  • なぜ必要になったのかの説明を書いたほうがいい
    • 人によっては聞かれる
  • コミットメッセージをもっと伝わりやすく

まとめ

  • 常にメモをする
    • 詰まったところに気づくため
  • ソースコードをいじるのだけがOSSではない
  • サポータの方々が一生懸命支援してくれるので本当にありがたい!
  • 個人的な課題
    • gitとgithubの機能をもっと知っていく
    • 英語
    • 英語
    • 英語

ドキュメントを編集するだけでもOSSに貢献しているんだと、ハードルがすごく低くなりました。 改めて常にメモをとることは習慣化していきたいです。 OSS参加のハードルは低くなりましたが、英語のハードルが… 簡単な中学英語でいいと何回も言っていただいたので難しく考えずOSSに参加していければいいなと思います。

OSSのredashに対して、初めてPullRequestも出すことができて大変満足でした! 自分と同じような思いを持っている方がいましたら、ぜひともワークショップへ参加してみてほしいと思います!

次は、もう一回ビギナーとして参加するか、サポーターとしてOSS Gateの活動にも貢献していきたいと思います!

ラズベリー・パイ専用 学習リモコン基板 ADRSIRの使い方

少し前にラズベリー・パイ専用 学習リモコン基板 ADRSIRを買って色々弄ったので、 今日はADRSIRの使い方をまとめておこうと思います

yoshitaku-jp.hatenablog.com

  1. 物理的な操作編
    1. 赤外線を記憶させる
    2. ボタンからテレビの電源を付ける・消す
  2. プログラムでの操作編
    1. 記憶させている赤外線データを取得する
    2. Pythonからテレビを付ける・消す

1.赤外線を記憶させる

始まりの状態

真ん中のスイッチをLEARN状態に変更して、青いランプが光る。 そして記憶させたいボタンを1回押す 今回は5番ボタンにする

記憶させたいリモコンボタンを押す

緑のランプが光ったら成功!

2. ボタンからテレビの電源を付ける・消す

5番のボタンを押して、テレビのオン・オフをしています。

3. 記憶させている赤外線データを取得する

手順1で5番ボタンに記憶させた、テレビの電源赤外線データを取得してみます。

リモコンいじり放題!!ラズパイ専用 学習リモコン基板で使えるソフトウェア3種詰め合わせ公開 このページからダウンロードが出来るIR-remocon02-commandline.pyを使います。

ダウンロードした資材を /home/pi/に置きます

物理ボタンは1,2,3,4,5,6,7,8,9,10で指定されていますが、 プログラムで指定する場合は0,1,2,3,4,5,6,7,8,9になります。

Python3で

python3 I2C0x52-IR/IR-remocon02-commandline.py r 4 > 5.dat

のコマンドを実行すると、 物理ボタン5に設定した赤外線データを/home/pi/5.datファイルに出力することが出来ます

デフォルトだと、下のような内容のファイルが出来ると思います

3
[8]
memo_no write= [8]
data_num = 50
[133, 0, 67, 0, 18, 0, 16, 0, 19, 0, 50, 0, 18, 0, 16, 0, 18, 0, 18, 0, 18, 0, 16, 0, 18, 0, 18, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 17, 0, 19, 0, 17, 0, 51, 0, 18, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 18, 0, 18, 0, 18, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 19, 0, 50, 0, 18, 0, 50, 0, 18, 0, 16, 0, 19, 0, 16, 0, 19, 0, 50, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 18, 0, 17, 0, 17, 0, 18, 0, 18, 0, 51, 0, 17, 0, 17, 0, 17, 0, 19, 0, 17, 0, 51, 0, 17, 0, 17, 0, 18, 0, 51, 0, 18, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 19, 0, 16, 0, 18, 0, 51, 0, 18, 0, 50, 0, 18, 0, 66, 5]
8500430012001000130032001200100012001200120010001200120012001100120011001200110012001100120011001200110011001300110033001200100013001000130010001300100013001000120012001200100013001000130010001300320012003200120010001300100013003200120011001200110012001100120011001200110012001100110012001200330011001100110013001100330011001100120033001200100013001000130010001300100013001000120033001200320012004205

必要なのは、配列より後ろの

8500430012001000130032001200100012001200120010001200120012001100120011001200110012001100120011001200110011001300110033001200100013001000130010001300100013001000120012001200100013001000130010001300320012003200120010001300100013003200120011001200110012001100120011001200110012001100110012001200330011001100110013001100330011001100120033001200100013001000130010001300100013001000120033001200320012004205

部分なので、他の部分は削除しても構いません。コマンドを実行すればすぐにとれますしね。

これで、赤外線データを取得することが出来ました。

4. Pythonからテレビを付ける・消す

まずは公式から提供されているプログラムを修正します笑 提供されているものはどう頑張っても動きません

202行目の

write_command(memo_no,block2)

trans_command(memo_no,block2)

に変更します

trans_commandの第二引数のblock2へ

8500430012001000130032001200100012001200120010001200120012001100120011001200110012001100120011001200110011001300110033001200100013001000130010001300100013001000120012001200100013001000130010001300320012003200120010001300100013003200120011001200110012001100120011001200110012001100110012001200330011001100110013001100330011001100120033001200100013001000130010001300100013001000120033001200320012004205

が流れます。

これで、

python3 I2C0x52-IR/IR-remocon02-commandline.py t `cat I2C0x52-IR/5.dat`

を実行すると、テレビの電源がつきます。 もう一回実行すると、テレビの電源が消えます。

まとめ

  • 物理ボタンでテレビをオン・オフしました
  • 赤外線コードを取得しました
  • Pythonからテレビをオン・オフしました

公式のコードに手を加えて、動かすようにしました。 もう少しわかりやすくコードを直して、誰でも使えるようにしたいです。

I2Cがよくわからないなぁ… どうしたらいいんだろ。

毎月ひとつ新しいことをやるプロジェクト2018年3月版:将棋

3月は将棋をやる

3月は何をやろうかなと思っているところで、友人に誘われて将棋を始めた。

アクティブな自分としては、頭を使う趣味を持っていなかったのでちょうどよかった。 羽生永世七冠藤井聡太くんの活躍、アニメ「りゅうおうのおしごと」の影響もあってか、将棋の話題がすごく増えているので、このブームにも乗り遅れることなく切磋琢磨していきたい。

まずは詰将棋で勝つための感覚を養いつつ、戦術の本も読んでレベルアップしていきたい。 初心者軍団から速く一抜けしたい。 せっかくなので、将棋会館とかも行ってみたいな。

頭がさらに活性化しますように。

2月を振り返って

2月の活動の振り返り

週1回ブログを更新する

継続できています

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

yoshitaku-jp.hatenablog.com

こちらの記事を読ませていただいて、自分でも気をつけなければならないことが多々あった気がするので、今後気をつけていきます。過去にあげた記事についても適宜修正していきます。 http://blog.jnito.com/entry/2018/01/23/075856
くー!!過去記事の修正できてない!!! やります。。。

iPhoneのアクティビティを毎日閉じる

継続中!けどなぜか太ってしまった! 減量も目標に入れないと…

週1冊本を読む

現在資格試験の勉強にシフトしているのでお休み中。。。

その他アレコレ

3月からブログのメンターをお願いしました

週一更新はできているのですが、記事の質や構成など見てほしい部分がたくさんあるので、 外部の方の目を通してなおしていきたいと思います。

将来誰かが困ったときに役立つブログでありたい。 今までネットの人たちにお世話になったから自分も貢献したい、なんとなく今はそれだけです。

ブログ記事のリライトをお願いされました

お手伝いとして、IoT関連のブログ記事をリライトすることをお願いされました。 これも様々なイベントに足を運んで人脈を広げたからですかね。 個人で任されたことがなかったので不安もありますが、楽しんでやれたらいいなと思います。

まとめ

2月を振り返りました。 LT用資料も作り始めないと… モチベーションが下がってしまったときもあったけど、落ち込んでる隙がないのですぐに復活しました。 3月もいい出会いがありますように。

Raspberry Piのユーザまわり初期設定

raspberry piもくもく会で他人のraspberry piにログインしてしまったり、されてしまったりしたので、 ユーザまわりの設定をしっかりおこなおうと思います

rootユーザのパスワード設定

rootユーザのパスワードを設定します

pi@raspberrypi:~ $ sudo passwd
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
pi@raspberrypi:~ $  

rootユーザでログインが出来るか確認する

pi@raspberrypi:~ $ su
Password: 
root@raspberrypi:/home/pi#

rootユーザログアウト

root@raspberrypi:/home/pi# exit
exit
pi@raspberrypi:~ $ 

新規ユーザの追加

testユーザを作成する

pi@raspberrypi:~ $ sudo adduser test
Adding user `test' ...
Adding new group `test' (1001) ...
Adding new user `test' (1001) with group `test' ...
Creating home directory `/home/test' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
Is the information correct? [Y/n] Y
pi@raspberrypi:~ $ 

testユーザをsudoグループに追加する

pi@raspberrypi:~ $ sudo gpasswd -a test sudo
Adding user test to group sudo
pi@raspberrypi:~ $

新規ユーザをpiユーザと同じgroupに追加する

piユーザの所属グループを確認する

test@raspberrypi:~ $ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev spi i2c gpio

testユーザに対して、piユーザが所属しているグループをすべてに所属させる

test@raspberrypi:~ $ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio test

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for test: 
test@raspberrypi:~ $ 

パスワード無しでsudoを実行する

ファイルを操作する

sudo visudo

追記する

#includedir /etc/sudoers.d

test  ALL=(ALL) NOPASSWD: ALL

piユーザのパスワードを変更する

passwd

piユーザをsudoグループから外す

sudo gpasswd -d pi sudo

いちばんやさしい教える技術を読んだ

いちばんやさしい教える技術を読んだので、 読書メモを書く

教えることの考え方を改める

教えるとは

教えるという言葉は非常に難しく、自分がどれだけ熱意を持って取り組んだとしても、相手ができるようにならなければ全く意味がない。 つまり、相手に対して「教えた」といえる状態は、相手がどれだけ出来るようになったということだけが重要となる。 この部分を勘違いして、「これだけ自分が教えているのに…」となったとしても、自分だけが頑張ったとしても相手に響かなければ全く意味が無いのである。 相手ができなかったことが出来るようになった状態で初めて「教えた」と言える。

教えることとコミュニケーション

  • 教え上手がやっていること
    • 教える相手をよく観察して相手の状況をつかむ
    • 相手の状況にそって、ちょうどよい知識を提供できる
    • 相手に実践の機会を与えて、結果をフィードバックする

教える側の心構え

  • 教える前にできるようになって欲しい具体的なゴールを決める
  • 相手の心を変えるよりも行動を変えよう
  • 気持ちを変えるのは自分自身でしかおこなえず、教える技術では「相手の心までは変えられない」
  • 相手が今までできなかった行動を取れるようになったときが、「教えた」ということになる。

教えるルール10ヶ条

  1. 熱意よりも何をどうすればいいのか具体的な指示を
  2. 「教えた」かどうかは「学ぶ側が万だかどうか」で考える
  3. 結果が思わしくないのは、すべて教える側の責任
  4. 上手に教えたいならコミュニケーション上手になる
  5. 教えるときは相手をよく観察して、相手の状況をつかむ
  6. 相手にとってちょうどいい知識を与える
  7. 相手に教えたことを練習させて結果をフィードバックする
  8. 相手にできるようになって欲しい具体的なゴールを決める
  9. 相手の「心」は変えられないが、「行動」は変えられる
  10. ゴールは必ず「行動」として設定する

教えるゴールは3つ

  1. 運動スキル
  2. 認知スキル
  3. 態度スキル

5000時間練習すれば誰でも上手に出来るようになる

5000時間は1日5時間を毎日練習すると3年で到達できる 平日7時間練習したとしても3年で到達することができる

認知スキルのゴール

頭を使って、うまい思考をするのかが、認知スキルのゴール

頭を使って考えるパターンは3つにわけられる 1.記憶すること - 耳で聞いて覚える - 目で見て覚える - 詰め込み学習よりも、「分散学習」 - 知っている知識と関連付をさせる 2.問題を解決すること - 解き方のパターンを「スキーマ」という - スキーマをできるだけ多く習得させる 3.話したり書いたりすること − 小さなステップを踏んで書く - ノートを取る習慣をつけさせる - スピーチメモを作り、繰り返し練習をさせる

教えることで、教えている人も成長する

誰かに教えることで、自分自身の中で知識が整理され、教える前よりも深く理解するようになる

教えることには、自分にあった新しい学び方を発見することが出来るという、良い作用がある。

上手に教えることができれば、まわりのみんなから信用されるようになる。

周りの人は教えることがめんどくさいことだと思っているので、うまく教えることで信頼を得ることができ、 うまく教えるために自分の知識を深め整理しさらに自分自身を高めることが出来る。

しかし、教えたがりになることに注意する。 あくまで自分自身の成長は副作用のようなものであり、教えることの最大の目的は「相手ができるようになる」ことである

ブログを書くということ

まだまだ書き始めたばかりですが、 自分で得た知識を整理して、アウトプットすることで誰かの役に立ったり、 自分自身でわからないところが浮き彫りになって、更に知識を得ようとする良いサイクルが生まれていけばいいなと思います。

Raspberry PiとAIで作るIoTデバイス ミニハッカソン(isaax勉強会#2)に参加してきた

Raspberry PiとAIで作るIoTデバイス ミニハッカソン(isaax勉強会#2)に参加してきた

詳細な内容はこちら↓

Raspberry PiとAIで作るIoTデバイス ミニハッカソン(isaax勉強会#2)

オープニングトーク・デモ

開始

  • isaaxの登録
    • GitHubから紐付けると楽
  • isaaxでやること
  • 環境変数の登録
    • バイスの登録からアプリケーションの再起動を忘れないこと

ハッカソンとプレゼン

ハッカソンとメモを兼ねていましたので、後半はメモがあまり取れず…
書いてくれた方がいましたら、ブログ記事をリンク貼らせていただきます…

Tips

isaaxログの見方

tail -f /var/log/isaax-agent.log

isaaxプロジェクトがあるディレクト

/var/isaax/project/

バグったときにcommitをすると、強制的にアップデートがかかる

  • 自分はブラウザのGitHubからリポジトリのREADME.mdに空行を追加し、コミットした

ハッカソンとしては、サンプルコードではSlackにPOSTしていたので、 送信先Dropboxにしてみたいと思いました。 会場のネットワークが遅く、全チーム苦戦していました。 最後までやりきることが大切だと思いますので、送信先Dropboxにしてものを完成させてみます。

完成したら追記予定 まずはカメラモジュールを買う!!!

おわり

ラズベリー・パイ専用 学習リモコン基板 ADRSIRを買いました

こんな製品です。

ラズベリー・パイ専用 学習リモコン基板は、ラズベリー・パイを高度な赤外線学習リモコンとして動作 させることが可能な拡張基板です。基板上に 10 個のスイッチを搭載し、それぞれスイッチ毎に外部赤外 線リモコンの動作を基板本体内に記録可能です。さらにビット・トレード・ワン WEB サイトにて、家電 からエアコンまで、各社 2500 以上のリモコンコードを公開することでユーザーがリモコンコードを自由 に選んでオリジナルな高機能リモコンを作成できます。 またプログラミングにより高度な学習リモコンモジュールとして動作し別途ラズベリー・パイや照度セ ンサなどと組み合わせることで「照明を定時に点灯し、TV の電源を入れ、いつも見る朝のニュースにチ ャンネルを変更する」など複数の高度な動作を行うことが可能となります。

Alexaからテレビを操作したい

Alexaからテレビのオンオフやチャンネルを変えたりしたいなと思っています。 自分はテレビを見ないのですが、家族用に…

リモコン取ってとか、リモコンがなくなったとかずっと煩わしいと思っていたんですよね。 なので、リモコンから発せられる赤外線をRaspberry Piの方に学習させて、 AlexaからIFTTT経由で操作してみたいと思います。