OmniAICreator/Qiita-1.07M huggingface dataset:
素人がiPhoneアプリを作った話＜ことの始まりとツール選択＞

#プロローグ
全6回で、ズブの素人である私が2年前に、モラハラの依存関係を脱出したい人を援助する機能のあるアプリを開発した話を書きます。 

知識も経験もないながら、Appleの申請却下:sob:にもめげず:muscle:に工夫:bulb:と情熱:fire:で何とか完成し:v:、<strong>約6ヶ月</strong>で販売まで漕ぎ着けました:tada:。 

アプリを**素人が開発する**ということに興味がある方の読み物として、ご自身で何かやっていて壁に当たっている方の参考になるならと思い、また、これをお読みになった方でさらに改善するのにちょこっとでもご協力いただける方など現れたらとても嬉しいな:heart_eyes:と思い、ここに記録を書いてみたいと思いました。 

簡潔に箇条書きでどんどん書いていきますので、詳しくお知りになりたい方はコメントなどを残していただければ対応してまいります。 

#ことの始まり 

昔同棲していた恋人が罵倒する嘘をつく無視するなどする人で、傷つき弱ってマインドコントロール状態になって自尊心をそこない、どうしても嫌で辛くて離れたいと一念発起するも、自ら元サヤに戻ろうとしてしまうという、自分の気持ちの不可思議に見舞われ、自分の心のコントロールをするための心理学やらなんやらの勉強をして、訓練をして、なんとか恋人と離れることができましした。 

その間、**いつでもそばにいてくれる携帯アプリによって非常に助けられ**、**モラハラさんとの苦しい共依存関係から脱出した**ことから、**頼ったアプリを全部まとめ**、**経験を生かして効果を最大化**できれば、たくさんの同じような境遇にいる人たちを助けられるのではないかと思ったことからアプリ開発にいたりました。 

#使ったアプリ 

+ スピリチャル系のアプリをリリースしているOCEANHOUSE MEDIAという会社の<strong>Archangel Guidance Bundle</strong>

1. 全4種類あり特に人間関係を司る天使と言われていた<strong>Archangel Raphael</strong>を使用した

2. スピリチャル系のアファーメーションや励ましのメッセージが設定した時間ごとにノーティフィケーション表示される

3. 届く時の音が選択できる

4. 夜間停止ができる

5. 開くとメッセージが天使のメッセージとして読め、他のメッセージも表示できる 

6. おみくじ的に迷いがあるときに引く特別なメッセージを表示させるページがある


+ <strong>YouTube</strong>

1. アメリカの方が精神的な虐待について研究が進んでおり、ウェビナー動画などで勉強ができた 

2. 動画は文献を読むより10分程度で説明されており、著者自身の動画で手っ取り早く情報が入手できた 

3. 精神的な虐待を受けているかどうかに自信がない場合に世界共通で同じ手口を使って虐待すること、それを責任転嫁することなどを知ることができた 

4. どうやって失った自尊心を取り戻せばいいのか、ヒントになる考え方などをウェビナーを通して学ぶことができた 

+ **Twitter**

1. 許してしまう、忘れてしまう、誤魔化されてしまう、嘘をつかれても記憶に自信がないなどを、その時の気持ちや出来事、相手の言っていた言葉などをなるべく早いうちに記録することで、精神的な虐待の事実を自分で理解できた 

2. 他にも同じような体験をしている人がいることがわかった 

3. 他の人たちのつぶやきを見ることで、自分が悪いのかと思っていたことが、違うということがわかった 

4. 違うモラハラ関係の中でもデジャヴュのごとく、全く同じ方法が使われているのだということがわかった 

+ <strong>Google</strong>

1. 文献や自助グループなどを調べた 

2. 小町や質問箱などで自分と同じ境遇の人がいることがわかってホッとした 

3. 護身法やPTSDからの脱却ワークショップなどの情報を得ることができた 

+ <strong>Kindle</strong>

1. 本を買って読むのが大変な時にはAmazon + Kindleでパッと買って流し読みできて便利だった 

 

#開発方法と資金調達 

+ アプリ開発は素人なので、チョイスは2つ 

1. 開発を発注する（相場的に資金が非常に多く必要になる）→却下 

2. 自分で勉強して開発する（ラーニングコストはさておき、開発期間の自分の生活だけなんとかなれば良い）→採用 

+ 自己資金はゼロだったので、チョイスは2つ 

1. 何らかの公的な補助金・助成金を探す→知り合いの中小企業診断士に聞いてみた→無かった 

2. クラウドファンディングでやってみる→採用 

<strong>結論：クラウドファンディングで資金を募り、自分で開発することになった</strong>

 

#ツール選択 

条件が以下の通りあった 

+ テスト機がiPhoneのみ 

+ Windows機のみ（のちに中古でMacBookProを購入） 

+ XML（マニュアル制作）/HTML（ホームページ作成）とWordPress（ホームページ作成）の経験があるのみ 

+ CSSは教本を読みながらならできる程度 

+ JavaScriptはJavaとの違いすらわからない程度 

+ バックエンドの知識ゼロ 

+ 載せたい機能がはっきり決まっていて、それが可能かどうかが重要 

<strong>Monaca x OnsenUI x AngularJSに決定、経緯と理由は以下の通り</strong>

+ テスト機としてAndroid機を買うつもりがなかった 

+ Swiftを勉強してみた 

+ Xcodeを触ってみた 

+ SNS機能をどうやって作ればいいのか皆目見当がつかなかったため却下した 

+ 素人でもできそうなアプリ開発ツールを探した 

+ ツールの候補（2017年当時）は以下の通り 

1. Buildy 

2. Monaca 

3. Yappli 

4. Appgyver 

5. Appery 

+ トライアル版をそれぞれ使ってみて、簡単そうに見えるものほどやりたいことがはっきりしていると制約が多いことがわかり、且つ費用の面からも制約があるため、無料で使える<strong>Monaca</strong>に決めた 

+ デザインおよび、JavaScript知識ゼロのハンデをカバーすべく<strong>OnsenUI</strong>と<strong>AngularJS</strong>を採用

＜開発したアプリの機能の構成＞へと続きます。
tibbleの値を編集する

Rのtibbleはdata.frameのように直接個別の値を編集する方法は提供されていないが、`mutate`関数を用いて、既存の値の更新を行うことができる。
まず、data.frameの場合では、以下のように値を編集できる。

```r
# データフレームの作成
my.data <- data.frame(x=c(1:5),
                      y=c(letters[1:4], NA),
                      stringsAsFactors = FALSE)
my.data
```
```
  x    y
1 1    a
2 2    b
3 3    c
4 4    d
5 5 <NA>
```
```r
# `my.data`の5行2列目に、文字列"e"を代入する。
my.data[5,2] <- "e"
my.data
```
```
  x y
1 1 a
2 2 b
3 3 c
4 4 d
5 5 e
```

tibbleの場合、行、列を指定して代入することはできないが、`case_when`にて対象となるセルを指定して、`mutate`で列ごと更新する。

```r
# tibbleの作成
my.data <- tibble::tibble(x=c(1:5), y=c(letters[1:4], NA))
my.data
```
```
# A tibble: 5 x 2
      x y    
  <int> <chr>
1     1 a    
2     2 b    
3     3 c    
4     4 d    
5     5 NA 
```
```r
# これはエラーになる
# my.data[5,2] <- "e"
my.data <- my.data %>% 
  dplyr::mutate(y=dplyr::case_when(x==5 ~ "e",
                                   TRUE ~ y))
my.data
```
```
# A tibble: 5 x 2
      x y    
  <int> <chr>
1     1 a    
2     2 b    
3     3 c    
4     4 d    
5     5 e 
```
rubyのバージョンを上げようとしたら最新バージョンが表示されない

#経緯
rubyのバージョンを上げようとして***$ rbenv install --list***を実行した際に最新のバージョンが表示されなかったので表示させるまでの手順を記載しておきます。


#最新バージョンが表示されるまでの手順

##Homebrewの更新
```
$ brew update
```

##rbenv、ruby-buildを更新

```terminal
$ brew upgrade rbenv ruby-build
```

##リストの確認

```terminal
$ rbenv install --list
  2.6.0
  2.6.1
  2.6.2
  2.6.3
  2.7.0-dev
  2.7.0-preview1
```

これで表示されていれば完了
E2Eテストフレームワーク Cypress の運用Tips

# インストール
一般的なケースだとプロジェクト（リポジトリ）にパッケージをインストール

```bash
$ npm install --save-dev cypress
```

ただ上記だと実行バイナリが`npm`の中に入ってしまうので `$(npm bin)/cypress` として呼ばなければならない。
頻繁に使う場合はグローバルインストールで `cypress` コマンドで呼べるようにしてしておくと便利。（ただしプロジェクトとのバージョン違いが出るので注意）

```
$ npm install -g cypress
```

## 実行方法をpackage.jsonに書いておく
他のメンバーにわかりやすいよう、`package.json`に書いておく。

```json:package.json
{
  "scripts": {
    "cypress:open": "cypress open",
    "cypress:run": "cypress run"
  }
}
```

# 実行方法

## Cypressデスクトップ

```bash
$ cypress open
```

## CLI（ヘッドレス）でテストを実行

```bash
$ cypress run
```

## 環境ファイルを切り替える

例えば環境ファイルが３つあるとして…。

```json:cypress.dev.json
{
  "baseUrl": "https://develop.example.com/"
}
```

