OmniAICreator/Qiita-1.07M huggingface dataset:
ドシロウトがGoogle Apps ScriptでサークルアプリBANDと連携してみた


## ０．初めに

私はエンジニアではないただのドシロウトです。とある運動サークルに所属して事務をやっています。

最近サークルにてLINEの姉妹アプリのサークル管理アプリBAND（無料）を利用したサークル運営に変更しようとしています。

BAND - グループコミュニケーションアプリ
https://band.us/home

試してみてBANDはすばらしいアプリでしたが、もう少し通知機能を強化しないと利用できないと感じました。そこで強化する方法を考え始めました。

## １．利用したもの

題名にもある通りBANDとGAS(Google Apps Script)を連携させる形にしました。私は初めてGASを使いましたがGASを利用した理由は以下です。やはり無料で学習コストが小さいことが大きいです。

* 無料でメールやWeb APIでの通知ができる
* 上限はあるが少人数のサークルであれば問題なし
* Webアプリケーションを作成できる
* トリガーで指定日時や繰り返し自動実行ができる
* サーバーレス
* JavaScriptの１種であり学習コストが低い

GASの上限は以下に書かれています。

Quotas for Google Services
https://developers.google.com/apps-script/guides/services/quotas

私の場合気になったのはメール一日100通制限くらいです。メールの通知は上限にかからないよう日70件程度に抑えました。

## ３．参考にしたサイト

なにせ初めてつくったので参考にしたサイトはやたら多いです。一覧は以下です。

BANDの予定をY!カレンダーに同期（インポート・表示）させる方法
https://anncierge.com/band-y/ 

毎朝、当日の予定をGoogleカレンダーから取得してチャットワークに送る
https://tonari-it.com/gas-calendar/ 

[GAS]スクリプトを自動制御する[トリガー]
http://emplos.jp/petit/2607.html 

Class UrlFetchApp(GAS)
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app 

Write Post(BAND)
https://developers.band.us/develop/guide/api/write_post 

GASでのメール送信についてまとめてみる
https://qiita.com/mistolteen/items/404c10657b1b27007a3c 

Google Apps Script(GAS)でのメール送信方法
https://qiita.com/matsuhandy/items/bbfa357db4e3e1e5c92a 

Class MailApp(GAS)
https://developers.google.com/apps-script/reference/mail/mail-app 

Google Apps Script（GAS）でWEBアプリケーションを開発してみる
http://befool.co.jp/blog/8823-scholar/gas-web-applicaton-intro/ 

Google Apps Script 事始め Webアプリ編
https://tech.actindi.net/2016/12/08/beginning-of-google-apps-script-webapp.html 

[GAS] Google Apps Script のHtmlServiceまとめ
http://dackdive.hateblo.jp/entry/2015/02/01/010540 

【容量制限】これは困った。GAS(Google Apps Script)の落とし穴
https://routecompass.net/gas-ana/ 

LINE Notify(LINE)
https://notify-bot.line.me/ja/ 

Google Apps ScriptからLINE NotifyでLINEにメッセージを送る
https://qiita.com/tadaken3/items/5f916a12587e42ece814 

LINEのグループにBOTが予定を呟くと意外と便利だった話
https://qiita.com/Yuki_BB3/items/457fdba9dcb523f1069d 

## ３．実際どうだったか

Qiitaの記事なのに外部サイトでスライド作っちゃいました。詳しくは以下をご覧ください。

BAND+GASでサークル運営してみる
http://slides.com/sigematu/band-gas/fullscreen

## ４．まとめ

私には初めてのGASだったので延べで120時間くらいかかったような気がします。ドシロウトで初めてなので個人的には超大変でした。

GASの便利さはよく分かったので今後も利用したいと思います。

以　上
vagrant up時のマウントフォルダのエラー


vagrant upすると、
以下のメッセージが表示された

```
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o dmode=777,fmode=777,uid=1000,gid=1000 vagrant /vagrant

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device
```



以下の記事を参考にさせて頂きました。
https://qiita.com/wakaba260/items/b5c87b7815b710f303a0

vagrant sshで仮想マシンに入り
以下のコマンドを実行。

```
$ sudo yum -y update kernel
$ sudo yum -y install kernel-devel kernel-headers dkms gcc gcc-c++
```

その後、仮想マシンを再起動すると共有フォルダは共有されてました。
PHP で Mysql の戻りが想定と違う

あるテーブル(table)の文字列(name)の中に、"AAA"と"BBB"の双方が含まれているレコードを探したい。

```php
  $sql = "SELECT name FROM table WHERE name LIKE ? AND name LIKE ?";
  $stmt = $pdo->prepare($sql);

  $key='%AAA%';
  $stmt->bindParam( 1, $key, PDO::PARAM_STR);
  $key='%BBB%';
  $stmt->bindParam( 2, $key, PDO::PARAM_STR);

  $stmt->execute();
  while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) {
    echo $row["name"];
    echo "<br>";
  }
```

これが想定した戻りにならない。 
WHERE 区の AND が OR になったような値を返す。(厳密にはちょっと違う)
で、色々調べていったら、

```php
  $key='%AAA%';
  $stmt->bindParam( 1, $key, PDO::PARAM_STR);
  $key2='%BBB%';
  $stmt->bindParam( 2, $key2, PDO::PARAM_STR);
```

と、異なる変数名(key2)にしたら想定通りの動きになった。

説明のために AAA と BBB をバラして書いたけど、本当は検索文字は Array に入っているなので、ループで回して処理したいのに、同じ変数だと想定した値が戻らない。

現象だけわかっていて、理由はよくわからないのですが、困ってます(笑)。

↓

コメントで情報をいただき、解決しました。

bindParam の第二パラメータは参照渡しなので、使いまわすと上書きされて、

```SQL
SELECT name FROM table WHERE name LIKE '%AAA%' AND name LIKE '%BBB%'
```

のつもりが 

```SQL
SELECT name FROM table WHERE name LIKE '%BBB%' AND name LIKE '%BBB%' 
```

と、なっていたようです。
ループ内で使うときは、bindParam の第二パラメータに Array とすることで、想定通りの動作なりました。

例えば、こんな感じ。

```php
  for( $i=0 ; $i < count( $keywords ) ; $i++ ) {
    $stmt->bindParam( $i, $keywords[$i], PDO::PARAM_STR);
  }
```
GitHubのプロジェクトにMakefileを入れよう

新規プロジェクトに参加した時にGitHubのREADME.mdやwikiに転がってる導入手順書みたいなのを読んでセットアップをすることが多いと思いますが、そういった秘伝のタレ的なコマンドをMakefileにしておくといいよねって独り言です。


```bash:Makefile
help:
	@echo 'clean-branches -- Remove merged branches'
	@echo 'setup-rails -- setup rails environment'
clean-branches:
	git branch --merged | grep -v '^\*' | grep -v master | xargs git branch -d
	git fetch --prune

setup-rails:
	cp -f ./config/database.yml.tmp ./config/database.yml ;
	cp -f ./config/secrets.yml.tmp  ./config/secrets.yml ;
	bundle install --path vendor/bundle
	bundle exec rake db:create
	bundle exec rake db:migrate
	bundle exec rake db:seed
```

ってのをプロジェクト直下に用意して、それぞれコマンド叩くだけ

```
$ make clean-branches
```

最初に入れておくと他の人も勝手にアップデートしてくれるのでオススメ
nginxのDockerイメージを使用して一瞬で静的なwebサイトを立ち上げる

# Overview
タイトルの通りです。
自分のための備忘として残します。
開発中にfileプロトコルで動かしていたらchromeさんに

```
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
```

と拒否られましたので。

# Environment
OS: macOS
使用イメージ: https://hub.docker.com/_/nginx/

# Actions

```
docker run --name mysite -p 8080:80 -v /fullpath/to/staticfiles:/usr/share/nginx/html:ro -d nginx
```
```:ro``` はRead Onlyの意味です。

これでひとまずはサーバーが立ち上がりますが、このままではCSSやJSがキャッシュされてしまい開発がしづらいので、nginxの設定ファイルを書き換えます。

* まずデフォルトの設定ファイルをローカルにコピー

```
docker cp mysite:/etc/nginx/nginx.conf .
```

* 元のファイル

```nginx:nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

* 変更後

```nginx:nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    add_header Cache-Control no-cache;
    sendfile off;
    etag off;
    if_modified_since off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

* 変更を加えた設定ファイルを使用し、コンテナを立ち上げる

```
docker run --name mysite -p 8080:80 -v /fullpath/to/staticfiles:/usr/share/nginx/html:ro -v `pwd`/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
```

