OmniAICreator/Qiita-1.07M huggingface dataset:
圧電スピーカー使ってみた

# 概要
圧電スピーカーを購入したので試してみました。
振動などを検知するセンサーです。

# 部品
**圧電スピーカー:**[セラミック圧電振動センサーモジュール](https://ja.aliexpress.com/item/4000299901478.html?spm=a2g0s.9042311.0.0.27424c4dZr31Qa)
84円
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/7c56c485-b5b1-d938-958d-fadd4f1a4c1c.png">



**表示機:**[TM1637が組み込まれた7セグLED](https://ja.aliexpress.com/item/4000174141889.html?spm=a2g0s.9042311.0.0.27424c4dboG22l)
73円
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/4ce296b8-61c4-8857-770e-6173b76eb6bc.png">

**コンピュータ:**[Arduino UNO互換機](https://www.amazon.co.jp/FC-%E5%B7%A5%E5%A0%B4-R3%E9%96%8B%E7%99%BA%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%90%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-ATmega328P-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B%E6%80%A7/dp/B07H4KTVK5/ref=sxbs_sxwds-stvp?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2S335VL3VWB52&cv_ct_cx=arduino+uno&keywords=arduino+uno&pd_rd_i=B07H4KTVK5&pd_rd_r=d31aaf3a-0258-4866-b883-ee3cb37525ae&pd_rd_w=II02q&pd_rd_wg=kzB7i&pf_rd_p=e29507e3-7937-4495-82f4-55b5d5ca8047&pf_rd_r=SN5PWYGF5TQS3EX5XFVB&psc=1&qid=1584128141&s=diy&sprefix=Ard%2Cdiy%2C251)
699円
<img width="400" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/47f88a1f-c4ae-cc1d-84cc-12b8cc736b9b.png">


#配線
<img width="400" alt="スクリーンショット 2020-03-24 6.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/d52e6f12-347d-a22c-7bea-0876eb27c06f.png">

#ソースコード

アナログ信号を受け取り、１０回の平均を表示するようにしています。

```c++

#include <Arduino.h>
#include <Wire.h>
#include <TM1637Display.h>
#define SERIAL_BAUD 115200

#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO);
#define PIEZOELECTRIC_LEN 10
int Piezoelectrics[PIEZOELECTRIC_LEN] = {0,0,0,0,0,0,0,0,0,0};
int Piezoelectrics_idx = 0;

void setup() {
  Serial.begin(SERIAL_BAUD);
  while(!Serial) {}

  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
  display.setBrightness(0x0f);
  display.setSegments(data);
  delay(1000);
}

void loop() {
  int ave = 0;
  int Piezoelectric;
  Piezoelectrics_idx++;
  if(! (PIEZOELECTRIC_LEN > Piezoelectrics_idx) )
    Piezoelectrics_idx = 0;
  Piezoelectrics[Piezoelectrics_idx] = analogRead(A0);
  for(int i=0 ; i<PIEZOELECTRIC_LEN;i++){
    ave+=Piezoelectrics[i];
  }
  Piezoelectric = ave/PIEZOELECTRIC_LEN;

  display.showNumberDec(Piezoelectric, false); 
  Serial.print("Piezoelectric: ");
  Serial.print(Piezoelectric);
  delay(100);
}
```
[github](https://github.com/hashito/arduino_startup/tree/master/piezoelectricspeaker)


# 動作確認
gif動画で上げても分かりにくかったので、Youtubeにて確認いただけると幸いです。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/rnVoettFB4s/0.jpg)](http://www.youtube.com/watch?v=rnVoettFB4s)
音センサ(KY-038/KY-037)を使ってみた。

# 概要
音センサを購入したので試してみました。

# 部品
**音センサ:**[KY_038/KY_037](https://ja.aliexpress.com/item/4000299901478.html?spm=a2g0s.9042311.0.0.27424c4dZr31Qa)
49円
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/245499bb-ccc8-1d08-e899-a92e38d4bd5e.png">

**表示機:**[TM1637が組み込まれた7セグLED](https://ja.aliexpress.com/item/4000174141889.html?spm=a2g0s.9042311.0.0.27424c4dboG22l)
73円
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/4ce296b8-61c4-8857-770e-6173b76eb6bc.png">

**コンピュータ:**[Arduino UNO互換機](https://www.amazon.co.jp/FC-%E5%B7%A5%E5%A0%B4-R3%E9%96%8B%E7%99%BA%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%90%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-ATmega328P-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B%E6%80%A7/dp/B07H4KTVK5/ref=sxbs_sxwds-stvp?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2S335VL3VWB52&cv_ct_cx=arduino+uno&keywords=arduino+uno&pd_rd_i=B07H4KTVK5&pd_rd_r=d31aaf3a-0258-4866-b883-ee3cb37525ae&pd_rd_w=II02q&pd_rd_wg=kzB7i&pf_rd_p=e29507e3-7937-4495-82f4-55b5d5ca8047&pf_rd_r=SN5PWYGF5TQS3EX5XFVB&psc=1&qid=1584128141&s=diy&sprefix=Ard%2Cdiy%2C251)
699円
<img width="400" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/47f88a1f-c4ae-cc1d-84cc-12b8cc736b9b.png">


#配線
<img width="400" alt="スクリーンショット 2020-03-24 6.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89227/21e37873-82d4-77f8-7d02-ca4f46baa296.png">


#ソースコード

アナログ信号を受け取り、１０回の平均を表示するようにしています。

```c++

#include <Arduino.h>
#include <Wire.h>
#include <TM1637Display.h>
#define SERIAL_BAUD 115200

#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO);
#define KY_03x_LEN 10
int KY_03xs[KY_03x_LEN] = {0,0,0,0,0,0,0,0,0,0};
int KY_03xs_idx = 0;

void setup() {
  Serial.begin(SERIAL_BAUD);
  while(!Serial) {}

  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
  display.setBrightness(0x0f);
  display.setSegments(data);
  delay(1000);
}

void loop() {
  int ave = 0;
  int KY_03x;
  KY_03xs_idx++;
  if(! (KY_03x_LEN > KY_03xs_idx) )
    KY_03xs_idx = 0;
  KY_03xs[KY_03xs_idx] = analogRead(A0);
  for(int i=0 ; i<KY_03x_LEN;i++){
    ave+=KY_03xs[i];
  }
  ky_03x = ave/KY_03x_LEN;

  display.showNumberDec(ky_03x, false); 
  Serial.print("ky_03x: ");
  Serial.print(ky_03x);
  delay(100);
}
```
[github](https://github.com/hashito/arduino_startup/tree/master/KY_038-KY_037)


# 動作確認
gif動画で上げても分かりにくかったので、Youtubeにて確認いただけると幸いです。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/1tQvt8X-BfQ/0.jpg)](http://www.youtube.com/watch?v=1tQvt8X-BfQ)
UNVT工程概念図

私は、伝わらないアナロジーをよくやるほうだと自覚していますが、ベクトルタイルの生産・ホスト・スタイル・最適化の４工程の関係を多良山系でアナロジーするということをやってみました。スタイル工程は急ぎさえしなければ苦しくないが、退屈で長い。生産工程はパワーを必要とするがよく整備されている。ホスト工程は登り方が分かっている場合には簡単だが、分かっていなければ滑ることも多い。３ルートが良いタイミングで揃わないと最適化工程には入れないが、実は最適化工程はリズミカルな下りコースでここが楽しかったりもする。３コースからタイミングよく、ゴールである金泉寺になだれこめ、というゲームがベクトルタイルのゲームです、というアナロジーです。計画性と冷静さ、それからスタミナが求められるスポーツなんだな、と思います。

<img width="836" alt="スクリーンショット 2020-03-24 6.02.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/25767f89-a8f9-e53c-7e61-6188935b50e1.png">

遠目山あたりの展望が見えにくい縦走路を辿っているのが、ちょうどこの toki にあたります。https://github.com/optgeo/toki

黒木の谷にベースをおく、という行為が Misora の開発なのだと思います。https://github.com/un-vector-tile-toolkit/tsukuba

「経ヶ岳と五家原岳を早くおさえてもらうことがどのプロジェクトでも肝要」ということと「早く行きたいなら一人で行け、遠くへ行きたいならみんなで行け」ということを、考えています。単騎での下見ができているからこそ、みんなで行ける方法を考えるのだと思います。草を刈るぞ。
地理院地図 Vector は、先週の段階で、五家原岳を見事におさえましたね。

こちらも黒木谷ベースを作る仕事ですね。こちらは、開発フェーズの支援。https://github.com/unvt/nanban
本日の学習内容Part3

##追加ボタンがクリックされたかどうか判断する
```input.php
<form action="" method="post">
   <input type="submit" name="add" vaule="追加">
</form>
<?php 
if (isset($_POST['add']) {
   print('追加されました');
}
?>

?>
```

今さらながら学習記録について、その日に特に使い方を覚えておいた方がいいものを一つだけ取り上げます。
Tracktion Waveform FreeのRaspberryPiでの動作テスト

[Mac／Windowsだけでなく、Linux／Raspberry Piにも対応した“完全無償のDAW”、「Waveform Free」のダウンロード提供が開始](https://icon.jp/archives/19100)というニュースを受けて、製作した[AK4558ENオーディオ入出力ボード](https://qiita.com/kmitsu76/items/0a0fac24d448ccf242fd)での動作を試した。

#環境
Raspberry pi 3B
Raspbian Buster
Linux pi3 4.19.102-v7+ #1295 SMP Thu Feb 6 15:43:59 GMT 2020 armv7l GNU/Linux

#動作テスト

[過去のドライバー組み込み例](https://qiita.com/kmitsu76/items/07b0bea26ad996e16b30)を参考に、オーディオ入出力ボードを認識させておく。
[Tracktion Waveform Free](https://www.tracktion.com/products/waveform-free)はユーザー登録することで、無料でダウンロードができる。

2020/3/24現在、waveform_pi_v11.0.22.debというファイルがダウンロードできるのでRaspberry Pi上で下記にてインストール。

```
sudo dpkg -i waveform_pi_v11.0.22.deb
```

ウイザード形式でセットアップをやっていくが、オーディオデバイスの設定は下記のように行った。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/c8d60e18-298c-9266-0e64-5f3161026413.png)

Audio Buffer Sizeはデフォルトの480samplesで問題なし。
デモソングのSynthetiqueでは256sampleまでは追い込めた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/65bf4c25-dbf2-4da9-a046-f26d45dbc8a5.png)


オーディオ入力を使ったレコーディングも問題なく動作した。

Jetson NanoはOSアーキテクチャがarm64となり、Waveform Freeが対応しておらずインストールはできなかった。

コンパクトな音楽制作ができる環境が整ってきたようだ。
失敗するかもしれないシェルコマンドを無視する

凄く簡単なものなのですが、あるパイプラインで、Create Role Assignment をするコマンドがあり、既に既存で存在するという可能性があるので、最初の一回のみ実行したいというシーンがありました。ほっといたらエラーで終わって何もしないのでよいのですが、exitステータスのため、Pipeline自体がFailします。

このようなケースの場合にどうすればよいでしょう？

凄く単純で

```bash:fail.sh
#!/bin/bash
exit 1
```

と必ず失敗するファイルを作成します。

```bash
$ chmod +x ./fail.sh
$ ./fail.sh
$ echo $?
1
$ ./fail.sh | true
$ echo $?
0
```

うん。簡単。
dotnet コマンド要約

# はじめに
最近dotnetを使い始めたんだけど、どういうふうにコマンド打っていくのか毎回調べている状態で、面倒なのでここにまとめて簡単に記そうと思います。
適当に記してるだけなので、間違っていたら指摘ください。。。

# 基本的なコマンド

## プロジェクト開始

```powershell
dotnet new console -n <プロジェクト名> -o <作成フォルダ名>
```

## とりあえず動作確認

```powershell
dotnet run
```

## Nuget パッケージ追加

```powershell
dotnet add package <パッケージ名>
```
尚、基本的なNugetの参照先は
https://www.nuget.org/
のサイトから取ってくる。

## 自己完結型アプリケーション作成
自己完結型：PCにインストールされているFWに依存しないアプリケーション

```powershell
dotnet publish -c Release -r <RID>
```
RID:https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog#windows-rids

# 使用頻度の低いコマンド(所感)

## clean

```powershell
dotnet clean
```

## ソリューションファイル作成

```powershell
dotnet new sln
```
要は、makeみたいなもの。ビルドタスクを回す際は次のコマンドで実行

## ソリューションビルド
通常のリリースビルド

```powershell
dotnet msbuild -property:Configuration=Release
```

自己完結型パッケージのビルド作成

```powershell
dotnet msbuild -target:Publish -property:RuntimeIdentifiers=<RID>
```

## 依存関係解決
Nuget等の依存関係の解決コマンド。
ただ、ビルドする時に自動で行ってくれるため基本的にコマンドを明示的に実行する必要性があまりない。

```powershell
dotnet restore
```

## Nugetパッケージ作成
Nugetパッケージ作ると他のプロジェクトファイルから参照できるようにNugetパッケージを作成する。（具体的な使い方はよくわからない・・・）

```powershell
dotnet pack
```

## 単純なビルド
ビルドも、publishやrunする時に勝手に行われるため明示的にやる必要性は基本的にない。

```powershell
dotnet build -c Release
```

# おわりに
とりあえず、なんとなくわかる範囲で調べた内容をまとめました。
なんか追加で調べて行ったら、またここに追加していこうと思います。
Xojo  で Web＋DBアプリを作ってみる (MySQL/MariaDB編）


「Xojo で Web+DBアプリを作ってみる」
https://qiita.com/nanbuwks/items/2cefc72528a16d60a329

では SQLite を使いましたが、MySQL(MariaDB)で試してみます。


# データベースの用意

「MariaDB on Ubuntu18.04 LTS」
https://qiita.com/nanbuwks/items/c98c51744bd0f72a7087

のようにして、インストールします。

# アプリ作成

最初のメニューでWebを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/26c07474-3bba-a46a-b9f6-8445bc3b759c.png)

App を選び、メニューバーの Insert-Property で Name を db, Typeを MySQLCommunityServer とします。

もう一度 App を選び、Insert-Event Handler-Open で以下を書く

```

self.db = New MySQLCommunityServer
self.db.Host = "127.0.0.1"
self.db.UserName = "webdb"
self.db.Password = "password"
self.db.DatabaseName = "test"
Try
  self.db.Connect
  // proceed with database operations here..
Catch error As DatabaseException
  MessageBox("The database couldn't be opened. Error: " + error.Message)
  Return
End Try
try
  self.db.SQLExecute("set names utf8 collate utf8_general_ci")
  self.db.SQLExecute("set character set utf8")
  self.db.SQLExecute("use test")
Catch error as DatabaseException
  MessageBox error.Message
end try
```

WebPage1に移ってText Fieldを２つ、ボタンを１つドラッグドロップします。ボタンをダブルクリックしてActionに以下を書きます。

```
var Record as new DatabaseRow
dim temp as string
temp = tempField.Text
dim hemi as string
hemi = hemiField.Text
try
  app.db.ExecuteSQL("INSERT INTO sensor ( sensor,temp,hemi ) VALUES (1,"+temp+","+hemi+");")
Catch error as DatabaseException
  MessageBox error.Message
end try
```

次に、ボタンをもう一つ置き、ダブルクリックしてActionに以下のコードを書きます。

```

var temp,hemi as double
var rs as RowSet
try
  rs =app.db.SelectSQL("SELECT id,sensor,temp,hemi FROM sensor")
Catch e as DatabaseException
  messagebox e.Message
end try
try
  for each row as databaserow in rs
    temp = val(row.column("temp").stringvalue)
    hemi = val(row.column("hemi").stringvalue)
    Listbox1.AddRow( row.column("id").StringValue,row.column("sensor"),format(temp,"##.#"),format(hemi,"##.#") )
  next
Catch e as DatabaseException
  messagebox e.Message
end try
```

最後に、List Box を WebPage1 に置き、カラム数を４にします。

ラベルをつけたりOKを書き直したりして体裁を整えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/63e4b1b6-fa76-cccf-826b-830719f3e9fb.png)


# 実行

本来は、Playボタンを押すと内蔵Webサーバが起動し、ブラウザが自動で起動してアプリ画面が表示される。
今回は、コーディングは Windowsで、実行は Linuxサーバで動かした。MySQL/MariaDB も Linuxで動かしている。
こうした理由は日本語でのMySQL/MariaDB を Xojo で使う場合 Windowsでは問題があり、Xojo IDEがLinuxでは問題があるからである。

ローカルLAN同士で接続し、以下のように実行する。
「Xojo でリモート開発」
https://qiita.com/nanbuwks/items/4743756186060c3c3d20

Webアプリであるが、 Remode Debugger Desktopでなければ動かなかった。
リモートでなければWebブラウザが自動で起動するが、今回は手動でWebブラウザを http://(LinuxサーバのIPアドレス):8080
を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/cd2ede15-fd94-0286-d799-b5138ac1d6b2.png)

# デスクトップアプリと違うところ

「ojo で Web+DBアプリを作ってみる (SQLite編)」と同じ内容：

- WIndow1 → WebPageとなる
- ListBox という名前は予約されているためListBox1という名前にした
- テキストフィールドを使ったhemiFieldの値： hemiField.Value は  hemiField.Text になる
メモ: Oracle Cloud

* Ubuntu 20.04 にて確認。

## oci-cliを使うには

### 成功した方法

```sh
apt install -y python3-pip
pip3 install oci
pip3 install oci-cli
```

```sh
~/.local/bin/oci -v
```

> 2.9.8

### oci setup config

* oci setup config
    * `ap-tokyo-1` を選択
* ~/.oci/config に鍵やパスフレーズが(yを押していたら)保存される。

### oci コマンド

```
oci os ns get
oci resource-manager job list
```


## Terraformを使う

* 2つの仮想マシンを作るには https://github.com/MallocArray/Unifi-OracleCloud の [zip](https://github.com/MallocArray/Unifi-OracleCloud/raw/master/UnifiController-OCI.zip) をダウンロードして使う。
* mushop を動かす場合、[公式ドキュメント](https://docs.oracle.com/cd/E97706_01/Content/FreeTier/freetier.htm) で [ここ](https://github.com/oracle-quickstart/oci-cloudnative) で配布されている Terraformのzipを使うと

![スクリーンショット_2020-03-24_05-52-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/565e2437-f87e-1d78-34ee-02e2656208a2.png)


Out of host capacity..

![スクリーンショット_2020-03-24_05-47-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/850f9198-e314-f5a2-86a1-14974ca7980f.png)


## ubuntu 20.04

```sh:swapの作成
dd if=/dev/zero of=/swapfile bs=1M count=1024
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

echo "/swapfile swap swap  defaults,nofail 0 0" >> /etc/fstab
```

```sh:iptablesのルールを削除
systemctl disable iptables
```

```sh:dockerのインストール
apt update

apt install -y \
 docker.io \

sudo systemctl enable docker
```

```sh:その他
apt install -y \
 cron \
 ranger \
 screen \
 vim \
 zip
```

## port を開ける方法

* 8000番を開ける例

![スクリーンショット_2020-04-03_13-41-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/202dd914-3dbf-f670-8d62-347bd467be9a.png)
初心者によるプログラミング学習ログ 271日目

#100日チャレンジの271日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
271日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>271日目<br>・XDデザインカンプからのwebサイト模写<br>・あと、gitも併用<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1242180501353287680?ref_src=twsrc%5Etfw">March 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Swift：App GroupsとUserDefaultsとNSKeyedUnarchiverの話

iOSでToday Extensionと母機アプリを連携したいときに，App Groupsを使います．そして，UserDefaultsでデータを共有するのですが，独自クラスのデータを共有するとなると少し厄介でした．

# App Groupsの準備

データを共有するターゲットのそれぞれにて下記の作業をします．

1. [Signing & Capabilities]より`App Groups`を追加
2. グループIDを追加する（データを共有する全てのターゲットにて同じグループIDを使用すること）．

そして，`UserDefaults`を使うときは`UserDefaults.standard`ではなく`UserDefaults(suiteName: "グループID")`を使います．なお，グループIDは`group.`から始まるのが通常らしいです．

# 独自クラスの準備

基本的には[この記事](https://qiita.com/Kyome/items/46403b1422d13f29078a)と同様ですが，`NSCoding`だけでなく`NSSecureCoding`も使います．

```swift:独自クラスのサンプル
class Sample: NSObject, NSCoding, NSSecureCoding {

    var dataA: Bool
    var dataB: Double
    var dataC: String

    static var supportsSecureCoding: Bool {
        return true
    }

    init(_ dataA: Bool, _ dataB: Double, _ dataC: String) {
        self.dataA = dataA
        self.dataB = dataB
        self.dataC = dataC
    }

    required init?(coder: NSCoder) {
        dataA = coder.decodeBool(forKey: "dataA")
        dataB = coder.decodeDouble(forKey: "dataB")
        dataC = coder.decodeObject(of: NSString.self, forKey: "dataC") as String? ?? ""
    }

    func encode(with coder: NSCoder) {
        coder.encode(dataA, forKey: "dataA")
        coder.encode(NSNumber(value: dataB), forKey: "dataB")
        coder.encode(dataC as NSString, forKey: "dataC")
    }
    
}
```

`supportsSecureCoding`をtrueにする必要があります．
ここで，ターゲットごとの初期化の場面（AppDelegateのdidFinishLaunchingとかViewDidLoadとか）で`NSKeyedArchiver`と`NSKeyedUnarchiver`に独自クラスを登録します．

```swift:例
override func viewDidLoad() {
    super.viewDidLoad()
    NSKeyedArchiver.setClassName("Sample", for: Sample.self)
    NSKeyedUnarchiver.setClass(Sample.self, forClassName: "Sample")
}
```

# データの取得/保存

```swift
let userDefaults = UserDefaults(suiteName: "group.com.hoge.sampleApp")!

var sample: Sample {
    get {
        guard
            let data = userDefaults.data(forKey: "sample"),
            let unarchived = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data),
            let sample = unarchived as? Sample
            else {
                return Sample(false, 0.0, "")
        }
        return sample
    }
    set(newSample) {
        let data = try? NSKeyedArchiver.archivedData(withRootObject: newSample,
                                                     requiringSecureCoding: true)
        userDefaults.set(data, forKey: "sample")
    }
}
```

このように`get`と`set`を定義してしまうとデータの出し入れがしやすいかもしれません．

# 参照

- [iOSアプリでApp Groupsを実装](https://qiita.com/jpmos7/items/7cbf02136810230e9c6a)
- [Swift：独自クラスをUserDefaultsで保存する](https://qiita.com/Kyome/items/46403b1422d13f29078a)
- [NSInvalidUnarchiveOperationException raised only in iOS extension, not main app](https://stackoverflow.com/questions/29201432/nsinvalidunarchiveoperationexception-raised-only-in-ios-extension-not-main-app)
- [NSCoding Tutorial for iOS: How to Permanently Save App Data](https://www.raywenderlich.com/6733-nscoding-tutorial-for-ios-how-to-permanently-save-app-data#toc-anchor-012)
Flask:  [root] Error: Can't locate revision identified by 'XXXXXXX' が出てしまい、migrateできないとき。

## エラーの発生
migration ファイルを消して再度`flask db init` -> `flask db migrate`した際、

```console
(flask_env) C:\Users\ryosu\Desktop\sample_2>flask db migrate
C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.")
  result = self._query(query)
C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\x93\\x8C\\x8B\\x9E (...' for column 'VARIABLE_VALUE' at row 1")
  result = self._query(query)
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [root] Error: Can't locate revision identified by 'e7c58547f941
```
が発生し`migrate`できなくなってしまった。

## 解消方法
mysqlでdbを覗くと、`alembic_version`というテーブルが残っていた。

```console
mysql> show tables;
+---------------------+
| Tables_in_sample_db |
+---------------------+
| alembic_version     |
+---------------------+
1 row in set (0.00 sec)
```
これを`drop`し、

```console
mysql> drop table alembic_version;
Query OK, 0 rows affected (0.18 sec)
```

再び、`migrate`すると無事エラーが解消した。

```console
C:\Users\ryosu\Anaconda3\envs\flask_env\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\x93\\x8C\\x8B\\x9E (...' for column 'VARIABLE_VALUE' at row 1")
  result = self._query(query)
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'infos'
Generating C:\Users\ryosu\Desktop\sample_2\migrations\versions\3b7a65a2d497_.py ...  done
```
エラーを検索しても英語の記事しか出てこなかったため、メモとして残しておきます。
AtCoder Beginner Contest 159の復習, E問まで(Python)

競プロ初心者の復習用記事です。

ここで書く解は解説や他の人の提出を見ながら書いたものです。自分が実際に提出したものとは限りません。

# A - The Number of Even Pairs
偶数が書かれたボールN個と奇数が書かれたボールM個、合計が偶数になる組み合わせの数の数を答える問題です。

単純に偶数同士の組み合わせ$N(N-1)/2$と奇数同士の組み合わせ$M(M-1)/2$を合わせれば答えになります。

```python

N, M = map(int, input().split())
print((N*(N-1))//2 + (M*(M-1))//2)
```

# B - String Palindrome

与えらえた文字列が「回文二つを組み合わせた回文」になっているかを判定する問題です。

左側の前半、左側後半、右側前半、右側後半の4つの文字列が一致しているかを、文字列Nの1/4まで回して判定します。

```python
s = input()
n = len(s)
for i in range((n-1+3)//4):# +3は切り上げ用
    if not(s[i] == s[(n-1)//2-i-1] and s[(n+3)//2 + i-1] ==  s[-i-1] and s[i] == s[-i-1]):
        print('No')
        exit()
print('Yes')
```

他の解答とか解説見たらもっときれいな書き方がありました。

```python
s = input()
n = len(s)
sl = s[:n//2]
sr = s[n//2+1:]
if sl == sr and sr ==  sr[::-1]:
    print('Yes')
else:
    print('No')
```

文字列を左右に切り分けて、右側```sr```が回文になっているならそれと一致する```sl```も回文。```sl```と```sr```がそれぞれ一致する回文なので二つを合わせても回文。条件が二つで済みました。

# C - Maximum Volume
高さ横幅縦幅の合計がLの直方体の持つ最大の体積を答える問題です。

高さ=横幅=縦幅の時体積が最大となるので、それぞれの長さは$L/3$。これを3乗するだけです。

```python
L = int(input())
print((L/3)**3)
```

なんで辺の長さが一致する時最大になるのかは説明できなかったので、一応数学的な説明を書いておきます。
以下が変数三つでの相加相乗平均の公式です。
$$ {a＋b+c\over 3}\geq (abc)^{1/3}$$
高さを$a$, 幅を$b$, $c$と考えると直方体の体積は$abc$で求まります。
$$ \({a＋b+c\over 3}\)^3\geq abc$$
$a=b=c$の時この式の等号が成立するので最大の体積となります。
 
# D - Banned K

数字の書かれたN個のボールから同じ数同士を選ぶ組み合わせが何通りあるかを、ボールを除外しながら考える問題です。

まず全部のボールから組み合わせ数の合計$S$を求めます。そこから、数字$n$のボールが$m$個あるとき、数字$n$のボールを一個取り出すと$m-1$通りだけ合計$S$が減ることになります。取り出すボールごとに数字$n$を当てはめて出力していきます。

```python
import collections
N = int(input())
li = list(map(int, input().split()))
cn = collections.Counter(li)
sumC = sum([n*(n-1)//2 for n in cn.values()])
for k in range(N):
    print(sumC-cn[li[k]] + 1)

```

# E - Dividing Chocolate

板チョコ内のホワイトチョコの量が一定以下になるように割る回数を答える問題です。

「探索の考え方」「割った内のホワイトチョコレートの数の数え方」どちらもわからなかったので諦めました。

解説を見ました。$H\leq 10$という狭い範囲指定があるため、横向きの割り方は愚直に$2^{H-1}$通りの全探索ができます。全探索には`itertools.product()`を用いて、0か1が含まれる長さH-1の配列を全通り作成します。これで探索はOK。

横向きに割られたチョコレートは縦向きにホワイトチョコの数を数えた1次元配列として二次元配列`SW`内に格納し、左から数えていきます。どれかの列のチョコの数が規定数`K`を超えたらチョコを縦向きに割ってカウントを0に戻します。これでチョコレートのカウントもできます。ただし1次元配列の持つ値が`K`を超えていたらチョコを何度割っても不可能なため、その状況は横向きに割るところからやり直し。

というわけで以下のようなコードになります。

```python
import itertools

H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
ans = 1e4
for t in itertools.product([0, 1], repeat=H-1):
    cnt = t.count(1)
    SW = []
    tmp = [int(s) for s in S[0]]
    for i, c in enumerate(t):
        if c:
            SW.append(tmp)
            tmp = [int(s) for s in S[i+1]]
        else:
            tmp = [tmp[j] + int(S[i+1][j]) for j in range(W)]
    SW.append(tmp)
    H_ = len(SW)
    sums = [0] * H_
    if max(itertools.chain.from_iterable(SW)) > K:
        continue
    for w in range(W):
        sumtmp = [sums[i] + SW[i][w] for i in range(H_)]
        if max(sumtmp) > K:
            cnt += 1
            sums = [SW[i][w] for i in range(H_)]
        else:
            sums = sumtmp
    ans = min(ans, cnt)
print(ans)        
```

この記事はE問まででとりあえず終わりとします。
git checkoutって色んな意味持たせ過ぎじゃない？

# きっかけ
前回の記事（[「こんなことしたい」って時にどんなgitコマンド使えば良いのか？](https://qiita.com/kabu0404/items/ea5e48b4e27ccd2cc5ef)）を書いているときに、
コマンドについて下図のようなお絵かきをして整理していたのですが

![コマンドの整理](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224361/c93e25a2-f961-cd28-b0d6-af41beedb9c9.png)

**`git checkout`って状況/条件によって挙動が色々ありすぎじゃない？**

※ちなみにお絵かきしている途中で同じような物を公式が[チートシート](https://ndpsoftware.com/git-cheatsheet.html)として用意していることに気づきました...

# `git checkout`の挙動整理
## ブランチ名を指定した場合
|ローカルブランチに存在する|リモート追跡ブランチに存在する|`git checkout`の挙動|
|---|---|---|
|×|×|ブランチを切り出す|
|×|○|リモートからブランチをローカルリポジトリ内に持ってくる|
|○|○|参照するローカルブランチを切り替える|

## ファイル名を指定した場合
ワーキングツリー内の指定したファイルの編集内容をローカルブランチの内容でもとに戻す

# チェックアウトという名前の範囲から逸脱していないか？

ブランチを切り出したり、ブランチを切り替えたり、ファイルの編集内容をもとに戻したりと
チェックアウトという名前を付けられていながら、実際にはある意味**やりたい放題**のコマンドになっている印象が強いです。

（svnをずっと触っていたこともあり）チェックアウトとは、「リポジトリから何かしらを持ってくる」ものだと思っていまいたため、gitを触り始めたときに「？？？」となったポイントの一つでした

# 新しいオフィシャル見てみたら新しいコマンドが追加されてた
このやりたい放題の`git checkout`について[gitのオフィシャル](https://git-scm.com/docs/git-checkout)を読んでいたら最後のsee alsoにそれっぽい名前のコマンドが書かれていました。

|コマンド|内容|
|---|---|
|`git switch`|Switch branches（ブランチ切替）|
|`git restore`|Restore working tree files（ワーキングツリー内ファイルの復元）|

どうやら去年(2019年)の8月のアップデート2.23.0で追加されたコマンドのようです。
※使っていたgitが2.21.?だったので気づきませんでした……

# 新コマンド含めて、役割を再整理しよう

|やりたいこと|使うコマンド|
|---|---|
|ブランチ切り出し|`git branch`|
|ブランチ取得|`git checkout`|
|ブランチ切替|`git switch`|
|ファイル復元/編集内容取消|`git restore`|

以後こんな感じで整理してコマンドを理解しておけば変なこともないよね？
**と思っていたのですが**
`git switch`と`git restore`のDESCRIPTIONにこんな記載がありました
> THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

- これは実験的なコマンドなので、挙動が変わる可能性があるよ

# 結論

|やりたいこと|使うコマンド|
|---|---|
|ブランチ切り出し|`git branch`|
|ブランチ取得|`git checkout`|
|ブランチ切替|`git checkout` ~~`git switch`~~ |
|ファイル復元/編集内容取消|`git checkout` ~~`git restore`~~|

- コマンドの役割分担的に考えて、少なくともブランチ切り出しは`git branch`で良いと思う
- ブランチ切替、ファイル復元は新コマンド（`git switch`と`git restore`）が用意されているが、変更される可能性があるのでしばらくは様子見して`git checkout`を使い続けた方が良さそう

と言う微妙な結論になりました。

新コマンドの注意書きにでは**挙動が変更となる可能性**という書き方なので、少なくともコマンドがなくなる事はなさそうなので、今後のgitのリリースで`git switch`と`git restore`がどうなるのか注目しておいたほうが良さそうですね。
git pull時に 【Your local changes to the following files would be overwritten by merge】とエラー

#エラー内容

$ git pull origin masterをすると

```
error: Your local changes to the following files would be overwritten by merge:
	config/routes.rb
Please commit your changes or stash them before you merge.
```

が出てくる。

#原因
pullした内容と自分の編集した箇所(ここではconfig/routes.rb)が被っている。

#解決策
pullした内容の箇所が自分も編集している所の為、
mergeする前にcommitするかstashしてと言われる。

なので、今回はコミットを選択。

```
$ git add * 
$ git commit -m "コミット名" 
$ git push origin 自分の作業ブランチ 
```

でpushし、Github上で
コンフリクトが起きなければ再度、

```
$ git pull origin master 
```

とpullすればOK。
コンフリクトの場合はコンフリクト内容を修正してから再度、pull。
【Python】Numpyでパーリンノイズ生成関数を無理やり短く書いた。

#はじめに
**・パーリンノイズとは**
パーリンノイズというのは程よい連続性と乱雑さがある使い勝手のいい（地形のランダム生成など）ノイズのことです。
詳しいことは他の人が書いているのでここではコードの紹介にとどめます。

#書いた関数

```python:perlin.py
#ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt

#線形補間と連続性を生み出す子たち
def fade(t):return 6*t**5-15*t**4+10*t**3
def lerp(a,b,t):return a+fade(t)*(b-a)

#本体
def perlin(r,seed=np.random.randint(0,100)):
    np.random.seed(seed)

    ri = np.floor(r).astype(int) #整数部、インデックスとして使用
    ri[0] -= ri[0].min()         #
    ri[1] -= ri[1].min()         #インデックスとして使用するための準備
    rf = np.array(r) % 1         #小数部
    g = 2 * np.random.rand(ri[0].max()+2,ri[1].max()+2,2) - 1 #格子点の勾配
    e = np.array([[[[0,0],[0,1],[1,0],[1,1]]]])                       #四隅
    er = (np.array([rf]).transpose(2,3,0,1) - e).reshape(r.shape[1],r.shape[2],4,1,2) #四隅の各点から見た位置ベクトル
    gr = np.r_["3,4,0",g[ri[0],ri[1]],g[ri[0],ri[1]+1],g[ri[0]+1,ri[1]],g[ri[0]+1,ri[1]+1]].transpose(0,1,3,2).reshape(r.shape[1],r.shape[2],4,2,1) #おなじみファンシーソートで四隅の勾配をまとめて内積計算できる形に加工
    p = (er@gr).reshape(r.shape[1],r.shape[2],4).transpose(2,0,1) #全点まとめて勾配との内積計算
    
    return lerp(lerp(p[0],p[2],rf[0]),lerp(p[1],p[3],rf[0]),rf[1]) #補間して返す
```

#計算・プロット

```python:perlin.py
N = 512
y = np.zeros((N,N))
for i in np.random.rand(1):         #パーリンノイズは周波数を変えて何枚か重ねると本領を発揮するらしいのでループして加算（好きなだけどうぞ）
    x = np.linspace(0,8*i,N)
    r = np.array(np.meshgrid(x,x))
    y += perlin(r)                  #meshgridの形(2,N,N)で渡す

plt.imshow(y)
plt.show()
```
`結果：`
![perlin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501281/6f081587-fa00-c267-982d-38cc94b22a3e.png)

##その他　3Dプロット及び次元拡張版
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501281/ace2e4ec-c6d0-f342-ba50-85a2bf8b1873.png" width=45%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501281/d13bf1a2-00b9-28dc-7c46-2d6b1ab91399.png" width=50%>



#まとめ
ループ使いたくなさが嵩じて書いたコードです。
途中、５階テンソルとか出てくるけどスッキリ書けると気持ちいいよね。
【StyledComponent + CSSアニメーション】keyframesに引数をつける

StyledComponentを使ってCSSアニメーションを作る時に使う`keyframes`に引数を渡して動的にアニメーションを調整する方法を、忘備録として。

# 結論

こんな感じ。

```typescript:keyframes
import { keyframes } from 'styled-components'

export const zoomInToAnyScale = (num: number) =>
  keyframes`
    from { transform: scale(0) }
    to { transform: scale(${num}) }
  `
```

```typescript:使い方

const StyledDiv = styled.div`
  animation: ${zoomInToAnyScale(3)} 0.3s ease 0.5s forwards;
`

const ZoomInDiv = styled.div<{ scale: nuber }>`
  animation: ${({scale}) => zoomInToAnyScale(scale) } 0.3s ease 0.5s forwards;
`
```

### 環境
一応、環境はこんな感じ。

| package | version |
|---|---|
| React | 16.13.0 |
| StyledComponents | 5.0.1 |
| TypeScript | 3.8.3 |


# 解説
（解説というほどのものでもないけど）
StyledComponentsで宣言する`keyframes`は元はただの関数です。引数にとるのは`TemplateStringsArray | CSSKeyframes`となっていますが、要はCSSが書かれた文字列orオブジェクトなので、こんな書き方もできます。

```typescript:keyframes
import { keyframes } from 'styled-components'

export const zoomInToAnyScale = (num: number) => {
  return keyframes({
    from: { transform: `scale(0)` },
    to: { transform: `scale(${num})` }
  })
```

つまりは、テンプレートリテラルなどに埋めてそのまま引数として渡せばいいだけ。
ちなみに`styled.div`などはただの関数もうちょっと複雑になってるようです。

# 終わりに
最近CSSアニメーションに夢中になって、いろいろな作品を見て「すげええええ」って言いながら勉強しています。
いや、本当にすごいんですよ。CSSアニメーターの方全員尊敬してます。神。

StyledComponents自体の記事は多いのですが、keyframesはあまり見かけなかったので書いてみました。
実務とかだと、ただのCSSアニメーションは扱いづらいのかもしれないですね。

トリガーで発火させるようなアニメーションは、JS側で管理しやすい[react-spring](https://www.react-spring.io)とかの方が良さそうです。
ニューラル機械翻訳ライブラリのざっくりとした紹介

# はじめに
機械翻訳研究の世界最大のワークショップ、WMTに2020年から英日翻訳が追加されたり、DeepLが日本語対応したり、日本語機械翻訳への注目が高まっています。そんな中で機械翻訳モデルを試しに使ってみたい、学習してみたい、そんな人もいるでしょう。私もこの分野は素人ですが今後使いたくなるかもしれません。今、どんな機械翻訳のライブラリが研究で使われているのか、自分のために調べました。なお筆者はFairseqと昔のOpenNMTしか使ったことがありません。

# どんなライブラリが使われているのか
機械翻訳コンペ、WMT2019の[Findings](http://www.statmt.org/wmt19/pdf/53/WMT01.pdf)によると
- Marian 30%超
- Fairseq 18%
- OpenNMT 16%
- Tensor2Tensor 14%
- Sockeye 14%
だそうです。それぞれ独自の機能（手法やモデルの実装）があるのですが、普通のTransformerはどれでも使えます。

## [Marian NMT](https://marian-nmt.github.io/)
MarianはMicrosoft翻訳チームが開発したフレームワークです。C++で書かれているので非常に高速というのが特徴です。また、精度面も、WMT2019でMarianを利用したMicrosoftチームのシステムがさまざまな言語対で上位になっているという実績があります。

使い方は、Exampleを見る限りtokenizeされたコーパスからMarianのコマンドで語彙ファイルを作って学習、という流れのようです。

GPU版のインストールのためにはCMake 3.5.1、GCC/G++ 5.4、Boost 1.65.1、CUDA 9.0 or newerを用意してmakeすれば良いです（若かりし時の僕は何も知らずにmakeしてコケて断念しました）。

残念なことに、Marianをインストールして使ってみたという日本語記事は今のところ見当たりません。英語のdocumentやtutorialを読みましょう。

## [Fairseq](https://github.com/pytorch/fairseq)
FairseqはFacebook AIが開発したツールキットです。Pytorchで書かれており、拡張がしやすいように設計されているのが大きな特徴で、どんどんアップデートされている印象があります。精度についてもWMT2019でFacebookチームが優秀な成績を残しています。速度はFP16モードを使えば高速です（当初はMarianより速かったがアップデートによりMarianの方が速くなったとどこかで見た気がします）。

使い方は専用のpreprocessスクリプトでコーパスと語彙をバイナリ化してから訓練します。推論時はテスト文をバイナリ化せずそのまま入力することもできます。個人的に有難い点の一つに、バイナリ化された訓練データ、および学習したモデルのcheckpointファイルをFairseqのコマンドで上書きできないようになっている（AssersionErrorが出て停止する）ことです。。Fairseqについてはいろいろ書けることはあるのですが、それだけで１記事が書けてしまいますし他の日本語記事もあるので、本記事ではこの程度の言及にとどめておきます。公式のexampleもありますし、非常に使いやすいです。

インストールはPyTorchさえ動けばほぼ大丈夫です。PyTorchは[公式](https://pytorch.org/)にOS、Package、CUDAバージョンに応じたインストール方法が書いてあるのでそれに従いましょう。

## [OpenNMT](https://opennmt.net/)
OpenNMTはHarvard NLP groupとSYSTRANが開発したツールです。今日紹介するもので最も歴史が古いです。
かつてはLua版が存在していたのですがTorchのメンテ終了とともに終了したようです。現在PyTorch版（OpenNMT-py）とTensorFlow版（OpenNMT-tf）の開発が継続されています。両者は利用できる機能がかなり異なっています。また機械翻訳、言語モデリング以外にimage to text、speech to text、要約、系列分類、系列タギングもできるようです。

使い方は専用の前処理をして学習という感じで普通です。

かつで自分がOpenNMT-pyを使ったときは、インストール時にtorchtextのバージョンに苦しめられたこと、validationで一番良かったモデルを自動保存してくれたりしないので推論時に学習ログを見てモデルを選ぶ必要があること、精度が出るオプション・ハイパラがよくわからないことなどが不満でした。現在どうなってるのかわかりません。日本語記事はそこそこあるのでそちらを参考すると良いかもしれません。

##[Tensor2Tensor](https://tensorflow.github.io/tensor2tensor/)
T2TはGoogle Brainチームにより開発された、深層学習とデータセットのライブラリです。TensorFlowで書かれています。
この記事で取り上げた他のライブラリは機械翻訳がメインの機能ですがこれは画像分類、画像生成といった様々なタスクの深層学習モデルが利用できます。

大雑把な使い方はデータ生成コマンドを実行して学習して推論という流れでですが、`--problem`というオプションがあります。これは単にタスクを指定するというよりは、利用するデータセットを指定するオプションになります。そのため既存のベンチマークデータセットで実験をする分には大変楽なのですが、自前で用意したデータセットを利用するときは`Problem`というクラスを継承したクラスを自分で定義する必要があります。この仕様によってモデルとデータ（と前処理方法）が明示的に紐づかせられるのは良い点ですが、お手軽さという観点では他のライブラリが勝ると思います。

日本語記事や公式のJupyter NotebookがあるのでExampleは充実している印象です。またTensorFlow Servingが使えるということもあるので、プロダクションで深層学習モデルを利用するときはこれになるのかな、と思います。

## [Sockeye](https://github.com/awslabs/sockeye)
Apache MXNet (Incubating)を用いたSeq2Seqフレームワークです。使い方はOpenNMTとかと似た感じのようです。

このライブラリだけ調べても特徴がよくわかりませんでした・・・いかがでしたかブログみたいですみません・・・。

# おわり
上から試していくのが良いんじゃないかと思います。
js関数まとめ

# 関数

## 関数宣言文と関数リテラル式の違い

```js
//関数宣言文
function func_name() { /* 処理 */ };
//関数リテラル式
var f = function func_name() { /* 処理 */ };
var f = function () { /* 処理 */ }; // 関数名func_nameは省略可。
```
関数宣言文は巻き上げ（hoisting ホイスティング:varによる変数宣言と、functionによる関数宣言はスコープ内の一番先頭で"宣言"されたものと見なされる）が起こるため、宣言より前に呼び出してもエラーしない。

## 引数

関数内から実引数にアクセスするには`arguments`オブジェクトが使える。
`arguments.length`として実際に受け取った実引数の数を取得できる。
反対に関数自身の持つlengthプロパティを使うと仮引数の数を取得できる。

# スコープ

varにはブロックスコープが存在しない。letではこれがある。

```js
if (var i = 0; i < 2; i++){
}

//ブロックを抜けてもiは2
```

また、letは以下のようにブロックスコープをもった文や式を作れる。

```js
//let文
let ( x = 1 ) {
    // 処理
}
//let式
let ( x = 1 ) 式;
```

# Functionクラス

StringやNumberのように、Function関数・コンストラクタが存在する。
同じく関数宣言文やリテラル表記で定義する方が望ましいらしい。

プロパティ(一部)

* apply() : 第一引数にthis参照先、第二引数に渡す要素のリストを指定して関数実行。
* bind()  : 第一引数にthis参照先、第二引数に渡す要素を1つ1つ指定し、クロージャを返す。可変長。
* call()  : 第一引数にthis参照先、第二引数に渡す要素を1つ1つ指定して関数実行。可変長。
* length  : 関数の仮引数の数（上述）

なお、this参照、クロージャについては下記。

# this参照

```js
var obj = {
    x: 10,
    f: function() {
        print this.x;
    }
}
var fn = obj.f

fn() // thisの参照先はグローバルオブジェクトとなる。
```

オブジェクトリテラルとして定義した時にはオブジェクトobjのプロパティであるためthis参照はobjのxを指す。
変数fnにobjの関数オブジェクトfを代入した時、グローバルオブジェクトのプロパティが生成し、fnを呼び出すとthis参照先はグローバルオブジェクトの持つxとなる。

apply関数、call関数は第一引数に指定したオブジェクトがthisの参照先となる。

```js
function f() { print(this.x); }
var obj = { x: 10 };

f.apply(obj);
// 10
```

# クロージャ

表層的な理解:関数スコープを抜けてもローカル変数が生き続け、状態を持つことができる関数。

```js
function f() {
    var x = 0;
    function g() { return ++x; }
    return g;
}

var fn = f();
fn() //1
fn() //2
fn() //3
```

上記のように関数fのローカル変数が生き続けているように振る舞う。

細かなしくみ。

関数(ここではf)がコールされると、その瞬間Callオブジェクトと呼ばれるものが暗黙裡に生成する。Callオブジェクトは自身のプロパティとして関数スコープの変数や関数を持つ、すなわちここではxやgがCallオブジェクトのプロパティとなる。最後に関数gへの参照がreturnされ、グローバルオブジェクトのプロパティであるfnに格納される。

ここで、本来であればCallオブジェクトはその関数が終了し、どこからも参照されなくなった時点で消滅する(＝ガベージコレクション)のだが、プロパティである関数gへの参照がfnに渡っているためCallオブジェクトが消滅しない。

そのため、表面上関数fnが状態を持っているように見える。

# クロージャの利用

* グローバル変数の回避
* 変数の隠蔽(privateな変数)

```js
var calc = (function() {
        var private_val = 5;
        return function (x) {
            print private_val * x;
        }
    }
)();

calc(2); //10
```

無名の関数は定義と同時に実行され、プロパティである関数への参照がcalcに渡されるため、Callオブジェクトが生き続け、クロージャとなる。
このcalcは関数としてprivate_valにアクセスできるが、ダイレクトにアクセスして値を書き換えたり読み出したりすることはできない。

# 式クロージャ 
Firefoxの独自拡張？deprecatedらしい。詳細は触れない
エクセルVBAでRedmineのデータを取得する

#概要
　Redmineのチケット数が多い場合、ページネーションされるため、無限スクロールで確認したかった。とりあえずチケットの主要な項目をエクセルで一覧できるようにしました。
　抽出ボタンを押すと、同シート６行目以降にデータが書き出されます。ただし、チケット数が多きときはかなり時間が掛かります。プログレスバーを付けるべきかもです。

![ui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569955/dd7b5ac7-643f-e5ee-78f3-8a0a36e13dc3.png)

#環境
* Windows 10
* Excel 2016
* Redmine 4.1.0

#準備
* Excel
    * 「リボン > 開発 > Visual Basic > ツール > 参照設定 > Microsoft XML v6.0」にチェックをする。
    * リボンに開発タブが無いときは下記を参照ください。
        * [開発タブを表示する](https://support.office.com/ja-jp/article/-%E9%96%8B%E7%99%BA-%E3%82%BF%E3%83%96%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B-e1192344-5e56-4d45-931b-e5fd9bea2d45)
* Redmine
    * 「個人設定 > 右側のAPIアクセスキー」を確認する。
    * チケットをxmlで開く、もしくはjsonで開く。
        * ブラウザのURL末尾に.xmlを付ける。
        * ブラウザのURL末尾に.jsonを付ける。

#コード
```vb
:vba
    Dim baseurl As String, targeturl As String
    Dim header As Integer, row As Integer
    Dim min As Integer, max As Integer
    Dim cnt As Integer
    Dim ticketid As String
    Dim dom As Object
    Dim issue As Object
    
    baseurl = "http://redmine/"
    header = 5
    row = header + 1
    min = 1
    max = 100
    cnt = min

    '[A～G]欄の[row～(max-min+1)]行まで一気にクリアする
    Range(Cells(row, 1), Cells(max - min + 1, 7)).Clear
    
    Do While Cells(row, 1) = ""
        
        ticketid = Trim(str(cnt - header))

        'APIアクセスキーなし
        targeturl = baseurl + ticketid + ".xml"
        'APIアクセスキーあり
        'targeturl = baseurl + ticketid + ".xml?key=aaaaaaaaaaaaaaaaaaaa"
        
        Set dom = CreateObject("MSXML2.DOMDocument")
        dom.async = False
        dom.setProperty "ServerHTTPRequest", True
        dom.Load (targeturl)
        Set issue = dom.ChildNodes.Item(1)
        
        If Not (issue Is Nothing) Then
            Cells(row, 1) = issue.getElementsByTagName("id").Item(0).text
            Cells(row, 2) = issue.getElementsByTagName("project").Item(0).getAttribute("name")
            Cells(row, 3) = issue.getElementsByTagName("tracker").Item(0).getAttribute("name")
            Cells(row, 4) = issue.getElementsByTagName("status").Item(0).getAttribute("name")
            Cells(row, 5) = issue.getElementsByTagName("priority").Item(0).getAttribute("name")
            Cells(row, 6) = issue.getElementsByTagName("assigned_to").Item(0).getAttribute("name")
            Cells(row, 7) = issue.getElementsByTagName("subject").Item(0).text
            row = row + 1
        End If
        
        cnt = cnt + 1
        If cnt > max Then
            GoTo 9999
        End If
    Loop
9999
```

xlsmファイルは下記GitHubへアップしてあります。
https://github.com/i-chiaki/RedmineToExcel.git

#参考サイト
https://yujisoftware.hatenablog.com/entry/20130421/1366543773
ロジスティック回帰分析pythonで自作

#はじめに
今日から頑張って連続100日を目指して、pythonでなんらかの実装をしていこうと思います。
毎日１つでもやっていけば、成長できるのではないかと考えました。
最初のうちはUdemyの講座を見ながら実装なので、値を少し変えたり、少し工夫をしながら公開していこうと思います。
~~100日後に成長してるワニを目指して...~~

#1日目
##ロジスティック回帰
ロジスティック回帰モデルは分類を主に目指しているモデルです。
尤度というもっともらしさを数値から推測して、
尤度関数を最大化するように、最急降下法を使っていきます。
##実装するもの
Udemyの[人工知能・機械学習エンジニア養育講座](https://www.udemy.com/course/machine-learning-3algo/)を参考にして、
タバコとお酒の摂取量から、生活習慣病かどうかを分類するものを実装していきます。
##指針
健康な人に対するオッズを使用して、リスクの相乗モデルの関数を作成して、そこからシグモイド関数を導出してモデル構築します。
`シグモイド関数:1/1+e^-x`
`目的の関数:x=β0+β1*x1+β2*x2`
##コード
実際のコードはこちらから
[day1.py](https://github.com/HinataAoki/Everyday-AI-life/blob/master/day1.py)

##1日目感想
初めの日がやっぱり一番時間がかかると思います。めげずに頑張ります。
応援よろしくお願いいたします。
チーム開発

本番環境でのみ画像が反映されない
public/images/に画像を移動
SCSS記述background-image: url("/images/bg-topMiddleDl-pict.jpg");
HTML記述　= image_tag asset_path("material/logo/logo.png")
で解決。
必ず、GitHubdesktopでプル→ローカルでbundle exec cap production deploy
で本番環境に反映

S3の導入でミスがあり、商品画像投稿を実装の時にやり直す予定。
pip install で依存ライブラリのインストールに失敗したときの対処

## 環境
Python3.4.3
Windows10 64bit

## やったこと
```
$ pip install Sphinx
~~ 中略 ~~
Collecting colorama>=0.3.5; sys_platform == "win32" (from Sphinx)
  Downloading https://files.pythonhosted.org/packages/31/cb/88c908c1be067fb6bacd3d7488ccab1a212533767b951933aac3d22648e2/colorama-0.4.2-py2.py3-none-any.whl
colorama requires Python '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*' but the running Python is 3.4.3
```
インストール失敗。
Downloadingの行からcolorama-0.4.2がインストールされていることがわかるが、最後の行でpython3.4は対応していないことがわかる。

## 対処
```
$ pip install colorama==0.3.9
```
PyPIのcoloramaのサイトからPython3.4.3に対応しているバージョンをインストールする。

```
$ pip --no-cache-dir install Sphinx
~~ 中略 ~~
Successfully installed Jinja2-2.10.3 MarkupSafe-1.1.1 Pygments-2.3.1 Sphinx-1.8.5 alabaster-0.7.12 babel-2.8.0 certifi-2019.11.28 chardet-3.0.4 docutils-0.15.2 idna-2.8 imagesize-1.2.0 packagi
ng-20.3 pyparsing-2.4.6 pytz-2019.3 requests-2.21.0 six-1.14.0 snowballstemmer-2.0.0 sphinxcontrib-websupport-1.1.2 typing-3.7.4.1 urllib3-1.24.3
```
インストールできた。
Wordpress プラグインの作成と管理画面の作り方

## プラグインの作成
プラグインを作るにはプラグインフォルダを作成し、プラグインの設定項目を記入する。

プラグインフォルダは、`wp-content/plugins`に作成する。

プラグインフォルダの最初のファイルはプラグイン名と同じようにする。ここでは`test-plugin.php`にした。

このファイルに最低限記入が必要なのは次のような内容。

```php
<?php
// wp-content/plugins/test-plugin/test-plugin.php
/*
Plugin Name: プラグイン名（他と被らないようにする）
Description: プラグインの説明文
Author: 作者名
Version: 0.1
*/
```

これだけだと何の変化もないので、`Hello World`と表示してみる。

```php
<?php
/*
Plugin Name: Test plugin
Description: A test plugin to demonstrate wordpress functionality
Author: Test Name
Version: 0.1
*/

function test_function() {
  echo '<h1>Hello World</h1>';
}
add_action( 'wp_footer', 'test_function' );

```

プラグイン一覧画面に作成したプラグインが表示されてるので有効化する。

`wp_footer`にアクションを追加したので、トップページを開くと画面下に`Hello World`が表示されるはず。

## プラグインにメニューと設定画面を追加する
次に管理画面を作成してみる。

管理画面は、`add_menu_page()`に簡単な設定項目を記入するだけ。

```php
<?php
/*
Plugin Name: Test plugin
Description: A test plugin to demonstrate wordpress functionality
Author: Test Name
Version: 0.1
*/

function test_function() {
  echo '<h1>Hello World</h1>';
}

function test_plugin_setup_menu(){
  add_menu_page(
    __( 'TestPlugin', 'textdomain' ), // ページタイトル
    'Test Plugin',  // メニュータイトル
    'manage_options', // 
    'test-plugin',  // メニューslug
    'test_function',  // 実行する関数
    'dashicons-chart-pie',  // メニューに表示するアイコン
    6 // メニューの表示位置
  );
}
add_action('admin_menu', 'test_plugin_setup_menu');
```

<img width="389" alt="plugin.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549249/9103c6c6-855e-452e-889a-2661d7b89a26.png">


メニューのリンクをクリックすると、`add_menu_page()`で指定した関数が実行されている。

あとはHTMLとCSSでページを作っていくだけ。
Youtubeのチャンネル登録者数を取得する

[Youtube Data APIを用いたバーチャルYoutuberのデータ収集 \- Qiita](https://qiita.com/kon2/items/f09def292c3b0be2bb8e) の写経

[Channels  \|  YouTube Data API  \|  Google Developers](https://developers.google.com/youtube/v3/docs/channels?hl=ja)

```py:nijisanji.py
from googleapiclient.discovery import build

YOUTUBE_API_KEY = '<API KEY>'


def youtube_channel_detail(channel_id, api_key):
    api_service_name = 'youtube'
    api_version = 'v3'
    youtube = build(api_service_name, api_version, developerKey=api_key)
    search_response = youtube.channels().list(
        part='snippet,statistics',
        id=channel_id,
    ).execute()

    return search_response['items'][0]


def main():

    d = youtube_channel_detail('UCHVXbQzkl3rDfsXWo8xi2qw', YOUTUBE_API_KEY)
    print(d['snippet']['title'])
    print(d['statistics']['subscriberCount'])
```

```
$ python3 nijisannji.py
アンジュ・カトリーナ - Ange Katrina -
257000
```
subversion error 70014 対応

## こんなエラー

```
Error 70014 can't synchronize with repository, ...\db\current: End of File Found
```

## 対応
- db/current ファイル存在しないエラーの場合、新規テキストファイルを作成
- db/revs/ と db/revprops/ フォルダーの中から最大の数字を db/current を一行目に記載
- 末尾に改行（LF）を入れる
- tx-currentファイルも同じ対応（しないと、コミット失敗する）

## 確認
以下のコマンドを実施して、エラー発生しこと

```
svnadmin verify レジストリへのパス
```

## 原因

- 自分の場合、コミット最中にVMの電源を落とし、\db\current ファイルが空になってしまったのが起因。
- 「End of File Found」は改行が忘れた場合に起きる


#### 参考
https://svn.haxx.se/users/archive-2014-06/0100.shtml
【Node】dotenvで環境変数を設定する

## 概要

- Nodeでプログラムを実行する時に環境(dev/stag/prodなど)ごとに値が異なる部分はコードを修正せずに実行するため環境変数として埋め込むことがよくあると思います
- セットする環境変数が1つ2つであればコマンド実行時に設定すればよいですが規模が大きくなってきたらファイルでまとめて定義したくなるでしょう
- そんな時は[dotenv](https://github.com/motdotla/dotenv)を使うと便利です
    - dotenvを使うと`.env`ファイルに定義された値を環境変数として使うことができます
    - また、システムの環境変数として値が設定されていればそちらを優先して使うということもできます
    - なので、開発時はローカルで`.env`を配置し、本番ではホスティングサービスの機能で環境変数として設定するといった使い方をすることでリポジトリ内のファイルを変更せずに実行することができます

## Nodeスクリプトの実行時にdotenvを使う場合

- シンプルな形でいうと`index.js`があって`node index.js`で実行するようなケースです
- まずはdotenvをinstallします

```sh
npm i dotenv
```

- 次にサンプル用の`index.js`を作成します
    - `require('dotenv').config();`としておくことでdotenvが適用されるようになります
    - `process.env`で環境変数を取得できます
    - `TEST_VALUE`という環境変数の値を取得しコンソールに出力するサンプルです

```js:index.js
require('dotenv').config();

const value = process.env.TEST_VALUE;

console.log(value);
```

- 最後に値を定義する`.env`ファイルを作成します

```config:.env
# 環境変数を定義
TEST_VALUE=.envで値を設定しています
```

- 実行してみましょう

```sh
node index.js
```

- ログに`.envで値を設定しています`と出力されているはずです
- `.env`の値をシステム環境変数で上書きできることも確認しておきましょう

```sh
TEST_VALUE="コマンドで値を設定しています" node index.js
```

- ログに`コマンドで値を設定しています`と出力されているはずです

## webpackでビルド時にdotenvを使う場合

- webpackなどでビルドしてから実行するケースも多くあると思います
- ここではWebpackでdotenvを使う場合の手順を紹介します
- [dotenv-webpack](https://github.com/mrsteele/dotenv-webpack)というライブラリを使用します

```sh
npm i webpack webpack-cli dotenv-webpack
```

- webpackの設定ファイルを作成します

```js:webpack.config.js
const Dotenv = require('dotenv-webpack');

module.exports = {
  plugins: [
    // { systemvars: true } を設定するとシステム環境変数も読み込まれるようになる
    new Dotenv({ systemvars: true }),
  ],
};
```

- `index.js`を修正します
    - dotenvはビルド時に適用されるため設定が消えてスッキリしました

```js:index.js
const value = process.env.TEST_VALUE;

console.log(value);
```

- ビルドして実行してみましょう

```sh
# ビルド(dist/main.jsが出力される)
npx webpack -p index.js
# 実行
node dist/main.js
```

- 実行すると`.envで値を設定しています`とログが出力されるはずです
- システムの環境変数で上書く場合ビルド時に環境変数を設定します

```sh
# 環境変数を設定してビルド
TEST_VALUE="コマンドで値を設定しています" npx webpack -p index.js
# 実行
node dist/main.js
```

- 実行すると`コマンドで値を設定しています`とログが出力されるはずです

## まとめ

- dotenvを使った環境変数の設定のしかたを紹介しました
- Nodeを使ったアプリでもこういった技術を活用してCI/CD回していきましょう！
Goのintスライスの値をスペース区切りで出力


# int型のスライスのままではstrings.Join()できない
```golang:main.go
package main
import (
    "fmt"
    "strings"
)

func main() {
    intSl := []int{1, 2, 3}
    fmt.Println(strings.Join(intSl, " "))
    // => cannot use intSl (type []int) as type []string in argument to strings.Join
    // strings.Join()の第一引数はstring型のスライスでなければいけない
}
```

# string型のスライスを作ってからstrings.Join()する
```golang:main.go
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    intSl := []int{1, 2, 3}
    strSl := []string{}
    for _, v := range intSl {
        // intSlの値を文字列にしてstrSlに突っ込む
        strSl = append(strSl, strconv.Itoa(v))
    }
    fmt.Println(strings.Join(strSl, " "))
    // => 1 2 3
}
```

# ついでに
Pythonならリスト内包表記で１行で書ける

```python:python.py
nums = [1, 2, 3]
print(" ".join([str(num) for num in nums]))
# => 1 2 3
```
MacでAWS Glueを実行したい

# 概要
- AWS の GlueをMac上で実行するための環境構築を行います

# 環境情報
- Mac Catalina 10.15.3
- Python2.7.16(Mac 標準)
- JDK(openjdk version "1.8.0_242")

# 参考
- Classmethodさん
https://dev.classmethod.jp/articles/aws-glue-local/
- aws 公式 
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-etl-libraries.html

# 手順
1. AWS Glue Python ライブラリをダウンロード
2. Apache Mavenダウンロード
3. Apache Sparkダウンロード

# 1.AWS Glue Python ライブラリをダウンロード
- 任意の場所にライブラリをダウンロードします。
- 今回はデスクトップのlocal_glueディレクトリにダウンロードします
 - Glue バージョン 1.0 の場合は、glue-1.0をcheckoutします
 - 今回は0.9を使用するため、checkoutは行いません

```
mkdir ~/Desktop/local_glue/
cd ~/Desktop/local_glue/
git clone https://github.com/awslabs/aws-glue-libs.git
```

# Apatch Mavenのダウンロード
- こちらも `~/Desktop/local_glue/` にダウンロードしておきます。
- wget入れてないので、curlコマンド

```
curl -OL  https://aws-glue-etl-artifacts.s3.amazonaws.com/glue-common/apache-maven-3.6.0-bin.tar.gz

tar -xzvf apache-maven-3.6.0-bin.tar.gz
```

# 3.Apache Sparkダウンロード
- こちらも `~/Desktop/local_glue/` にダウンロードしておきます。
- glueバージョン1.0の方はこちら : https://aws-glue-etl-artifacts.s3.amazonaws.com/glue-1.0/spark-2.4.3-bin-hadoop2.8.tgz 

```
curl -OL  https://aws-glue-etl-artifacts.s3.amazonaws.com/glue-0.9/spark-2.2.1-bin-hadoop2.7.tgz

tar -xzvf spark-2.2.1-bin-hadoop2.7.tgz
```

# 4.PATHの設定
- ~/.bashrcへ以下を設定する

```
vi ~/.bashrc

↓ 以下を記載
## set glue local
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
export PATH=$JAVA_HOME/bin:$PATH
export M2_HOME=$HOME/Desktop/local_glue/apache-maven-3.6.0
export PATH=$M2_HOME/bin:$PATH
export SPARK_HOME=$HOME/Desktop/local_glue/spark-2.2.1-bin-hadoop2.7

source ~/.bashrc
```

環境構築編はここまでとさせていただきます。次回はGlue実行を記載していきます。

## ハマりところ
- Anacondaをダウンロードしていたりすると、Python3系をデフォルトで使用する設定になっているかと思います
 - Glueバージョン0.9ではPython2系が動きます
 - そのためGlueバージョン0.9をPython3系で動かそうとすると・・・
 - `no module found error`で怒られ続けました。。。（Python2を使うようにすると解決）