```json:cypress.staging.json
{
  "baseUrl": "https://staging.example.com/"
}
```

```json:cypress.prod.json
{
  "baseUrl": "https://prod.example.com/"
}
```

開くときに `--env configFile=dev` とすると環境ファイルを指定できる。

```bash
cypress open --env configFile=dev
```

## 特定のspecを実行する

```console
$ cypress run --spec "cypress/integration/examples/actions.spec.js"
```

https://docs.cypress.io/guides/guides/command-line.html#cypress-run

# 記述

## Basic認証を通す

`cy.visit()`に引数で渡す

```js
cy.visit('https://www.acme.com/', {
  auth: {
    username: 'wile',
    password: 'coyote'
  }
})
```

[visit | Cypress Documentation](https://docs.cypress.io/api/commands/visit.html#Options "visit | Cypress Documentation")

## Basic認証に環境変数を使う場合

```json:cypress.json
{
  "env": {
    "basic_user": "wile",
    "basic_password": "coyote"
  }
}
```

```js
cy.visit('https://www.acme.com/', {
  auth: {
    username: Cypress.env('basic_auth'),
    password: Cypress.env('basic_password')
  }
})
```


## n番目の子要素を取得

`.eq()`を使う。

```js
    cy.get('.button').eq(0).click();
```

https://stackoverflow.com/questions/50750956/how-to-select-nth-item-inside-select-element-in-cypress

# テストをするホスト名などの定数
## ホスト名設定

シェル側から与える環境変数には `CYPRESS_` の接頭語をつけて渡すと、接頭語を省いた変数が `Cypress.env()` に渡されます。

シェル変数 | Cypressの定数
-----|-----
CYPRESS_HOSTNAME | Cypress.env('HOSTNAME')
CYPRESS_USER | Cypress.env('USER')


```javascript:access.spec.js
   const host = Cypress.env('HOSTNAME');
```

```console
$ export CYPRESS_HOST=http://localhost:8080/; npm run cypress open
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/6f421033-e11e-78af-fb48-9b2cfe275c48.png)


# その他
## npm runで実行する際に引数を渡す

```console
$ npm run cypress:run -- "--spec" "cypress/integration/example/002_create_test.spec.js"
```
緯度と経度を入力することによって現在位置から目的地の方角・距離を表示するPGM

緯度と経度を入力することによって現在位置から目的地の方角・距離を表示するPGMを作成しました

ちなみに現在位置の緯度経度は最初に距離再計算のボタン
を押すことで自動で入力されるようになっています...
作成の目的はどこかの話でグーグルマップの通信のデータ量が多すぎるとのことを聞いた
覚えがありましたので、最低限方向と距離だけわかるようなPGMがあれば良いな、と思ったからです...

修正しました(方向の描画処理を変更) 2019.08.24


参考githubURL: 
https://github.com/NanjoMiyako/ZatuMap

サンプルページ: <a href="https://nanjomiyako.github.io/ZatuMap/">
https://nanjomiyako.github.io/ZatuMap/
</a>


動作時の画像
![screenshot1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/86841986-6bbb-5329-5583-a90dfb363fa8.jpeg)


参考URL:
<a href="https://blog.codecamp.jp/javascript-geolocation">
JavaScriptによる位置情報の取得を簡単に解説（geolocation） | CodeCampus
</a>
<a href="https://developer.mozilla.org/ja/docs/Web/API/Geolocation/getCurrentPosition">
Geolocation.getCurrentPosition() - Web API | MDN
</a>
<a href="https://arakaze.ready.jp/archives/3931">
スマホのセンサーから上下左右の傾きと方向をJavascriptで取得する DeviceOrientationEvent | ARAKAZE NOTE
</a>
<a href="https://qiita.com/chiyoyo/items/b10bd3864f3ce5c56291">
2つの座標間の距離を求める - Qiita
</a>
<a href="https://qiita.com/kyrieleison/items/a3ebf7c55295c3e7d8f0">
HTML5 Canvas 入門 - Qiita
</a>
<a href="https://keisan.casio.jp/exec/system/1257670779">
２地点間の距離と方位角 - 高精度計算サイト
</a>
<a href="https://thr3a.hatenablog.com/entry/20190502/1556772556">
Javascriptで２地点間の距離と方角を計算するライブラリ - 動かざることバグの如し
</a>
<a href="https://www.logical-arts.jp/archives/136">
緯度経度から距離と方位を求めるプログラム - ロジカルアーツ研究所
</a>
<a href="https://www.logical-arts.jp/archives/18">
緯度経度から距離と方位を求める方法 - ロジカルアーツ研究所
</a>
<a href="https://qiita.com/ampersand/items/b67818ee9f9c742ad7b8">
ラジアンから角度を求める関数をMathオブジェクトに定義する - Qiita
</a>
<a href="http://www.htmq.com/canvas/lineWidth.shtml">
lineWidth = 線の幅－Canvasリファレンス
</a>
<a href="http://www.htmq.com/canvas/strokeStyle.shtml">
strokeStyle = "色・グラデーション・パターン"－Canvasリファレンス
</a>
<a href="https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes">
canvas に図形を描く - 開発者ガイド | MDN
</a>

<a href="https://qiita.com/_lemon2003_/items/c6f4a6332afd806974df">
GitHub で超簡単に静的サイトをホスティングする！ - Qiita
</a>


<a href="https://javascript.programmer-reference.com/js-canvas-clearrect/">
[JavaScript] canvasの内容をクリアする（.clearRect） | コピペで使える JavaScript逆引きリファレンス
</a>
Laravelで.vimrc.localのnoexpandtabが効かなかった

# 先に結論
Laravelインストール時に設置されていた`editorconfig`が効いているだけでした。

# 経緯

Laravelでbladeファイルをタブインデントにしたかったので、以下の`.vimrc.local`を設置したが効かなかった。

``` :.vimrc.local
if &filetype == "blade"
	set noexpandtab
endif
```

# 原因の確認

vim上で以下のコマンドを叩いて、インデントの設定で何が優先されているのかを確認。

```vim
:verbose set expandtab?
noexpandtab
        最後にセットしたスクリプト: ~/.vim/bundle/editorconfig-vim/plugin/editorconfig.vim 行 545

```

Laravelのプロジェクトルートディレクトリにある`.editorconfig`が優先されていた。  
`.vimrc.local`をやめて`.editorconfig`に以下を追記することで解決。


``` :.editorconfig
[*.blade.php]
indent_style = tab
indent_size = 3
```
【C#】SQLで読み込んだデータをクラスプロパティに格納して返すメソッド

##SQL Serverのデータベースに接続して、読み込んだ値を変数に格納する文法を記述します。

はじめに、データベースに接続するまでの文。

```C#:Service1.svc.cs
public SavedData SetData(int selected_id)  //メソッド名　引数には主要キー、返り値にはクラス名
{
    const string connStr = @"Data Source=(local);
                        Initial Catalog=　stafflist; Integrated Security=True;";

    using (var conn = new SqlConnection(connStr))
    {
        conn.Open();
        var cmd = conn.CreateCommand(); 
        // コネクションからコマンドへ-SqlConnectionに関連付けられているSqlCommandオブジェクトを作成

        cmd.Parameters.Add(new SqlParameter("@selected_id", selected_id));
        cmd.CommandText = @"SELECT Id,Name,DepartmentId,Sex,JoinedYear,Note
                            FROM dbo.Staff Where Id = @selected_id ";

```
ここまででデータベースに接続。以下、データベースから読み込んだ値をクラスのプロパティに代入

```C#:Service1.svc.cs
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                int demoid = (int)reader["Id"]; 
                //クラスプロパティ'ID'のデータ型がintの場合は、このように変換
                        
                setdata.ID = demoid.ToString();
                setdata.NAME = (string)reader["Name"];
                setdata.DEPARTMENTID = (int)reader["DepartmentId"];
                setdata.SEX = (int)reader["Sex"];
                setdata.JOINEDYEAR = (int)reader["JoinedYear"];
                setdata.NOTE = (string)reader["Note"];
            }
        }
    }

    //メソッドが呼び出されたインスタンス自身を返す
    return setdata;
}
```

これで、この返り値にあてたクラスをインスタンス化して、変数を自由に格納できる。

##追記
編集リクエストをくださった@nogic1008さん、ありがとうございました。
SpringBootの起動を高速化する

# はじめに

新たに作成した仮想環境でSpringBootのアプリケーションを起動したら、起動に4-5分かかってとても試験に使えない状態だたったので調査しました。

# 環境

- OS：CentOS 7.3
- Java：OpenJDK 1.8_191
- tomcat：8.5.24
- SpringBoot：1.5.12.RELEASE

# 解決法

以下の記事を参考にした。macの記事だけどLinuxでも同じことをやってみた。
[MacOSでJDK8が重い問題](https://qiita.com/akikinyan/items/ad0dd5c9b8b762f33f89)

## hostsファイルにhostnameを記載する

### hostnameを確認

```
[user@hoge ~]$ hostname
hoge.local　←この値をコピーしておく
[user@hoge ~]$
```

### hostsファイルに追記

```
[user@hoge ~]$ sudo vi /etc/hosts
```

localhostの行にコピーしておいたホスト名を追記

``` diff
-127.0.0.1 localhost
+127.0.0.1 localhost hoge.local
```

保存して終了

# 実行してみる

war形式にしたSpringBootアプリケーションを配置したtomcatを起動して検証してみました。

## 処置前

``` catalina.out
[localhost-startStop-1] deployDirectory Deployment of web application directory [アプリ名] has finished in [212,763] ms
```

## 処置後

``` catalina.out
[localhost-startStop-1] deployDirectory Deployment of web application directory [アプリ名] has finished in [12,890] ms
```

## 比較

かなり高速化されました。

||起動時間(ミリ秒)|起動時間(秒)|
|---|---|---|
|処置前|212,763|212|
|処置後|12,890|12|

## おわりに

参考記事に貼られていた[stackoverflowの記事](https://stackoverflow.com/questions/33289695/inetaddress-getlocalhost-slow-to-run-30-seconds/40487173?stw=2#40487173)はSpringBootには関係のない記事に見えますが、相当な高速化がされましたね。
SpringBootの起動時に環境の情報を取得したりしているのでしょうか。参考記事的にはJDKの問題？（詳しい人教えてください）

この方法で、tomcatから実行しないjar形式のSpringBootアプリケーションの起動も高速化されました。
React Axios Tutorial - Make HTTP GET and POST Requests - positronX.io

In this React Axios tutorial, we are going to learn how to make Axios GET, and POST requests using Axios. I will create a backend server for React app using MongoDB, Node, and Express.js. We will create a frontend using React.js and Bootstrap 4. Then, we will learn to make REST API calls using Axios.

click here to read more
https://www.positronx.io/react-axios-tutorial-make-http-get-post-requests/
ガイドのための掲示板式マッチングサービスGuide Searchをつくった

#はじめに
TechAcademyのWebアプリケーションコースを2か月間受講してオリジナルサービスを作りました。その過程で役に立った知識をまとめていきます。

Guide Search　：https://guide-search.herokuapp.com/

TechAcademyのWebアプリケーションコースを受講する経緯などはこのページにまとめてあります。
https://yokubarilink.com/techacademy-learningdeliverable/

#Guide Searchの説明
アプリの仕組みとしては、家庭教師の募集の掲示板のように掲示板の形式でマッチングを行います。ガイドを募集する側は募集の投稿を行います。一方ガイドをしたい側は、掲示板を見ながら自分にあったサービスに応募するという仕組みです。

主な機能は：
・userの作成、編集、退会
・投稿の作成、編集、削除
・ログイン機能
・投稿の検索
・フォロー機能

#具体的な作成の流れ

基本はTechAcademyのWebアプリケーションコースでつくったTwitterクローンをもとにしています。
Ruby on Rails チュートリアルで学べることと基本は変わりません

追加で実装した機能と参考にしたサイトをまとめていきます。

・検索機能
https://qiita.com/yusuko/items/cff4e46aeafbc3beecf2
https://qiita.com/mochikichi321/items/5c9630c5d87b47130942

・投稿一覧に自分の投稿以外を並べる
https://teratail.com/questions/62493

・退会機能
https://qiita.com/kenzoukenzou104809/items/d52054000c16cb363707
https://teratail.com/questions/200344

#難しかった点・課題・今後実装したい機能

・慣れないうちは、このコードをどこに書けばいいのかなどわからないことだらけです。機能の実装を繰り返すうちに感覚を身につけ、それから本質的な理解に移ればいいと思います。
・今後はDM（ダイレクトメール）機能・管理者の機能・ガイドする側とされる側でUserテーブルを分けるなど…
WORLDの特徴量をcsvに出力してみた

# WORLDとは
音声分析変換合成システムの１つで，UTAUやCeVIOの音声分析の一部にもWORLDが使われているそうです．

詳しい内容はこちらの論文を参照してください．
https://pdfs.semanticscholar.org/560a/be3b4482335a93df309cb6a0185ccc3ebd8e.pdf?_ga=2.60932075.677969946.1566283448-268225603.1564207121

# WORLDの特徴量
以下の3つの特徴量で構成されています．

■基本周波数（F0）
　簡単に言えば「音の高さ」のことです.

■スペクトル包絡
　人の声道特性のことですが，わかりやすく言うと「音色」のことです.

■非周期性指標
　「音のかすれ具合」などのことです．

それぞれの特徴量は5msごとに取得していきます.
サンプリング数16kの音声を分析するときは以下の次元数を取得できます．
※スペクトル包絡と非周期性指標はサンプリング数に依存します．

・基本周波数：1次元
・スペクトル包絡：513次元
・非周期性指標：513次元

# 実行環境
今回試した環境は以下の通りです．
OS: Ubuntu 18.04 LTS
CPU: i3-4130 3.40GHz
メモリ: 16GB

# 1. 準備
Pythonでは[pyworld](https://github.com/JeremyCCHsu/Python-Wrapper-for-World-Vocoder)が用意されていますが，今回は[WORLD4py](https://github.com/yamachu/WORLD4py)を使っていきます．
以下のコードでWORLD4pyをクローンしてください.

```
$ git clone https://github.com/yamachu/WORLD4py.git
```

次に以下のコードでsetupしていきます．

```
$ cd WORLD4py
$ python setup.py install
```
ここまでが準備となります．

# 2. WORLDを実行
以下のコードでdemoディレクトリに移動します．

```
$ cd demo
```
次に以下のサンプルプログラムを作成します．
※このサンプルは[こちら](https://github.com/yamachu/WORLD4py)のREADME.md を参考にしています．

```:wav2world_features.py
# -*- Coding: utf-8 -*-
from world4py.np import apis, tools
import numpy as np

