Tea break

ちょっとした息抜きに

OSXでRのパッケージtidyverseのインストールに詰まった

AdventCalendar 13日目! 人手足りないけどだんないよ精神でいくよ!!!

概要

MacR言語に入門する際に便利パッケージであるtidyverseのインストールに詰まったので対処法

環境

OS

ProductName:   Mac OS X
ProductVersion: 10.13.6

XCode

Xcode 9.3
Build version 9E145

R

R version 3.5.1 (2018-07-02) -- "Feather Spray"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin17.6.0 (64-bit)

エラーコード

肝心のエラーコード

>install.packages("tidyverse")
Installing package into ‘/usr/local/lib/R/3.5/site-library(as ‘lib’ is unspecified)
also installing the dependencies ‘rvest’, ‘xml2’

 URL 'https://cran.rstudio.com/src/contrib/rvest_0.3.2.tar.gz' を試しています 
Content type 'application/x-gzip' length 1597137 bytes (1.5 MB)
==================================================
downloaded 1.5 MB

 URL 'https://cran.rstudio.com/src/contrib/xml2_1.2.0.tar.gz' を試しています 
Content type 'application/x-gzip' length 251614 bytes (245 KB)
==================================================
downloaded 245 KB

 URL 'https://cran.rstudio.com/src/contrib/tidyverse_1.2.1.tar.gz' を試しています 
Content type 'application/x-gzip' length 61647 bytes (60 KB)
==================================================
downloaded 60 KB

* installing *source* package ‘xml2’ ...
**  パッケージ ‘xml2’ の解凍および MD5 サムの検証に成功しました 
Found pkg-config cflags and libs!
Using PKG_CFLAGS=-I/usr/include/libxml2
Using PKG_LIBS=-L/usr/lib -lxml2 -lz -lpthread -licucore -lm
------------------------- ANTICONF ERROR ---------------------------
Configuration failed because libxml-2.0 was not found. Try installing:
 * deb: libxml2-dev (Debian, Ubuntu, etc)
 * rpm: libxml2-devel (Fedora, CentOS, RHEL)
 * csw: libxml2_dev (Solaris)
If libxml-2.0 is already installed, check that 'pkg-config' is in your
PATH and PKG_CONFIG_PATH contains a libxml-2.0.pc file. If pkg-config
is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:
R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'
--------------------------------------------------------------------
ERROR: configuration failed for package ‘xml2’
* removing ‘/usr/local/lib/R/3.5/site-library/xml2’
Warning in install.packages :
  installation of package ‘xml2’ had non-zero exit status
ERROR: dependency ‘xml2’ is not available for package ‘rvest’
* removing ‘/usr/local/lib/R/3.5/site-library/rvest’
Warning in install.packages :
  installation of package ‘rvest’ had non-zero exit status
ERROR: dependencies ‘rvest’, ‘xml2’ are not available for package ‘tidyverse’
* removing ‘/usr/local/lib/R/3.5/site-library/tidyverse’
Warning in install.packages :
  installation of package ‘tidyverse’ had non-zero exit status

The downloaded source packages are in/private/var/folders/mf/h8zpddh14778rlv254chg2000000gs/T/RtmpO6u1wZ/downloaded_packages’

対処1

ANTICONF ERRORで「libxml2が入ってないよ」的なエラーが出たのでとりあえずインストール

$ brew install lib2xml

再実行するが、同じエラーが出る 何故???

対処2

調べていると、どうもXCode絡みのよう

$ xcode-select --install

入った!!!

> library(tidyverse)
─ Attaching packages ────────────── tidyverse 1.2.1 ─
✔ ggplot2 3.0.0     ✔ purrr   0.2.5
✔ tibble  1.4.2     ✔ dplyr   0.7.6
✔ tidyr   0.8.1     ✔ stringr 1.3.1
✔ readr   1.1.1     ✔ forcats 0.3.0
─ Conflicts ──────────────── tidyverse_conflicts() ─
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()

下のConflictsに関してはデフォルトっぽいのでそのままでOK

まとめ

そもそもXCodeコマンドラインツールが入ってなかった 学習始めの環境構築で詰まるとモチベーションをグッと持っていかれる、、、

pykakasiとMeCabを使ってモールス信号変換器を作る

CSGAdventCalendar 9日目 最近ラズパイを使ってモールス符号変換器を作ったので、備忘録。 f:id:wisteria30:20200325235655j:plain

概要

