読者です 読者をやめる 読者になる 読者になる

どくぴーの備忘録

真面目なことを書こうとする情報系大学生カッコカリのブログ。いつ投げ捨てられるのかは不明

でなlangに見る手を抜いてつくる3文字言語

この記事は denari01 Advent Calendar 2016 - Adventar 5日目の記事です

諸注意

特に何もしてないのでご注意

動機

誰かが「Grassのトークンさえ入れ替えたら任意の3トークンを用いた言語ができるゾ」とか言ってた

まずGrassって何さ

ちょっと草植えときますね型言語 Grass

要は「W」「w」「v」だけで書く言語です.型無しラムダ計算がベースの関数型プログラミング言語ですが特にこれ以降このことに絡んだお話はしません.

やったこと

github.com

まずこちらのyagi.rbを拝借します.こちらを改変するだけです.基本的には「W」「w」「v」のトークンを使いたい任意の3トークンに入れ替えてあげましょう.今回は「で」「な」「り」なので
W -> でw -> なv -> り
ですね.

# W -> で
# w -> な
# v -> り

App = Struct.new(:m, :n)
L = Struct.new(:src)
src = File.read(ARGV[0])
src = src.gsub(/[^でなり]/, "")
# vで区切る,vなし区切りのために更に次で区切る
src = src[/.*\z/m].split(//).map.with_index do |sub, i|
  sub = sub.scan(/+|+/)
  arg_num = sub.first[0] == "" ? sub.shift.size : 0
  sub = sub.each_slice(2).map { |n, m| App[n.size - 1, m.size - 1 ] }
  arg_num.times { sub = [L[sub]] }
  sub
end.flatten(1)

# eval
eval = ->(src, env) do
  ctrue = ->(arg) { eval[[L[[App[2, 1]]]], [arg, ->(arg) { eval[[], [arg]] }]] }
  cfalse = ->(arg) { eval[[L[[]]], [arg]] }
  src.inject(env) do |env, insn|
    val = case insn
    when App
      clos, arg = env[insn.m], env[insn.n]
      case clos
      when Proc then clos[arg]
      when Fixnum then clos == arg ? ctrue : cfalse
      when :out then putc(arg); arg
      when :in then ch = $stdin.getc; ch ? ch.ord : arg
      when :succ then arg.succ & 0xff
      end
    when L
      ->(arg) { eval[insn.src, [arg] + env]}
    end
    [val] + env
  end.first
end

puts "-- denalang source code --"
puts File.read(ARGV[0])
puts "-- result --"
# プリミティブ
eval[[], [eval[[App[0,0]], [eval[src, [:out, :succ, "w".ord, :in]]]]]]
puts "\n"

できた

本当に何もしてないですが,これだけです,早速見てみましょう.じゃあHello World.

$ cat hello.dn
なりななででなでででなりでななななででなでででなででででなでででででなででででででなでででででででなでななななななななななななででででなでででででででなででででででででででででででなでででででででででででななででででででででででななででででででででででででなででででででででででななででででででででででななななななでででででででででででででででなでででででででででででででででででででででなででででででででででででででででででななでででででででででででででででででななでででででででででででででででででなななななででででででででででででででででででででななででででででででででででででででででででででなでででででででででででででででででででででででででななななななななななななななななななななななななななでななななななななななででなななななななでででなななななななででででなでででででななななななななででででででななななななななななななななななでででででででななななななななななななななななななななででででででででななななななななななななななななななななななななななななななななななななでででででででででななななででででででででででなななななななななななでででででででででででなななななななででででででででででででななななななななななななななななななでででででででででででででななななななななななななななななななななななななな
$ ruby denalang_interpreter.rb hello.dn
-- denalang source code --
なりななででなでででなりでななななででなでででなででででなでででででなででででででなでででででででなでななななななななななななででででなでででででででなででででででででででででででなでででででででででででななででででででででででななででででででででででででなででででででででででななででででででででででななななななでででででででででででででででなでででででででででででででででででででででなででででででででででででででででででななでででででででででででででででででななでででででででででででででででででなななななででででででででででででででででででででななででででででででででででででででででででででなでででででででででででででででででででででででででななななななななななななななななななななななななななでななななななななななででなななななななでででなななななななででででなでででででななななななななででででででななななななななななななななななでででででででななななななななななななななななななななででででででででななななななななななななななななななななななななななななななななななななでででででででででななななででででででででででなななななななななななでででででででででででなななななななででででででででででででななななななななななななななななななでででででででででででででななななななななななななななななななななななななな
-- result --
Hello, world!

できました(?)

おわび

Q: え?トークン入れ替えただけだよね?
A: はい,それだけなのに記事書いて申し訳ありませんでした.時間がないけどとりあえず書いた結果がこれです.クソ記事に付き合っていただきありがとうございました

#kosen10s slackでの自分のemojiのつくりかた

これは #kosen10s Advent Calendar 2016 - Adventar の4日目の記事です.

昨日の記事はこちらでした

www.zopfco.de

言い訳

昨日の記事で上がったハードルが高すぎる

技術系アドベントカレンダーに取り上げられたりしてるらしいですが僕は技術の話はしません.ご了承を

kosen10s slack

初日でもなっちゃんid:marin72_com )が言及していましたね