# please write Wavfile name
Wavfile_name = "sample.wav"

# get waveform from file
x, fs, nbit = tools.get_wave_parameters(Wavfile_name)

ana_param = {
    'threshold': 0.1,
    'frame_period': 5.0,
    'f0_ceil': 800.0,
}

#####################################
# can use Python wave module
# f0: 基本周波数
# sp: スペクトル包絡
# ap: 非周期性指標
#####################################
f0, sp, ap = apis.extract_all_from_waveform(x, fs, ana_param)
syn = apis.synthesis(f0, sp, ap, fs)

# 基本周波数とスペクトル包絡と非周期性指標を水平スタックしている
f0_re = np.reshape(f0, (len(f0), 1))
f0_sp = np.hstack([f0_re,sp])
all_features = np.hstack([f0_sp,ap])

# make csv file for WORLD features
with open(Wavfile_name.replace(".wav", "_syn.csv"), mode='w') as f:
	for all_part in all_features:
		for all_part_one in all_part:
			f.write(str(all_part_one)+",")
		f.write("\n")

# make synthesis_Wavfile
tools.write_wav_file(Wavfile_name.replace(".wav", "_syn.wav"), syn, fs, nbit)
```

そして，以下のコードで作成したPythonファイルを実行します．

```
$ python wav2world_features.py
```

実行し終わったら，同じディレクトリに「sample_syn.wav」と「sample_syn.csv」があることを確認しましょう．

```
$ ls
main.py  sample.wav  sample_syn.csv  sample_syn.wav  wav2world_features.py
```
確認できたら，無事終了です．
※「sample_syn.wav」：元音声をWORLD分析して作成した合成音声
　「sample_syn.csv」：左から基本周波数（1次元），スペクトル包絡（513次元），非周期性指標（513次元）の順番になっているcsvファイル

尚，音声はWORLD4py同様，[交換音ラボ](https://soundeffect-lab.info/)様の音声を使用しています．

# 参考文献
http://www.kki.yamanashi.ac.jp/~mmorise/world/introductions.html
https://github.com/yamachu/WORLD4py
https://qiita.com/ohtaman/items/84426cee09c2ba4abc22
https://github.com/mmorise/World
https://github.com/JeremyCCHsu/Python-Wrapper-for-World-Vocoder
https://soundeffect-lab.info/
Ruby on Railsで'require': No such file to load -- ***_helper.rb(LoadError)と言われるとき

# 状況
ローカルでRuby on Rails Tutorialをやってる時に遭遇。

- チュートリアル通りのコマンド`rails generate controller Relationships`後にテストを書き込んで`rails t`でエラー。
- ファイル(***_helper.rb)は存在する。
- ファイルの名前を変えると動く。元に戻すと同じエラー。

#エラーメッセージ
一部抜粋

```
~/.rvm/gems/ruby-2.6.3/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:33:in `require': No such file to load -- relationships_helper.rb (LoadError)
```

```
~/.rvm/gems/ruby-2.6.3/gems/actionpack-5.2.3/lib/abstract_controller/helpers.rb:151:in `rescue in block in modules_for_helpers': Missing helper file helpers/relationships_helper.rb (AbstractController::Helpers::MissingHelperError)
```

# 結論

~~bundle update~~

##### 追記
Gemfileの

```
gem 'rails', '~> 5.2.3'
```
の部分を下記に変更

```
gem 'rails'
```
その後、

```
bundle update
```

# 雑記
なんでファイル読み込んでくれなかったのか？謎

# 追記

`bundle update`だけでは治らない。

- boosnap-load-path-cache,bootsnap-compile-cacheを削除しても治らない。
- `rails generate controller testgen`のすぐ直後に`rails t`で同じエラー,前回治った`bundle update`で治らない。
→　別の要因（時間経過？何らかのversionのアップデート？模索中）

## 結論に追記

- railsを最新版にしたら治った。`rails generate controller testgen`のすぐ直後に`rails t`でもエラー起きない。
- バージョンの互換性部分に問題があった？バージョン管理を適当にしていたから起きたかも。
[30秒で理解]SwiftでDI(Dependency Injection)

最近、少しばかりKotlinでAndroid開発をしているときにSwift以上にKotlinの方がDIの文化が進んでそうだな(主にDaggerとか)と思ったんですが、意外とちゃんと時間をとってSwiftのDIについて調べていないなと思ったので時間をとって記事にした次第です。

## Dependency Injectionとは
名前の格好良さとか複雑さに惑わされて欲しくはないので言いますが、

ただ外部から値を渡して上げて受け取った物（主にclass)は受け取ったことを前提に記述することできる

ただそれだけです。

実際にcodeに起こしたときはこんな感じです。

```swift
class Hoge {
    var name: String