入力した文字列をモールス信号に変換、それをRaspberry PiのLEDを光らせて遊びました。 その際にpykakasiとMeCabを使ってアルゴリズムを組んだので備忘録です。 Githubリンクも載せておきます。 環境はMac, python3.5.2です。

モールス信号とは

文字や記号を表象する方法のひとつ。電信による伝達を目的として発明され、短点とその3倍の長さを持つ長点の組み合わせにより文字や記号を表す。ラテン文字を基礎とした国際モールス信号の他、和文モールス信号のように各国の文字に対応したモールス信号が考案されている。

みなさんご存知SOSのあれです。 日本語やアルファベットを「トン」「ツー」の二つの記号で表すことができます。 そんなモールス信号にもいくつかのルールがあります。

  1. 長点1つは短点3つ分の長さ
  2. 文字と文字の間には短点3つ分をあける
  3. 単語と単語の間には短点7つ分あける

この他にもSOSは例外的に連続して打つなどルールはありますが、 今回は上記の3つをルールを中心にしていきます。

やるべきこと

目標は日常的にSNSで書いている文章をモールス信号に変換できるようにすることです。 そのためにはやるべきことがいくつかあります。

  1. 漢字をひらがなにする(漢字は変換できない)
    1. pykakasiを使って変換する
  2. 自動的に単語で区切る(普通文章を書くときに単語では区切らない)
    1. MeCabを使って形態素解析で単語ごとに区切る
  3. 変換のための条件分岐をひたすら書く

pykakasi

pykakasiは日本語の漢字仮名交じり文を平仮名やローマ字綴りの文に変換するプログラムKAKASIPythonバージョンです。 pipでインストールしてください。

$ pip install six semidbm
$ pip install pykakasi

私は下記のように使いました。 setModeの引数で変換の形を決めることができます。

from pykakasi import kakasi
pic = "本日は晴天なり"
...
...
...
k = kakasi()
k.setMode("K", "H")  # カタカナをひらがなに
k.setMode("J", "H")  # 漢字をひらがなに
conv_k = k.getConverter()
pic = conv_k.do(pic)
print(pic) # ほんじつはせいてんなり

インストールや使い方は公式のリポジトリに載っています。

MeCab

MeCabオープンソース形態素解析エンジンです。 Mecabを選んだ理由は下記の二つです。

  1. 各種スクリプト言語バインディングされていること
  2. 他の形態素解析エンジンより高速であること

MeCabを使い、入力された文章を自動で単語に区切ります。 (正確にはMeCabは文章を形態素で区切るので、単語では区切りません。) インストールはMeCab本体とその辞書、そしてPythonバインディングしたライブラリを入れます。

$ brew install mecab #本体のインストール
$ brew install mecab-ipadic #辞書のインストール
$ pip install mecab-python3 #ライブラリのインストール

実際には下記のように使いました。

import MeCab
pic = "本日は晴天なり"
try:
    m = MeCab.Tagger("-Owakati")
    pic = m.parse(pic)
    pic = pic.strip()  # 先頭と末尾の空白を削除
    pic = pic.replace(' ', '_')  # 単語間に開けた空白を変換
except RuntimeError:
    pic = ""
print(pic) #本日_は_晴天_なり

こちらは「MeCab (和布蕪)とは」と「Python3からMeCabを使う」が参考になりました。

実際に使ってみる

上記のpykakasiとMeCabを使った変換器が下記のコードになります。 import morseはWeb上にあったモールス信号のコンバータを改変したものです。 コードはこちらにあります。

# coding:utf-8
from pykakasi import kakasi, wakati
import MeCab
import morse


def convert(pic):
    pic = ''.join(pic.split())  # 空白の削除

    # MeCabによる形態素解析
    try:
        m = MeCab.Tagger("-Owakati")
        pic = m.parse(pic)
        pic = pic.strip()  # 先頭と末尾の空白を削除
        pic = pic.replace(' ', '_')  # 単語間に開けた空白を変換
    except RuntimeError:
        pic = ""

    # pykakasiによるカタカナ・漢字のひらがなへの変換

    k = kakasi()
    k.setMode("K", "H")  # カタカナをひらがなに
    k.setMode("J", "H")  # 漢字をひらがなに
    conv_k = k.getConverter()
    pic = conv_k.do(pic)

    context = ""
    for c in pic:
        context += c + "~"
    context.strip()

    ans = ""
    for c in context:
        ans += morse.s2m(c)

    return ans

これを下記のように実行させます。