marin72.hatenablog.com

こんな感じでやいのやいのしているわけですが,emojiに関してルータ芸人( id:puhitaku ) も言及したので自分もemojiの話をします.

How to make emoji

自分はMacを使ってるのですが,Macに標準でついてくる「プレビュー.app」がやけに高機能なのでこれを使えば簡単に透過画像を作れます.プレビューのくせに…

画像をもってくる

適当なフリー素材でも探してきましょう.

プレビュー.appで編集する

プレビュー.appで開いて,編集機能を出します.

f:id:e10dokup:20161204104945p:plain

すると出てくるツールバーの中に「インスタントアルファ」があるので,選択しましょう.

f:id:e10dokup:20161204105132p:plain

「インスタントアルファ」は,ドラッグした部分の色合いに近い箇所を全部選択するツールです.ドラッグの長さで選択する領域の微調整も出来ますが,今回は白背景なのでそのまま選択してdeleteキーで全部背景を抜いてしまいます,

後はこれのサイズを縦・横両方128px以下になるようにして,Customize SlackからEmojiに登録しましょう.これで完成です.白背景なら簡単に背景を抜いて透過できるので楽なのですが,アニメのキャプチャなど,空や木がはいって背景が単色ではない画像などでも,うまいことそれぞれの色に合わせてインスタントアルファを描けたり,矩形選択や投げ縄選択を使ったりして微調整しながら比較的簡単に背景を抜くことが出来ます.

ね?簡単でしょ?これで皆も絵文字量産おじさん!

MultiSelectableCalendarなるライブラリを作った

github.com

Androidでカレンダーを操作する必要があったのですが,「この日はOK,この日はNG」みたいな指定の仕方が遷移なしでできるライブラリが無いなぁということになったのでいっそ自作して公開してみました

f:id:e10dokup:20161022015059g:plain

細かいことはリポジトリのREADME.mdを読むとわかるのですが

<dokup.xyz.multiselectablecalendar.ui.MultiSelectableCalenderView
        android:id="@+id/calender"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:monthBackgroundColor="#81D4FA" <!-- color of background parts for month -->
        app:monthTextColor="#546E7A" <!-- color of text for month -->
        app:weekBackgroundColor="#03A9F4" <!-- color of background parts for week -->
        app:weekTextColor="#FFFFFF" <!-- color of text for month -->
        app:dayBackgroundColor="#FFFFFF" <!-- color of background for date -->
        app:dayTextColor="#616161" <!-- color of text for date -->
        app:availableDayBackgroundColor="#FF9800" <!-- color of background for date which is available -->
        app:availableDayTextColor="#FFFFFF" <!-- color of text for date which is available -->
        app:unavailableDayBackgroundColor="#757575" <!-- color of background for date which is unavailable -->
        app:unavailableDayTextColor="#FFFFFF" <!-- color of text for date which is unavailable -->
        app:chevronColor="#1565C0" <!-- color of chevron for month change -->
        />

