OmniAICreator/Qiita-1.07M huggingface dataset:
【React】GithubでSPAサイトを公開するまで

#経緯
JavaScriptの学習を進めていく中で、React Routerを使用したSPAサイトの作成を学び、そのアウトプットとして自身のポートフォリオがてら、サーバー代も痛いのでGithubで無料で公開可能とのことなので、取り組んでみました。
今回はSPAサイトをGithubで公開するにあたっての経験を元に記して行ければと思います。
参考サイト
・https://create-react-app.dev/docs/deployment/#github-pages-https-pagesgithubcom


#条件
既にnode.js,React.jsの環境構築とGithubの登録ができていることを前提に進めていきます。

[node.js公式サイト](https://nodejs.org/ja/)
[React.js環境構築記事](https://qiita.com/komosyu4649/items/b59e3d4776b11c6eab27)
ディレクトリ内構造（node_modules, public,src, README.md, package.json, package-lock.json）


#手順
1.Githubでリポジトリの作成
2.package.jsonの編集
3.Github Pagesへの公開

#1.Githubでレポジトリの作成
<img width="583" alt="スクリーンショット 2020-03-22 12.37.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602592/4e907b83-f734-c79a-4653-fd2296115055.png">
[Github](https://github.com/)にログインして、マイページからリポジトリに移動して、新規で作成するのでNewボタンをクリックし、説明に沿って好きなリポジトリ名で作成します。
<img width="768" alt="スクリーンショット 2020-03-22 12.49.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602592/0e6143a6-b423-7649-77ba-7e83c6cc2eb0.png">


#2.package.jsonの編集

"nameプロパティ"の下に"homepageプロパティ"を作成してURLを記入する。

```ruby:package.json
{
  "name": "repository",
  "homepage": "https://komosyu4649.github.io/repository",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "gh-pages": "^2.1.1",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build",
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
```


・"homepageプロパティ"のURLを以下の要領で記入します。

```ruby:homepageプロパティ
"homepage": "https://自分のGithubアカウント名.github.io/リポジトリ名",
```

・"gh-pagesプロパティ"をインストールします。
ーターミナル内で"npm install gh-pages"のコマンドを入力すると、"gh-pageプロパティ"がインストールされます。

```ruby:gh-pageプロパティ
"gh-pages": "^2.1.1",
```

・scriptに"predeployプロパティ"、"deployプロパティ"の順で追加します。

```ruby:scripts
 "predeploy": "npm run build",
 "deploy": "gh-pages -d build",
```

#3.Github Pagesへの公開
ここまでで準備が整いました。
最後に、ターミナル内に"npm run deploy"のコマンドを入力し、GithubのURLが出力されれば成功です。
終わったら、Githubに戻りリポジトリを確認し、"gh-pages"ブランチができたことを確認しましょう。
無事表示されていれば問題ありません。
Githubにて無料でサイトを公開することができるようになるはずです^^
Next.js(React)でのCORSエラー解決（Next.js + Golang）

# Next.jsでのCORSエラー解決（Next.js + Golang）
React + GoでSPAを作りたく、ReactフレームワークのNext.jsを使ってみた。
SPAの最初で躓きがちなCORSエラーについて、案の定ハマったのでメモ。（Angularでの開発の際もだいぶハマった思い出）

## CORSエラーが出る
今回のようにフロントエンド、バックエンドでサーバを分けて開発する際に、そのままだとCORS(Cross-Origin Resource Sharing)についてのエラーが発生する。

これはブラウザの機能として、クロスドメイン（ドメインの違うサーバへの）アクセスが制限されているため起きます。
例えば、フロント `http://localhost:3000` , バック `http://localhost:5000` とした時、フロントからバックのapiを叩こうとするとcorsエラーとなります。（ドメイン違うので）

正常にapi叩くにはこれを解決する必要があります。


## Next.jsではカスタムサーバを利用し、プロキシする
Next.jsでカスタムサーバを使用するため、 プロジェクトルートに`server.js` を作成します。

また、 `http-proxy-middleware` というパッケージを使い、任意のリクエストをプロキシします。

```server.js
const express = require('express');
const next = require('next');
const { createProxyMiddleware } = require('http-proxy-middleware');

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const API_URL = process.env.API_URL || 'http://localhost:5010'

const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express();

  server.use(
    '/api',
    createProxyMiddleware({
      target: API_URL,
      pathRewrite: {
        "^/api": ""
      },
      changeOrigin: true
    })
  );

  server.all('*', (req, res) => {
    return handle(req, res)
  });

  server.listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  });
});
```

カスタムサーバを利用してサーバ起動するので `package.json` を修正します。

```package.json
...
"scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  },
...
```

これで `yarn dev` でカスタムサーバで立ち上がります。

### リクエストがプロキシされる
上記により、 `/api` へのリクエストは `http://localhsot:5010` にプロキシされます。
例えば `/api/auth` へリクエストした場合、 `http://localhost:5010/auth` にプロキシされます。

`pathRewrite` の記述を消せば `http://localhost:5010/api/auth` にアクセスします。


## まとめ
Next.jsのcorsエラーの解決は、カスタムサーバと `http-proxy-middleware` パッケージの利用で解決できます。

また忘れてハマりそうなのでメモしておいた。

> 参考

> [Next.js 公式ドキュメント日本語翻訳プロジェクト - カスタムサーバーとルーティング](https://nextjs-docs-ja.netlify.com/docs#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%A8%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)

>[Nextで特定のAPI リクエストをproxyする方法 - Qiita](https://qiita.com/onigiri_/items/d0c96662e1caeaf8db5f)
Jupyter NotebookのコードをSageMakerのJobとして動かす

## 概要
Jupyter Notebook(.ipynbファイル)をSageMakerのTraining JobやProcessing Jobのスクリプトとして使えるようにするためのライブラリの紹介です。

ライブラリ名: [Sagemill](https://github.com/yuki-mt/sagemill) (SageMaker+Papermill)

## 背景
SageMakerを使っていると大規模データに対する前処理や複雑なモデルの学習など、負荷のかかる処理は大体SageMakerのJobとしてハイスペックなサーバー上で動かす一方で、notebook instanceのスペックはそこまで高くないことが多いと思います。

ただnotebookに書いて動作確認したコードを、いちいちpythonファイルに書き写したりSageMakerのJobの環境設定(独自のdocker imageを使う場合はDockerfileや使用するライブラリの定義など)をするのは面倒です。
そこでnotebook上のコードをそのままSageMaker jobとして起動できたら特に初期の実験段階は便利だと思い作りました。


## Sagemillの機能
詳細は次の[サンプルコード](#サンプルコード)にあるexample notebookを見て頂けたらと思います。

### 1. notebook(=.ipynbファイル)をpythonファイルに変換
notebookのコードをpythonファイルに変換することで、SageMaker jobで使う独自docker imageに加えたり、`sagemaker.tensorflow.Tensorflow`のentrypointや `sagemaker.processing.ScriptProcessor`のcodeとして指定することができます。
#### parameterize notebook
papermillのように"parameters"タグがついたセルで定義した変数は、jobの実行時に値を渡して上書きことができます。
用途としては、

「notebook上で動作確認するときはepoch数が小さいけどSageMaker Training Job上では100 epoch分学習させたい」

といったときに、notebook上では `epochs = 2` にした上で、`sagemaker.estimator.Estimator`のインスタンス作成時に `hyperpameters={'epochs': 100}` を指定することで上の要件が満たされます。

#### SageMaker関係のコードを、作成するpythonファイルから除外
notebookのコードには `sagemaker.estimator.Estimator` などSageMakerのjobを定義するためのコードも書くと思いますが、これらはもちろんjobで実行するスクリプト内に含めてはいけません。
そこでSagemillは"sagemaker"タグがついたセルは作成するpythonファイルからは除外するようにしています。

### 2. SageMaker jobで使う用のdocker imageの作成
これは独自のdocker imageを使うときのみ使用する機能です。
#### テンプレートとなるDockerfileの作成
指定したdirectoryにDockerfileのテンプレート(+Training Jobの場合はentrypoint.shも)を作成する関数があります。
テンプレートなので、もちろん作成後は自由に書き換えられます。

#### requirements.txtの作成
作成したpythonファイルに対して `pipreqs`を実行してrequirements.txtを作成する関数があります。 

#### build image

notebookが動いているサーバーのAWS情報(アカウントIDとリージョン)を基にECRのpush先を決めてimageをbuildする関数があります。
#### ECRへのpush
- 作成したimageをECRにpush
  - notebookが動いているサーバーのIAM RoleからECRへの認証を自動で行う
  - 指定したrepositoryが存在しない場合は自動で作成

する関数があります。

## サンプルコード
Github上ではnotebookのタグが見れないので、どのセルにタグがついてるかは実際に動かして確認してみて下さいmm
### 予め用意されているdocker imageでモデルの学習を行う例
- [サンプルコード](https://github.com/yuki-mt/sagemill/blob/master/example/train_tf.ipynb)
- notebook上のコードをSageMaker Training Jobとして起動
- `sagemaker.tensorflow.Tensorflow`を使用し、tensorflowのモデルを学習


### 独自のdocker imageでモデルの学習を行う例
- [サンプルコード](https://github.com/yuki-mt/sagemill/blob/master/example/train_custom.ipynb)
- notebook上のコードをSageMaker Training Jobとして起動
- Sagemillの関数で自動作成されたDockerfile, entrypoint.sh, requirements.txt, entrypoint.pyをそのまま使用してdocker imageを作成

### 予め用意されているdocker imageで前処理を行う例
- [サンプルコード](https://github.com/yuki-mt/sagemill/blob/master/example/process_sklearn.ipynb)
- notebook上のコードをSageMaker Processing Jobとして起動
- `sagemaker.sklearn.processing.SKLearnProcessor`を使用し、csvファイルを処理

### 独自のdocker imageで前処理を行う例
- [サンプルコード](https://github.com/yuki-mt/sagemill/blob/master/example/process_custom.ipynb)
- notebook上のコードをSageMaker Processing Jobとして起動
- `sagemaker.processing.ScriptProcessor`を使用し、csvファイルを処理
- Sagemillの関数で自動作成されたDockerfile, requirements.txt, entrypoint.pyをそのまま使用してdocker imageを作成
Elasticsearch, Kibanaの勉強用メモ

(自分用メモ, 随時更新)

## 残件

* Logstatshはまたそのうち

## 1. サンプルを動かす
* こちらを参考に以下をやった
   * https://qiita.com/kiyokiyo_kzsby/items/344fb2e9aead158a5545
* Dockerfileなど
    * https://github.com/ki4070ma/elasticsearch-kibana-sample

1. DockerでElasticsearch, Kibanaを構築
2. `curl` を使用してElasticsearchに対していろいろリクエストを送る
    * ローカルにあるサンプルデータ(.json)をElasticsearchへ登録
3. Kibanaで↑で登録したサンプルデータを使ってbalanceに関してPie chartを作成

## 2. Elasticsearchメモ
1. (Tips) 手元でcurlでelasticsearchに対してrequestを送って, jsonを見やすくするためには `jq` を使うと良いかも
   * (参考) https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
2. (Note) ローカルにあるサンプルデータ(.json)をアップロードするとき
  * account.json内にあるようにindexが必要そう
  * [link](https://qiita.com/kiyokiyo_kzsby/items/344fb2e9aead158a5545#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%8A%95%E5%85%A5)
3. サンプルデータ

## 3. Kibanaメモ
1. Pie chartの作成
   * こちらでできた
      * https://dev.classmethod.jp/articles/amazon-elasticsearch-service-kibana6-tutorial-02/
2. Kibanaからデータの登録
   * Machine learning -> DnD
      * きれいなデータになっていればよさそう. filed名もこのときに決められる
   * https://www.elastic.co/jp/blog/importing-csv-and-log-data-into-elasticsearch-with-file-data-visualizer
3. 確認するリンク
   * https://thinkit.co.jp/article/14128

### 作りたいチャート
1. 日付毎の特定の値のカウント(A, B, C)
2. 日付毎のログから特定の値のカウント

## 4. Elasticsearchに入れるデータ
1. TBU

## 5. Elasticsearchにデータ入れたり
https://github.com/elastic/elasticsearch-py を使用すると吉
話題沸騰ポットに対して Property based testing を試してみる (4)沸騰/保温 - 状態遷移に合わせて実装を変更する

#はじめに
[話題沸騰ポットに対して Property based testing を試してみる (3)沸騰/保温 - 状態遷移を考える](https://qiita.com/freddiefujiwara/items/076cbe57cab936b54fc3)に引き続き
[fast-check](https://github.com/dubzzz/fast-check)を使ってProperty based testingを試しています。
題材として
[テスト設計コンテストU-30クラス](http://aster.or.jp/business/contest/rulebooku30.html)でテストベースに指定されている
[「話題沸騰ポット要求仕様書 (GOMA‐1015型) 第７版](http://www.sessame.jp/workinggroup/WorkingGroup2/POT_Specification.htm)にすることにしました.
fast-checkは状態をランダムウォークさせて失敗するテストケースを見つける方法も[実装されてる](https://github.com/dubzzz/fast-check/tree/master/example/004-stateMachine/musicPlayer)みたいですのでそろそろ状態遷移を考えつつこの機能を試していきたいなと考えている今日この頃ですが。。。
今日はproperty-based-testingの話題ではなく、実装の修正中心の話になります

#準備
[こちら](https://github.com/freddiefujiwara/goma-1015/blob/feature/boil/src/lib/index.ts)に今回実装したコードを配置してみました。
Nodejsの環境が手元にあれば、試すことができます。

```bash
git clone https://github.com/freddiefujiwara/goma-1015.git
cd goma-1015
npm i
npm test
```

#_isOpen,connected等の状態を表すものをenum Stateにすべて置き換える

以前のとおり、今後は状態が複雑化するのでちゃんとStateで管理していきましょう
現状状態はoff,open/off,idel,open/onの4つの状態があり、
将来沸騰中、保温中がでてくるので先に定義しておきましょう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817/755e34d5-73a9-63df-a3f1-6e342ca5871c.png)

```JavaScript
export enum State {
  OFF = -1,
  OFF_OPEN,
  ON_IDLE,
  ON_OPEN,
  ON_ACTIVE_BOIL,
  ON_ACTIVE_KEEP,
}
```
isOpenやthis._onで判別していたところをすべてStateをみて書き換えるようにします.
diffを取るとこんな感じです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817/8f8eeb9f-3b08-56ec-674d-f33657ee15ab.png)
結構変えている風ですが、基本は状態遷移をちゃんとswitch文で判別して
然るべき状態に遷移させているだけです

#テストを通してみる
テストが通るまで頑張ってデバッグしましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1817/7b6bdb8d-491e-928b-f919-33c49391b626.png)

基本実装を変えただけでテストコードはほとんど変更してません、
こういうリファクタリングのときにテストコードがあると本当に便利ですよね

#最後に
次こそいよいよ[model-based-testingを実現させて](https://qiita.com/freddiefujiwara/items/80f508c62b75dd273fde)みたいと思います
また、コードにもし間違いありましたら[Pull request](https://github.com/freddiefujiwara/goma-1015)は大歓迎です。
長くなってしまいましたが　最後まで読んでいただきありがとうございました。
checkSelfPermissionがPERMISSION_DENIEDしか返してくれない罠を踏み抜いた話

すでにリリース済みのアプリに対して某広告系ライブラリを入れた時に突如パーミッション関係が軒並みDENIEDを返すようになりパニックになったので自分のための備忘録として。


# 現象
```
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
```
もしくはその後、`requestPermission`をコールした後に`onRequestPermissionsResult`で戻ってきた後の第三引数が全部PERMISSION_DENIEDになる。
ちなみに勿論パーミッションは許可された状態で起きる。
今回の場合はすでにリリース済みのアプリで、このあたりは元々元気に動いていたのに急にスンッ・・・とおかしくなったので事態の把握は楽でした。

# 原因と対応
```
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
```

`AndroidManifest.xml` で定義しているpermissionは上記のような定義だったのだけれど・・・
`Merged Manifest`のほうで確認してみると
![2020-03-22_12h27_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85579/b3f6f2d9-12bf-694b-eb25-9ba14956722c.png)

／(^o^)＼・・・
そう。ライブラリ側で`uses-permission`に`maxSdkVersion`が有り難くも設定されていたのでそもそも`maxSdkVersion`を超えるSDKバージョンの場合は`uses-permission`の定義は無かったことになる。
すなわち`checkSelfPermission`がDENIEDなのは当然の結果だった・・・

ということで、

```
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace" />
```

`node="replase"`指定を追加して、有り難く設定されているライブラリ側の`maxSdkVersion`は無視させて頂くことにした。


# 教訓
新しいライブラリをリリース済みアプリに入れる時は、`Merged Manifest`がどうなっているかちゃんとチェックしようね！ぜったいだよ！
REAPERでノートの情報を得るPythonスクリプト

REAPERでノートのタイミングを数値で得られたら
いろいろ音と同期したビジュアライズにはかどるかと思ったので
作ったメモ

``` GetNoteList.py
RPR_ClearConsole()

outlist = ""

midieditor = RPR_MIDIEditor_GetActive()
take = RPR_MIDIEditor_GetTake( midieditor )

notecntOut = 0
ccevtcntOut = 0
textsyxevtcntOut = 0

( retval, take, notecntOut, ccevtcntOut, textsyxevtcntOut ) = RPR_MIDI_CountEvts(take, notecntOut, ccevtcntOut, textsyxevtcntOut )

for noteidx in range(notecntOut):
  selectedOut = True
  mutedOut = True
  startppqposOut = 0
  endppqposOut = 0
  chanOut = 0
  pitchOut = 0
  velOut = 0

  ( retval, take, noteidx, selectedOut, mutedOut, startppqposOut, endppqposOut, chanOut, pitchOut, velOut ) = RPR_MIDI_GetNote(take, noteidx, selectedOut, mutedOut, startppqposOut, endppqposOut, chanOut, pitchOut, velOut )
  
  outlist += str(pitchOut) + "," + str(startppqposOut) + "," + str(endppqposOut) + "\n"

#RPR_ShowMessageBox("End", "status", 0 )
RPR_ShowConsoleMsg(outlist)
```

これを実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/e7b5c777-d7bd-5b04-659b-568089e1a366.png)

こんな感じで　ノート番号とノートオン、ノートオフのタイミング情報がテキストで得られる。

#TIPS
- 対象となるMIDIEditor(MIDIリージョン)を選択して実行する。
- 時間を最初から知りたい場合は、リージョンをまとめて実行する。
- 途中テンポチェンジだとうまくいかない？



#以下いろいろ試したメモ

## quarter note count (QN)

QNとは、1/4ノートカウント、一小節が4拍として、1拍を表すカウントのよう。
960で1拍っぽい。


##QNからMS（ミリ秒）に変換
```
  start = RPR_TimeMap_QNToTime( startppqposOut)
  end = RPR_TimeMap_QNToTime( endppqposOut)
```
これ、テンポチェンジには対応していないのかな・・・

追記これミリ秒だったら1000で割れば秒になりそうだけど、なぜか960でちょうど良い値になるのはなんだろう？　
**※ヨクワカラン**

##プロジェクトの先頭からの絶対時間で得る
```
  start = RPR_TimeMap_QNToTime_abs(0, startppqposOut)
  end = RPR_TimeMap_QNToTime_abs(0, endppqposOut)
```
とリファレンスには書いてあるけどうまくとれない・・・
**※ので、先頭までエディターの範囲を伸ばす**

```
  start = RPR_TimeMap2_QNToTime(0, startppqposOut)
  end = RPR_TimeMap2_QNToTime(0, endppqposOut)
```
こちらの方が新しいのか・・・違いがよくわからない。
こちらも途中のテンポチェンジには非対応っぽいです。

##Reaperのコンソールログより長い出力の場合の対処
長いデータだとコンソールのログ量をオーバーしていた。
とりあえずテキストコピーできればよかったので

```
import pyperclip

#略

pyperclip.copy(outlist)
```
まぁ、ファイルとかに出力するのが妥当な感じもする。
Go言語でnull値を含むParquetファイルを生成する

## 環境

* macOS Catalina
* Go 1.14
* [parquet-go](https://github.com/xitongsys/parquet-go) 1.5.1
* [pyarrow](https://arrow.apache.org/docs/python/) 0.16.0（確認用）
* [pandas](https://pandas.pydata.org/) 1.0.3（確認用）

## Parquetファイルの生成

このソースコードを`main.go`として保存する。

```go
package main

import (
	"log"

	"github.com/xitongsys/parquet-go-source/local"
	"github.com/xitongsys/parquet-go/writer"
)

type Example struct {
	Col *string `parquet:"name=col, type=UTF8"`
}

func main() {
	fw, err := local.NewLocalFileWriter("example.parquet")
	if err != nil {
		log.Fatal(err)
	}

	pw, err := writer.NewParquetWriter(fw, new(Example), 4)
	if err != nil {
		log.Fatal(err)
	}

	row0 := "foo"
	row2 := "bar"
	rows := []*string{&row0, nil, &row2}
	for i := 0; i < 3; i++ {
		ex := Example{Col: rows[i]}
		if err := pw.Write(ex); err != nil {
			log.Fatal(err)
		}
	}
	if err = pw.WriteStop(); err != nil {
		log.Fatal(err)
	}
	fw.Close()
}
```
null値を含むParquetファイルを生成する上で重要なのは、下記行である。

```go
	Col *string `parquet:"name=col, type=UTF8"`
```
つまり、`string`ではなく`*string`を指定することで、parquet-goの[README.md](https://github.com/xitongsys/parquet-go/blob/v1.5.1/README.md#repetition-type)にある通りRepetition TypeをOPTIONALにする。

作成したファイルに対して`go run main.go`を実行すると、`example.parquet`が生成される。

## Parquetファイルの確認

下記のPythonスクリプトを使えば、確かにnull値を含むParquetファイルが生成されたことを確認できる。

```python
import pyarrow.parquet as pq

table = pq.read_table('example.parquet')
print(table.to_pandas())
```

このファイルを`read.py`として保存し、`python3 read.py`を実行すると

```
    col
0   foo
1  None
2   bar
```
と出力される。

もちろんGo言語でも、この`example.parquet`を読み込める。

```go
package main

import (
	"fmt"
	"log"

	"github.com/xitongsys/parquet-go-source/local"
	"github.com/xitongsys/parquet-go/reader"
)

type Example struct {
	Col *string `parquet:"name=col", type=UTF8`
}

func main() {
	fr, err := local.NewLocalFileReader("example.parquet")
	if err != nil {
		log.Fatal(err)
	}
	pr, err := reader.NewParquetReader(fr, new(Example), 4)
	if err != nil {
		log.Fatal(err)
	}
	num := int(pr.GetNumRows())
	ex := make([]Example, num)
	if err := pr.Read(&ex); err != nil {
		log.Fatal(err)
	}
	for i := 0; i < num; i++ {
		col := ex[i].Col
		if col != nil {
			fmt.Println(*col)
		} else {
			fmt.Println("<nil>")
		}
	}
	pr.ReadStop()
	fr.Close()
}
```


このファイルを`main.go`として保存し、`go run main.go`を実行すると

```
foo
<nil>
bar
```
と出力される。
TWELITE 簡単アプリで電波状況の確認テスト

# やること

TWELITEを2台使って、通信している間の電波状況を確認します。
ファームウェアは、出荷時に内蔵している簡単アプリを使います。

1台を親機、もう1台を子機に設定。

親機でUSBシリアルモジュール経由でPCにつないで、データを取得します。
子機から送信したデータを親機で受信し、電波強度を確認します。

# 配線

## 親機側

![IMG_20200322_103122.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/54e063df-936f-b8b6-98f9-8ec9f990bdd5.jpeg)

|TWILITE 端子|信号名|接続先|
|:---:|:---:|:---:|
|VCC||USBシリアルモジュール 3.3V|
|GND||USBシリアルモジュール GND|
|RXD|RX|USBシリアルモジュール TX|
|TXD|TX両方|USBシリアルモジュール RX|
|10|M1|GND|



## 子機側


![IMG_20200322_103206.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/aa51b582-ab00-7da6-c124-7790a27d1fd2.jpeg)

|TWILITE 端子|信号名|接続先|
|:---:|:---:|:---:|
|VCC||スイッチ(ジャンパー)経由でバッテリー + |
|GND||バッテリー - |
|12|DI1|スイッチ経由でGND|

 2.0V〜3.6Vの電圧を持つ、バッテリーにつなぎます。

# USBシリアルと通信ソフト

PC で USBシリアルからの信号が表示できるようにしておきます。
通信条件は以下の通り

- 115200bps
- 8N1（8bit パリティ無し ストップビット1)
- フロー制御 なし


# 起動メッセージ

親機の起動時には、以下のように起動メッセージが取得できます。

```

!INF TOCOS TWELITE DIP APP V1-01-3, SID=0x81000F99, LID=0x78
!INF DIO --> 00000000000000000000
```


# 子機からの受信

子機から信号を受信すると親機で以下のような電文が得られます。

```

:78811501B481000F9778031D000BA51D0001390C2207DE64
:78811501C381000F9778033D000BA51D00013C1F480EF3DD
:78811501B181000F97780367000BA51D00013A0A1B04BF47
・
・
・
```

# 電文の解釈

例えば、

```

:78811501B181000F97780367000BA51D00013A0A1B04BF47
```

これの、電文の内訳は https://mono-wireless.com/jp/products/TWE-APPS/App_Twelite/step3-81.html
によると以下のとおりです。


|カラム|例|意味|
|:---:|:---:|:---:|
|0|:|電文の開始|
|1-2|78|送信元の論理デバイスID|
|3-4|81|コマンド(0x81: IO状態の通知)|
|5-6|15|パケット識別子 (アプリケーションIDより生成される)|
|7-8|01|プロトコルバージョン (0x01 固定)|
|9-10|B1|LQI値、電波強度に応じた値で 0xFF が最大、0x00 が最小|
|11-18|81000F97|送信元の個体識別番号|
|19-20|78|宛先の論理デバイスID|
|21-24|0367|タイムスタンプ (秒64カウント)|
|25-26|00|中継フラグ(中継回数0~3)|
|27-30|0BA5|電源電圧[mV]|
|31-32|1D|未使用|
|33-34|00|DI の状態ビット。DI1(0x1) DI2(0x2) DI3(0x4) DI4(0x8)。1がOn(Lowレベル)。|
|35-36|01|DI の変更状態ビット。DI1(0x1) DI2(0x2) DI3(0x4) DI4(0x8)。1が変更対象。|
|37-44|3A0A1B04|e1～e4: AD1～AD4の変換値。0～2000[mV]のAD値を16で割った値を格納。|
|45-46|BF|ef: AD1～AD4の補正値　（LSBから順に２ビットずつ補正値、LSB側が　AD1, MSB側が AD4）|
|47-48|47|チェックサム|


# 受信電波品質

上記の LQI 値が受信電波品質で 00〜FF の範囲で表され、例では B1 になってます。

B1 は10進数に直すと177となります。

https://mono-wireless.com/jp/tech/Programming/Tips_LQI.html
によると、以下の目安が挙げられています。

- 50未満（悪い -80dbm 未満）
- 50～100（やや悪い）
- 100～150（良好）
- 150以上（アンテナの近傍）

また、以下の計算式で dBm の目安が計算できるそうです。

dBm=(7*LQI-1970)/20

今回の例だとLQIが177なので、-36.55dbm になります。
mecab-python  インストール時のエラー対応

## mecab-python  インストール時にエラーが出る場合
環境 CentOS8 python 3.8.2

```
# dnf install python3-devel
# pip install mecab-python
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting mecab-python
  Downloading https://files.pythonhosted.org/packages/86/e7/bfeba61fb1c5d1ddcd92bc9b9502f99f80bf71a03429a2b31218fc2d4da2/mecab-python-0.996.tar.gz (40kB)
    100% |████████████████████████████████| 40kB 947kB/s
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-9vu16hz5/mecab-python/setup.py", line 18, in <module>
        include_dirs=cmd2("mecab-config --inc-dir"),
      File "/tmp/pip-build-9vu16hz5/mecab-python/setup.py", line 10, in cmd2
        return string.split (cmd1(str))
    AttributeError: module 'string' has no attribute 'split'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-9vu16hz5/mecab-python/

```

setup.py を書き換えて対応する

## ダウンロード
まず mecab-python-0.996.tar.gz をダウンロードして解凍する

```
# wget https://files.pythonhosted.org/packages/86/e7/bfeba61fb1c5d1ddcd92bc9b9502f99f80bf71a03429a2b31218fc2d4da2/mecab-python-0.996.tar.gz
# tar xvzf mecab-python-0.996.tar.gz
# cd mecab-python-0.996
# ls
MeCab.py  MeCab_wrap.cxx  PKG-INFO  README  setup.py
```

## setup.py のコード書き換え
エラーになっている部分を書き換える

変更前

```
def cmd2(str):
    return string.split (cmd1(str))
```

変更後

```
def cmd2(str):
    #return string.split (cmd1(str))
    return cmd1(str).split()
```

## インストール

```
# python setup.py install
```

## 確認

```mecab-test.py
import MeCab

text = '米経済対策、総額220兆円も　GDP10％、外出規制が拡大'
m = MeCab.Tagger ()
words = m.parse (text).split('\n')
for elm in words:
    print(elm)
```

```
# python mecab-test.py
米      名詞,固有名詞,地域,国,*,*,米,ベイ,ベイ
経済    名詞,一般,*,*,*,*,経済,ケイザイ,ケイザイ
対策    名詞,サ変接続,*,*,*,*,対策,タイサク,タイサク
、      記号,読点,*,*,*,*,、,、,、
総額    名詞,一般,*,*,*,*,総額,ソウガク,ソーガク
220     名詞,数,*,*,*,*,*
兆      名詞,数,*,*,*,*,兆,チョウ,チョー
円      名詞,接尾,助数詞,*,*,*,円,エン,エン
も      助詞,係助詞,*,*,*,*,も,モ,モ
　      記号,空白,*,*,*,*,　,　,　
GDP     名詞,一般,*,*,*,*,*
10      名詞,数,*,*,*,*,*
％      名詞,接尾,助数詞,*,*,*,％,パーセント,パーセント
、      記号,読点,*,*,*,*,、,、,、
外出    名詞,サ変接続,*,*,*,*,外出,ガイシュツ,ガイシュツ
規制    名詞,サ変接続,*,*,*,*,規制,キセイ,キセイ
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
拡大    名詞,サ変接続,*,*,*,*,拡大,カクダイ,カクダイ
EOS
```

## エラーが出る場合

```
# python mecab-test.py
Traceback (most recent call last):
  File "mecab-test.py", line 4, in <module>
    m = MeCab.Tagger ()
  File "/usr/local/lib64/python3.6/site-packages/MeCab.py", line 307, in __init__
    this = _MeCab.new_Tagger(*args)
RuntimeError
```

環境変数MECABRCを設定

```
[mecab インストールパス]/etc/mecabrc
```

設定の例

```/etc/profile
export MECABRC=/usr/local/etc/mecabrc
```

## mecabインストール手順
[php-mecabインストール](https://qiita.com/katafuchix/items/c19407f34ac9d23d3b34)
jqueryのonメソッドについて

jqueryのイベント紐づけのonについて書いていきます。

###基本的な使い方

```javascript

$('button').on('click',function(){
    alert('a');
})
```

###データを渡すこともできる

```javascript

var hoge = 'a'
$('button').on('click',{hoge:hoge},function(e){
    alert(e.data.hoge);
})
```
第二引数にjsonを指定するとeで値を渡せます。
これを知るまでグローバルに変数を置いてその値を使うという原始的なことをしていたから、グローバル汚染が大変だった。

###複数のイベントを一度に指定
同じ関数を使うなら半角スペース区切ると指定できます。

```javascript

$('button').on('click touchstart',function(){
    alert('a');
})
```

別の関数を使うならjsonで指定

```javascript

$('button').on({
    click :function(){
       alert('click'); 
    },
    touchstart :function(){
        alert('touchstart');
    }
})
```

###後から追加された要素も対象にする
```javascript

$('.btn').on('click',function(){
    alert('a');
})
$('button').addClass('btn');
```

.btnはイベントが登録された後に追加されてるので↑ではイベントが発火しません。

後から追加された要素も対象にするには↓

```javascript

$(document).on('click','.btn',function(){
    alert('a');
})
$('button').addClass('btn');
```
これはdocumentの中にある.btnにイベントを紐づけています。
$('body')のようにすれば範囲を狭めることができます。

###trigger()で強制発火
```javascript

$('button').on('click',function(){
    alert('a');
});
$('button').trigger('click');
```
.trigger('click')を使えば、クリックしてないのにclickイベントが発火します。
WinのVSCodeでリモートリポジトリにpushできない [Git: Remote: HTTP Basic: Access Denied]

### 対象
WindowsのVisual Studio Code (以下、VSCode)でリモートリポジトリにpush/pullしようとしたときに、次のエラーが出る人向けの解決策

```
Git: Remote: HTTP Basic: Access Denied
```

### 詳細

私の場合は会社の認証Proxy経由で通信しており、この認証パスワードを更新したときに付随して発生したエラーだったので、すぐにそれが原因だと分かった。

当然、Proxy関連の設定項目を見直し、`.gitconfig`や`.bashrc`のproxyパスワード部分を更新し、PowerShellやコマンドプロンプトからのコマンド直打ちは出来ることを確認していたが、これだけではVSCodeのエラーは解消できなかった。

### 結論

**■Windows資格情報のパスワードを書き換えるべし**

VSCodeの設定自体にproxy関連の設定項目はあるが、どうもgit remoteのときはこの設定を参照していない様子。調べてみると、http通信時ではVSCodeはWindows資格情報を使うっぽい。

GitLabのサイトにこんな記事があった。
[HTTP Basic Access denied in Visual Studio Code for Gitlab Group Repo.](https://gitlab.com/gitlab-com/support-forum/issues/1654)

上のissueでは細々とコマンドが説明されているが、Windowsユーザならばコントロールパネルから「Windows資格情報」の編集画面にいき、リモートリポジトリに関連している項目のパスワード更新するほうが手っ取り早い。


社内IT環境が数世代前の、認証Proxyのパスワードを定期的に変更させようとしてくる企業にお勤めの方の参考になれば…。
java コールバックパターン

javaでコールバックパターンの簡単なサンプル

文字列を
・CamelCase → snake_case
・小文字 → 大文字
した後に表示する処理を例にやってみる

### コールバックパターンを用いない場合

```NoCallbackPattern.java
public class NoCallbackPattern {
    /**
     * CamelCaseからsnake_caseへ変換
     */
    private String camelToSnake(String input) {
        return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, input);
    }

    /**
     * 小文字から大文字へ変換
     */
    private String capitalize(String input) {
        return input.toUpperCase();
    }

    /**
     * 変換して表示
     */
    public void print(String input) {
        System.out.println(capitalize(camelToSnake(input)));
    }
}
```

```Main.java
public class Main {
    public static void main(String[] args) {
        NoCallbackPattern noCallbackPattern = new NoCallbackPattern();
        noCallbackPattern.print("replaceString");
    }
}
```


### コールバックパターンで書いた場合

```CallbackPattern.java
public class CallbackPattern {
    private List<MyFilter> myFilters;

    public CallbackPattern(List<MyFilter> myFilters) {
        this.myFilters = myFilters;
    }

    public void print(String input) {
        String output = input;
        for (MyFilter myFilter : myFilters) {
            output = myFilter.replace(output);
        }
        System.out.println(output);
    }
}
```

```MyFilter.java
public interface MyFilter {
    String replace(String input);
}
```

```CamelToSnake.java
public class CamelToSnake implements MyFilter {
    @Override
    public String replace(String input) {
        return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, input);
    }
}
```

```Capitalize.java
public class Capitalize implements MyFilter {
    @Override
    public String replace(String input) {
        return input.toUpperCase();
    }
}
```

```Main.java
public class Main {
    public static void main(String[] args) {
        List<MyFilter> filters = Arrays.asList(new CamelToSnake(), new Capitalize());
        CallbackPattern callbackPattern = new CallbackPattern(filters);
        callbackPattern.print("replaceString");
    }
}
```



**コールバックパターンを用いて書いた方が、printメソッドがMyFilterインターフェースにしか依存していないため、変換処理を追加する場合にCallbackPatternクラスの修正が必要ないことがわかります**
Microsoft Docsの日英 URL変換

## はじめに

MicrosoftのDocsは量が多く、幅が広くて読み応えあり、素晴らしいのですが、ときどき
　- 日本語わかりづらいなぁ..
　- このスクリーンショットあっているの?
　- このスクリーンショットの英語のままだね
となりました。本日勉強しました[Power BI Desktop の概要 - Power BI | Microsoft Docs](https://docs.microsoft.com/ja-jp/power-bi/desktop-getting-started)の途中から、スクリーンショットで？？となることがありましたので、日、英並べて、わかりにくいところは英語コンテンツをみて、よくわかりました。そこで、日本語ページを開いて、ブックマークレットで一括変換するボタンを作っておいて、今後も両読みすることにしました。そのブックマークレットについて紹介します。

## リファレンス

こちらのブログ（[URLを入れ替える(置換する)Bookmarklet - シンプルな暮らし。 - 家族とWEBマーケティングな日々](http://www.abilitydesign.net/2014/02/urlbookmarklet.html)）のやり方をそのまま使わせてもらっています。

## ブックマークレットの配置

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/78515a1a-87fa-6862-ff64-f93289f90990.png)

こんな感じでブックマークバーにブックマークレットを置いて、Docsの日英のどちらかを開いて、逆に置換する形をとります。

## 日本語のDocsと英語のDocsの行き来はトグル

こちらをブックマークレットに設定します。

```ruby:日・英どちらか、開いている方の反対となる
javascript:(function(){a='ja-jp';b='en-us';if(document.location.href.indexOf(a)==-1){location.href=document.location.href.replace(b,a);}else{location.href=document.location.href.replace(a,b);}})(location.href);
```
## おまけ

Docsの右上に「英語で読む」というのがありますが、こちらは本文が日から英にいくもので、図は変わりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/12505bc1-21aa-b2d6-47cd-ac8fa838e316.png)

Docsの英語の原文、すごく大事なので、日本語の翻訳と併用で、頑張って読むぞ、おー!

拡張機能についてはこちら @hanaseleb さんより

https://qiita.com/hanaseleb/items/6e3cf7e2b08258c4b480


### 更新履歴
- 2022年10月25日 拡張機能について追記
- トグルについて追記。文言微修正。
PowerPointの使い方で調べたことメモ

# ルーラーとガイド
![スクリーンショット 2020-03-22 10.35.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131286/4087e587-2771-15de-5ec2-6430043c82ab.png)

# ガイドを複数表示する (Mac PowerPoint 2011)
Alt + ドラッグ
13日の金曜日(4桁) (paizaランク C 相当)

[問題文](https://paiza.jp/works/mondai/dateset/friday_13_4?language_uid=c-sharp&t=b50c659b70fae10bc7d59c28a127e3ee)
[YouTube解説動画](https://www.youtube.com/watch?v=XtMbP6k4Ej0&t=464s)

```c#

    class Program
    {
        static void Main(string[] args)
        {
            DateTime date = new DateTime(2020,3,13);
            DateTime endDate = date.AddYears(400 * 7);
            int all = 0;
            int friday13 = 0;
            while(date.CompareTo(endDate) == -1) //-1で以前、0で同じ、1で以後
            {
                if (date.Day == 13 && date.DayOfWeek.Equals(DayOfWeek.Friday)){
                    friday13++;
                }
                date = date.AddMonths(1);
                all++;
            }
            double p = (double)friday13 / all;
            double result = ((int)(p * 10000)) / 10000.0;
            Console.WriteLine(result);
        }
    }
```````
#####メモ
日付の比較はDatetime構造体の**CompareTo**メソッドを使う。
戻り値はint型で引数より前で-1、同じで0、より後で1を返す。

日付の加算はDatetime構造体の**AddMonths**、**AddDays**メソッドを使う
【Ruby】最新バージョンにしようとしてハマったこと

rbenvでバージョンがうまく切り替わらなかったことはありませんか？
Macのrbenvで最新バージョンにしようとしてハマったことを共有したいと思います。

## 最新バージョンまでの流れと状況
### rbenvのバージョン一覧を確認
`$ rbenv versions
=>
system
 2.3.7
 2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)`

### Homebrewをアップデートして、rbenvをアップグレード
`$ brew update`
`$ brew upgrade rbenv ruby-build`

### rbenvからインストールできるRubyのバージョンを確認
`$ rbenv install -l`
### たくさん出てきますが2020年3月22日時点での安定最新バージョンの2.7.0をインストール
`$ rbenv install 2.7.0`

### 再度、rbenvのバージョン一覧を確認
`$ rbenv versions
=>
system
  2.3.7
  2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)
  2.7.0`
2.7.0がインストールされています。

### rbenvのバージョンを切り替える
#### 全体に反映ならglobal
`rbenv global 2.7.0`
#### 特定のディレクトリのみならlocalを設定
`rbenv local 2.7.0`

切り替わって成功するはずですが切り替わりませんでした。
### rbenvのバージョン一覧を確認
`$ rbenv versions
=>
system
  2.3.7
  2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)
  2.7.0`
2.5.1のままで変わっていない。

## 解決方法

## viコマンドで/Users/use_name/.ruby-versionファイルの中身を確認
`$ vi /Users/use_name/.ruby-version
=>
2.5.1`

2.5.1と書いてある。(use_nameはrbenv-versionsで表示されているset byの後に書いてあるものを使う)

### iキーを押してから2.7.0に変更(入力できない場合は、escキーを押してからiのキーを押す)

### 保存して抜けるためにescキーを押してから:wqと入力してエンターキーを押す。

### rbenvのバージョン一覧を確認
`$ rbenv versions
=>
system
  2.3.7
  2.4.1
  2.5.1 
* 2.7.0 (set by /Users/use_name/.ruby-version)`
2.7.0に変わっている。

### rubyのバージョンを確認
`$ ruby -v
=>
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin17]
`
最新バージョンに変わりました！！

## 参考記事
TECHACADEMY magazine
[Rubyバージョンアップの方法](https://techacademy.jp/magazine/19790)
モンティ・ホール問題を色々試した

ふと私は研究的なことをしたくなりました。C++で。ということでモンティ・ホール問題についての検証をしてみました。
モンティ・ホール問題については[ここ](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C)を参照してください。知ってる前提で話は進みます。
普通はドアが3つあってヤギが2匹いますが、今回はココを色々いじってみようということです。

# 動作環境

Windows10 1903
VisualStudio 2019 Community(v142)
C++14　(競プロのプロジェクトを流用したため。設定変えるの忘れてた。再検証はめんどいのでしません。一緒やろうし)

# ソース

```c++:main.cpp
#include<fstream>
#include <string>
#include <random>

constexpr int DOOR = 3;	//ドアの数
constexpr int CAR = 1;	//景品（車）の数
constexpr int TIMES = 100000;	//試行回数(EXCELの行数的に10万で)

#define CHANGE	//ドアを変えるかどうかのマクロ

int main() {
	std::string name = std::to_string(DOOR) + '_' + std::to_string(CAR)
#ifdef CHANGE
		+ "_Change"
#endif
		+ ".csv";
	std::ofstream file(name);
	for (int iiiiii = 0; iiiiii < TIMES; iiiiii++) {
		std::random_device seed_gen;
		std::mt19937 engine(seed_gen());
		std::uniform_int_distribution<> dice(0, DOOR - 1);

		bool car[DOOR] = { false };
		for (int i = 0; i < CAR; i++) {
			int v = -1;
			while (true) {
				v = dice(engine);
				if (car[v]) continue;
				else break;
			}

			car[v] = true;
		}

		
		int select = dice(engine);
		int open = -1;
		for (int i = 0; i < DOOR; i++) {
			if (i != select && !car[i]) {
				open = i;
				break;
			}
		}
#ifdef CHANGE
		for (int i = 0; i < DOOR; i++) {
			if (i != select && i != open) {
				select = i;
				break;
			}
		}
#endif
		file << (car[select] ? "1" : "0") << '\n';//1が出力されれば正解、0が出力されれば不正解
	}
}

```
EXCELで全て集計してます。
やりやすいように、マクロで変更が効くようにしてあります。
変数名が`iiiiii`とか適当なところは突っ込まないで。
間違ってたら教えて。あれば再検証します。
#結果
|  ドア  | 車(景品) | 変えるか | 確率[%] |
|:------:|:-------:|:--------:|:----:|
|   3    |    1    |    YES   |66.825|
|   3    |    1    |    NO    |33.273|
|   4    |    1    |    YES   |50.009|
|   4    |    1    |    NO    |25.082|
|   4    |    2    |    YES   |83.234|
|   4    |    2    |    NO    |49.982|
|   5    |    1    |    YES   |40.095|
|   5    |    1    |    NO    |20.074|
|   5    |    2    |    YES   |70.117|
|   5    |    2    |    NO    |40.060|
|   5    |    3    |    YES   |89.931|
|   5    |    3    |    NO    |59.951|

結構しっかり出てくれました。
別に扉変えない場合は単純な計算でいいので、やる必要は一切ないのですがまあついでに。車の数がドアの数に対して2少ないのがないのは、100%になるからです。わかりますよね？
結果としては、**一つ不正解が提供される場合は、変更するほうが圧倒的に良い**です。

確率の計算とか大嫌いなので、数学的説明はしません。というかできません。

# 他にやりたいこと
開ける扉の数を変える
もっと台数とか増やす(しんどいので気が向けば。そう、気が向けば。)

#あとがき
モンティ・ホールのコードって結構簡単にかけるもんですね。
~~これCSV出力する必要なかったんじゃ...？~~
手数料の計算。Mathオブジェクトについてまとめてみた。

#Math
今回はMathオブジェクトのメソッドについてまとめました。
アプリで使ったのは少数切り捨て（超初歩）
今後使いそうなのを軽くピックアップ。
[![Image from Gyazo](https://i.gyazo.com/78f973143e6fbddc97740e12b0e4acd8.gif)](https://gyazo.com/78f973143e6fbddc97740e12b0e4acd8)

###Mathオブジェクトとは
Math は、数学的な定数と関数を提供するプロパティとメソッドを持つ、組み込みのオブジェクトです。
組み込みとは、JavaScript側であらかじめ用意してくれているオブジェクトのことです。Mathオブジェクトは、組み込み関数の1つで、数値計算を扱う際に使います。
Math.〇〇とすることで求めている数字を引き出したり、変換することができます！（便利）


####初心者が使いそうなのまとめ

|method|return value|example|
|------|------------|-------|
|ceil|引数として与えた数以上の最小の整数を返す。|Math.ceil(.95)= 1|
|floor|引数として与えた数以下の最大の整数を返す。|Math.floor(1.95)= 1|
|max|引数として与えた複数の数の中で最大の数を返します。|Math.max(1, 3, 2)=3|
|min|引数として与えた複数の値の中で最小の値を返す。|Math.min(1, 3, 2)=1|
|round|引数として与えた数を四捨五入して、近似の整数を返す|Math.round(5.95)=6 <br> Math.round(5.05)=5|

他にも円周率やルートを求めるようなのもありました！
興味ある人は調べてみてください。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math

####使ってみた
今回はフリマアプリで入力された価格に対し、その場で手数料（１０％）と利益を出す為にjQueryで計算結果を出力しました。
４０４円などの時に小数点を切り捨てられるようにfloorを使用。
これがコードです。

```items.js
$(function(){
  $("#item_price").on('keyup', function(){
    var price = $("#item_price").val();
    if( 300 <= price && price <= 9999999) {
    var fee = Math.floor(price / 10);
    var profit = (price - fee);
    $(".fee-span").text(fee);
    $(".profit-span").text(profit);
    }else{
    $(".fee-span").text('');
    $(".profit-span").text('');
    }
  })
});
```

javascript自体がとても便利なので、Mathオブジェクトも今後使いそう！
色々なメソッドも多いですし、Math以外のDateオブジェクトとかもまとめたいですねー！
分からない時は、公式リファレンスを覗いてその周辺知識も見てまとめるのは効果的ですね。
間違えているところあったら申し訳ございません。
ありがとうございました！！
Ubuntu Sambaではまったことメモ

#Ubuntu でSamba を設定していて色々ハマったことのメモ
## Windowsからは書き込み可、だがMacからは不可
　ディレクティブで[raspberry pi] という設定を定義して、そこに色々設定をしていたつもりだったが、Macからアクセスした際に、[homes]の設定が継承されていた模様。[homes]はデフォルトのsmb.conf記載で書き込み不許可であるため、書き込みができない動作となっているようだった。Windowsからは書き込みまでできていたため、Windowsからのアクセスでは設定はhomesまでフォールバックしていなかった模様。結局、[homes]ディレクティブを丸々削除すると、Macからも[raspberry pi]ディレクティブで設定が読まれるようになった（ようにみえる）。理由が今一つよくわからない。
　また、他の方の記事によると、
**unix extensions = no**
を、global ディレクティブ配下に定義することで解決した、との記事があったが、こちらは私の環境では定義済みであったため、該当しなかった。ここから得られる教訓としては、余計なものは書くべきでない、ということか。。。

参考URL: http://www.samba.gr.jp/project/translation/3.5/htmldocs/manpages-3/smb.conf.5.html

## Windows のユーザアカウント制御の話
こちらはいまだ未解決で、暫定対処の状態だが、ユーザ認証が通らず、Windows10から正常にSamba接続ができない状態に陥った。
以下の記事が参考になりました。：
https://blog.treedown.net/entry/2019/06/03/010000

ntlm v2 の通信サポートの問題のようなので、運用しようとしている自宅環境で問題がないかを確認して、追記しようと思います。

以上、個人アカウントでの初投稿、自分用のメモでした。
Terraform0.12での変数定義と参照

## はじめに

Terraform使ってこなかった系SREやってた系エンジニアです。
アプリケーションエンジニアに僕は戻る。

とある案件でTerraform0.12つかうことになったんだけど、なんかうまくいかねえなあ、と思ってたこの基本的になやつ。
あちこちに書いてあるようで書いてなかった。基本的なことなのになあ。

日本語にQiitaとかみると0.11時代の書き方をそのまま持ち込んでいる人がおおかったりして、うーん、という感じ。
時代にのろう。

## 変数定義

varaiableなんとかで書く。

```variable.tf
variable "project_name" {
  default = {
    production = "srockstyle-prd"
    staging = "srockstyle-stg"
    development = "srockstyle-dev"
  }
}

variable "region" {
  default = {
    production = "asia-northeast1"
    staging = "asia-northeast1"
    development = "asia-northeast1"
  }
}

variable "vpc_network_name" {
  default = "srockstyle"
}
```

terraformにはworkspaceっていう機能があって、環境ごとに違う変数を割り当てたいときに使う。
workspaceごとの設定なので`production = "~~~"`ってのはproductionっていう名前のworkspaceの時に使われる。

workspaceごとに変更なんてしなくてもいいのなら、defaultにそのまま指定で構わない。

## 変数参照

参照する際は`var.[変数名]` で参照する。

```main.tf
resource "google_compute_network" "srockstyle-main" {
  name = var.vpc_network_name
  project = lookup(var.project_name, "${terraform.workspace}")
]
```

workspaceごとの設定をしている場合はlookupを使う。
二つ引数で`lookup(var.[変数名], ${terraform.workspace)`で参照できる。
0.11？のときのように変数を`"${}"`とかで囲んで指定すると「そんな古い書き方してんじゃねーよ」って怒られる。

僕は0.11つかったことないんでいいんだけど。

## まとめ

完璧に理解した。
Kaggle Titanic 0.78468

次のプログラムを改造しました。
>[Kaggle Titanic 0.62200](https://qiita.com/ekzemplaro/items/c38da264c50dd1a7b769)

そして、次の結果を得ました。
![kaggle_mar2201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/85062242-e0ba-3c90-319e-450583715f66.png)

次のページを参考にしました。
[Kaggle超初心者向け】Titanicにチャレンジしてみた](https://qiita.com/5sigma_AAA/items/0c23907da9330681147b)

```py:titanic03.py
#! /usr/bin/python
#
#	titanic03.py
#
#					Mar/22/2020
# --------------------------------------------------------------------------
import sys
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import  train_test_split
from sklearn.metrics import (roc_curve , auc ,accuracy_score)
# --------------------------------------------------------------------------
# [4-2]:
def convert_proc(df):
	df['Fare'] = df['Fare'].fillna(df['Fare'].median())
	df['Age'] = df['Age'].fillna(df['Age'].median())
	df['Embarked'] = df['Embarked'].fillna('S')

	df['Sex'] = df['Sex'].apply(lambda x: 1 if x == 'male' else 0)
	df['Embarked'] = df['Embarked'].map( {'S': 0 , 'C':1 , 'Q':2}).astype(int)
#
	df = df.drop(['Cabin','Name','PassengerId','Ticket'],axis =1)
#
	return df
# --------------------------------------------------------------------------
# [4]:
def read_train_proc():
	train_df = pd.read_csv("train.csv", header=0)
#
	train_df = convert_proc(train_df)
#
	return	train_df

# --------------------------------------------------------------------------
# [6]:
def read_test_proc():
	test_df = pd.read_csv("test.csv", header=0)
	ids = test_df["PassengerId"].values
#
	test_df = convert_proc(test_df)
#
	return ids,test_df
# --------------------------------------------------------------------------
# [10]:
def submit_proc(ids,output):
	file_submit = "titanic_submit.csv"
#
	dft = pd.DataFrame({'PassengerId': ids, 'Survived': output})
	dft.to_csv(file_submit,index=False)
# --------------------------------------------------------------------------
# [8]:
def predict_proc(train_df,test_df):
#
	train_X = train_df.drop('Survived',axis = 1)
	train_y = train_df.Survived
#
	(train_X , test_X , train_y , test_y) = train_test_split(train_X, train_y , test_size = 0.3 , random_state = 0)
#
	clf = RandomForestClassifier(n_estimators = 10,max_depth=5,random_state = 0)
	clf = clf.fit(train_X , train_y)
	pred = clf.predict(test_X)
	fpr, tpr , thresholds = roc_curve(test_y,pred,pos_label = 1)
	auc(fpr,tpr)
	score = accuracy_score(pred,test_y)
	print(score)
#
	predictions = clf.predict(test_df)
#
	return predictions
# --------------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

train_df = read_train_proc()

ids,test_df = read_test_proc()
#
predictions = predict_proc(train_df,test_df)

submit_proc(ids,predictions)

sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------------
```

titanic_submit.csv　を　kaggle.com に Submit して次の結果を得ました。

```text
You advanced 11,478 places on the leaderboard!
Your submission scored 0.78468, which is an improvement of your previous score of 0.62200. Great job!
```
[Swift] Class-only Protocolは": class"じゃなくて": AnyObject"で宣言することに慣れましょう

# 概要

本記事の前提環境：Swift 5.1

ちょっと今さら感があるネタですが。。。

Class-only Protocolは、
**↓こうじゃなくて**

```swift
protocol MyDelegate: class {
}
```

**↓こう宣言しましょう**、という話題です。

```swift
protocol MyDelegate: AnyObject {
}
```

私なりに知ってはいたのですがメンバーに理由をうまく説明できなかったので、今さらながら整理してみました。

# 前置き

Xcodeでこのような実装をするとエラーになるので、こういう実装はできないのだな、ということにすぐに気づくと思います。

```swift
protocol MyDelegate {
}

class MyClass {
  weak var delegate: MyDelegate?
}
```

`weak`は循環参照を避けるために「弱参照にします」というキーワードであって、参照型の変数じゃないと意味がないため、`MyDelegate`を参照型だけに適用できるような宣言をしないとダメですよ、という訳です。

# 本題

Swift 3までは、このような↓書き方をしていました。

```swift
protocol MyDelegate: class {
}
```

Swift 4で、[SE-0156](https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md)という提案に基づいて、`AnyObject`が導入されました。
以降は、こちら↓の書き方が推奨となっています。

```swift
protocol MyDelegate: AnyObject {
}
```

参考：[Swift Documentation – Class-only Protocols](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID281)

[SE-0156](https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md)の背景と意図は私には完璧に読み取り難いですが、`AnyObject`とは**「参照型全般」という意味を明確にしたモノ**、という理解です。

参考：[SwiftのAnyObjectとAnyについて](https://dev.classmethod.jp/articles/anyobject-and-any/)

Swift 4以降、`class`は後方互換のために`AnyObject`のtypealias（別名）として残っている状態です。

# 結論

Swift 5.1現在では、`: class`で宣言してもエラーになりませんし警告も出ません。
また、ビルドや実行時に遅くなるということもないようです。

ただし、[SE-0156](https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md)には以下のような記述もあり、将来はdeprecatedとして警告が発生する可能性があります。

>  Later, `class` could be removed in a subsequent version of Swift.

このため、コードに`: class`を見かけたら、`: AnyObject`にリファクタリングしておいた方が良さそうです。
[iOS] [Xcode] WKWebViewで位置情報を取得するコンテンツをloadする

# 前提環境

- Xcode 11.3 
- Swift 5.1

# info.plistの設定

ユーザーから位置情報取得の許諾を得るための設定
![スクリーンショット 2020-03-21 11.19.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/90b14aef-0869-edf8-661e-a43c1ccf8f56.png)

許諾アラートを日本語にする設定
![スクリーンショット 2020-03-21 10.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/cea1fbe9-4dad-d759-9357-1192579034de.png)
<img width="485" alt="スクリーンショット 2020-03-21 10.58.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/eb6d293e-ef2e-3c9f-5873-962634c9e68c.png">

# 謎の挙動

許諾アラートで「OK」をtapして、WKWebViewをいったん閉じて、再度WKWebViewを開いてもまた許諾アラートが表示されます。
**2回目の「OK」で記憶されて、3回目は表示されなくなるようです。**
この挙動の原因と回避方法は謎です。。。どなたかご存知でしたら教えてください。

# 注意点

Xcode 11.3で新規作成したプロジェクトでは、**コンテンツが位置情報を取得しようとした際にコンソールに以下のログが出力されてクラッシュします。**

```
*** Terminating app due to uncaught exception 'NSObjectNotAvailableException',
reason: 'UIAlertView is deprecated and unavailable for UIScene based applications,
please use UIAlertController!'
```

許諾アラートが表示されるタイミングで、Xcode 11で新規にプロジェクトを作成した時のデフォルトである「scene baseアプリケーション」の場合にクラッシュしてしまうようです。

許諾アラートはアプリ側で実装している訳ではないので、どうやらSDKのバグっぽい雰囲気です。
**Xcode 11.3現在では、window baseアプリケーションにするしかなさそうです。**

１．SceneDelegate.swiftをファイルごと削除

２．AppDelegate.swiftを修正

```swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow? // この行を追加

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

// ここから下を削除
//    // MARK: UISceneSession Lifecycle
//
//    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
//        // Called when a new scene session is being created.
//        // Use this method to select a configuration to create the new scene with.
//        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
//    }
//
//    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
//        // Called when the user discards a scene session.
//        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
//        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
//    }

}
```

３．info.plistから"Application Scene Manifestを削除
![スクリーンショット 2020-03-21 10.43.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/cd214950-9dbf-c161-d2a4-9c9a56443126.png)

この件については、Xcodeがバージョンアップされたら再確認しようと思います。
RStan のコードを PyStan に移植する際の注意点: COVID-19の論文を例に

# CAUTION

- この記事は公衆衛生、疫学、医学の観点からの考察は一切ありません。COVID-19 に関する情報は、専門家の包括的な意見を必ず参照してください。


# この記事を書こうとしたモチベーション

- [@Med_KU](https://twitter.com/Med_KU) 氏の blog 紹介 tweet がたまたま目に入ったので、元論文 & supplement（付録物）見てみた
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">&quot;COVID-19 の潜伏期間をrstanで推定する - 驚異のアニヲタ社会復帰の予備&quot; <a href="https://t.co/ztcnDcQyAR">https://t.co/ztcnDcQyAR</a></p>&mdash; Kentaro Matsuura (@hankagosa) <a href="https://twitter.com/hankagosa/status/1241245858915475456?ref_src=twsrc%5Etfw">March 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- [論文の](https://www.eurosurveillance.org/content/10.2807/1560-7917.ES.2020.25.5.2000062) Rstan のコード量が多くないので、こりゃPyStanのリハビリをかねてPythonで書き直してみようと思い立つ三連休初日。COVID-19も話題なので公開すればちょっとバズるんじゃないかとスケベ心が芽生える
- 1時間くらいで終わるかとおもいきや、鈍った脳みそにはハマりポイントが多数あったので、言語化して誰かに役に立てばと思うのが三連休3日目の朝

# PyStan code

https://gist.github.com/koizumihiroo/df83bb72c94153acc4ea9049e395ea93 をご覧ください。

# はまったポイント

ぶっちゃけ特にない。method名や引数は Rstan も PyStan も大きくはかわらない。 いうのはウソで次に時間を取った。

- `loo` の計算がオフィシャルに提供されていないので、検索に手間取った。最初は [stanity.psisloo()](https://github.com/hammerlab/stanity) を使おうとしたが、返り値が [Psisloo class](https://github.com/hammerlab/stanity/blob/6c36abc207c4ce94f78968501dab839a56f35a41/stanity/psisloo.py#L77-L101) とオリジナルの psisloo と異なるため、 [Stan 
 Official Site の loo のpage](https://mc-stan.org/loo/) の一番下の LINK から辿ったオリジナルを使った。
- sampling() が返す object の annotation を付けようとしたが `pystan.StanFit4Model` はアクセスできなかった。よくわからん

```python
(Pdb) p type(stanfit)
    <class 'stanfit4anon_model_df568c9723cbf759ca5759b36acb4c6f_2883001500315052076.StanFit4Model'>
```

- stan 以外の観点
    - `math.gamma()` は引数 broad cast できない（array を渡せない）ので `scipy.stats.gamma()` を使う必要がある
    - Python のワイブル分布が `weibull_min` `weibull_max` と二つあることに手間取った
- gist の code の review をもらいたいです。

以上
#Rails / permit and require Nested params / Without method chains / ActionController::Parameters

```rb

# Execute with rails console

# Rails like Nested params with ActionController::Parameters instance
params = ActionController::Parameters.new(
  name: 'Alice',
  age: 22,
  contact: ActionController::Parameters.new(
    tel: 07011112222,
    email: 'user@example.com'
  )
)
# <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: false>} permitted: false>

# Ooops
# Args must be Array
params.require(:name, :age, :contact)
# ArgumentError: wrong number of arguments (given 3, expected 1)

# It works
params.require([:name, :age, :contact])
# => ["Alice", 22, <ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: false>]

# But with method chain
# How to permit multiple params Require and Permit ?

# require method returns values Array
# it is not work for generate permitted params
# because .permit .require both method does not change "params"
params.require([:name, :age, :contact])[2].permit(:tel, :email).require([:tel, :email])
# => [941921426, "user@example.com"]

# require method returns values Array
# Unable to use methods chain
params.require([:name, :age, :contact])[2].require([:tel, :email]).permit(:tel, :email)
# NoMethodError: undefined method `permit' for [941921426, "user@example.com"]:Array

# It is answer?
# User require and permit methods
# Without return values
# Without method chains
# 
# And last execute permit!

params.require([:name, :age, :contact])
params[:contact].require([:tel, :email])

peritted_params = params.permit(:name, :age, contact: [:tel, :email])
# <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: true>

# OR
params.permit(:name, :age, contact: [:tel, :email])
params.permit!
params
# => <ActionController::Parameters {"name"=>"Alice", "age"=>22, "contact"=><ActionController::Parameters {"tel"=>941921426, "email"=>"user@example.com"} permitted: true>} permitted: true>
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3044








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->