    init(name: String) {
        self.name = name
    }
}
```
```swift
let hoge = Hoge(name: "hogehoge")
```

これが一番シンプルなDIと言えると思います。DIってなんだろうと思って検索した場合は、これは当たり前のことだし、これをDIっていうの思った人も少なくないと思います。ライブラリを使うと`コンテナ`とか` ファクトリ`とかいろいろな単語が出てきて混乱するかもしれませんが、DIという手法をより有効的に使用するための要素でその手法本体ではありません。

それでもまだ信じられない人はこの記事をみてみることを推奨します

https://qiita.com/ostk0069/items/03c968bacf8e1372b7e7

この記事は以前私が書いた物ですが、`UITableView`を使うときに`UITableViewCell`を`dequeue`(呼び出す)するタイミングでパラメータを挿入しているだけです。上のサンプルコードでも`name`を挿入しているのと同様です。

しかし、これだけではおわりません。いまの説明で完全に理解するにはDIのDの方、`Dependency`への理解が不十分です。ここでいう`Dependency`とは`Singleton`であると考えて良いです。

## Singletonについて
`Singleton`とはその物(class, protocol)が実行時に一つのオブジェクトにのみ依存することを約束することです。ここでSwiftにおいてSingletonを約束するために必要なのがコンテナという概念です。これ以上深く話すには実際にDIのライブラリ等でDIのコンテナの解釈のもと、ライブラリが作られているかで少し変わってきます。思想の問題です。

## Swiftで書かれているDIのライブラリ

### コンテナを用いる場合

- 一番使われれているであろうライブラリ
https://github.com/Swinject/Swinject

- 使ったことないけど良さそう
https://github.com/ivlevAstef/DITranquillity

### コンテナを用いない場合

- Uberが作成しているライブラリ（バージョンが1.0未満なので安心して使えるか微妙)
https://github.com/uber/needle

- 星の数は多いけど少し前から更新が止まってるので不安（8/20時点）
https://github.com/square/Cleanse

### その他(injectionが綺麗にかけるライブラリ)

- 激推しライブラリ  
https://github.com/tarunon/Instantiate
iOS13でUISegmentedControlの見た目をカスタマイズする

※ 実装/動作確認環境: Xcode 11 beta5 + Simulator
※※ iOS13正式リリース前につき、スクリーンショットは未掲載(100%見た目についての話なのでなんとも物足りない感じですが…)。

### 背景

iOS13では`UISegmentedControl`の見た目が変更される。
それに伴い、見た目(主に色)のカスタマイズをする場合、iOS12以前とは異なる方法で行う必要がある。

さしあたりの対応として行ったことをメモ。
(DarkMode対応なども鑑みるとカスタマイズなしで使うようにUIを設計し直すのが妥当とは思うが…)

### iOS12以前
`tintColor`がビューやラベルの色に適用されるため、ここに任意の色を指定するだけでOKだった。

```Swift
tintColor = UIColor.orange
```

### iOS13
デフォルトの表示が無彩色となり、`tintColor`に依存しなくなった。

以下の方法でそれなりにカスタマイズできる。しかしそれぞれ一長一短あり。

#### `selectedSegmentTintColor` を使用する方法
`tintColor` ではなく `selectedSegmentTintColor` を指定することで、選択中のセグメントの背景色を設定できる。
また、文字色はデフォルトで黒色であるため、設定する背景色によっては文字色も変更したほうがベター。

```Swift
func configure() {
  let color = UIColor.orange
  
  selectedSegmentTintColor = color
  setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: .selected)
  setTitleTextAttributes([NSAttributedString.Key.foregroundColor: color], for: .normal)
}
```

##### メリット
コード量も少なく、やっていることも明確である点。
基本的にはこの程度のカスタマイズで収めたい。

##### デメリット
この方法ではビューの背景にある薄いグレーはそのままなので、`selectedSegmentTintColor` の明度によってはコントラストが弱くなる恐れがある。
(View Hierarchyを確認したところ、SegmentControlのsubview内に半透明のグレー画像が設定されたUIImageViewがある模様)

コントラストに懸念があり、かつ色も変更できない場合は次の方法で薄いグレーの背景を除去するのがよさそう(ただし急場しのぎ。詳細は後述)。

#### `setBackgroundImage()` を使用する方法

```Swift
func configure() {
  let color = UIColor.orange

  // 背景を単色画像に差し替え
  setBackgroundImage(UIColor.clear.toImage(), for: .normal, barMetrics: .default)
  setBackgroundImage(color.toImage(), for: .selected, barMetrics: .default)

  // ラベルのスタイルを設定(選択中のセグメントのラベルがBoldでなくなるので、合わせて設定)
  setTitleTextAttributes(
    [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 13.0),
     NSAttributedString.Key.foregroundColor: UIColor.white],
    for: .selected)
  setTitleTextAttributes([NSAttributedString.Key.foregroundColor: color], for: .normal)
 
 // グレー領域がなくなったことで境界がわかりづらくなるので、ボーダーを追加
 layer.borderColor = color.cgColor
 layer.borderWidth = 1.0
}
```
↑で使用している `UIColor.toImage()` は1x1の単色UIImageを生成する拡張メソッド。実装方法は[こちらの記事](https://dev.classmethod.jp/smartphone/iphone/ios-uigraphics-image-renderer/)等を参照。

##### メリット
背景のグレーがなくなるので、SegmentedControlの色をより自由に決められる点。

##### デメリット
ビューの構造も変わってしまうらしく、見た目はiOS12以前のSegmentedControlのようになってしまう。

また、たかだか6ステップ程度ではあるが、先の方法よりは回りくどい。
そうまでしてiOS12以前っぽい見た目にするのか？となるので、やはりiOS13標準に則ったUIに変更するのが真っ当だと思う。

### 参考
- [uikit - How to change the colors of a segment in a UISegmentedControl in iOS 13? - Stack Overflow](https://stackoverflow.com/questions/56436559/how-to-change-the-colors-of-a-segment-in-a-uisegmentedcontrol-in-ios-13)
対数計算

```python:python
>>> import math
```
## 底が2の2の対数
底が2の2の対数 $\log_2 {2}$

```python:python
>>> math.log(2,2) 
1.0
```
#### Googleで計算 -> lg(2)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277081/3ec275df-b171-f5d2-9d70-8d35acdc0b57.png)
参考:[google電卓リファレンス](https://hp.vector.co.jp/authors/VA013937/google.html)

## 底が2の3の対数
底が2の3の対数 $\log_2 {3}$

```python:python
>>> math.log(3,2)
1.5849625007211563
```
#### Googleで計算 -> lg(3)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277081/cae03a4b-2589-da3a-e604-be8e477de2b3.png)
参考:[google電卓リファレンス](https://hp.vector.co.jp/authors/VA013937/google.html)

## 底が2の4の対数
底が2の4の対数 $\log_2 {4}$

```python:python
>>> math.log(4,2)
2.0
```
## 底が2の8の対数
底が2の8の対数 $\log_2 {8}$

```python:python
>>> math.log(8,2)
3.0
```

## 底が10の4の対数
底が10の4の対数 $\log{4}$
#### Googleで計算 -> log(4)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277081/a0c7cd0e-9c70-45f9-d49d-04eb176c78bb.png)

#### CASIOの高精度計算サイトで計算 -> log(4)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277081/39692be2-f790-05ff-469c-d04b3a311c3d.png)
参考：[高精度計算サイト](https://keisan.casio.jp/exec/system/1260332465)
CircleCIの動作するブランチに別の利点と欠点

# 概要
CircleCIの設定において、ジョブの実行するブランチを`filter`で制御できる。
git-flowを採用している場合、CircleCIの動作確認のブランチによって発生する利点と欠点を出してみた。

## ジョブ実行対象を`develop`ブランチ以降にする場合
### 利点
`develop`以降ブランチへのマージで自動実行されないため、最終的なCI/CDの待ち時間が減る。

### 欠点
CircleCIの動作確認のために、プルリクエストを作成する必要がある。


## ジョブ実行対象を`feature`ブランチ以降(無制限)にする場合
### 利点
CircleCIの動作確認のために、プルリクエストを作成する必要がない。

### 欠点
`feature`ブランチのコミットごとにジョブを実行するため、最終的なCI/CDの待ち時間が増える。  
(不要なジョブ手動で止める運用で回避可能)
Google Colaboratory上でアニメーションを表示する

# TL;DR

Google Colaboratory上で何かイメージを描画して、それをアニメーションにするなら、ファイルを連番で吐いてapngにしてしまうのが楽ちん。

# はじめに

Google Colab上で何か計算して、その計算結果をアニメーションとして見せたい。普通にやるならmatplotlibで可視化するのだろうが、これをColab上でアニメーションにするのはわりと面倒くさい。そもそもColab上で画像を表示するのも、[一度ファイルに吐いてから表示する](https://qiita.com/kaityo256/items/ce34f412ceec1b72755d)のが楽だったりする。

で、アニメーションについてもいろいろ試行錯誤したのだが、結局のところ一度連番ファイルで吐いてしまってから、アニメPNG(APNG)にしてしまうのが一番楽だった。

# サンプルコード

## APNGのインストール

Google Colabの最初のセルで`APNG`をインストールする。

```py
!pip install APNG
```

おそらく問題なくインストールされて「Successfully installed APNG-0.3.3」とか表示されるはず。

## 連番ファイルの出力

なんでもよいので、連番のPNGファイルを吐くコードを書こう。以下は円周上を円が周回するだけのアニメーション。

```py
from apng import APNG
from math import cos, pi, sin
from PIL import Image, ImageDraw
import IPython