のようにほとんど全てのパーツについて色指定をできるようにしたり, ScheduleMode というenumを設定することで

  • ScheduleMode.SINGLE
    • OK/NG/特になしを日にちごとにタップすることで設定
    • available -> unavailable -> nothing -> available -> ...
  • ScheduleMode.RANGE
    • A日からB日までタップした範囲の全ての日付をOKにする
    • MultiSelectableCalendarView#setInterval(int interval) によって前後にNGの日にちを設定可能
  • ScheduleMode.DISPLAY
    • 操作不能の表示用モード

というように複数の表示モードを指定したりできるようにしてみました.

カレンダーで設定したOK/NGの日付一覧ですが,

AvailableSchedule schedule = calendarView.getAvailableSchedule // get AvailableSchedule instance
List<Calendar> available = schedule.getAvailableCalendarList(); // get available date as java.util.Calendar's list
List<Calendar> unavailable = schedule.getUnavailableCalendarList(); // get unavailable date as java.util.Calendar's list

のようにすることで java.util.Calendar のListとして取得できます.また MultiSelectableCalendarView#setOnScheduleChangedListener(OnScheduleChangedListener listener) のcallbackでも取得できます.

勉強になったこと

  • custom viewの実装
  • werckerによるデプロイまでのCI
    • 昨日やっとデプロイできるようになりました.というのもdocker imageを作れるだけのストレージに余裕がなかったので研究室のPCを借りてdocker hubにimageをpushするという()

PR/issueや「こここうした方がいいんじゃね」みたいな意見でもなんでもいいのでいただけると泣いて喜ぶと思うのでお願いします

くそおまけ

記事を書いている間に年齢がインクリメントしました.

https://www.amazon.co.jp/gp/registry/wishlist/22SFRRHYUCWKL

Raspberry PiとBluetoothスピーカーとRuby + Sinatraで天の声APIを作ってみる

最近,研究室でRaspberry Piを借りてきたのでせっかくだから喋らせてみることにしました

なんかもうあった

nwpct1.hatenablog.com

カレーメシ先輩( id:nwpct1 )がラズパイ内で音声合成して喋らせていたのでコレを参考にしてみようと思ったのですが,docomo developer supportにはいっているHOYAサービスの音声合成APIを使ってRESTで殴って生成済み音声データを持って来て再生する仕組みにしておうちの中でPOSTすると喋らせてみることにします.

dev.smt.docomo.ne.jp

用意するもの

docomo developer supportに登録

dev.smt.docomo.ne.jp

にアクセスしてアカウントを取得します.取得したら,マイページからAPI利用申請・管理にアクセスしてアプリケーションを登録します.基本情報を入力し,『音声合成 【Powerd by HOYAサービス】』を選択してAPIキーを取得しましょう.

APIエンドポイントを作る

まずはGemfileの定義から.

source "https://rubygems.org"

gem 'sinatra'
gem 'sinatra-contrib'

ただ喋らせるだけなのでこれで十分です.DB用意したりして工夫する際は適宜追加しましょう.完了したら bundle install --path /vender/bundle でインストールします.

app.rb にエンドポイントを定義します.今回は適当に /api/v1/speech とします.ついでに /api/v1/speech/test にテスト用のエンドポイントも用意します.

#!/usr/bin/env ruby
# coding:utf-8
require 'sinatra'
require 'sinatra/json'
require 'json'

require './speech.rb'

# API

get '/api/v1/speech/test' do
  speech = Speech.new
  data = {result: speech.do_speech("これはテストです.音量などを確認してください.")}
  if data[:result] == 'success' then
    status 200
  else
    status 400
  end
  json data