import call

txt = "本日は晴天なり"
txt = call.convert(txt)
print(txt)

すると下記のようにちゃんと変換できているのがわかります。 -・・ ・-・-・ --・-・ ・・ ・--・   -・・・   ・---・ ・- ・-・-- ・-・-・   ・-・ --・ 後は、文字列で条件分岐をして光らせるなり音を鳴らす等すれば、完成です。

RaspberryPi LED発光のサンプル

import RPi.GPIO as GPIO
import time
import call

# それぞれの処理の秒数
dot = 0.33333333  # トン
stick = dot*3  # ツー
space = dot*3  # 空白
between_sleep = dot/3 #「トン」と「ツー」の間の時間

txt = "本日は晴天なり"

# 光らせる
def light_up(sec):
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    time.sleep(sec)
    GPIO.cleanup()

# 光らせない(何もしない)
def light_down(sec):
    time.sleep(sec)
    pass

for c in call.convert(txt)
    if c == '・':
        light_up(dot) #1拍点灯
    if c == 'ー':
        light_up(stick) #3拍点灯
    if str[num] == ' ':
        light_down(space) #3拍消灯
    time.sleep(between_sleep)

まとめ

kakasiMeCabといった既存の変換器を使うことで簡単にモールス信号変換器を作ることができました。 pykakasiのwakatiを使えばMeCabは必要なかったのですが、勉強のために色々触ってみました。 テキスト処理はしっかりしてるはずなので次はこれをAmazon EchoのSkillと組んで遊びたいです。

Go API Server 環境構築

概要

開発の際に Go 言語の API Server をローカル開発環境で立ち上げる事があったので、備忘録です。

そもそも Go 言語とは

Google が開発しているマルチプラットフォームプログラミング言語です。 大抵のことはできるそうです。(docker も Go 言語で作られている) 詳しくは公式サイトを確認してください。

API Server とは

API = Apprication Programming Interface の略。 どのアプリーケーションでも共通で使える機能を提供する仕組みのことです。 API Server = http 等の Web 技術を用いて構築されたもので、API より意味合いは限定的になります。 また、データ通信は JSON で行うので、プログラミング言語に縛られません。

環境構築

前提

Homebrew が入っていない場合

下記をターミナルで実行して下さい。 詳しくはこちらで確認して下さい。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Go 言語のインストール

Go 言語をインストールしていきます。 下記をターミナルで実行して下さい。

brew install golang
# Goのバージョン確認
go version

以下を~/.bashrc に書き込む

お好みのエディターを使って ~/.bashrcを開き、下記の内容を追記して下さい。

export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$GOBIN:/usr/local/go/bin:${PATH}

上記では Go 言語の PATH を設定しています。

  • デフォルトの\$GOPATH は \$HOME/go になっていますが、明示しています。
  • \$GOPATH/bin を \$GOBIN として設定しておきます。
  • go get したツールは\$GOBIN に入るため、PATH を通しています。

また、デフォルトでは~/.bashrcは常時読み込みではないので、同様に~./bash_profileに下記を追記して下さい。

if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi

ここまでの内容を追記し終えたら、一度ターミナルを再起動しましょう。

補助ツールのインストール

Go API Server を立てる際に便利な補助ツールです。

dep の導入

依存パッケージ管理ツールです。 下記でインストールして下さい。

brew install dep

dep version でバージョンを確認して、 v0.4.1 以上を使うようにしてください。

ghq の導入

GitHubリポジトリを手軽にクローンできます。

brew install ghq
# ghqのディレクトリ設定
git config --global ghq.root $GOPATH/src

実際に使用する場合は下記のようにして、GitHub リポジトリをクローンして下さい。

# リポジトリをクローン
ghq get <リポジトリのURL>

nodemon

ファイルの変更があれば、自動で再起動をかけてくれる便利なツールです。 このツールは Node.js という JavaScript の環境からインストールして下さい。

npm i -g nodemon

もし Node.js が入っていなければ、これまでと同じように brew でインストールして下さい。

brew install node

make

mac であればデフォルトで入っているはずです。 念のためにwhich makeで確認して下さい。 もし上手くいかなければ、こちらが参考になります。

まとめ

以上で、Go API Server の環境構築が完了しました。 この記事では API Server を立ち上げることはしませんが、 実際に API Server を立ち上げるところまで書いていきたいと思います。

jsのMapオブジェクトをソートしようとした愚かな話

javascript何もわからん...