def save(index, frames):
    filename = "file%02d.png" % index
    im = Image.new("RGB", (100, 100), (255, 255, 255))
    draw = ImageDraw.Draw(im)
    x = 30*cos(2*pi*index/frames) + 50
    y = 30*sin(2*pi*index/frames) + 50
    draw.ellipse((20,20,80,80),outline=(0,0,0))
    draw.ellipse((x-5, y-5, x+5, y+5), fill=(0, 0, 255))
    im.save(filename)
    return filename
```

後で`APNG`にわたすので、ファイル名を返している。

## APNGに渡してアニメーションを作成

`APNG`は、ファイルリストを食わすとAPNGにしてくれるメソッド`from_files`があるので、それにファイルリストを食わせて、`save`で適当なファイル名で保存する。

保存したファイルは`IPython.display.Image`でそのまま表示できる。

```py
files = []
frames = 50
for i in range(frames):
    files.append(save(i, frames))
APNG.from_files(files, delay=100).save("animation.png")
IPython.display.Image("animation.png")
```

実行結果はこんな感じ。

![animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/3c08464d-18c6-d05f-cc97-cdf42c9da01c.gif)

セルを実行したら、無事にGoogle Colab上でアニメーションが表示された。

# まとめ

Google Colab上でアニメーションを表示させる方法を紹介した。数値計算のシミュレーションや、何か動くものの可視化なんかをする場合、Matplotlibで頑張るより、PILで連番png吐いてAPNG作っちゃう方が楽だと思う。
パワーポイントでプロジェクションマッピングやってみた

## 前書き

プロジェクションマッピングがカッコイイので試してみたい。
PowerPointで出来るらしい。30分位でできた。
![ezgif-4-26d7e8269086.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109904/fafd6b1c-1d8e-8813-15ca-1d8dd653e59c.gif)

## 必要機材

* PC
    * ソフト：Power Point
* プロジェクター
* 箱

## 試した

http://s-hashimoto.org/?p=322
この記事をもとに試してみた。
下記引用（要約）

> * プロジェクタ設定
    * PCのプロジェクタ出力をミラーリングではなく、2画面に変更
    * PowerPointの「スライドショー」→「スライドショーの設定」を選び、「複数モニタ」の設定で「スライドショーの表示」をプロジェクタに設定
* PowerPoint作成
    * 背景は黒
    * 図形を配置
        * 右クリック「頂点の編集」で箱にフィットするよう修正
    * アイコンとか置いてアニメーションさせるとプロジェクションマッピングっぽい。

こんな感じ
![IMG_3254.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109904/e446fc75-a202-42fa-55d9-943bcd951bfb.jpeg)
![IMG_3253.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109904/78e4b002-567a-f9ee-0b40-b95d4fff5ad4.jpeg)
![IMG_3255.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109904/0c15d0fd-433a-450d-732d-2170588ade0f.jpeg)


気軽にできた。

## 参考リンク

* パワーポイント アニメーションの繰り返し
    * https://office-powerpoint.com/powerpoint-animation/ppt108.html
swiftでポップアップの値渡しを簡単に実装する方法

はいどうもこんにちは

相変わらずGithubがろくすっぽ使えませんが何とか生きています

いつもハマった話ばかり書いていますが、今日は別にハマっていないけど、デリゲートでコールバックするより綺麗だなと思ったので書きます！

デリゲートは沢山コールバックをするならひとまとめにできるのでわかりやすいのですが、一つコールバックしたいってくらいだとこっちのがシンプルで楽な気がします。

特にポップアップが閉じられた時にコールバックしたことってよくあると思うのですが、今回はそれです。


方針としては

**1. ポップアップのコントローラに"メソッドの入れ物"を配置
2. ポップアップを開く前のコントローラに、ポップアップを開くときのコードと、ポップアップが閉じたあとの処理を実装
3. ポップアップのコントローラに閉じるボタンを押されたときの処理を実装**

こんな流れです

それではまずは

#1. ポップアップのコントローラに"メソッドの入れ物"を配置

メソッドの入れ物です。今はまだ空っぽです。
これを置いておくことで、渡されたメソッドをポップアップのクラスで実行することができます。

```swift:PopupVC.swift
class PopupVC: UIViewController {
    // メソッドの入れ物みたいなものです
    var emptyClosure: (() -> Void)?
}
```

#2. ポップアップを開く前のコントローラに、ポップアップを開く前の処理と閉じた後にやりたい処理を実装

特筆すべき点はありませんが、ポップアップのVCの開き方はケースバイケースなのでよしなにお願いします。


```swift:SomeVC.swift
class SomeVC: UIViewController {
    func showPopup(){
        let pupupVC = (略)（何かしらの方法でポップアップのコントローラをここに）
        // ここで入れ物にメソッドを渡します
        pupupVC.emptyClosure = {self.hogeMethod()}
        // (ここで何かしらの方法でポップアップを開く処理を書きます)
    }
    func hogeMethod(){
        // (ポップアップが消えたときにやりたい処理)
    }
}
```


#3. ポップアップのコントローラに閉じるボタンを押されたときのコールバック処理を実装

既に2.で空だった入れ物にはメソッドが入りました。

そしてここでdismiss()のcompletionにて、閉じるときにSomeVCで定義したメソッドを発動します。


```swift:PopupVC.swift
class PopupVC:UIViewController {
    // 空の入れ物でしたが、既にこいつはメソッドをもっています
    var emptyClosure: (() -> Void)?

    @IBAction func closeBtnAction(_ sender: UIButton) {
        self.dismiss(animated: false, completion: {
            // UIViewControllerが閉じられると共に実行します
            self?.emptyClosure!()
        })
    }
}
```


こんな感じでシンプルにコールバック処理が書けました。

コールバックの量が多い場合はdelegateを使った方が保守性は高いかもしれませんが、簡単なものならこれでもいいですね
MacでFireFoxのタブを左側に配置し、上部のタブの領域を削除（非表示）する方法

PCを変えるたび、イライラしながら設定しているので書いておきます。

## アドオン【ツリー型タブ】をインストールします。

ツリー型タブ (Tree Style Tab)

https://addons.mozilla.org/ja/firefox/addon/tree-style-tab/

これをインストールするだけでタブがいい感じになります。


デフォルトだと右側にツリー型タブがでてきますが、お好みで右側にツリー型タブ移動させましょう。

<img width="217" alt="スクリーンショット 2019-08-20 15.36.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186346/6be79bd9-037f-5960-54e4-2627c78bb4a4.png">


このままだと画面上部にタブが表示されたままです。
非常に鬱陶しいので非表示にしていきます。

## 上部のタブを非表示に

ブラウザ右上のハンバーガーメニューから、
【ヘルプ】→【トラブルシューティング情報】をクリック。

<img width="288" alt="スクリーンショット 2019-08-20 15.41.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186346/f8cae34f-e85d-ee13-0db8-a4dad59e8e07.png">


<img width="288" alt="スクリーンショット 2019-08-20 15.41.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186346/1e9caa44-eb2d-b5e7-bc09-ea409770eeb2.png">

そして表示された画面上に、

<img width="259" alt="スクリーンショット 2019-08-20 15.44.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186346/a2376ad2-69d8-36b5-812e-172fae969284.png">

というのがあるので、【Finderに表示】をクリック

すると２つくらいフォルダがありますが、
なんちゃら-releaseっていうのほうのフォルダの中に入ります。

フォルダの中に入ったら、【chrome】というフォルダを新たに作ります。
（すでにある場合は特になにもしなくてよいです）

そのフォルダの中に、
`userChrome.css`
というファイルを作成し、

```css
/* タブバーを非表示にする */
#tabbrowser-tabs {
    visibility: collapse !important;
}

/* サイドバーのヘッダーを消す */
#sidebar-header {
    display: none;
}

/* サイドバー幅の制限をなくす */
#sidebar-box {
    overflow-x: hidden !important;
}
#sidebar {
    min-width: 0px !important;
    max-width: none !important;
    overflow-x: hidden !important;
}
```

あるいは、

```css
#main-window[tabsintitlebar="true"]:not([extradragspace="true"]) #TabsToolbar > .toolbar-items {
  opacity: 0;
  pointer-events: none;
}
#main-window:not([tabsintitlebar="true"]) #TabsToolbar {
    visibility: collapse !important;
}