今回はnginx.confを自体を書き換えてしまいましたが、```/etc/nginx/conf.d```に.confファイルを追加する方法でも良いと思います。
むしろその方が良いかもです。
Magick++で利用可能なフォント一覧を取得するには

# 背景

mruby-mrmagickでフォントを扱えるようにしてインスタ映えをめざそうかなぁ
とふと思いついた

# Magick++のAPIにはなさそう

Magick++のAPIを睨めっこしたが、三日たったがそれらしい記述を
みつけることが出来なかった。


# Wandじゃない、MagickCore APIでやるみたいな雰囲気

まぁ、

```
convert -list font|grep Font:
```

をsystem関数で呼び出すのでも十分実用的な気がしなくもなかったが、
GraphicsMagickでImageMgaickのv6/v7の両版でも動くような
コードが以下に出来上がった。

```cpp
#include <iostream>
#include <Magick++.h>
using namespace std;
using namespace Magick;
int
main (int argc, char **argv)
{
  InitializeMagick (*argv);
  long unsigned int num;

#if MagickLibVersion > 0x100000
  char **fontList = MagickLib::GetTypeList ("*", &num);
#else
#if MagickLibVersion < 0x700
  MagickCore::ExceptionInfo exception;
#else
  ExceptionInfo exception;
#endif
  char **fontList = GetTypeList ("*", &num, &exception);
#endif

  for (int i = 0; i < num; i++)
    {
      cout << fontList[i] << endl;
    }
  return 0;
}
~                               
```

以下の様にしてビルドできるハズ

```
clang++ -o fontTest fontTest.cpp `Magick++-config --cppflags --cxxflags --ldflags --libs`
```

g++でもビルドできます。

# メモ

GraphicsMagickはUbuntu16.04LTSのモノでしか試していないので、
最新のもだと対応が必要かも。

GraphicsMagickだとMagickLibの名前空間でCoreなAPIが
ラップされ、ImageMagick内の例外情報もC++側からは、
触らずに済むようになっている。
まぁ、これはこれで、C++で閉じてる感があり悪くない。

ImageMagickのv6だと、ExceptionInfoがMagickCoreの名前空間内に
定義されており、これを使う必要がある。

ImageMagickのv7が一番素直にCのAPIを直接叩けた。

# 関連投稿

