pco2699’s blog

学んだコード・技術について、保存しておく場所

Python + Heroku + LINE BOT SDKでコーランを教えてくれるbotを作った

LINE BOT AWARDSでLINE BOTが盛り上がってるので作成してみました。
LINE BOT AWARDSにも「ローカライゼーション」部門でエントリしておきました。
ほぼ一発ネタなので、暇つぶしにでもフォローしてみてください。

つくったもの

言葉に対してなんでもコーランの開端の章の一節を返してくれるbot
「意味は?」とか聞くとそのコーランの意味を教えてくれたりします。
こんな感じです。 f:id:pco2699:20170303145726p:plain

なぜつくったか

  • 最近 海外に出かけるときは、なにかと物騒なのでコーランを覚えておいたほうが安全なのでは、と思ったため
  • これをきっかけにイスラム教の人と仲良くなれるかな、と思ったため (まだイスラム教の友達はいないけど..)

利用したもの

ソースコードはLINE BOT SDKの中のサンプルsimple-server-echoをベースに作りました。
その他に利用したものは以下。

Github

github.com

ライフゲームをNovation Launchpadに実装して、シーケンサーにしてみる

引き続き、前回紹介した「ジェネラティブアート」の本読んでます。 その中で、後半に出てくる「ライフゲーム」が面白かったので、ちょっと発展させて楽器にしてみました。

[普及版]ジェネラティブ・アート―Processingによる実践ガイド

つくったもの

こんな感じになりました
(我ながらTENORI-ON感がすごい音)
うす緑色の縦線が現在、鳴っている音で、Cメジャー・スケールで音を鳴らしてます。

youtu.be

ライフゲームとは

碁盤の目のような格子があって、それぞれの格子が周りの状態を見て 自立的に、一定のルールで自分の状態を決める。(これがセル・オートマトンと呼ばれるもの) で、このセル・オートマトン上で、以下のルールに従って格子の状態が決まるのがライフゲーム

  1. 生きている格子は、2つか3つの隣接セルが生きていればそのまま生き続ける。
    さもなければ過疎か過密のどちらかで死んでしまう。
  2. 死んだ格子の周囲に、ちょうど3個の生きた隣接セルがあれば奇跡が起こり
    その格子は生き返る。

百聞は一見にしかず、以下のサイトを見てみるとなにかよくわかる。

ライフゲーム

ちなみにGoogleで「ライフゲーム」で検索すると実は裏側で ライフゲームが動いているという。。。さすがGoogle f:id:pco2699:20161210153635p:plain

参考資料など

Launchpadをプログラミングするときは Novationから出ている Launchpad プログラミングリファレンスが参考になりました。

https://d19ulaff0trnck.cloudfront.net/sites/default/files/novation/downloads/4080/launchpad-programmers-reference.pdf

ソースコード

PythonMIDIライブラリmidoで実装しました。

gist7806d8a4dc543a2ca71ed23d360b294b

Processingを用いて間違った円を描く方法

3331α Art Hack Day 2016というアート×エンジニアリングの共演みたいな面白そうなハッカソンに応募したんだけど 見事に抽選(というか審査)に落ちて、参加できなかったので、悔しくて以下の本を買ってみました。

[普及版]ジェネラティブ・アート―Processingによる実践ガイド

この本おもしろくて、最初は単純の線を描く方法ばっかりなんだけど(実際、著者も「これは退屈だが」って書いてるあたりわかってる。) 「間違った円を描く方法」という章あたりから大分、様子がおかしくなってくる。
というわけなので、自分も、とっかかりとしてこの様子がおかしい円を描いてみることにした。

書いたもの

様子がおかしいというか、なんだか悪夢感がすごい円が描けました。 f:id:pco2699:20161103161922p:plain

実際にうごくやつ

実際に動くと悪夢感がさらにすごい。

Processing Demo

書いたコード

// setupでアニメーションを動かす前のセットアップを行う
void setup(){
  // キャンバスサイズの設定を横:500 縦:300に設定
  size(500,300);

  // 背景を白に設定
  background(255);

  // らせんの線の太さを細めに設定
  strokeWeight(0.5);

  // 形をなめらかに
  smooth();
}

// drawで実際にアニメーションの内容を設定
// このdrawで書いた内容が無限ループされる感じ
void draw(){
  // ループ毎に背景をリセット
  background(255);

  // らせんの中心を設定
  int centx = 250;
  int centy = 150;

  float x, y;

  // らせんを100個描くfor ループ
  for (int i = 0; i < 100; i++){
    float lastx = -999;
    float lasty = -999;
    float radius = 10;

    // 直径を乱数化するシードをランダムに設定
    float radiusNoise = random(10);
  
    // 線の色の濃さもランダムに
    stroke(random(20), random(50), random(70), 80);

    // らせんを描きはじめる角度をランダムに
    int startangle = int(random(360));

    // らせんを描きはじめる角度もランダムに
    int endangle = 1440 + int(random(1440));

    // 角度のステップもランダムに
    int anglestep = 5 + int(random(3));

    // らせんを描くforループ
    for (float ang = startangle; ang <= endangle; ang += anglestep){
      radiusNoise += 0.05;
      radius += 0.5;

      // 今回の直径を ランダムに0~100の間でランダムに加算
      float thisRadius = radius + (noise(radiusNoise) * 200) - 100;
      float rad = radians(ang);

      // らせんの中心から三角関数でx軸、y軸を設定
      x = centx + (thisRadius * cos(rad));
      y = centy + (thisRadius * sin(rad));

    // 前の座標から今回計算した座標へ線を引く
      if(lastx > -999) {
        line(x, y, lastx, lasty);
      }

      // 次のforループで利用するため今回のx,y座標を保存
      lastx = x;
      lasty = y;
    }
  }
}