end

post '/api/v1/speech', provides: :json do
  params = JSON.parse(request.body.read,  {:symbolize_names => true})
  text = params[:text]
  speech = Speech.new
  data = {result: speech.do_speech(text)}
  if data[:result] == 'success' then
    status 200
  else
    status 400
  end
  json data
end

実際に喋らせるSpeechクラスを実装します.do_speech メソッドだけですが.

require 'net/http'
require 'uri'

API_KEY = '(docomo developer supportで取得したAPIキー)'

class Speech
  def do_speech(text)

    endpoint = URI.parse('https://api.apigw.smt.docomo.ne.jp/voiceText/v1/textToSpeech')
    endpoint.query = 'APIKEY=' + API_KEY

    request_body = {
        'text'=>text,
        'speaker'=>'hikari'
    }

    res = Net::HTTP.post_form(endpoint, request_body)

    case res
      when Net::HTTPSuccess
        file_name = "voice.wav"
        File.binwrite(file_name, res.body)
        `aplay voice.wav` #Macに喋らせたいときはafplayにしましょう
        File.delete(file_name)
        return "success"
      else
        return res.body
    end
  end
end

ちなみに上のコメントにあるようにaplayをafplayにするとmacで喋れるようになります.この時点で,とりあえず bundle exec ruby app.rb -o 0.0.0.0 で起動して localhost:4567/api/v1/speech

{
    "text": "ほげほげ"
}

みたいなJSONをPOSTするとPCが喋ると思います.

Raspberry Pi側の環境構築

とりあえず頑張ってRaspberry Pirubyをインストールします.

qiita.com

Raspberry Piなのでインストールには凄い時間がかかりますが気長に待ちましょう.

完了したら

gem install bundler

でbundlerをインストールします.完了したらさっきのsinatraアプリケーションをgitなりでRaspberry Pi上に移動して bundle install --path /vender/bundle して, bundle exec ruby app.rb -o 0.0.0.0 で起動します.この時点で,Raspberry Piのイヤホンジャックにイヤホン等を繋いで '(Raspberry PiのIP):4567/api/v1/speech' に先程のJSONをPOSTすると喋るのですが,今回はBluetoothスピーカーに喋らせるので

apt-get install bluetooth bluez bluez-tools pulseaudio pulseaudio-module-bluetooth

でbluezとpulseaudioをインストールします.インストールしたら pulseaudio --start でpulseaudioを起動します.終了は pulseaudio -k です.

続いて,Bluetoothスピーカーの電源を入れ,bluetoothctlでペアリングを行います.

$ bluetoothctl -a
[bluetooth]# power on  //パワーオン
[bluetooth]# scan on   //スキャン開始
[NEW] Device A0:E9:xx:xx:xx:xx BT Speaker name  // Bluetoothスピーカーを見つける
[bluetooth]# connect A0:E9:xx:xx:xx:xx    
[bluetooth]# trust A0:E9:xx:xx:xx:xx
[bluetooth]# exit

ペアリングが完了したらデフォルトをそのスピーカーに設定して

$ pacmd set-default-sink bluez_sink.A0_E9_xx_xx_xx_xx

音量を設定します,

$ pactl set-sink-volume bluez_sink.A0_E9_xx_xx_xx_xx 60%
または
$ alsamixer

これで,Raspberry PiAPIを叩くとBluetoothスピーカーからおもむろに声が鳴り響くと思います.天井付近に設置すれば天の声っぽくなる…か?

サンプルコード

github.com

#wakate2016 第49回情報科学若手の会に参加してきました

TL;DR

エモかった

去年の

e10dokup.hateblo.jp

何をしてたの

9/17 - 9/19の間,伊東市の山喜旅館にて行われる情報科学若手の会に参加してきました.