/* サイドバーのヘッダーを消す */
#sidebar-header {
    display: none;
}
```

※こっちのほうがいいかも。

上記の内容を貼り付けます。
※フォルダの中にファイルを作成する仕方がわからない場合は（僕ですが）適当な場所にテキストエディタとかで保存しておいて持っていくとか、ターミナルソフトとかで直接そのディレクトリまで移動して作成してもよいと思います。

参考：https://turtlechan.hatenablog.com/entry/2019/11/09/193440
参考：https://github.com/piroor/treestyletab/wiki/Code-snippets-for-custom-style-rules#for-userchromecss

ここまでやったら、firefoxを再起動することで、いい感じになると思います。
幸せいっぱいですね。
CircleCIで複数のイメージを利用する場合の注意点

# 発生した事象
CICDフローにおいて、CircleCi上でrspecを実行するために準備として`rails db:create`を実行した。
しかし、実行中にDB接続エラーが発生した。
# 結論
CircleCIのジョブ実行において複数のイメージ指定する場合、DBの接続ホスト指定は`localhost`を指定ではなく`127.0.0.1`を使おう。

# 失敗時のエラーメッセージ
```
rails aborted!
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")
```
良くあるrailsからDBへの接続エラーですね。  　　
ローカルのmysqlを参照しにいこうとしている様子。

# 現状の設定見直し
接続エラーなので、DBの接続情報の設定を見直してみる。

## Circleciの`config.yml ` 
接続コマンドや環境変数や`RAILS_ENV`も適切で問題なさそう。
## Ruby on Railsで利用している `database.yml` 
設定ファイル上に、DB接続ホスト、ユーザ名、DB名が指定してあるため接続には問題なさそう。

# 調査

調査を進めると次の記事にヒットしました。
> また、各コンテナ間の連携には localhost を使うことはできません。 127.0.0.1 を指定するようにすることと、Rails であれば config/database.yml で以下のような記述を追加することを忘れないようにしましょう。
https://tech.smarthr.jp/entry/2017/07/12/073000

# 対応
上記の記事より、本件も同一事象と仮定しrailsで指定しているDBのhost指定を、`localhost`ではなく、`127.0.0.1`に変更し動作確認。

# jobの確認
```
#!/bin/bash -eo pipefail
bundle exec rails db:create
bundle exec rails db:migrate
bundle exec rspec
Created database 'hoge'
(中略)
Finished in 0.00373 seconds (files took 0.87988 seconds to load)
```
実行も完了し、ジョブも正常終了したのでOK！。
すぐに忘れる phpcs を設定する際に使うコマンド 

※phpcsにpathが通っている前提です。

# 現在使用可能な規約

```
$ phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1 and PSR12
```

# 自作ルールの格納ディレクトリを確認

```
$ phpcs --config-show
Using config file: /Users/hoge/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer.conf

installed_paths: /Users/hoge/.phpcs
# installed_paths: 〜 が自作ルールを入れるフォルダ。
```


# 自作ルールの格納ディレクトリを指定

```
# installed_pathsは上書きされるので注意。（この場合 /Users/hoge/.phpcs の指定が消える。）
$ phpcs --config-set intalled_paths path/to/standarts/dir
```
[mysql] ユーザのIP制限を確認する

前提 : rootになれる

rootになってからスタート

```mysql
mysql> use mysql;
mysql> select * from user\G

*************************** 1. row ****************************
                  Host: 10.20.30.40
                  User: mike.neko
              Password: 
```

mike.neko ユーザは 10.20.30.40 からのIPからしか許可していないことが確認できる
Vue.jsのvuetifyコンポーネント「v-file-input」で、ファイル名を取得する方法


初投稿となる新米Webエンジニア（３０代ですが汗）なので、初歩的な内容ですがご了承ください。

Vue.jsのvuetifyテンプレートを使ってアプリ開発に挑戦しているのですが、その際に「ファイルの選択→アップロード」という作業が必要になり、input要素で選択したファイル名を取得する必要がありました。

vuetifyコンポーネントの[v-file-input]を使ったファイル名取得がわからなかったので、備忘録として残しておきます。


<h1>vuetifyコンポーネント「v-file-input」で、ファイル名を取得する方法<h1/>

やり方はすごく簡単でした。



```
template側

<v-file-input
  @change="getFileName"
  accept="image/*"
  label="File input"
></v-file-input>
```

```　
method側

   getFileName(e) {
      console.log("fileが選択されました。");
      console.log(e.name);      
    },
```

この際、(e.name)の部分を（e.size）などと指定したりして、いろいろな情報の取得ができます。VisualStudioCodeで「e.」と入力すると、自動で候補がでてきてくれるのでありがたい。
(※Vueプラグイン入れたからかもしれません)

vuetifyを使った場合、この方法で選択したファイル名を取得するのが簡単そうです。
AlibabaCloud DATAVでフィルタする方法

#追記

下記の件はTableStoreというAlibabaCloud固有のNoSQLを題材していますが、
先日、TableStore用のJSONのクエリにはコールバックIDが使えないということわかりました。
別記事でまとめたいですが、こちらに備忘しておきます。

-----
DataVには参照結果をフィルタする機能がある。

ドキュメントには詳細は書かれていないがJavascriptでフィルタ条件を記載するっぽいのでやってみた。

```json
[
{"uid":0,"address":"China","age":0},
{"uid":1,"address":"China","age":1},
{"uid":2,"address":"China","age":2},
{"uid":3,"address":"China","age":3},
{"uid":4,"address":"China","age":4}
]
```

javascriptのフィルタサンプル

```js
function filter(data){
var newData = data.filter(function (item, index) {
  if (item.uid != 0) return true;
});

data = newData;
return data;
}
```

#設定イメージ

こん感じで書く

<img width="541" alt="スクリーンショット 2019-08-20 15.43.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/6230ea24-883c-3504-e253-3950c9ef08ec.png">

プレビューを押せばフィルタされているのが確認できる。
jsあんまり触らない人だとちょっとよくわからないので投稿しておきます。
Enum制約下のジェネリック・クラスでenumとintの相互キャスト (C#)

# 前提
- C# 7.3

# やりたいこと
- ジェネリックなenumを扱うクラス`class <TEnum> where TEnum : System.Enum`で、`TEnum`と`int`を相互に変換したい。

# できなかったこと
普通にキャストしてみたところ、コンパイラが「このキャストはできない」とエラーを吐きました。

```cs:
public class EnumeratedArray<TEnum, TObj> where TEnum : Enum {
	private TObj [] objects;
	public TObj this [TEnum n] { get { return objects [(int) n]; } } // エラー
	public TEnum this [TObj o] { get { return (TEnum) Array.IndexOf (objects, o); } } // エラー
}
// この例は、やりたいことを端的に表現したもので、やりたいことそのものではありません。
```

通常であれば、intとenumの相互キャストは可能なはずで、ジェネリックだからできないのでしょうね。

# できたこと
System.Objectとの変換メソッドを使いました。

```cs:
public class EnumeratedArray<TEnum, TObj> where TEnum : Enum {
	private TObj [] objects;
	public TObj this [TEnum n] { get { return objects [Convert.ToInt32 (n)]; } }
	public TEnum this [TObj o] { get { return (TEnum) Enum.ToObject (typeof (TEnum), Array.IndexOf (objects, o)); } }
}
```

とはいえ、この方法なら、型制約がなくても(7.3未満でも)書けてしまうんですね。

# わかったこと
- C# 7.3でEnum制約が書けるようになったけど、存外と制限が厳しい。

# 蛇足

```cs:EnumeratedList.cs
using System;
using System.Collections.Generic;

/// <summary>EnumでインデックスするList</summary>
/// <typeparam name="TEnum">インデックスの型</typeparam>
/// <typeparam name="TObj">要素の型</typeparam>
public class EnumeratedList<TEnum, TObj> : List<TObj> where TEnum : Enum {

	/// <summary>インデックスが範囲内か調べる</summary>
	public bool ContainsKey (TEnum n) {
		var index = Convert.ToInt32 (n);
		return (index >= 0 && index < this.Count);
	}

	/// <summary>正引き</summary>
	public TObj this [TEnum n] => this [Convert.ToInt32 (n)];

	/// <summary>逆引き</summary>
	public TEnum EnumOf (TObj o) => (TEnum) Enum.ToObject (typeof (TEnum), this.IndexOf (o));

}
```

素直に`Dictionary<TEnum, TObj>`を使っておけと言われそうですね。



# 参考
以下を参考にさせていただきました。

- [New C# 7.3 feature allowing Enum as a generic type constraint is useless as implemented - Developer Community](https://developercommunity.visualstudio.com/content/problem/254082/new-c-73-feature-allowing-enum-as-a-generic-type-c.html)
- [C# によるプログラミング入門 > [オブジェクト指向] ジェネリック > C# 7.3 での追加 ～ ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/sp2_generics.html#cs7.3)

いつもありがとうございます。
ターミナルでrubyのコマンドが使えなくなった　rails sやrails cなど

devise　gemをインストールしたり、間違ったらファイルを全部削除したりしていたら `bundle exec rake db:create` や`rails c`や`rails s`などが使えなくなってしまった。以下エラー文。

```
AkiyoshinoMacBook-Pro:人生逆転7 aki$ bundle exec rake db:create
bundler: failed to load command: rake (/Users/aki/.rbenv/versions/2.6.2/bin/rake)
Gem::Exception: can't find executable rake for gem rake. rake is not currently included in the bundle, perhaps you meant to add it to your Gemfile?
  /Users/aki/.rbenv/versions/2.6.2/lib/ruby/2.6.0/bundler/rubygems_integration.rb:462:in `block in replace_bin_path'
  /Users/aki/.rbenv/versions/2.6.2/lib/ruby/2.6.0/bundler/rubygems_integration.rb:482:in `block in replace_bin_path'
  /Users/aki/.rbenv/versions/2.6.2/bin/rake:23:in `<top (required)>'
```
some random test