感想

  • Javaベースだから、馴染みやすい文法で線とか絵がかけるProcessingすごい
  • こんなわかりやすいコードでこんなカオスな絵をかけるマットピアソンさん(↑の本の著者ね)すごい

しかも、この「間違った円を描く」章以降、かなりカオスな絵ばっかり出てくるので わくわくが止まらない。。。
また読み進んだら、ここにも載っけようかと思います。

ラズパイと天気予報APIとマルチカラーLEDで出勤時にチャリ使えるか教えてくれる装置つくった

つくったもの

出勤時(AM 6:00-7:00)の間に、マルチカラーLEDでその日 雨が降るか降らないか教えてくれる装置

雨がふるよ〜ってとき

こんな感じで赤色で点滅 (Live Photosで撮影)
関係ないけどLive PhotosをGIFに変換してくれるMotion Stillsマジ便利

f:id:pco2699:20161002172405g:plain

晴れるよ〜ってとき

こんな感じで青色で点灯

f:id:pco2699:20161009070937g:plain

作った理由

自分は徒歩 or チャリ出勤なんだけど、朝 毎回「チャリで今日出れんのかな〜」と天気予報アプリで調べるのがおっくうだったので

用意したもの

この記事を参考にしつつを以下を、用意。

回路図

回路図はこんな感じ
抵抗の配置の仕方は、前述のブログ記事からそのまま借用しました。。。
高校の時の物理を復習して自分で抵抗値とか出せるようにしたいところ。。。

一番左→GPIO 22番から150Ωの抵抗かまして赤色LED
二番左→カソード
二番右→ GPIO 23番から直で緑色LED 一番右→GPIO 24番から直で緑色LED

f:id:pco2699:20160919145014p:plain

ソースコード

Githubに上げてあります。

github.com

ポイント

帰りの天気が重要なので、直近の予報と9時間後の予報をそれぞれ調べて、どちらか一方でも雨が含まれていたら
雨判定となるようにした。
(でも、後から気づいたんだけど直近の予報 雨だったら窓から外みればいいから 9時間後の天気だけみりゃいいのでは。。。とか思ったり)

    # 朝時点で雨フラグ
    morning_rain_flag = False
    # 夕方時点で雨フラグ
    evening_rain_flag = False

    # 直近の天気情報を取得しプリント
    print(get_desc(0))
    # 9時間後の天気情報を取得しプリント
    print(get_desc(3))

    # 直近天気を検索、もしrainが含まれていたらフラグを真に
    if 'rain' in get_desc(0):
        morning_rain_flag = True

    # 直近天気を検索、もしrainが含まれていたらフラグを真に
    if 'rain' in get_desc(3):
        evening_rain_flag = True

    # 直近・9時間後のフラグをかけ合わせてresultに格納
    result = morning_rain_flag or evening_rain_flag

動かし方

ソースコードをcronで毎日 AM 6:00に起動するようにする。

今後の予定

  • 現状AM 6:00起動なので、なんかボタン押したら起動するようにしたい

AngularJSのcomponentにui.routerのresolveの変数を注入を試してみる→失敗しました...

AngularJSのcomponentにui.routerのresolveの変数を注入する方法がわからなく
色々調べたのメモしておく。

結論から言うとui.routerは0.2系のverだとcomponentで注入するのは無理そう。。。
(こうやれば解決できる!的な解決策あれば教えてほしいです)

当初書いたコードはこんな感じ
まずステート定義から

angular.module('myApp', [ui.router])
   .state('main', {
     url: 'main',
     resolve: {
        test: function ($http) {
          return $http.get({
            url: '/api/test/'
          });
        }
     },
     template: '<main></main>'
   })

コンポーネント部はTypeScriptで記述

class mainComponent{
    constructor(public test){
    }
    // 機能記述...
}

angular.module('myApp')
   .component('main', {
     templateUrl: 'main.html',
     controller: mainComponent
   }
);

ここでmainComponentでそんなサービスないよボケと怒られるわけである。
(testがサービスとみなされ、AngularJSで怒られる。)

なんとかならんかと色々ググってみたところ以下のサイトを発見

www.codelord.net

The beloved ui-router doesn’t really support exposing resolved dependencies except to the controller of the state.
The maintainers mentioned this might be addressed in the upcoming 1.0 version of ui-router.

オゥ、ui-routerはresolveの依存性注入はコントローラー以外できないってバッチリ書いてありまっせ。。。
ui.router 1.0では解決されまっせ、とのことです。

というわけで素直に、resolveで解決するのを諦めて$onInitで取りに行く形としました。

angular.module('myApp', [ui.router])
   .state('main', {
     url: 'main',
     template: '<main></main>'
   })
class mainComponent{
    constructor(){
    }
    $onInit{
       $http.get('/api/test')
       .then(
         //機能記述...
       )
    }
}

angular.module('myApp')
   .component('main', {
     templateUrl: 'main.html',
     controller: mainComponent
   }
);