個人的には特に話すネタを一切用意していなかったのですが,前日に偶然ポケモンGO Plusを入手することに成功してしまった(発売日がその日であることすら知らなかった)ため,とりあえずおもむろにAndroidからBLEの中身を見るアプリを使ってどんなサービスがあるんかなー,どんなふうに動いてるんかなーって感じのLTをしてきました.模造品を作らせない努力を垣間見ました.

セッション

去年とはまた違った方向に多岐にわたった分野の発表があった気がしました

  • 機械学習
  • HCI
  • Java 8の ' String.format() ' の話
  • ロボット(ロボカップとかおっちゃんに使ってもらう話とか)
  • 通信系(LoRa)
  • 小型ドローン(Phenox)
  • 電子決済と個人間送金
  • 株と為替の話
  • キャリア
  • 蚊をRESTfulに殺す
  • 海外で就活とかする話

などなど,本当に多岐にわたる発表があったのですが,何よりキャリアに関する発表が エモかった です.言葉では表せないくらいのいい話でとにかく エモかった です.最高.

あとHCI界隈はPV(?)に凄いアゲ↑アゲ↑なBGMを使ってて,すごいクラウドファウンディングな感じがしました(実際そうではない)

交流イベント

去年はパスタを使ってマシュマロを出来る限り高い高度に持ち上げるマシュマロ・チャレンジだったのですが,今年は何が起きたのかLANケーブル作成競争でした.しかもクイズに答えられないと部材も機材も手に入らないという.難易度の高い問題を引き続けるあまり幹事の方から「好きな数字の問題えらんでいいよ!w」的なご容赦が飛んできましたがなんとかLANケーブルは3本くらい作れて,問題は全部消化しました.一杯回答スルーした気がするけど気にしてはいけない.

ちなみに勝者の商品の一部ですが,らん(?)とけーぶる(?)でした

f:id:e10dokup:20160917220719j:plain

ナイトセッション

ここに居ないと知らないような話が大量にあって,なんというか エモさのラスボス みたいな感じでした.ドローン飛ばしたのを見てたり,本当にここでしか聞けないレベルの話を聞いたり,色々とヤバい(すごい)という記憶しか残っておりませんが,本当に楽しかったです.

他に何をしてたのかというと,「君の名は。」の話をしてたりピングーの話でひとしきり笑ってたりロボカップでつかうロボットを見せていただいたりしました.ついでにルータ芸人 ( id;puhitaku )の撮影会が執り行われました

この時撮影した写真は見事クロージングにて使われました.やったね(?)

無事に帰ってきて

実は今年は「んおおおおお行くかなぁどうしようかなぁ」ってなっていたのですが,行ってよかったなぁって思います.毎年違うエモさが襲い掛かってきて最高って感じなのでこれからも行けるのであればぜひ行きたいなぁ.って思いました.

最後になりましたが,幹事の方々,本当にありがとうございました.お疲れ様でした!!!! :bow: :bow:

ポートフォリオサイトを作った

すごい今更感しか無いですが,ポートフォリオサイトを作りました.

e10dokup's portfolio

なんで作ろうと思ったの

ちなみに,研究室の先生に見られた時の反応は

「えっ?なんでこんな時期に?」 です.当たり前ですよね.

やってみたこと

  • デザインよくわからないけどbootstrapは使いたくなかったのでMaterial Design Lightの導入
  • ムダにアカウントのアイコンにアニメーションをぶっこんでみる
  • アイコン部分とかを独自に書いてみたりしたのでその部分をレスポンシブっぽく(というか画面幅が狭くなったら横並びを縦並びになるように)した
  • gulp.jsを使ってみる
    • よくわからないなりに便利でした

ちなみに,画面幅対応はこの本を参考にしてみたり

gulp.jsの使い方はLIG.incの記事を参考にしてみたりしてました

liginc.co.jp

ちなみにgithub pages上にデプロイしてます.簡単お手軽って感じで楽ちんでした.

感想

  • 難しい
    • 純粋に勉強しないとなと思いました
  • なんだかんだポートフォリオサイトが完成すると嬉しい気分になる
    • ちゃんと更新していかないと行けない