jsで連想配列を扱いたかったので、Mapオブジェクトを使用(なんとなくObject使うより良さそうだと思ってた)

その後なんだかんだでMapオブジェクトをソート、イテレート回して途中でbreakしたいみたいなことになった

forEachはbreakできないし、lambda使うほどでも無いし、mapのソートはArrayに一度戻して行うしでとても(とても)めんどくさかった

調べるとObjectならfind()で済むらしい

let map = new Map();
map.set('2-1', 8);
map.set('0-1', 12);
map.set('3-1', 4);

map = new Map([...map.entries()].sort((a, b) => a[1] < b[1] ? 1 : -1));

for(let i of map){
    if(i[1] < 5) break;
    console.log(i[0], i[1]);
}
> "0-1" 12
> "2-1" 8

【Dockerfile】Ubuntuにgolangをインストール

Dockerfile用メモ
aptから欲しいバージョンがなかったので公式からバイナリーでインストール
go.modを使用する想定

FROM ubuntu:18.04

RUN apt update && \
        apt install wget git gcc make -y

RUN wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz && \
        tar -C /usr/local -xzf go1.13.5.linux-amd64.tar.gz && \
        rm go1.13.5.linux-amd64.tar.gz

ENV PATH $PATH:/usr/local/go/bin

iPhoneとMacのiCloud連携を始めてから止めるまで

最初に

2年間ほど使ってきたiCloud連携を切る事にしたので、使い始めてから止めるようになるまでの流れを残します。

使い始めるきっかけ

私はスマホiPhone、パソコンはMacというAppleの民なのですが、同じくAppleの民である友人がiCloud連携でiPhoneからMacのコードや授業資料を見ているのを見て便利だなぁやりたいなぁと思ったのがきっかけです。 その後50Gのタイプで契約してiCloud連携を使い始めました。月額150円ぐらいなのも凄い。

使い始めてから

ドキュメントとデスクトップのディレクトリを共有できるのは良かったです。パソコンに入れてる授業資料やコードをスマホから見れるのは想像通り便利でした。

加えてメモ帳の同期も素晴らしかったです。元々メモはboostnoteをDropboxで同期して使っていたのですが、こちらに移行しました。

また、クリーンインストールした後に同期していたデータを自動で戻してくれたのは意外と助かりました。

疑惑が生まれ始める

最初に気になり始めたのは使用してから1年半ぐらいしてから、一度iCloud連携をMac側でオフにした時です。オフにした瞬間、同期していたデータが全て消えました。(消えますよとwarningが出るが...)これには思わず驚いてすぐオンに戻しました。

次に気になったのは同期しているデータを同期していないディレクトリに動かした時です。高々数メガのファイルを移動させるのに10分ほどかかって唖然としました。

決定的におかしくなる

それ以降もファイル操作に多少のイラつきを覚えながらも使っていると、次第にMac自体がかくつき始めました。 終いにはchromeが1日に2回以上落ちたり、他のアプリケーションが固まったり、日本語入力プログラムが応答不能になったり(これは自動変換を切るとマシになった)、しばらく操作しないと1分ほど固まって動かないなど最早使い物にならない状態になってしまいました。

おかしくなった原因

アクティビティモニターを見ると、birdというiCloud関連のプロセスが常時CPU稼働率の80%程度を占めていた。 これはiCloud同期をする際にファイルに不具合などがあるとおかしくなる事があるらしい

私が同期していたのはドキュメントとデスクトップのディレクトリだったが、これらにはそれぞれ、node_moduleなども入っているコード類、「とりあえず置いておくか」と放置しがちで貯まった重いファイルも込みの雑多なファイル類が入っていました。

端的に言えば同期が厄介なファイルや256GあるMacのストレージの大半のファイルを同期している状態でした。 これは私が悪いと言えばそうなんですが()

iCloud連携を止める

同期しているデータを別でバックアップして、iCloud連携を切ります。ついでに気になっていたのでクリーンインストールもします。50G契約も切ります。

今後はコードはGitHubから、授業資料はAirDropで送ってから見ることにします。

2年間使ってきた感想としてはiCloud連携をするのであれば適切なディレクトリ管理を行うか、Macのストレージよりも大きなストレージサイズを契約しましょうという感じです。

最後に

メモ帳は今後もiCloud連携で使います(タイトル詐欺)

追記

外付けHDDにバックアップを取ろうとしたが、3日かけてもバックアップできなかった(25Gぐらい) 連携切ると爆速になりました。