>Euler's formula (in the field of electronics)

# code block
```latex:euler.tex
e^{j\theta}=\cos{\theta}+j\sin{\theta}
```

# math block
```math
e^{j\theta}=\cos{\theta}+j\sin{\theta}
```

# embedded
Now in a sentence; $e^{i\theta}=\cos{\theta}+j\sin{\theta}$

# link
https://en.wikipedia.org/wiki/Euler%27s_formula

# extra
```math
\bar{L}(f(\boldsymbol{x}), \bar{Y})=\frac{1}{K - |Y|}\sum_{y' \not\in \bar{Y}}{\ell(g_y'(\boldsymbol{x}))} + \frac{1}{|\bar{Y}|}\sum_{\bar{y} \in \bar{Y}} \ell(-g_{\bar{y}}(\boldsymbol{x}))
```
ザックリまとめ Path Aggregation Network for Instance Segmentation論文

# Path Aggregation Network for Instance Segmentation論文まとめ
- 2018年3月にsubmitされた論文
- [arXivはこちら](https://arxiv.org/abs/1803.01534)
- 略称としてPANetと呼ばれることが多いです。

## 関連論文
- [Feature Pyramid Network for Object Detection論文](https://arxiv.org/abs/1612.03144) 2016年発表
- [Mask R-CNN論文](https://arxiv.org/abs/1703.06870)　2017年発表 →[こちら](https://qiita.com/chobaken/items/3cb5f43ecff2d388f95b)からInstance segmentation,Mask R-CNNの内容を含むザックリまとめに飛べますので、よかったら見てやってください。

本論文はMask R-CNNを改良して、より精度の高いInstance Segmentationを目指した論文になります。

では本論文の概要から見ていきましょう。

## PANet論文概要
PANetの特徴は以下の点になります。
1. Mask R-CNNをベースにした手法
2. 異なるレベルの空間的な特徴量を利用した

Mask R-CNNの弱点として、SegmentationやObject Detectionを行う部分が入力層から離れており、広い受容野の特徴量のみが利用されます。
しかし、精度の高い出力を行うには、より狭い範囲を捉えた特徴量が必要になるため、入力に近い層の情報もうまく活用することが重要になると考えられます。
そこで、本論文では情報の流れ方を変更することでより精度の高い出力を達成しました。

考え方はとてもシンプルな手法です。早速ですがモデル概要図を見ていきましょう。

## PANetモデル
![スクリーンショット 2019-08-20 14.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391968/4bd281d4-fee6-3113-d349-46209c2b9bb4.png)

本論文より引用しました。
上図の(a)〜(c)がいわゆる特徴量抽出にあたり、(d),(e)はそれぞれObject DetectionとSegmentationを担う部分になります。

このモデルのベースとなったMask R-CNNとの大きな違いは「特徴量抽出」の部分の(b),(c)になります。

(a)はFPNをベースとした抽出器になっており、複数のスケールで予測をおこない、さらにそこに特徴量マップを注入していく構造になっています。

(b)では、入力に近い層がより局所的な特徴を捉えるという考えに基づき、low lebelからtop lebelへの接続を緑、赤の点線で行なっています。

(c)では、それぞれのスケールに適した重み付けを行なってpoolingを行います。この部分の実装はMask R-CNNで使われているRoIAlignを利用しています
このAdaptive feature poolingは以下の図でより詳しく説明されています。
![スクリーンショット 2019-08-20 15.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391968/d0edec81-c7e4-9a46-5102-35fb55ad6de1.png)


これによって、様々なスケールから得られた特徴量を、どの程度の割合で利用すれば良いかが学習されます。

(d)に関してはMask R-CNNとあまり差がないので説明は割愛させていただき、(e)の説明に移ります。

Mask R-CNNとの変更点はクラス予測と前面/後面予測を二つのbranchに分けたことです。具体的な構造は以下のような図になります。
![スクリーンショット 2019-08-20 15.11.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391968/5bee89d9-d276-cfcd-2687-f7dc86e7c533.png)

Mask R-CNNではConvolutionのみの処理がなされていますが、本論文では全結合層の処理が追加されています。
Convolutionによって要素数が少なくなっているので、比較的軽量な処理になっています。


以上がPANetのモデルとなります。一番上の画像が全てを語り尽くしてる感がありますね。

### コメント
- Mask R-CNNを知っていたら理解しやすい気がします
- 手前味噌で恐縮ですが、[ザックリまとめ HTC](https://qiita.com/chobaken/items/3cb5f43ecff2d388f95b)(上でも貼ったリンクです)に目を通していただけると理解しやすくなると思います

最後までお読みいただきありがとうございました！
ご質問等あればお気軽にコメントください！
Pocessingでライブカメラから顔を検出して、立方体の一面に貼り付ける

OpenCVで顔を検出するプログラムと、立方体の一面にテクスチャとして画像を貼り付けるプログラムを組み合わせました。



//OpenCVによる顔検出
import gab.opencv.*;
import processing.video.*;
import java.awt.*;
Capture video;//ビデオキャプチャー
OpenCV opencv;//OpenCV

PImage img;

float rx = 0.0;//x軸周りの回転角度
float ry = 0.0;//y軸周りの回転角度
float rz = 0.0;//z軸周りの回転角度


void setup(){
  size(640,480,P3D);//3Dモード
  strokeWeight(0.05);
  
    //ビデオキャプチャー初期化
  video = new Capture(this,640,480);
  //OpenCV初期化
  opencv = new OpenCV(this,640,480);
  //顔の学習データを読み込み
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
  video.start();
  
}

void draw() {
  //画面をリフレッシュ
  background(31);
    opencv.loadImage(video);
  Rectangle[] faces = opencv.detect();
  
  translate(width/2,height/2,0);
  
  //回転
  rotateX(rx);//x軸周り
  rotateY(ry);//y軸周り
  rotateZ(rz);//z軸周り
  scale(100);//50倍に拡大
  
  
  //テクスチャをマッピングした立方体を描画
  if (faces.length>0) {
  makeTexturedCube(video.get(faces[0].x,faces[0].y,faces[0].width,faces[0].height));
  }
  
}


void makeTexturedCube(PImage img){
  
  beginShape(QUADS);
  //前面
  texture(img);
  vertex(-1,-1,1,0,0);//頂点1
  vertex(-1,1,1,0,img.height);//頂点2
  vertex(1,1,1,img.width,img.height);//頂点3
  vertex(1,-1,1,img.width,0);//頂点4
  endShape();
  
  //後面
  beginShape(QUADS);
  fill(0,255,0);//緑
  vertex(-1,-1,-1);//頂点5
  vertex(-1,1,-1);//頂点6
  vertex(1,1,-1);//頂点7
  vertex(1,-1,-1);//頂点8
  
  //上面
  fill(0,0,255);//青
  vertex(-1,-1,1);//1
  vertex(-1,-1,-1);//5
  vertex(1,-1,-1);//8
  vertex(1,-1,1);//4
  
  //底面
  fill(255,255,0);//黄
  vertex(-1,1,1);//2
  vertex(-1,1,-1);//6
  vertex(1,1,-1);//7
  vertex(1,1,1);//3
  
  //左面
  fill(255,0,255);//マゼンタ
  vertex(-1,-1,1);//1
  vertex(-1,1,1);//2
  vertex(-1,1,-1);//6
  vertex(-1,-1,-1);//5
  
  //右面
  fill(0,255,255);//シアン
  vertex(1,-1,1);//4
  vertex(1,1,1);//3
  vertex(1,1,-1);//7
  vertex(1,-1,-1);//8
  
  endShape();
}


void mouseDragged() {
  rx = mouseY *0.1;
  rz = mouseX *0.1;
}

//キャプチャーイベント
void captureEvent(Capture c) {
  c.read();
}
自分で撮った写真に隠し署名をつけよう

#はじめに
最近流行りのソーシャルメディアのおかげで自分が撮影したオリジナルの写真を世の中に見てもらえる機会が増えてモチベーション向上につながるが、その一方、画像のコピーやスクリーンキャプチャーで著作権侵害が生じる恐れも増えていると思う。
その防止策として、自分で撮影した写真に何らかの形で隠し署名を入れておくことを考えられる。
署名を入れておく方法もいろいろある中、よく知られている一つの簡単な方法は、例えば、カラー画像（RGB）のR,GかBのいずれかの最下位Bitに[0,1]の組み合わせで何らかの署名をつけておくことである。
本稿では、MATLABを使ってそのようなことをやってみた。

#署名を追加する方法の概要
カラー画像はR（赤色成分）、G（緑色成分）、B（青色成分）の組み合わせであり、それぞれの成分画像が２次元の行列になっている。例えば、よく目にするM×N画素数の画像は、実は、R、G、Bそれぞれに対するM×N行列を合わせ、合計 M×N×３の行列になっている。この、M×N行列のそれぞれの要素を画素（ピクセル）という。一般的に、８ビット画像だと、画素一つ一つが０～２５５の間の一つの値（以下、ピクセル値）を持っている。１０ビット画像だとその範囲が０～１０２３になるという。
署名を追加する方法では、例えば、青色成分のB画像のすべてのピクセル値の最下位ビットを０にすると、ピクセル値が奇数の画素に対してその値が１だけ減り、全体的画像の見た目にほぼ影響を及ばないと言える。
この処理によって、B画像のすべてのピクセル値の最下位ビットが空くので、そこに、[0,1]の組み合わせで作ったバイナリ（１ビットの白黒）画像（例えば、黒い背景で白いテキストが見えるような画像）を足し算して簡単に署名を追加できる（この追加でも上記同様に、画像の見た目に影響がほぼ出ないといえる）。

#環境
Windows上でMATLABを使っている。そのバージョン、と、ツールボックスリストは以下になる。

```MATLAB
>> version
    '9.6.0.1072779 (R2019a)'
>> license('inuse')
image_toolbox
matlab
video_and_image_blockset
```

#処理のステップ
以下、MATLABコードを使いながらそのステップを示す。

###ステップ１：元画像に合わせ、署名画像を作成
まずは、画像を読み込む。今回は、MATLABに入っている'pears.png'を使用。

```MATLAB:
'I = imread('pears.png');%変数Iに画像を読み込んだ'
```

次は、何らかの署名入り白黒画像を作成する。

```MATLAB:
signText = 'Don Quixote';%署名内容
fontsize = 25;%フォントサイズ
bI       = zeros(size(I,1),size(I,2));%空の背景（黒）画像を作成
position = [10 size(I,1)/2-10 size(I,2)*0.8 size(I,1)*0.3];%署名の位置を指定
```

これで、パラメータがそろったので、後は、署名画像を作成。
※今回はテキスト文字列を埋め込んでみましたが、MATLABのdrawfreehand()関数を利用して自分オリジナルの手書き署名も入れることができる。

```MATLAB:
In      = insertObjectAnnotation(bI,...
    'rectangle',...
    position,...
    signText,...
    'Color',[0 0 0],...
    'TextColor',[1 1 1],...
    'FontSize',fontsize);%署名を挿入（MATLABのビルトイン関数）
In      = rgb2gray(In);%グレー画像
In      = In >=1;%ピクセル値が「1」未満のピクセルの値を０に戻す
```
これによって、下記のような署名画像（０か１のバイナリ画像）が作られる。
![img1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484040/eaa9f414-54e3-ba74-525d-1d85071c7959.jpeg)

###ステップ２：元画像のB成分の最下位ビットに署名画像を加算
この処理は、元画像のB成分で、ピクセル値が奇数の画素について、１を引き算しておくと、B成分のすべての画素の最下位ビットが０を持つようになる。そこに、署名画像（０か１の値を持つ）を足し算するだけで、B成分の最下位ビットに署名のテキストだけが残るようになる。

```MATLAB:
Iout        = I;%出力画像初期化
ind         = mod(Iout,2)>0;%出力画像のピクセル値が奇数の画素を検出
Iout(ind)   = Iout(ind) - 1;%上記検出した画素のピクセル値より１を引き算
In          = cast(In,'like',I);%署名画像の型を元画像と合わせる
Iout(:,:,3) = Iout(:,:,3) + In;%出力画像のB成分に署名画像を入れる
```

###ステップ３：表示確認
元画像、署名を入れた後の画像、を表示する。以下画像をご参考すると、見た目にほとんど差異がないことがわかる。
ここで、例えば、署名を入れた後の画像をソーシャルメディアに投稿すれば、誰かに著作権が侵害されてもクレームできる。その方法については、ステップ４をご参考。

```MATLAB:
subplot(1,3,1), imshow(I), title('元画像')
subplot(1,3,2), imshow(Iout),title('署名入れた後の画像')
```

![img2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484040/5c63a412-4343-9d12-949a-a642aac61a90.jpeg)

###ステップ４：署名の復元
自分の写真の何番目の成分に署名を入れたかのみをパラメータとして持っていれば、いつでもその写真から入れておいた署名の復元ができる。

```MATLAB:
indI = mod(Iout(:,:,3),2)>0;%3番目の成分（B成分）のピクセル値が奇数の画素のみが１になるようなバイナリ画像を作成
subplot(3,1,3), imshow(indI),title('復元した署名') %バイナリ画像を表示
```

#おわりに
今回の投稿では多少遊び間隔で、MATLABによってできる画像処理系の簡単な用途を紹介した。
こんなことがやりたいなど、アイディアがあればぜひ、シェアーしてください。
最後に、面白かったと思われたら、「いいね」をお忘れなく！　:sweat_smile:
homebrewでインストールしたPHPだとtinkerが使えない！？

##tinkerとは？

##PHPのバージョン

PHP7.3.4

##僕の現象
まずはターミナルでtinkerを実行。

```:ターミナル
$php artisan tinker
```

以下のように起動はする。。

```:ターミナル
$php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.4 — cli) by Justin Hileman
>>>
```

MySQLを操作してみる。。。

```:ターミナル
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.4 — cli) by Justin Hileman
>>>App\User::find(20);
$
```

tinkerが終了してしまう。。。。

##解決方法
~/.config/psysh/config.phpに設定を書き込む必要がある！

ターミナルで設定ファイルを起動。

```:　ターミナル
$vi ~/.config/psysh/config.php
```

以下を追記してください！
vimコマンドがわからなければこちらを参考に。
https://qiita.com/kon_yu/items/b8864ff566b8b67a9810
https://qiita.com/hide/items/5bfe5b322872c61a6896

```:~/.config/psysh/config.php
<?php
  return [
    'usePcntl' => false,
  ];
```

##動きました！

```:ターミナル
$php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.4 — cli) by Justin Hileman
>>> App\User::find(20);
=> App\User {#2954
     id: 20,
     name: "アンパンマン",
     email: "anpanman@gmail.com",
     email_verified_at: null,
     created_at: "2019-08-14 15:37:24",
     updated_at: "2019-08-19 16:24:43",
     state: 0,
   }
>>> 
```

##参考
https://teratail.com/questions/169061
https://qiita.com/aoitrain/items/266c2a4b051312607715
Joblibで共有メモリを設定する時につまづいたこと

Pythonで並列処理をしたい時、選択肢としてmultiprocessingかJoblibの二択がまず出てきますが、サクッとやりたい時はJoblibを使うことになると思います。

しかしプロセス毎に参照可能なメモリ領域が異なるため、並列実行している関数から外部スコープの変数に代入するためには共有メモリを設定しなければいけません。そこで以下の記事を参考にValueクラスを使って共有メモリを設定しようとしましたが、

[[Python] Joblibでお手軽並列処理](https://qiita.com/Yuhsak/items/1e8533343cf5458e2e08)


なぜか動きません。試しに記事内に書かれているコードをそのままコピペしても、


~~~python
# -*- coding: utf-8 -*-
from joblib import Parallel, delayed
from multiprocessing import Value, Array

shared_int = Value('i', 1)

def process(n):
    shared_int.value = 3.14
    return sum([i*n for i in range(100000)])

# 繰り返し計算 (並列化)
Parallel(n_jobs=-1)( [delayed(process)(i) for i in range(10000)] )

print(shared_int.value)
~~~
~~~python
RuntimeError: Synchronized objects should only be shared between processes through inheritance
~~~

同様のエラーが起きちゃいます。さあどうしよう。どこも同じやり方しか書いてなくて困った。じゃあ公式リファレンスを見てみよう。

[Embarrassingly parallel for loops](https://joblib.readthedocs.io/en/latest/parallel.html)

>However if the parallel function really needs to rely on the shared memory semantics of threads, it should be made explicit with require='sharedmem', for instance:


~~~python
>>> shared_set = set()
>>> def collect(x):
...    shared_set.add(x)
...
>>> Parallel(n_jobs=2, require='sharedmem')(
...     delayed(collect)(i) for i in range(5))
[None, None, None, None, None]
>>> sorted(shared_set)
[0, 1, 2, 3, 4]
~~~

えっ、Parallelの引数に`require='sharedmem'`設定するだけでいいんですか？試しにさっきのコードを書き換えてみると、

~~~python
# -*- coding: utf-8 -*-
from joblib import Parallel, delayed

shared_int = 1

def process(n):
    global shared_int
    shared_int = 3.14
    return sum([i*n for i in range(10000)])

# 繰り返し計算 (並列化)
Parallel(n_jobs=-1, require='sharedmem')([delayed(process)(i) for i in range(10000)])

print(shared_int)
~~~
~~~python
3.14
~~~

できました。ちゃんと並列化した関数の中から外部スコープの変数に代入できています。

てことで、どうやらParallelの引数に`require='sharedmem'`を入れるだけで共有メモリを設定できちゃうようです。簡単！

でも

>Keep in mind that relying a on the shared-memory semantics is probably suboptimal from a performance point of view as concurrent access to a shared Python object will suffer from lock contention.

>ーー和訳ーー
>共有Pythonオブジェクトへの同時アクセスではロック競合が発生するため、パフォーマンスの観点からは、共有メモリーのセマンティクスに依存するのは最適とは言えないことに注意してください。

とも書いてあるので、気をつけて使ったほうが良さそうです。

##参照
[[Python] Joblibでお手軽並列処理](https://qiita.com/Yuhsak/items/1e8533343cf5458e2e08)

[Embarrassingly parallel for loops](https://joblib.readthedocs.io/en/latest/parallel.html)