- [Magick++を使ったソースをWindowsでビルドするには - Qiita](https://qiita.com/kjunichi/items/c4362f666f74c1636a75)

# 関連記事

- [ChocolateyでImageMagickをヘッダ、Libファイルとレガシーコマンドも一緒に入れるには](http://abrakatabura.hatenablog.com/entry/2018/02/21/071914)
- [Ubuntu16.04LTSでapt install imagemagick-devしてもImageMagickがリンクされない件](http://abrakatabura.hatenablog.com/entry/2018/03/02/071533)
- [mruby-mrmagickをGraphicsMagickに対応させた](http://abrakatabura.hatenablog.com/entry/2018/03/07/160617)
- [InkscapeをmacOSでビルドして動かせなかったが学べたこと](https://abrakatabura.hatenablog.com/entry/2018/05/12/215927)
GooglemapのAPIをjavascriptでサイト内に埋め込む

まずGooglemapのAPIのサイトから自分のAPIキーを取得します。
https://developers.google.com/maps/documentation/javascript/?hl=ja
英語が多いです。

次にコードを書きます。

```googlemap.html
<!DOCKTYPE html>
<head>
<meta charset="utf-8" name="viewport" content="width=300">
<style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            height: 500px;
            width: 50%;
        }
    </style>

</head>
<body>
 <div id="map"></div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8
        });
      }
    </script>
//グーグルマップのAPI登録から自分のキーを作る
//それを下のURLのところに貼る
<script src="https://maps.googleapis.com/maps/api/js?key="ここに自分のgooglemapのAPIキーを貼る"&callback=initMap"
    async defer></script>
    
</body>
</html>

```
以上で表示されるはずです。
github上にあるリモートのブランチを手元に持ってくる方法

github上にあるリモートのブランチを手元に持ってくる。
(リモートのブランチ名で新しいブランチを作成し、そのブランチにチェックアウトするコマンド。masterにcheckoutして行う。)

毎回調べているのでめも。

```
$ git checkout -b branch_name origin/branch_name
```

[参照](http://blog.inouetakuya.info/entry/20120826/1345979787)
Amazon RDS(MySQL)でutf8mb4を使いたい場合の設定

ちょいちょい忘れるのでメモ。

## パラメータグループで下記を設定
```
character_set_client:utf8mb4
character_set_connection:utf8mb4
character_set_database:utf8mb4
character_set_results:utf8mb4
character_set_server:utf8mb4
innodb_large_prefix:1
innodb_file_format:Barracuda
innodb_file_per_table:1
```

## 確認
DB再起動して`show variables like 'character_set%';`叩いて変わってればOK

## その他
上記設定後、character_set_databaseがlatin1になってしまう現象があったが、下記で解決。
`ALTER DATABASE dbname default character set utf8mb4;`
Pythonでメンバ変数(フィールド)に入れる手間を省く

メンバ変数が大量だったり、開発中に頻繁に変わったりすると `__init__` で入れ込む処理を書くのが面倒だったりする。
メンバ変数の定義を増やせば勝手に入れ込んでくれるようにしてみる。

注意

* メンバ変数が足りないかどうかの判定はしていない
* クラス変数の有無に依存している為、クラス変数を後から増やしたり減らしたりすると保持できるメンバ変数が変動する

```python
class MyClass:

	member_val_1 = None
	member_val_2 = None
	member_val_3 = None

	def __init__(self, mast_val, **params):
		"""
		初期化処理
		"""

		# メンバ変数に代入していく
		for key, val in params.items():
			if hasattr(self, key):
				self.__dict__[key] = val

		# それ以外の初期化処理
		print(mast_val)
		if 'other_val' in params.keys():
			print(params['other_val'])
```

```python
my_cls = MyClass('test', member_val_1=123, member_val_2='aaa', other_val='bbb')
```

サブクラスの場合はこんな感じで書ける。

```python
class SubClass(MyClass):

	member_val_4 = None
	member_val_5 = None

	def __init__(self, **params):
		super(SubClass, self).__init__(**params)
		# サブクラス用の初期化処理
```
AWS CloudWatchのイベントから複数のターゲット（Lambda）を設定する

例えば、ECSのタスクステータスの変化を取得してLambdaを起動する場合を例に、CloudFormationでの定義を確認すると。

```yaml
EventRuleMultipleTarget:
  Type: "AWS::Events::Rule"
  Properties:
    Name: multiple-target-event-rule
    EventPattern:
      source:
      - "aws.ecs"
      detail-type:
      - "ECS Task State Change"
      detail:
        clusterArn: !Sub ${ClusterArn}
    State: "ENABLED"
    Targets:
    - Arn: TargetLambda1.Arn
      Id: multiple-target-event-rule-1-id
    - Arn: TargetLambda2.Arn
      Id: multiple-target-event-rule-2-id
```

このように、 `Targets` が配列を取るようになっている。
呼び出しの対象となるLambdaのARNと、イベントのIDをそれぞれ定義することで、1つのイベントから複数のターゲットをフックすることができる。
なお、これはCloudWatchに限らずイベントの設定に汎用性があるものと思われる。
GitHub issue のテンプレートを作るJSを書いた

ここに置いてます。 [github-issue-templatize.user.js](https://gist.github.com/oieioi/bbc040f4d8a2c8116ed526580a54dfc5)

[Tampermonkey](https://tampermonkey.net/) でのみ動作確認した。

## 何を解決するか

- GitHub の issue 作成のページを決まった形式で書かせたい
- テンプレートを複数使い分けたい
    - GitHub の issue 作成はクエリパラメータでテンプレート化できる [参考ページ](https://help.github.com/articles/about-automation-for-issues-and-pull-requests-with-query-parameters/)
    - [こんな感じ](https://github.com/oieioi/oieioi.github.io/issues/new?title=%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB%E3%81%A7%E3%81%99%E3%82%88&body=%23%23%20%E8%83%8C%E6%99%AF%20%20%0A%0A-%20aiueo%0A%0A%23%23%20%E4%BD%95%E3%82%92%E3%82%84%E3%82%8B%E3%81%8B%0A%0A-%20hoge%0A%0A%23%23%20TODO%0A%0A-%20%5B%20%5D%20hogehgoe&labels=bug,invalid)


## 使い方

1. 任意のリポジトリの issue 作成ページにアクセス
2. タイトル、本文、ラベルを書く
3. 「Templatize」をクリック
4. 遷移先のURLをコピペする
5. 便利
Rails(Ruby)でBase64化された画像を取り回すときのSnippet

## エンコード

```rb
image = File.read(Rails.root.join('test', 'files', 'sample.jpg'))
b64_image = Base64.strict_encode64(image)
```

## デコード

```rb
bin = Base64.decode64(b64_image)
```

## Carrierwaveで保存

```rb
def image_from_base64(b64)
  bin = Base64.decode64(b64)
  file = Tempfile.new('img')
  file.binmode
  file << bin
  file.rewind

  self.image = file
end
```
XGBoost のインストールに関する問題

anacondaでインストールした Pythonの環境で、pipを使ってXGBoostをインストールする場合 `import xgboost` でエラーとなる。

`conda install` でGCCをインストールしておく必要があるようなので、下記のように実行しておく。

```
conda install libgcc
```
MAX32620FTHR# Development Platform

Digi-Keyから届くメールで気になった製品。

[MAX32620FTHR# Development Platform](https://www.digikey.jp/ja/product-highlight/m/maxim-integrated/max32620fthr-development-platform?utm_medium=email&utm_source=npa&utm_campaign=23070_NPA1803A&utm_content=supplier6image_JP_175-Maxim&utm_cid=8447059&WT.v_sub=8447059&WT.mc_id=em_NPA1803A.JP.Send&WT.z_email=23070_NPA1803A0I0DJP_supplier6image--175-Maxim&mkt_tok=eyJpIjoiTldRM05UWmxNRFpoTkdZMyIsInQiOiJXRmlQYmtkMW93eHBPZmFxRFFIc2FkUklqYTRoNXE4dDJ3dVczRWFZaU9OcENDeitsczEzbHVHZjJ0MnlGYlwvamxmcnBib3FReXJTM0tDcmtzcFowbTlpODBqRDlEZTBPam5CajQ3TEtHb3FBRkxjWW5nckMwNmJabFRvRkk4UU0ifQ%3D%3D)


Featuresを抜粋 (興味のある部分は太字とした)。

- Convenient development platform
    - **Feather wing compatible**
    - **Pmod-compatible sockets**
    - Supports SPI, UART, I2C, and GPIO
    - Integrated battery management
    - Single-cell Li+ charger
    - Fuel gauge
    - User interface peripherals
        - **Two RGB LEDs**
        - **Two pushbuttons**

- MAX32620 microcontroller
    - 96 MHz Arm Cortex-M4 microcontroller **with FPU**
    - 2048 KB Flash
    - 256 KB SRAM
    - Full-speed USB
    - SPI, I2C, UART, and 1-wire
    - **4-channel 10-bit ADC**
    - **49 dual voltage GPIO**
    - 3.9 mm x 4.1 mm, 81-bump WLP

AdafruitのFeather対応のWingが使えるとのこと。

開発環境としてはArduino IDEが使えそうか。
https://github.com/MaximIntegratedMicros/arduino-max326xx

価格は2600円程度。
https://www.digikey.jp/product-detail/ja/maxim-integrated/MAX32620FTHR-/MAX32620FTHR--ND/8259021

マルツから購入できるだろうか (すぐに買うというわけではないが）。
http://select.marutsu.co.jp/list/detail.php?id=526

### 備考

- 登場後、何年でdiscontinueになるだろうか
- Featherというフォームファクターを踏襲する限りは長期間(10年-20年)の入手性は高いだろうか
- RGB LEDによりLEDの色をソフトで変更可能なのだろう
- 似たような基盤を独自開発する場合と比べて、コストは安いだろう
    - What's the catch?

### 関連

- [Single Board Computer > UDOO Neo](https://qiita.com/7of9/items/045e72acedef61887404)
HTML5カスタムデータの属性にスネークケースでアクセスするように見せかける方法

Rails側のスネークケースとJavaScript側のローワーキャメルケースとの違いで置換や検索がスムーズにできなくて辛いときは、lodash の camelCase をかましてからアクセスします。

```js
import _ from "lodash"
dataset[_.camelCase("foo_bar")]) // dataset.fooBar と同じ
```

これで名前の二重脳内管理からも開放されます。

# おまけ

あと次のように vue で引数を渡すためにカスタムデータ属性をしかたなく利用している場合は、

```ruby
link_to("...", "#", "@click" => "func", data: {foo_bar: "xxx"})
```

このように直接引数を渡してfoo_barとして受け取ればそもそもカスタムデータ属性を使わなくてよくなります。

```ruby
link_to("...", "#", "@click" => "func('xxx')")
```
Project Euler 48「自身のべき乗(self powers)」

難易度の起伏が激しすぎやしませんか？

# Problem 48 「自身のべき乗(self powers)」
次の式は, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317 である.
では, 1^1 + 2^2 + 3^3 + ... + 1000^1000 の最後の10桁を求めよ.

```python
def hoge(num):
    return str(sum( n ** n for n in range(1, num+1) ))[-10:]

print(hoge(1000))
```
(data1 === data2)と(data1 != data2)の判定は、どちらが速いのか。

### どちらが速いのか。
```js
let flg = (data1 === data2);
```
```js
let flg = (data1 != data2);
```

### 結果
https://jsperf.com/equal-and-not

### 追加　型が違うと ===は速い。

### 追加　javaにある hashCodeを実装して文字列チェックすると速いのか。
```js
let fn={};
 fn.hashCode =(s)=>{
    var h=0;for(var i=0;i < s.length; i++) h = h * 31 + s.charCodeAt(i)|0;return h; 
  }
```
Railsで「Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)」と言われたときの対処方法

ローカル環境でrailsを使って開発していたら突如ブラウザにCan't connect to local MySQL server through socket '/tmp/mysql.sock' (38)の文字が現れすこし詰まったのでメモ代わりに。
今回もインターネットにお世話になりまくりましたありがとうございました。

## 結論
```
sudo rm -rf /tmp/mysql.sock.lock
```
したら直りました。


## 試したこと
まずはエラー文で検索。
[この記事](https://qiita.com/fujitora/items/d341c52706d1954cae28)を参考にしよう..と思ったところ、
一つ目のここ(`$ sudo mysql.server start`)で
`... ERROR! The server quit without updating PID file (/usr/local/var/mysql/macname.local.pid).`
と怒られた。

新しいエラー文を授かったので検索。
[この記事](https://qiita.com/yuki0208/items/1d5554d98e9ec76084bd)を参考に、/usr/local/var/mysql/を見に行ってみると確かにそんなものはなかった。

```
$ ls -la /usr/local/var/mysql/macname.local.pid
$ ls: /usr/local/var/mysql/macname.local.pid: No such file or directory
```

ので、作成して再度ls -laで作成されたことを確認。
その後記事の通り権限の付与などをした後に実行してもまたもや失敗したのでインターネットにすがっていると[こんな質問](https://teratail.com/questions/19778)を発見。
根本的な解決には至らなかったが、やり取りの中で直接エラーログを見ていくのが早そうだな〜とヒントをもらう。

で、
`$ sudo tail -n 100 /usr/local/var/mysql/macname.local.err`
してあげると
`[ERROR] Could not open unix socket lock file /tmp/mysql.sock.lock.`
の一文が。悪さをしていた原因がだいぶ絞られてきた。

またもやエラー文で調べると[こんな記事](http://morototo.hatenablog.com/entry/2017/07/29/103204)が。

なるほど。消せばいいらしい。
`$ sudo rm -rf /tmp/mysql.sock.lock`
からの
```
$ sudo mysql.server start
Starting MySQL
. SUCCESS!
```
からの

`rails s `
で確認。

無事解決しました。インターネットってすごい
AVFoundationやCoreLocationを利用したバイク用のスピードメーター兼簡易ドライブレコーダー

# ドラカメ

### 概要

オートバイを運転していてうっかり速度違反してしまうのをなるべく減らしたいので、危険速度を認識しやすくするための機器です。

使わなくなったiPhone 5sで使えれば良いと思い、画面の大きさの違う端末への対応はしていません。

![doracame.PNG](https://qiita-image-store.s3.amazonaws.com/0/87984/f676e101-aa5a-c99c-11ad-7ca2f6bb7f4b.png)

プロジェクトは[GitHub](https://github.com/kazz12211/drivecamera)に置いてありますので自由にお使いください。
開発過程や使用した様子は[椿工藝舎のブログ](https://tsubakicraft.wordpress.com)に日記のような形式で書いています。

### 主な機能（平成３０年３月６日の時点）

+ GPSを利用した走行速度の表示（スピードメーターの背景は50km/hで青、70km/hで紫、100km/hで赤、110km/h以上で赤の点滅）
+ 緯度・経度・高度・バッテリー残量・ストレージ空き容量の表示
+ Bluetoothマイコンへの速度送信（マイコン側はLEDの点灯・点滅で速度警告灯として振る舞います）
+ Bluetoothマイコンとの接続状態の表示
+ ビデオの品質は1280x720または1920x1080
+ 走行を始めると自動的に録画を開始する（時速10km/hが閾値）
+ Gを検知すると自動的に録画を開始する（Gセンサーの感度の調整は車載方法によっては調整が必要）
+ 音声録音のON/OFF
+ GPSロギングのON/OFF
+ 記録されたビデオの再生
+ 記録されたGPSログの地図への表示
+ AirDropなどを利用したビデオとGPSログの転送


### 開発環境
+ iOS 11.0+
+ Xcode 9.2
+ Swift 4.0
+ iPhone 5s (画面サイズは5s専用です)


### BLE接続するマイコンアプリケーション
Adafruit Bluefruit LE Microを使ったスピードディスプレイ。

 [Speedmeter](https://github.com/kazz12211/blespeedmeter)

### 開発上の課題

+ AVCaptureMovieFileOutputを使用した録画では、ビデオにタイムスタンプや速度をオーバーレイできないので、AVCaptureVideoDataOutputを使用したいところ。
+ 例えば、停車した際に自動で記録を停止する機能が欲しい。
+ GPSログはGoogleMapなどに取り込んで経路表示ができるフォーマットで書き出すのが良い。

### 実用上の課題

+ iPhone+防水型ケースはバイクの車載機器としては重いので走行時の振動の影響が小さくない。その為、防振対策を施さなければ綺麗なビデオを記録することができない。
+ 雨天時に給電しながら使用できるケースはほとんどなく浸水対策が困難。（少しの雨なら問題ない）
+ 駐車時にiPhoneの盗難に遭わないために、毎回取り外すのは面倒臭いし、完全に固定して容易に取り外せないようにすると取り外したい時に面倒臭い。
+ 給電しながら運用した場合の熱対策が難しい。
+ バイクの種類によっては搭載場所が確保しにくい。
How to Install VirtualBox 5.2 in the Ubuntu 18.04 LTS

# 1. Add source
```
# sudo vim /etc/apt/sources.list

...
...
...
### VirtualBox5.2.x.
deb http://download.virtualbox.org/virtualbox/debian bionic contrib
...
...
...
!wq
```

# 2. Add Keys
```
# wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
# wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
```

# 3. Install
```
# sudo apt-get update
# sudo apt-get install virtualbox-5.2
```

# 4. Download and Install [VirtualBox 5.2.8 Oracle VM VirtualBox Extension Pack](https://download.virtualbox.org/virtualbox/5.2.8/Oracle_VM_VirtualBox_Extension_Pack-5.2.8-121009.vbox-extpack)
はじめてのatom

久々に触ったら前より印象良かったので使おうかな。atomのことをメモしていこう

# tree side bar を隠す

>> https://flight-manual.atom.io/hacking-atom/sections/the-init-file/
> When Atom finishes loading, it will evaluate init.coffee in your %USERPROFILE%\.atom directory

> https://discuss.atom.io/t/hide-treeview-by-default/7718/40


```python
vim ~/.atom/init.coffee

以下追加

## tree隠す
# https://discuss.atom.io/t/hide-treeview-by-default/7718/40
# ->
workspaceView = atom.views.getView(atom.workspace)
workspaceView.classList.add('loading')

atom.packages.onDidActivateInitialPackages () ->
  workspaceView = atom.views.getView(atom.workspace)
  atom.commands.dispatch(workspaceView, 'tree-view:toggle')
  workspaceView.classList.remove('loading')
  # <-
```

# sublimeの ctrl + shift + l が見当たらない

みつけた

```
File > Keymap...
```

```
'atom-text-editor':
    'ctrl-shift-l': 'editor:split-selections-into-lines'
```

> https://stackoverflow.com/questions/25597327/selecting-multiple-lines-in-atom
Expo/CRNA+NativeBaseのIcon(Ionicons)使用時にエラー

エラー内容
-----

```
Device: (1:0) Error loading dependency: Error: Failed to install module 'native-base': Attempted to import missing module '@expo/vector-icons/Ionicons'
```

対応
----
最初に読み込んでおく

```
import { Font } from 'expo';
import { Ionicons } from '@expo/vector-icons'

async componentWillMount() {
  await Font.loadAsync(Ionicons.font);
}
```

参考
----
- https://github.com/GeekyAnts/NativeBase/issues/72#issuecomment-297906070
- https://docs.expo.io/versions/latest/guides/preloading-and-caching-assets.html
StreamRelay.jarに同梱している ZipStream.class と ArchiveStream.jar でアーカイバを操作する

`java.exe -jar ArchiveStream.jar`
⇔
`ArchiveStream.bat`

### ZipStream.class と ArchiveStream.jar

今回は、StreamRelay.jar ではなく、同梱している ZipStream.class と ArchiveStream.jar の話

- ZipStream.class; zipアーカイバを操作できる
- ArchiveStream.jar; zipアーカイバ以外を操作できる

### アーカイバ内部のファイルの一覧

`java.exe ZipStream list 『ZIPファイル』`
とか
`java.exe -jar ArchiveStream.jar 『タイプ』 list 『アーカイバ』`

という感じ。

アーカイバ内部のエンティティオブジェクトの名前を出力しているだけ。

ファイル名として不正なファイル「../../etc/passwdとかでも」でも、これは標準出力に出力しているので、エラーになることはないのが、他のアーカイバに比べての利点。

### アーカイバ内部のファイルの一覧(ver8.2以降)

ver8.2 以降、-v オプションを指定すると、ファイル名だけではなく、最終更新日時、データサイズ(可能なら圧縮前と圧縮後と圧縮率も)も出力するようにした。

`java.exe ZipStream list 『ZIPファイル』 -v`
とか
`java.exe -jar ArchiveStream.jar 『タイプ』 list 『アーカイバ』 -v`

という感じ。

### アーカイバ内部のファイルの一覧(ver8.2以降)(7z)

ver8.2で、[Apache-Commons Compress](http://commons.apache.org/proper/commons-compress/) を ver1.17, [XZ for Java](https://tukaani.org/xz/java.html) を ver1.8 にしたので、7z は、書き込みのみから、書き込みと一覧表示に対応した。

### アーカイブのタイプ

ArchiveStream.jar で対応しているタイプは以下

- cpio
- ar
- tar
- zip
- arj
- 7z
- lha

### アーカイバ内部のファイルの内容を出力

`java.exe ZipStream read 『ZIPファイル』 『ファイル名』`
とか
`java.exe -jar ArchiveStream.jar 『タイプ』 read 『アーカイバ』　『ファイル名』`

という感じ

『ファイル名』で指定されたエンティティ名の内容を標準出力に出力する

なので、ファイルにしたければ、↓な感じ

`java.exe ZipStream read 『ZIPファイル』 『ファイル名』 > 『保存ファイル名』`
とか
`java.exe -jar ArchiveStream.jar 『タイプ』 read 『アーカイバ』　『ファイル名』 > 『保存ファイル名』`

まぁ、リダイレクトしているだけだけどね。

### アーカイバへの保存

`java.exe ZipStream write 『ZIPファイル』 『ファイル名』 < 『入力ファイル名』`
とか
`java.exe -jar ArchiveStream.jar 『タイプ』 write 『アーカイバ』　『ファイル名』 < 『入力ファイル名』`

または、

`type 『入力ファイル名』 | java.exe ZipStream read 『ZIPファイル』 『ファイル名』`
とか
`type 『入力ファイル名』 | java.exe -jar ArchiveStream.jar 『タイプ』 read 『アーカイバ』　『ファイル名』`

な感じ。

既存のアーカイブファイルに追記はできないので、新規作成にする必要がある。

例えば、

`type phpinfo.php | java.exe ZipStream read test.zip ../../../../cgi-bin/bkdoor.php`
とかで面白い脆弱性試験ができるかもしれない。

### StreamRelay.jar と連携

アーカイブ内部のファイルの内容が、標準入力(write)とか標準出力(read)で取り出せるので、StreamRelay.jar と連携させることができるでしょう。

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
comment > 意図について記載する, if/for/whileの後の空白, 関数の後の空白(なし)

```txt:動作環境
C++ Builder XE4
```

### 擬似コード

```
while(!UDP受信(50msec).IsEmpty);

UDPコマンド送信;
UDP受信処理；
```

50msecごとに受信しているのは何をしているのか?

### 推測

コマンド送信の前に受信バッファ内をすべて読込むことで空にしている、という処理のようだ。

### コメント: 意図について記載する

以下のようにすると意図が分かる。

```
// 受信バッファのクリア
while(!UDP受信(50msec).IsEmpty);

UDPコマンド送信;
UDP受信処理；
```

意図のコメントはある方がいいと思うが、それ自体を書かないスタイルの人はいる。

さらに、`!`を使っているため、手違いで`!`を消してしまうと追跡不能な不具合に発展する。

### 失敗

上記のコードに別の不具合対策をするうちに、!IsEmpty()の論理をIsEmpty()の論理にする失敗をしていた。

その時点で、以下の間違った考えを持っていた。

- 間違い
    - 受信バッファが空の間はUDP受信を50msecごとにする
    - 受信バッファが入った時点で後の処理をする
- 正しい
    - 受信バッファを空にする
    - 受信バッファが空の状態で後の処理をする

前者はプログラムが「命令受信側」として使う実装で、後者はプログラムが「命令送信側」として使う実装である。
【Android】Androidの定期購読テストの更新期間が変更された

Androidで定期購読のプラン更新などのテストを行なう際、日をまたぐ必要がありましたが、どうやら最近変更されたようです。

・１週間：５分
・１ヶ月：５分
・３ヶ月：１０分
・６ヶ月：１５分
・１年：３０分

上記のように、商品を登録する際の期間で、分単位での更新が走るようになりました。
一応以下で告知はされていたらしいです。

■掲載先
https://android-developers.googleblog.com/2018/01/faster-renewals-for-test-subscriptions.html

Apple側の仕様とほぼおなじになりました。
６回更新されると定期購読が自動で解約されるようになったため、注意が必要です。
※現状、購入ダイアログが英語表記になってしまっているのは謎…（対応してほしい。。。

※追記：2018/04/11
↑ですが、ダイアログ・ストア共に現時点では日本語表記されるようになっていました！よかった！
#Quantopian Algorithm で order_target_percent

## order_target_percent
[order_target_percent](https://www.quantopian.com/help#api-order-target-percent "order_target_percent")は，[order_percent](https://qiita.com/shinseitaro/items/943cfafe00dd3841a79e "#Quantopian Algorithm で order_percent - Qiita")と同様，現在のポートフォリオ価値の〜％分注文する関数で，現在のポジションの評価額と現金の合計に対して，〜％注文するのですが，他の「order_target 〜〜 」 関数と同様，既にポジションを保有している場合は買い増し（売り増し）はしません．

## アルゴリズム例

```python
def initialize(context):
    context.security = sid(35902)
    schedule_function(rebalance, 
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_close(minutes = 1))

def rebalance(context, data):
    if data.can_trade(context.security):
            order_target_percent(context.security, 1)
```

## メモ

上記は，Phillip Morrisでシミュレーションしています．
取引開始日にPMを自己資金の100％で買い，売らずに保有する．というアルゴリズムです．

このシミュレーションを初期投資額１０００ドル，2017/1/1〜2017/12/31で回した結果，
1月4日に10株，10月13日に1株買っていました．

![Screenshot from 2018-03-06 11-38-20.png](https://qiita-image-store.s3.amazonaws.com/0/14019/d734c2cb-469a-9e08-614f-105246bb6d7e.png)


1月4日は最初の取引日と言うことでわかりますが，
10月13日の１株買い増しは一体なんでしょう？

それは，配当金です．
PMが１０月１２日に行ったPaymentの結果，自己資金に対して一株だけ，買う余裕が出来て１３日のクローズに買い増しをしていました．（[PMの配当履歴](https://www.nasdaq.com/symbol/pm/dividend-history "Philip Morris International Inc (PM) Dividend Date &amp; History - NASDAQ.com")）

こういう事も自動でやってくれるSimulationはとても便利です．


## 他のオーダー方法

[#Quantopian Algorithm で order](https://qiita.com/shinseitaro/items/4e88c0b05c3452a86fbc "#Quantopian Algorithm で order - Qiita")
[#Quantopian Algorithm で order_value](https://qiita.com/shinseitaro/items/16f0f12ad65f428c2f4b "#Quantopian Algorithm で order_value - Qiita")
[#Quantopian Algorithm で order_percent](https://qiita.com/shinseitaro/items/943cfafe00dd3841a79e "#Quantopian Algorithm で order_percent - Qiita")
[#Quantopian Algorithm で order_target](https://qiita.com/shinseitaro/items/f1ea0245bba1e7ccc82d "#Quantopian Algorithm で order_target - Qiita")
[#Quantopian Algorithm で order_target_value](https://qiita.com/shinseitaro/items/7f9b45ab6fd5149e7a1e)
gitのコミットメッセージのテンプレ

#記事を書いたきっかけ
gitのコミットメッセージを英語で書く際、いちいちそれっぽいものを検索して真似ていたのが面倒になったため、メモ用に。
あまり種類が多くても迷ってしまいそうなので、なるべくシンプルなものに絞ります。
頻繁に使うものを発見次第、随時アップデート予定。

#動詞
##fix （バグの修正）
| 例 | 意味 |
| ---- | ---- |
|  Fix A of (in) B  |  BのAを修正  |
|  Fix for A   |  Aに対する修正  |

##add （追加）
|  例  |  意味  |
| ---- | ---- |
|  Add A to B   |  AをBに追加  |
|  Add A for B  |  BのためにAを追加  |

##remove （除去）
|  例  |  意味  |
| ---- | ---- |
|  Remove A from B  |  BからAを除去  |
|  Remove A in B    |  Bの中のAを除去  |
|  Remove unused A  |  不必要なAを除去  |

##update （バグ以外の修正、拡張）
|  例  |  意味  |
| ---- | ---- |
|  Update A for B  |  Bに対してAをアップデート  |

##make （〜にする）
|  例  |  意味  |
| ---- | ---- |
|  Make use A       |  Aを使うようにする  |
|  Make it A 比較級  |  Aをより○○にする  |
|  Make sure to A   |  必ずAするようにする  |

#move （移動）
|  例  |  意味  |
| ---- | ---- |
|  Move A from (in) B  |  BからAを移動させる  |
|  Move A to B    |  AをBへ移動させる  |


##change （変更）
|  例  |  意味  |
| ---- | ---- |
|  Change A to B   |  AをBに変更する  |
|  Change A in (for) B  |  BのAを変更する  |

##rename (リネーム)
|  例  |  意味  |
| ---- | ---- |
|  Rename A to B   |  AをBにリネームする  |






#参考URL
GitHubで使われている実用英語コメント集
https://qiita.com/shikichee/items/a5f922a3ef3aa58a1839
Gitのコミットメッセージの書き方
https://qiita.com/itosho/items/9565c6ad2ffc24c09364
JSの動的の問題とは何？

最近、バグがあった、クリックイベントを利用できません。問題はプロジェクトのHTMLが動的なので、クリックイベントを利用できません。この問題わすれないようにメモします。

###どうすれば？
問題例えば

``` .js
$('#pg_menu_content').empty();
$div = $('<div data-role="fieldcontain"/>');
$("<input type='button' value='Dynamic Button' id='btn_a' />").appendTo($div.clone()).appendTo('#pg_menu_content');
```

上記のコードはHTMLの動的を作られます。

次、クリックイベントをかけます。

```.js
$("#btn_a").click(function(){
  alert ('button clicked');
});
```
その場合はクリックイベントをかけできません。

####問題とは何？

```#btn_a ``` をかけますね。ですけど、その場合は、```#btn_a ```はまだありませんので、クリックイベントをかけできません。

####問題解決
```.js
$(document).on("click", "#btn_a", function(){
  alert ('button clicked');
});
```
または、

```.js
$('#pg_menu_content').on('click', '#btn_a', function(){
    console.log(this.value);
});
```
上記のようなを対応いたします。

論理は
```#pg_menu_content``` があったら、セレクタというOnをかけます。いつ```#pg_menu_content```をかけます。その場合はjQueryでチェックして、```#btn_a```にマッピングするか。
UTCをJSTにする方法

### Excel

```
2018-02-27 15:03:48.000000 UTC
```

という文字列がA1に入ってるとしたらこう。

```
=DATEVALUE(MID(A1,1,10))+TIMEVALUE(MID(A1,12,8))+TIME(9,0,0)
```

### Rails

ほんとはJSTだったのにUTCのタイムゾーンがついてしまってる日時をタイムゾーンだけ変更するならこう(実行環境がJSTの前提)

```
d = Time.parse('2018-03-06 11:00:00 +00:00')
Time.zone.local_to_utc(d).in_time_zone #=> Tue, 06 Mar 2018 11:00:00 JST +09:00
```

UTCだと思ってたのは錯覚で、実はJSTだったというときも大丈夫。

```
d = Time.parse('2018-03-06 11:00:00 +09:00')
Time.zone.local_to_utc(d).in_time_zone #=> Tue, 06 Mar 2018 11:00:00 JST +09:00
```

- https://github.com/rails/rails/blob/v5.1.5/activesupport/lib/active_support/values/time_zone.rb#L491
- https://github.com/tzinfo/tzinfo/blob/v1.2.5/lib/tzinfo/timezone.rb#L463
webpackerを使ったrailsアプリを実行するとき、TypeError: environment.plugins.set is not a functionというエラーが出る

# 環境
* Rails 5.1.5
* webpacker 3.3.0

# 現象
```
Compilation failed:
remote:        /tmp/build_074ca0ee678491d6f72035c60cc5f616/config/webpack/environment.js:5
remote:        environment.plugins.set('Provide',
remote:        ^
remote:        TypeError: environment.plugins.set is not a function
remote:        at Object.<anonymous> (/tmp/build_074ca0ee678491d6f72035c60cc5f616/config/webpack/environment.js:5:21)
remote:        at Module._compile (module.js:643:30)
```

# 対策
`set`ではなく`append`か`prepend`を使う。webpacker 3.3.0で`set`がremoveされたため。

## 例
### Before
```config/webpack/environment.js
environment.plugins.set('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
)
```
### After
```config/webpack/environment.js
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
)
```

# 参考
https://github.com/rails/webpacker/issues/1318 https://github.com/rails/webpacker/blob/master/CHANGELOG.md#330---2018-03-03
http://more-caffeine.hatenablog.com/entry/2018/03/05/142450
https://stackoverflow.com/questions/49107725/i-got-webpacker-error-when-running-the-rails-app-typeerror-environment-plugin
Rails5でrails で google認証ができない「Not found. Authentication passthru.」

Qiita初投稿、書き方これでいいのかな？

#omniauth-google-oauth2 で認証させる
こちらの記事を参考に
[爆速ッ!! gem omniauth-google-oauth2 で認証させる](https://qiita.com/bino98/items/596b5cffeca7c104bd90)

>##[omniauth_callbacks_controller.rbを作成](https://qiita.com/bino98/items/596b5cffeca7c104bd90#omniauth_callbacks_controllerrb%E3%82%92%E4%BD%9C%E6%88%90)
>
>app/controllers/usersディレクトリを作成して、omniauth_callbacks_controller.rbというコントローラーを作成します。
>

のところまで作成しました。

>##[サーバ起動](https://qiita.com/bino98/items/596b5cffeca7c104bd90#%E3%82%B5%E3%83%BC%E3%83%90%E8%B5%B7%E5%8B%95)
>```
>$ rails s
>```
>で、サーバを起動し、
>http://localhost:3000/home/index にアクセスすると...
>

この記事ではGoogleのログイン画面へリダイレクトされているようですが

#実際にやってみると
ブラウザに
![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/241331/707dfd5b-fa29-26a3-e8bc-6c092bfdf7eb.png)

とだけ表示されました。

#原因
```erb:app/controllers/views/home.html.erb
<%= link_to 'Signin with Google', user_omniauth_authorize_path(:google) %>
```
このままだとバージョンの違いのせいかエラーが出ました。

```erb
undefined method `user_omniauth_authorize_path' for #<#<Class:0x0000000cf98330>:0x0000000cf92660>
Did you mean?  user_google_omniauth_authorize_path
```
ここをたぶんこうだろうと修正した結果が上の状況です。

```erb:app/controllers/views/home.html.erb（間違い）
<%= link_to 'Signin with Google', user_google_omniauth_authorize_path(:google) %>
```

引数要らなかったみたいですね。

```erb:app/controllers/views/home.html.erb（正解？）
<%= link_to 'Signin with Google', user_google_omniauth_authorize_path %>
```

![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/241331/81177f37-9fb1-5c92-a203-4b7bfb114b3c.png)

できました
【ポテチ】iOS 関連概要まとめ #48

# はじめに
本記事は、potatotips #48 で行われた発表の中から、iOS関連の一部概要を紹介するとともに、まとめたものです。詳しい内容はイベントページの[プレゼン資料](https://potatotips.connpass.com/event/77702/presentation/)をご覧ください。

# Metal Accelerated かどうかを調べる方法
shu223 氏による発表

UIKit を含む多くのフレームワークが Metal を利用していることが公式発表資料等からわかっているが、実際にどの処理が Metal を利用しているかなど公式の**詳細情報が公開されていない**のが現実です。
これでは、低レイヤに踏み込んで自前実装することを検討する場合などに明確な判断を行うことができません。
そこで shu223 氏は**Instruments の System Trace**を利用した判別方法を提案しています。
[プレゼン資料](https://speakerdeck.com/shu223/metal-acceleratedkadoukawodiao-berufang-fa-anatafalseapurifalsedokodemetalgaan-yue-siteirufalseka-number-potatotips)

# iOSなフレームワーク Viper のススメ
hirothings 氏による発表

iOS 向けソフトウェアの開発現場から生まれたフレームワーク **Viper** は、**単一責任の原則**を元に作られており、各レイヤーは **Protocol にのみ依存**しています。
Viper のレイヤー :
- View
- Interaction
- Presenter
- Entity
- Router
ちなみに、 Viper は、上記レイヤーの頭文字から名付けられました。
先程述べたように、単一責任の原則を元に作られているため、各レイヤーは **Protocol で繋がって**おり、別レイヤーの詳細な実装を知ることはありません。
iOS を意識して作り出されたフレームワークなこともあり、 iOS アプリの開発には特に適しているようです。また、 Protocol で各レイヤーが繋がっているため、テストが書きやすいという利点もあります。
[プレゼン資料](https://speakerdeck.com/hirothings/iosnahuremuwakuviperfalsesusume)

# アプリの翻訳管理を楽にする
kosakos 氏による発表

iOS アプリを多言語に対応させる場合、 `NSLocalizedString` を利用する方法がありますが、冗長的なコードになりがちで、命名のめんどくささ、 typo によるミスなど様々なマイナス点が存在します。この問題を解消するライブラリも存在するが、　kosakos 氏 は Google Spreadsheet を利用した方法を提案しています。
仕組みとしては、 spreadsheet に書かれた翻訳データを Google Apps Script で spreadsheet からアプリで使用できるソースファイルに変換、各種アプリと同期して適応させるというものです。
[Qiita 詳細記事](https://qiita.com/aki/items/2e1e767af8993964151e)
[プレゼン資料](https://speakerdeck.com/kosako/apurifalsefan-yi-guan-li-wole-nisuru)
Raspberry Pi 3のPure Data Vanillaをコマンドラインから起動、終了する

# 1. 概要

タイトルのとおりです。

# 2. 環境、使用機器
* Raspberry Pi 3 (Rasbpian Stretch
* Pure Data Vanilla (pd-0.47.1)

# 3. 参考サイト
1. [Raspberry Pi エフェクター(2) Puredataで作成したプロジェクト(.pd)をコマンドプロンプトから実行する - ElectroBlog](http://www.electroblog.jp/entry/2017/09/17/232317)
    * コマンドラインからの実行方法が載っています。
2. [Running Pd on a &#8220;headless&#8221; Raspberry Pi | Guitar Extended](https://guitarextended.wordpress.com/2012/08/28/running-pd-on-a-headless-raspberry-pi/)
    * コマンドラインからの終了方法が載っています。
3. [Raspberry Piで音遊び！ | Device Plus - デバプラ](http://deviceplus.jp/hobby/raspberrypi_entry_012/)
    * コマンドラインからの音量変更方法が載っています
4. [alsamixerが起動しない件と解決法 - 有職故実](http://d.hatena.ne.jp/moerrari/touch/20111203)
    * alsamixerが実行できない場合の解決策が載っています。

# 4. 方法

## 4.1 起動
[参考サイト1 Raspberry Pi エフェクター(2) Puredataで作成したプロジェクト(.pd)をコマンドプロンプトから実行する - ElectroBlog](http://www.electroblog.jp/entry/2017/09/17/232317)に沿って以下のコマンドでPure Dataを起動します。


```:実行コマンド
pd -nogui /home/pi/test.pd &
```


```:結果
[1] 3949
```

`[1]`の後にでる数字は毎回異なります。

## 4.2 終了

[参考サイト2 Running Pd on a &#8220;headless&#8221; Raspberry Pi | Guitar Extended](https://guitarextended.wordpress.com/2012/08/28/running-pd-on-a-headless-raspberry-pi/)に沿って以下のコマンドで終了します。

```:終了コマンド
sudo killall pd
```

```:実行結果
[1]+  Terminated              pd -nogui /home/pd/test.pd
```

## 4.3 コマンドラインからの音量変更方法

[参考サイト3 Raspberry Piで音遊び！ | Device Plus - デバプラ](http://deviceplus.jp/hobby/raspberrypi_entry_012/)に沿って以下のコマンドを入力します。

```:コマンド
alsamixer
```
以下の画面が表示されて上下キーで音量を調整できてEscで終了できる。
<img width="682" alt="スクリーンショット 2018-03-06 10.39.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/94069/a34395b2-2a2a-ed68-bd7e-dcf0264252cf.png">

### うまくいかないとき

`alsamixier`を実行したときに以下のようなメッセージが出る場合があります。

```:メッセージ
ミキサーを開けません: そのようなファイルやディレクトリはありません
```

[参考サイト4 alsamixerが起動しない件と解決法 - 有職故実](http://d.hatena.ne.jp/moerrari/touch/20111203)に沿って以下のようにサウンドカードの番号を指定するオプションを付けてみるとうまくいきました。

```:うまく行った方法
alsamixer -c 0
```
Rails の Virtual Attributes と Nested Attributes の組み合わせでハマった話

解決までに時間がかかったので備忘録として残す。
以下のようなモデルで登録／更新処理をしたときに User モデルの `before_validation` が呼ばれない事があって、原因がわからずハマった。

```ruby:app/models/team.rb
class Team < ApplicationRecord
  has_many :users

  accepts_nested_attributes_for :users, allow_destroy: true
end
```

```ruby:app/models/user.rb
class User < ApplicationRecord
  belongs_to :team

  attr_writer :first_name, :last_name

  before_validation :set_name

  private

  def set_name
    self.name = "#{@last_name} #{@first_name}"
  end
end
```

ちなみにコントローラーの実装は以下のような感じ。

```ruby:app/controllers/teams_controller.rb
class TeamsController < ApplicationController
  # ...

  def create
    @team = Team.new(team_params)

    return render(:new) if @team.invalid?

    @team.save!
  end

  def update
    @team = Team.find(params[:id])
    @team.attributes = team_params

    return render(:edit) if @team.invalid?

    @team.save!
  end

  private

  def team_params
    params
      .require(:team)
      .permit(:name, :logo, users_attributes: [:id, :_destroy, :first_name, :last_name, :gender, :birthday])
  end
end
```

結論としては、Virtual Attributes の変更はモデルの `changed?` で検知ができないため、Virtual Attributes のみ更新した時に `changed? == false` となってバリデーションが実行されないことが原因。
以下のように `validates_associated` を親モデルに追加すると指定した子モデルで常にバリデーションが実行される。

```ruby:app/models/team.rb
class Team < ApplicationRecord
  has_many :users

  accepts_nested_attributes_for :users, allow_destroy: true

  # 追加
  validates_associated :users
end
```
Python3: A4 の PDF をマージして A3 にする

A4 のファイルを左右に並べて A3 にします。

```py:pdf_merge.py
#! /usr/bin/python
#
#	pdf_merge.py
#
#					   Jan/31/2023
#
import  sys
import  PyPDF2
from PyPDF2 import Transformation
#
# ------------------------------------------------------------------
def show_size_proc(page_obj_in):
	print(page_obj_in.artbox.lower_left)
	print(page_obj_in.artbox.lower_right)
	print(page_obj_in.artbox.upper_left)
	print(page_obj_in.artbox.upper_right)
# ------------------------------------------------------------------
def pdf_merge_proc(pdf_reader1,pdf_reader2):
	page_obj_a = pdf_reader1.pages[0]
	page_obj_b = pdf_reader2.pages[0]

	show_size_proc(page_obj_a)

	page_obj_out = PyPDF2.PageObject.create_blank_page(width=1190, height=842)
	page_obj_out_bb = PyPDF2.PageObject.create_blank_page(width=1190, height=842)

	page_obj_out.merge_page(page_obj_a)

	op = Transformation().translate(tx=595, ty=0)
	page_obj_out_bb.merge_page(page_obj_b)
	page_obj_out_bb.add_transformation(op)
	page_obj_out.merge_page(page_obj_out_bb) 
#
	show_size_proc(page_obj_out)
#
	pdf_writer = PyPDF2.PdfWriter()
	pdf_writer.add_page(page_obj_out)
#
	return pdf_writer
# ------------------------------------------------------------------
sys.stderr.write ("*** 開始 ***\n")
sys.stderr.write("PyPDF2.__version__ = %s\n" % PyPDF2.__version__)
pdf_in_a = sys.argv[1]
pdf_in_b = sys.argv[2]
pdf_out = sys.argv[3]
#
pdf_file1 = open(pdf_in_a, 'rb')
pdf_file2 = open(pdf_in_b, 'rb')
pdf_reader1 = PyPDF2.PdfReader(pdf_file1)
pdf_reader2 = PyPDF2.PdfReader(pdf_file2)
#
pdf_writer = pdf_merge_proc(pdf_reader1,pdf_reader2)
#
pdf_output_file = open(pdf_out, 'wb')
pdf_writer.write(pdf_output_file)
#
pdf_file1.close()
pdf_file2.close()
pdf_output_file.close()
#
sys.stderr.write ("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行コマンド
入力 in01.pdf (A4) in02.pdf (A4)
出力　out01.pdf (A3)

```bash
./pdf_merge.py in01.pdf in02.pdf out01.pdf
```

実行結果

```text
$ ./pdf_merge.py in01.pdf in02.pdf out01.pdf
*** 開始 ***
PyPDF2.__version__ = 3.0.1
(0, 0)
(595.2756, 0)
(0, 841.8898)
(595.2756, 841.8898)
(0, 0)
(1190, 0)
(0, 842)
(1190, 842)
*** 終了 ***
```


次のバージョンで確認しました。

```text
$ python --version
Python 3.10.7
```

```text
>>> import  PyPDF2
>>> PyPDF2.__version__
'3.0.1'
```
カメラ行列からFoV(視野角)や焦点距離を求める

どうしても忘れてしまうカメラ行列からFoVや焦点距離を求める方法のメモ

# カメラ行列の定義をおさらい

```math
K = \left[
  \begin{array}{rrr}
    f_x & 0 & c_x \\
    0 & f_y & c_y \\
    0 & 0 & 1
  \end{array}
\right]
```
* 便宜上、px単位で行列が得られたものとします。実際は任意の単位系です。

$ f_x, f_y $ は焦点距離[px]です。
$ c_x, c_y $ は主点[px]で通常画面の中心です。
### 以下の式に登場する変数の説明
$ W, H $ は画像の幅・高さ[px]です。
$ w, h $ はセンサーの幅・高さ[mm]です。
※センサーの幅・高さはご使用のカメラのカタログ等を確認してください。

## FoV(視野角)を求める
$ fov_x = 2\arctan\frac{w}{2f} $
$ fov_y = 2\arctan\frac{h}{2f} $
$ fov_d = 2\arctan\frac{\sqrt{w^2 + h^2}}{f} $
$ f $ は焦点距離[mm]です。
$ fov_x, fov_y, fov_d $ は水平・垂直・対角の視野角[ラジアン]です。

## 焦点距離[ピクセル]を求める
$ f = \frac{f_x}{W} $
$ f = \frac{f_y}{H} $

## 焦点距離[mm]を求める
$ f = \frac{f_x w}{W} $
$ f = \frac{f_y h}{H} $
キーボードでフランス語を打ちたい

# キーボード設定を変更(追加)

オススメのフランス語キーボードは，カナダのフランス語キーボード
フランスのフランス語キーボードだと，アルファベットの配置が変わってしまい英語のキーボードに慣れている人には使いづらいが，カナダのフランス語キーボードであれば，すでに慣れている英語のキーボード配列と同じ

## Mac の場合[^1]

[システム環境設定]、次に[言語とテキスト]または[キーボード]を開き、[入力ソース]で[Canadian French]を選択．
[キーボードビューア]を利用して，画面上にキーボードを表示すると便利．
***
# 設定を加えず，`option` キーを利用してフランス語を打つ場合  

é は `option` + `e` の後に `e`
è は `option` + `_` の後に `e` 
à は `option` + `_` の後に `a`
ù は `option` + `_` の後に `u`
â は `option` + `i` の後に `a` ( î，û，ê，ô は，`a` の代わりにそれぞれ `i`，`u`，`e`，`o` )
ï は `option` + `u` の後に `i` ( ü，ë は，`i` の代わりにそれぞれ `u`，`e` )
また，
ç は `option` + `c`
œ は `option` + `q`  
***
フランス語の勉強を始める方のお役に立てたら幸いです．
***
#### 参考文献
1) 佐藤 康『[フランス語のしくみ](http://amzn.to/2FuHdtA)』　白水社、2015年、pp.144-145。
[^1]: Windows での説明も『[フランス語のしくみ](http://amzn.to/2FuHdtA)』pp.144-145 でされています．
Golandでコード保存時に自動でgo fmtやgometalinterを効かせる様に設定する際のメモ

自動化できることはバンバン自動化してしまおう[(参考)](https://qiita.com/Sekky0905/items/095b45c46a80e933509c)ということで、Golandで「command + s」すると、自動で `go fmt` とかをしてくれる様にする。

以下の流れで設定できる。

Goland > Preferences > Tools > File Watchers > 「+」ボタン > `go fmt` や `gometalinter` などを追加(参考画像1を参照) > Apply(参考画像2を参照) > OK


参考画像1
![File_Watchers.png](https://qiita-image-store.s3.amazonaws.com/0/145611/a9567857-0877-a55b-c61c-07f3403a7062.png)

参考画像2
![completed.png](https://qiita-image-store.s3.amazonaws.com/0/145611/93dafd51-e345-4eff-1117-0b3e6ea66987.png)

これで、「command + s」すると、自動で `go fmt` とかをしてくれる様になる。
Project Euler 47「異なる素因数」

クッソ遅い。死ぬほど遅い。
20分強かかります。。。

# Problem 47 「異なる素因数」
それぞれ2つの異なる素因数を持つ連続する2つの数が最初に現れるのは:

14 = 2 × 7
15 = 3 × 5

それぞれ3つの異なる素因数を持つ連続する3つの数が最初に現れるのは:

644 = 2^2 × 7 × 23
645 = 3 × 5 × 43
646 = 2 × 17 × 19

最初に現れるそれぞれ4つの異なる素因数を持つ連続する4つの数を求めよ. その最初の数はいくつか?

```python
from itertools import count

def hoge(target):
    cnt = 0
    for n in count(1):
        if not is_prime(n) and is_four_prime_factors(n, target):
            cnt += 1
            if cnt == target: return n - (target - 1)
        else:
            cnt = 0

def is_four_prime_factors(n, target):
    primes = set()
    for m in get_prime(n):
        if n == 1 or len(primes) > target: break
        while True:
            if n % m == 0:
                primes.add(m)
                n = n / m
            else:
                break
    return True if len(primes) == target else False

def get_prime(n):
    yield 2
    for m in range(3, n // 2 +1):
        if is_prime(m): yield m

def is_prime(n):
    if n < 2: return False
    if n == 2: return True
    if n % 2 == 0: return False
    return all(n % i != 0 for i in range(3, int(n ** 0.5) + 1, 2))

print(hoge(4))
```

どうやったら早くなるんや。。。
Raspberry Pi 3のPure Data VanillaでOSC信号を受信する

# 1. 概要

前回、Raspberry Pi 3にPure Data Vanillaをインストールしました。

* [Raspberry Pi 3(Raspbian Stretch)にPure Dataをインストールする - Qiita](https://qiita.com/yuji_miyano/items/35144ebee1719ef8a07e)

これを使ってOSCで信号を受け取ろうとしましたが、ExternalのoscxがRaspberry Pi版のPure Data Vanillaでは使えなかったので別の方法を探ったメモです。OSCParseオブジェクトがVanillaに含まれていますが、バグがあるようなのでフォーラムへの書き込みを見ながらOSCの受信ができるようにしました。

<img width="674" alt="スクリーンショット 2018-03-06 10.00.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/94069/951cf97f-69d0-15da-fa55-31c6421aece8.png">

# 2. 環境、使用機器

* Raspberry Pi 3 (Rasbpian Stretch
* Pure Data Vanilla (pd-0.47.1)

# 3. 参考サイト

1. [|Pure Data 0.46.0 ||:--||         &mdash; ||         Pd Community Site |](https://puredata.info/downloads/pure-data/releases/0.46.0/#refoscparse)
  * OSCのオブジェクトが入っている情報が書かれていた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94069/9e140cb5-2964-a83c-0ca7-04defe68eccb.png)

2. [netsend | PURE DATA forum~](https://forum.pdpatchrepo.info/topic/11226/netsend/7)
  * OSCParseのバグ？と解決方法についての報告。今回はこの書き込みを参考にした。

# 4. パッチ

[参考サイト2 netsend | PURE DATA forum~](https://forum.pdpatchrepo.info/topic/11226/netsend/7)にあったパッチをダウンロードしたら動いたので、そちらをベースに作成したのが以下のパッチ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94069/1951fe55-f155-57db-8b9d-4ec7eab22520.png)
Spring boot スケジュール機能

# はじめに
お仕事でSpringbootを使って開発を行う案件があったのですがその際に
cronetabで定期的にbatキックしてメールを送信したいと言われたので、それってSpringでできますよね、、、

# Spring bootのスケジュール機能とは
Scheduledアノテーションを使うと、スケジュールされたタイミングでメソッドを実行することができます。 周期実行を行いたいときなどに使用できます。


# ソースコード
```
@Scheduled(cron = "0 0 0 * * *", zone = "Asia/Tokyo")
    public void checkbatch(){
    .....
    }
```
- cron= "秒 分 時 日 月 年"
という単位でづので上記のコードだと毎日0時0分0秒に実行されます。
- zone = "Asia/Tokyo"
日本時間を示しています。

# 最後に
定期実行といえばcrontabをすぐに使うのではなく変化を恐れずに、より便利な方法を使っていけるといいですね。
ソフトウェア品質向上セミナーを受講して

※ここでいう経験は講師のものである。
##傾向として
 - 成功するパターン : 最初にテストを考える
 - 失敗するパターン : 取り敢えず作るものを作って、後で確認

## テストのコツ
結論：最初にテストを考える（テスト駆動・テストファースト）
「何ができればOKか？」を考える。

スポーツと一緒で基本の「型」は大事

##レビューもテストの一つ

レビュー（静的テスト）
プログラムのテスト（動的テスト）

##仕様書を読むときの注意点
仕様書は足りないことが多い。
そのため、自分で補うことが必要

ただ、レビュー時点は書かれていることを注目しがちだが、
書かれていないことも注意すべき。

最初に何がmust・never・wantを考えてから仕様書を読むと書かれていないことに関しても気づきが得れる。
ここでは、機能面を注視しがちだが、セキュリティや信頼性も考える必要がある。

これは仕様書についてだけでなく開発における設計・実装・テストの全てにおいて言える。

これにより、リリースの3日前のテストでバグを見つけるのでなく、前もっと見つけるフローを用意できる。

##手戻りコストの法則

- （基本）設計１
- 単体テスト１０
- システムテスト４０
- リリース後１００以上

経験上、半分以上は設計段階で気づけば手戻りでもっと減るのに。

##要求分析
最低、5～10分やったら半日コストが浮ける

何ができればOKか？　＝　品質目標
開発がスタートするに連れ、劣化する。（忘却、伝言ゲーム）

方針としては

- 上流工程は品質を下げない
- 下流工程は品質を上げる

リバースエンジニアリング（足りない仕様を補う）は大事
仕様の無いことを片っ端から見つけ出して、提案して潰して行く必要がある（欧米では普通）

品質は「要求を満たすこと」である
品質は「誰か」にとっての価値である

見やすいGUIとは？（seniorなのかteenagerなのか）

##まとめ
人間は自分にとって大事なことでなければ思いつかない。
独りで考えるのではなくメンバー間で全体を考える（自分の考えは全体のどれだけを賄っているか）
全体でmust・never・wantを考えるが、各の機能must・never・wantも考える
（例：検索機能のmust・never・wantを考える）

上記を意識し生産性が高いエンジニアになろう。
GNOME > ファイルブラウザ > nautilus . > Ctrl+2でList表示

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```


### 状況とやりたいこと

- ファイルとディレクトリが600くらいある
- どういうファイルやディレクトリがあるかを見たい
- ls, grep, lessを組合せるのは手間であり、閲覧性も良くない
- ssh -Xで接続しているが、デスクトップの転送はしていない
- GNOMEを使用

### ファイルブラウザ

ファイルブラウザを起動する。

以下を見つけた。
[GNOME/ファイルブラウザをターミナルから起動する方法](http://linux.just4fun.biz/?GNOME/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%82%92%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%81%8B%E3%82%89%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
by @ JUST4FUN_BIZさん

情報感謝です。

ファイルリストを見たいディレクトリにおいて以下を実行すればいい。

```bash
$ nautilus .
```

## Nautilus操作

### List表示

起動後に<kbd>Ctrl</kbd>+<kbd>2</kbd>でList表示に変更できる。

### ファイルへの移動

ファイル名の先頭文字列を入力すると、そのファイルの位置に飛ぶ

例: `met_em`を入力