わからないなりに楽しめて,勉強になったのできっかけ作りとしては良かったかなぁって思っています.もっと頑張っていこう💪

kosen10s LTに初参加して考えたこと

大阪に来たので初参加してきました.kosen10s LT.

kosen10s.doorkeeper.jp

なにげにしれっとkosen10s slackには居たり,kosen10s有志で「大阪会場もあるのに」わざわざSPAJAMの東京A予選に参加したりしてはいたんですけど,LT会に関してはお金と日程的な関係で断念し続けてました.TOEIC前日に参加とか無理でしょ(白目)

何話したの

僕が個人として話したのは,kosen10s LT恒例らしい自己紹介と近況LTと,後おまけとしてAndroidでBLEビーコンで遊ぶ記事を書きました.SPAJAMで作ったアプリで一体何してたのか,って感じの内容です.

www.slideshare.net

一応スライドはあるにはあるんですがほとんどコード見ながら話をしていたのでこのスライドからじゃ一体何の話なのか全くわからない感じになっています.申し訳

皆のお話

やはり 「ぶっ飛んでんな」 というのが感想でした.カップル向けアプリを紹介したり,(幼少の)教育のお話だったり,(授業に使う)婚姻届持ってきたり,いつもどおりのルータ芸だったり,シェル芸だったり,E/D問題だったり,多岐に渡ってんなぁ…っていうすごい小並感レベルですが感心ばかりの内容でした.同じ同期の高専生っていっても本当にいろんな人種が居るんだなぁってつくづく思い知らされる感じです.

買い出し

僭越ながら買い出しに行ってきました.最初は「絶対おにぎりとサンドイッチ買うぞ」みたいな感じだったのですが,気づいたらお菓子とジュースしか買っていませんでした.なんかくっそ時間がかかっていたのは思ったより会場からスーパーが遠かったのとジュースとお菓子が別フロアで別々に会計済ませないといけなかったのと行きにうなすけくんがブランコ警察していたからです,うなすけくん本人曰く 「あれはΔtだから!!」 とのことですが多分あれで3分くらい食ってました.食った時間以上に面白かったので多分大丈夫でしょう(?)

kosen10sに思うこと

一言でいうと, 高専特有のぬるま湯の様な居心地と失われた語彙力 って感じです.別に皆一緒の何らかの目標があるわけでも何でもなく,個々が好きなときに好きな話題とイベントを持ってくる.そこにたまたま同調した人がやいのやいのしだす,そんな集団じゃないのかなぁ,って思います.僕は意識が低いので「皆でなんかでっかいことするチーム作ろうぜ」みたいな雰囲気よりはその場で自然発火して各位のたまたまの反応で鎮火したり爆発したりするそういう雰囲気が大好きです.語彙力は完全に消え去ってます.大体文字が書いてあるemojiで対応したり,とりあえず人物っぽいemojiの左右に筋肉をつけたりするあたり察しがつくかと思います.

f:id:e10dokup:20160509002237p:plain

僕の印象としてはそんな感じなんです.ただこの妙な(いい意味の)グダグダ感が好きなんです.高専に懐かしみを感じたり…ってわけでは無いんですが,ただでさえ全国的に少ない高専の同期がどんな感じでいまほげほげしてるんだろうか,っていうゆるーい繋がりでダラダラ会話をしていて,時々妙な刺激を受けてなんかよくわからないけどモチベーションが湧いてくる,そういうのもまたいいんじゃないかなって思います.ズブズブな関係になると流石に…って感じにはなってしまうとは思うんですけどその時はその時なんじゃないかな,って.あまりに適当ですけど

最後に

なんか 「おうお前何悟ったこと言ってるんだよ」 みたいな感じになっていますが, 深夜テンションなだけ ですすいません.多分僕はkosen10s界隈の中では意識低い部類に入ってると思うのでもっと語彙力の無い感じでなんかあったらお手伝い〜みたいな感じでやっていこうと思います.ありがとうございました