OmniAICreator/Qiita-1.07M huggingface dataset:
SREs vs DevOps – SREとDevOpsの違いとは

**SREとは**

Google で生まれ、他の企業にも広まりつつある Site Reliability Engineering（SRE）とは、サイト・リライアビリティ・エンジニアリング」の頭文字を取った略称で、Webサイトやサービスの信頼性向上に向けた取り組みを行い、価値の向上を進める考え方および方法論です。

**SREの基本**

次の 3 つは SRE の基本原則ですが、本番システムに対して責任を負うチームであれば、名前がどうであれ、SRE チームを作る前から、あるいは SRE チームへの転換と並行して、広く採用しているプラクティスでもあります。

何らかのサービス レベル目標（SLO）を決め（開発、事業部門の一部でない場合は、これらの部門のメンバーと共同で）、ほぼ毎月目標を達成していること。
非難を伴わない障害報告書を記録するカルチャーがあること。
本番環境におけるインシデントの管理プロセスが作られていること（これは全社的であることが望ましい）

**DevOpsとは**

DevOps（デブオプス）は、ソフトウェア開発手法の一つ。開発 (Development) と運用 (Operations) を組み合わせたかばん語であり、開発担当者と運用担当者が連携して協力する（さらに両担当者の境目もあいまいにする）開発手法をさす。[1]厳密な定義は存在しておらず、抽象的な概念に留まっている。[2]ソフトウェアのビルド、テスト、そしてリリースの文化と環境を以前よりも迅速に、頻繁に、確実に発生する確立を目指している（Wikipedia）


それらは具体的なプラクティスではなく思想・方針なのでプログラミングにおけるいわゆるinterfaceとも見なせます。

**DevOpsが扱う5つの領域**

Reduce organizational silos(組織のサイロを削減する)
Accept failure as normal(エラーが発生するのを前提とする)
Implement gradual change(段階的に変更する)
Leverage tooling and automation(ツールと自動化を活用する)
Measure everything(全てを計測する)
DevOpsとSREの違いは

そのような中でSREの草分け的存在であるGoogleが新たに class SRE implements DevOps というメッセージを発信し始めました。これは「SREはDevOpsというinterfaceの実装である」という意味で、いわゆるプログラミング言語の抽象化機能であるinterfaceを想像してもらえれば良いと思います。

[![DevOps vs SREs](http://img.youtube.com/vi/uTEL8Ff1Zvk/0.jpg)](https://www.youtube.com/watch?v=uTEL8Ff1Zvk)

**SREの本**

英語版は、オンラインで無料で公開されています。Google – Site Reliability Engineering
日本語版は、オライリー・ジャパンより出版されています。『SRE サイトリライアビリティエンジニアリング――Googleの信頼性を支えるエンジニアリングチーム』
Firebase Meetup #15 Cloud Functions Day 資料まとめ

## イベント内容

2019/12/03 に開催された Firebase Meetup #15 Cloud Functions Day の資料まとめです。

Connpass: https://firebase-community.connpass.com/event/154400/
YouTube: https://youtu.be/BaNrP26EzU0

## Firebase & Google Cloud によるサーバーレス帳票管理

* 発表者: @potato4d さん
* 資料: https://speakerdeck.com/potato4d/serverless-architecture-in-candy

## React x Firebase を用いた Web アプリケーション開発時のハマりどころと解決策

* 発表者: @tanabee 
* 資料: https://speakerdeck.com/tanabee/react-x-firebase-tips
* Qiita 版資料: https://qiita.com/tanabee/items/b2527deb3f2f4b87406b

## もしもFDLでiOSアプリが開かなかったら

* 発表者: @mtfum さん
* 資料: https://speakerdeck.com/mtfum/if-cant-open-ios-app-with-firebase-dynamic-links
* Qiita 版資料: https://qiita.com/mtfum/items/1effdba80265c194e93d 

## PoC using Firebase Cloud Firestore

* 発表者: @simonTokyo さん
* 資料:  https://www.slideshare.net/simontokyo/poc-using-firebase-cloud-firestore-200839761

## Firestoreのスキーマ定義をチームで共有したい

* 発表者: @kikuchy さん
* 資料: https://docs.google.com/presentation/d/1mYTabdA8WRTjOI5SlsLUg6MEQuEbguoeD1zWmyvInTA/edit#slide=id.p

## firebaseオンリー + React Nativeでアプリを作ると果たして簡単になるのか？

* 発表者: @watanabe_yu さん
* 資料: https://speakerdeck.com/watanabeyu/firebaseonri-plus-react-nativedeapuriwozuo-rutoguo-tasitejian-dan-ninarufalseka

## Functionsでhtmlベタ書きレンダリングした上でリダイレクトするのをやめるんだ

* 発表者: @nabettu さん
* 資料: https://speakerdeck.com/nabettu/oghua-xiang-falsetamedakefalsefunctionsde-htmlbetashu-ki-ridairekutowoyamerunda

## CQRSを学ぶついでにCloud FunctionsとFirestoreを連動させる時の小技も学ぶ

* 発表者: @hecateball　さん
* 資料: https://speakerdeck.com/hecateball/cqrswoxue-butuidenicloud-functionstofirestorewolian-dong-saserushi-falsexiao-ji-moxue-bu
Raspberry Pi 4B 画面解像度設定（TV出力版）改

## 【前文】
[Raspberry Pi 4B 画面解像度設定（TV出力版）](https://qiita.com/god19/items/da8ce82b93b36dd5489d "Raspberry Pi 4B 画面解像度設定（TV出力版） - Qiita") の続き。
やっと画面解像度の変更ができたと思いきや、kodi がこける問題が発覚。やはり付け焼刃な対応はダメってことで設定を元に戻す。
もうグダグダ。

## 【結論】
`Screen Configuration` で設定できる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/fb3a3f8d-aed2-2904-a578-37f54428f9e7.png" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/36bcac90-0ec7-3722-bde4-c6176a7fb585.png" width=75%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/b90a8684-72fa-4606-9472-ffd30a937ac6.png" width=75%>

改めて公式ドキュメントを隅から隅まで確認し、やっと以下のページに辿り着いた次第。トホホ。
[Screen Layout Editor](https://www.raspberrypi.org/documentation/configuration/arandr.md "Screen Layout Editor - Raspberry Pi Documentation")
Windows で Virtualbox の VM を自動起動/終了する

# はじめに
　業務で毎日決まった時間に自動起動/自動終了するデモアプリを作ることになり、Windowsマシンの起動と同時に Virtualbox の VM をを立ち上げる方法について調べました。

# VM の自動起動
　以下のバッチファイルを作成し、ショートカットを スタートアップフォルダ「C:\Users\[ユーザー名]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup」に配置することで、PCの起動時にバッチファイルが実行されてVMが立ち上がるようになります。
ちなみに、スタートアップフォルダは、エクスプローラーに「shell:startup」と入力して開くこともできます。そちらの方が楽なのでオススメです。

```startupVM.bat: 
start start "" /b "C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" startvm "<VM名>"
```

# VM の自動終了
　私の環境では、タスクスケジューラーで毎日決まった時間に VM の終了を待たずに PC を強制的にシャットダウンしており、それを繰り返すと仮想マシンが壊れてしまうことがありました。
　そこでコマンドプロンプトを開いて以下のコマンドを実行し、PCの終了時にVMをPCのシャットダウン時に自動終了させるように設定します。

```shutdownVM.bat
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe setextradata "<VM名>" GUI/DefaultCloseAction <終了方法>
```
末尾の終了方法には、以下の4つがあり、デフォルトは1のようです。私は3を設定しました。
1. SaveState（仮想マシンの状態を保存）
2. Shutdown（シャットダウン シグナル送信）
3. PowerOff（仮想マシンの電源オフ）
4. PowerOffRestoringSnapshot（現在のスナップショットに復元）

#
DS18B20 で温度を読む

Raspberry Pi に接続した温度計　（DS18B20) で温度を読む方法です。
GPIO4,GND,3.3V に接続します。
インターフェースは、one-wire です。
結線後、raspi-config で　one-wire を有効にします。

確認

```text
$ ls /sys/bus/w1/devices/
28-021317fe3eaa  w1_bus_master1
$ ls /sys/bus/w1/devices/28-021317fe3eaa
driver  hwmon  id  name  power  subsystem  uevent  w1_slave
$ cat /sys/bus/w1/devices/28-021317fe3eaa/w1_slave 
6a 01 4b 46 7f ff 0c 10 b8 : crc=b8 YES
6a 01 4b 46 7f ff 0c 10 b8 t=22625
```

上記の場合の温度は、22.6度です。

プログラム

```py:get_temperature.py
! /usr/bin/python3
#
#       get_temperature.py
#
#                                               Dec/03/2019
#
#
# --------------------------------------------------------------------
import  sys
#
# --------------------------------------------------------------------
def device_read_proc(device):
        str_out = ""
        try:
                fp_in = open(device,encoding='utf-8')
                lines = fp_in.readlines()
                fp_in.close()
        except Exception as ee:
                sys.stderr.write("*** error *** file_to_str_proc ***\n")
                sys.stderr.write(str (ee))
#
        return lines
# --------------------------------------------------------------------
def get_temperature_proc():
        tstring = ""
        device = '/sys/bus/w1/devices/28-021317fe3eaa/w1_slave'
        lines = device_read_proc(device)
        for line in lines:
                pp = line.find("t=")
                if (0<= pp):
                        print(line)
                        tstring = line[pp+2:]
#
        itemp = int(tstring)
        temperature = float(itemp) / 1000.0
#
        return temperature
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
temperature = get_temperature_proc()
print(temperature)
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

実行結果

```text
$ ./get_temperature.py 
*** 開始 ***
6a 01 4b 46 7f ff 0c 10 b8 t=22625

22.625
*** 終了 ***
```
VPS で CentOS8 にアップグレードする方法（ISOイメージ不要）

全体的な性能が30%上がったという報告もある CentOS8 を公式非対応・ISOインストール機能もない「[WebARENA Indigo](https://web.arena.ne.jp/indigo/)」に導入する方法です。

## 性能UPについて

WebARENA Indigoの2vCPU/2GBプランで実際に約20%アップ（！）

| UnixBench   |   CentOS7.5   |   CentOS8.0   |  UP率       |
|:-----------------|:-----------------:|:------------------:|:------------------:|
|   シングルコア   |   563.2   |   700.3   |   24%   |
|   マルチコア   |   1052.7   |   1194.2   |   13%   |

## 環境
 - WebARENA Indigo 2vCPU/2GBプラン
 - CentOS 7.5.1804 
 - 3.10.0-862.14.4.el7.x86_64
 - rootユーザ

# アップグレード手順

ツールインストールとアップグレード

```shell
yum -y install epel-release rpmconf yum-utils
yum -y update
```
`Rpmconf`の初期設定

```shell
rpmconf -a;
#Your choice:　←　N
```

クリーニングしてCentOS8.0にアップグレード

```shell
package-cleanup --leaves
package-cleanup --orphans
yum install -y dnf
dnf remove -y yum yum-metadata-parser
rm -Rf /etc/yum
dnf upgrade -y
dnf upgrade -y http://ftp.iij.ad.jp/pub/linux/centos/8.0.1905/BaseOS/x86_64/os/Packages/centos-release-8.0-0.1905.0.9.el8.x86_64.rpm
dnf upgrade -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf clean all
rpm -e `rpm -q kernel`
rpm -e --nodeps sysvinit-tools
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
dnf install -y kernel-core
dnf groupupdate -y "Core" "Minimal Install"
```

## WebARENA Indigoだけ
再起動するとNIC名が変わるため設定ファイルを移動

```shell
mv /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-ens10;
sed -i -e 's/eth0/ens10/g' /etc/sysconfig/network-scripts/ifcfg-ens10;
```

## 再起動

```shell
reboot now
```
## お好みで
[CentOS8 のデフォルトでは pythonコマンド がないため、](https://rheb.hatenablog.com/entry/rhel8-python)お好みで python3 からシンボリックリンクを張る

```
alternatives --set python /usr/bin/python3
```



#参考
[How to Upgrade CentOS 7 to CentOS 8](https://www.tecmint.com/upgrade-centos-7-to-centos-8/)
[CentOS7からCentOS8にアップグレードする方法 | VPS比較2019年版](https://vpshikaku.com/centos7%E3%81%8B%E3%82%89centos8%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
MySQLで大量のシンプルなクエリを高速化する

どんなに軽いクエリでも、たとえばWebサーバーとMySQLの間のRTTが5msあって20クエリを実行したらRTTだけで100msかかってしまいます。

たくさんのデータをinsertするときは bulk insert (VALUES の後に複数の行を書くクエリ) を使うテクニックは有名です。しかしこのテクニックは次のような場合に使えません。

* 複数のテーブルに1行ずつINSERTしたい
* 複数のUPDATEやSELECTをまとめたい

たとえば弊社のある案件で次のような場面がありました。

* 新規ユーザー作成時に大量のテーブルにINSERTしたい
* ログイン時に大量のテーブルにSELECTしたい

こういった場面を高速化するために multiple statements と multiple result sets を利用しました。

## Multiple Statements

複数のクエリを ; で区切って一発（Pythonレベルで言えば1つの Cursor.execute() 呼び出し、プロトコルレベルで言えば1つのCOM_QUERYパケット）で送ることができます。複数のINSERT文を ; で繋ぐことで、大量のINSERT文やUPDATE文を高速化することができます。

RTTを削減できるだけでなくTCPのパケット数も削減できるので、MySQLサーバー側のクエリを受信する部分の負荷の削減も期待できます。

ただし、この ; を使ってクエリを連結する仕組みはSQLインジェクションでもよく悪用されています。そのため MySQL protocol ではハンドシェイク時に multiple statements を無効化できるようになっています。MySQLクライアントのライブラリによっては multiple statements を利用するためにオプションが必要かもしれません。

例えば Python の mysqlclient はデフォルトで multiple statements が利用できます。（fork元の昔からあるライブラリとの後方互換性のため...）
一方 Go の [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) は `multiStatements=true` を指定する必要があります。

もう一つの注意点として、 MySQL の (PREPARE 文ではなくプロトコルレベルの) prepared statement を使う場合は、 placeholder を利用できません。自前でエスケープしてSQL文字列を組み立ててからクエリを投げるか、 prepared statement を使わないように設定する必要があります。


## Multiple Result sets

複数のSELECT文をまとめたい場合は、複数のクエリを投げるだけでなくその結果を受け取る必要もあります。そのためには mutltiple result sets を使います。

複数の Result Set が返されたとき、Python では `Cursor.nextset()` を使って次の Result Set を受け取ることができます。

```py
import MySQLdb

con = MySQLdb.connect(host="127.0.0.1", port=3306, user="test", password="test")
cur = con.cursor()

q = """\
select 1;
select 2;
select 3;
select 4;
select 5;
"""

cur.execute(q)

while True:
    print(cur.fetchall())
    if not cur.nextset():
        break
```

Go の場合は `database/sql` の [Rows.NextResultSet()](https://golang.org/pkg/database/sql/#Rows.NextResultSet) を使って同じように複数の Result Set を受け取ることができます。
初心者によるプログラミング学習ログ 175日目

#100日チャレンジの175日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

175日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>175日目<br><br>webサイトコーディングの課題<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</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/%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></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1201591811292172288?ref_src=twsrc%5Etfw">December 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

最近ただのログとりになってますね。
まあ、しょうがありません。
KotlinのEnum の JSON シリアライズ結果をカスタマイズする

## kotlinx.serialization

- 文字列に変換するなら `@SerialName` アノテーションを使う
- 数値に変換するなら custom serializer を実装する
 - 参考: https://github.com/Kotlin/kotlinx.serialization/issues/31#issuecomment-522943969

```CommonEnumIntSerializer.kt
open class CommonEnumIntSerializer<T>(
    val serialName: String,
    val choices: Array<T>,
    val choicesNumbers: Array<Int>
) :
    KSerializer<T> {

    override val descriptor: EnumDescriptor = EnumDescriptor(serialName, choicesNumbers.map { it.toString() }.toTypedArray())

    init {
        require(choicesNumbers.size == choices.size) { "There must be exactly one serial number for every enum constant." }
        require(choicesNumbers.distinct().size == choicesNumbers.size) { "There must be no duplicates of serial numbers." }
    }

    final override fun serialize(encoder: Encoder, obj: T) {
        val index = choices.indexOf(obj)
            .also { check(it != -1) { "$obj is not a valid enum $serialName, choices are $choices" } }
        encoder.encodeInt(choicesNumbers[index])
    }

    final override fun deserialize(decoder: Decoder): T {
        val serialNumber = decoder.decodeInt()
        val index = choicesNumbers.indexOf(serialNumber)
        check(index != -1) { "$serialNumber is not a valid serial value of $serialName, choices are $choicesNumbers" }
        check(index in choices.indices)
        { "$index is not among valid $serialName choices, choices size is ${choices.size}" }
        return choices[index]
    }
}
```

```SerialEnum.kt
interface SerialEnum {
    val serialNumber: Int?
}
fun <T> Array<T>.serial() where T : SerialEnum, T : Enum<T> = this.map { it.serialNumber ?: it.ordinal }.toTypedArray()
```

```TestEnum.kt
object TestSerializer :
        CommonEnumIntSerializer<TestEnum>("TestEnum", TestEnum.values(), TestEnum.values().serial())

@Serializable(with = TestSerializer::class)
enum class TestEnum(override val serialNumber: Int? = null) : SerialEnum {
    Foo(123), // Will be serialized to 123
    AnotherConstant // Will be serialized to 1
}
```

## Jackson

`@JsonValue` アノテーションを使う
https://qiita.com/t-otsuka/items/ef7cd9cac84b2c1915c1
A volute 3d sound expert のポップアップについて

##背景
Windows10を更新したら起動時にA volute 3d sound expertのポップアップが毎回でてきてうんざり

##解決まで
[こちら](https://www.ame-arare.com/entry/2019/11/21/%E8%B5%B7%E5%8B%95%E6%99%82%E3%81%AB%E6%AF%8E%E5%9B%9E%E3%81%86%E3%82%8B%E3%81%95%E3%81%84%EF%BC%81%E3%80%8Ca-volute_3d_sound_expert%E3%80%8D%E3%81%AE%E5%AF%BE%E5%87%A6%E6%B3%95)の方を記事を参考すると、どうやらNahimic VRが原因らしい。
VRはたまに使うので無効にはしたくない...

海外の[スレッド](https://www.dell.com/community/Alienware/A-Volute-3D-Sound-constantly-has-a-startup-UAC-warning/td-p/6154229)にある情報によると管理者権限を渡しておけば解決するらしい。


##解決方法
これらを合わせて、NahimicVRに管理者設定を渡すことで回避することに成功！
タスクマネージャー -> スタートアップ -> Nahimic VRを右クリック -> ファイルの場所を開く
exeファイルを右クリックしてプロパティ -> 互換性 -> 管理者としてこのプログラムを実行する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269181/42f90316-523d-5d36-3c95-a35bd4356eb8.png" width=30%>

タスクマネージャーからファイルの場所行けば辿り着くはず
デフォルトのファイルパスは
C:\Program Files\Nahimic\Nahimic VR\Foundation\x64
C:\Program Files\Nahimic\Nahimic VR\Foundation
だろうか

##ちなみに
Nahimicのポップアップも出てたけど何も調べずにアンインストールしてしまった。
特に問題は起きてない
（おそらく音を弄ることができるツールだろうが特に使わないので）
[ゼロから作るDeep Learning]ハイパーパラメータの最適化について

#はじめに
この記事は**ゼロから作るディープラーニング 7章学習に関するテクニック**を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。

#ハイパーパラメータとは
ハイパーパラメータとは、ニューラルネットワークの作成の時に必要となる人間の力で設定しないといけないパラメータのことを言います。例を出すと、層の数やニューロンの数などです。

このハイパーパラメータはニューラルネットワークの性能に大きく関わってきますので、ぜひ最適化したいですが、人間の力でとなるとすごく大変です。
そこで、これも機械に任せようということで、これからハイパーパラメータの最適値を自動で求める実装をしてみます。

やることを簡単にいうと、ランダムな値をハイパーパラメータにして学習の結果をはかり、その結果から最適な値の範囲を絞っていきます。

```python
# ハイパーパラメータチューニング
from sklearn.model_selection import train_test_split
def hayper_tyning(lr_m, lr_d, wd_m, wd_d, x_train, t_train, sanpule = 2):
    lr_list = []
    wd_list = []
    x_train = x_train[:500]
    t_train = t_train[:500]# 時間がものすごくかかるため
    (train_x, hayper_x, train_t, hayper_t) = train_test_split(x_train, t_train, test_size=0.2, random_state=0)

    for i in range(sanpule):
        train_acc_list = []
        test_acc_list = []
        lr = 10 ** np.random.uniform(lr_d, lr_m)
        weight_decay_lambda = 10 ** np.random.uniform(wd_d, wd_m)
        lr_list.append(lr)
        wd_list.append(weight_decay_lambda)
        
        network = MutiLayerNet(input_size = 784, hiden_size_list = [50], output_size = 10, weight_decay_lambda = weight_decay_lambda)
        
        for i in range(1, 101):
            grads = network.gradient(train_x, train_t)
            
            for p in ['W1','b1','W2','b2']:
                network.params[p] = network.params[p] - (lr * grads[p])
            
            
            if i % 100 == 0:
                train_acc = network.accuracy(train_x, train_t)
                test_acc = network.accuracy(hayper_x, hayper_t)
                train_acc_list.append(train_acc)
                test_acc_list.append(test_acc)
                
        #後はグラフだったり絞り込んだりする
```
#PowerApps でモブプロ！？

# はじめに
Power Apps で爆速、Low Code で開発できることは皆さんご存じのことかと思います。さて、その Power Apps を「自分（ないしお客さん）のため以外で活用する」という事例を得たので、同様のシーンで活用いただけるのではないか、と思い記事にしております。

なお、この記事は「PowerApps Advent Calendar 2019」へ参加しております。

■[PowerApps Advent Calendar 2019](https://qiita.com/advent-calendar/2019/powerapps)

# 状況
細かい箇所は皆さんの妄想力で補っていただきたいのですが、下記のような経緯です。

　- とある大規模システムの要件定義フェーズが始まります
　- ビジネス要件を出せる方々が非ITです
　- 利用者は、上記の非IT含めた方々です
　- 画面イメージすら想像し辛い感じらしいです
　- DB項目等ブレイクダウンするためにも、まずは画面項目とか決めたいよね、です

えーと、書いてて途中でツラくなってきましたｗ

ようは「ITよくわからない方々から設計につなげられる情報を引き出す」必要に迫られた、ということです。

あ、そうだ。これはフィクションですよ？

# Power Apps で モブプログラミング！
様々な会話がなされまして「まず画面を見せながら要件を吸い上げよう」という流れになりました。アジャイルとか、そんな感じですね。で、画面を手早くチャチャっと作成する方法はないか・・・と相談をうけまして。当方に相談したら、もう答えは決まっておりますよね？

キーマンの皆さんを集めてヒアリングをしながら平行して画面を作りながら、動きも見せつつアレしよう？
もうそこは「Power Apps でしょ！」となりますよね？（当方に相談したらそうなりますよね

なお、開発するシステムは様々な制約があり、Power Appsでは提供できないモノでした。（残念

で、実際に試してみたそうです。

# モブプログラミング とは？
ざっくりと、当方は下記の認識です。

- 開発するヒトが1名いる
- 大きな画面に開発中の画面を表示する
- その画面をプロジェクト関係者が確認して進める

![コメント 2019-12-03 194757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/ac80492a-4434-8b92-0b47-76621caa0185.png)

詳細は検索してください(;^ω^)

# 試してみた結果
その他の開発言語でも同じようなコトができるのでしょうが、Power Appsを利用した結果、下記のようなメリットがありました。

 1. 画面が速攻で作成できる
 2. 実際に簡単な動きも確認できる
 3. 作成した画面がそのまま設計のインプットになる
 4. 非ITの方々が「実際に近しいイメージ」を共有できるので齟齬が少なくなる
 5. データソースもあわせて設計するので、DB設計のインプットになる
 6. モバイルでの操作性を早い段階で探れる

ざっとあげただけでも、上記な感じです。
Power Apps でアプリを作っているのですが、実際に利用するモノでなくても活用できるのでは？と思った次第でした。

モブプログラミングを、Java や C# と Power Apps でやった場合の違いについて、もっとも効果が高いな、と感じる部分は「Power Apps は作った直後にスグ動作が確認できる」コトです。画面が完成していなくても、いま作ったトコロまでは実際に動く状態でスグにオーディエンスに見せることができます。そのため、初品を作成する → スグに動作イメージも共有する → 認識があっているか否かが速攻で判断、というプロセスを超高速で回すことができます。
もちろん、取りまとめ（あるいはファシリテーター）的な役割を置いておかないと、際限なく要望が出てきて収拾がつかなくなる可能性があります。しかし、やはり所謂PDCAサイクルを高速回転させるコトで、そのリスクを補って余りあるぐらい「実際にミンナで体験を共有して合意の方向性を探れる」というメリットが大きいかな？と感じました。

うまく回すコツとしては「この段階で完璧なモノを作ろうとしない」という意識を共有するコトかな、と考えています。Power Apps で運用するアプリを作るワケじゃない場合はとくに。

# 蛇足
実は、2019/12/7(土)に開催される[Power Platform Day Winter '19
](https://power-platform.connpass.com/event/149834/)で、当方が登壇するネタの1部です。一瞬だけしかでてこないので、補足の意味を兼ねてQiitaに書く予定だったのですが・・・。3日が空いてたので、思わず先にチョッとだけネタバラシしちゃいましたｗ

なお、当日は「Power Apps初心者から、もう1歩前へ！」というテーマで「どういう設計（というか考え方）をしたらよいか？」というネタをお届けする予定です。参加される方、会場でお会いしましょう！

それでは、皆さま。素晴らしい Power Platform Life を！
Xcode：普段通りにCocoaPodsのライブラリを導入したら実行できなくなった件

`Xcode 11.2.1`にて普段通りにpodのライブラリを導入しようと思い，Podfileを書いてライブラリを追加して，xcworkspaceを開き直してRunしたところ，以下のようにクラッシュした．

![Screen Shot 2019-12-03 at 20.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/7b2353bf-8c03-4897-11c5-f777c39c56ff.png)

よくわからないけれど，Libraryが読み込めていないらしいので`Build Path`とか`Linked Framework`とかを確認してみたが，悪いところはなさそう．
`DeriveData`が悪いのでは？と思って決してクリーンしてみてもダメ．
そこで証明証関連が悪いのでは？と思って`Signing Certificate`を`Sign to Run Locally`から`Development`に変更してみたら実行できた．

![Screen Shot 2019-12-03 at 20.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/0bb7cf38-988c-d045-a4e9-d03bc425d353.png)

そういえば，Xcodeのバージョンが上がってから，妙な項目が増えたなぁと思っていたけれど，自動で設定される`Sign to Run Locally`ってなんなんでしょうか．
ClojureでWebアプリケーションをつくるときに、Joda-Timeに依存しないようにする

この記事はScrapboxのURLにQiitaが対応できないため、Scrapboxへのリンクを貼るためだけに作った記事です。

本番は[こちら](https://scrapbox.io/ayato-p/ClojureでWebアプリケーションをつくるときに、Joda-Timeに依存しないようにする)
[ゼロから作るDeep Learning]Dropoutについて解説してみた

#はじめに
この記事は**ゼロから作るディープラーニング 7章学習に関するテクニック**を自分なりに理解して分かりやすくアウトプットしたものです。
文系の自分でも理解することが出来たので、気持ちを楽にして読んでいただけたら幸いです。
また、本書を学習する際に参考にしていただけたらもっと嬉しいです。

#Dropoutとは
皆さんはアンサンブル学習というものを知っているでしょうか。
アンサンブル学習とは、複数のモデルを使って学習を行うことで、良い学習結果を生み出すことができるものです。
Dropoutでは、そのアンサンブル学習を擬似的に再現することで、学習の結果を向上させています。

具体的にDropoutでは内を行なっているのでしょうか。それは、学習の際にランダムにニューロンを消去するです。
Dropoutでは、ニューロンをランダムで消去することにより、違うモデルを複数作りだしてアンサンブル学習を作り上げています。

下では簡単な実装例を紹介します。

```python
class Dropout:#活性化関数レイヤの後に生成させて、学習が行われるたびに発動させる。predictでは発動させない
    
    def __init__(self,dropout_ratio=0.5):
        self.dropout_ratio = dropout_ratio
        self.mask = None #消去されるニューロンが記された配列が入る
    
    def forward(self,x,train_flg=True):
        if train_flg:
            self.mask = np.random.rand(*x.shape) > self.dropout_ratio#ランダムで消去するニューロンを決定する
            return x * self.mask
        else:
            return x * (1 - self.dropout_ratio)

    def backward(self,dout):
        return dout * self.mask#Reluと同じ
        
```
九九のプログラム 

息子が九九の勉強をしていたので、高い商材を買わなくていいように、python3で九九のゲームを作成しました。


```Python
import random


point = 0

for i in range(10):
#    x = random.randint(1,9)
    x = 6
    y = random.randint(1,9)

    ans = 0
    
    try:
        print(str(i+1) + "問:" +str(x) + "×" + str(y) + "=")
        ans = int(input())

    except ValueError:
        print("数字が入力されていません")

    finally:
        if(ans == x*y):
            print("せいかいです")
            print("")
            point += 10
        else:
            print("まちがいです。せいかいは、"+str(x*y)+"です")
            print("")
        
print(str(point)  + "点ゲットしました")


while True:
    print("enterを入力してください")
    tmp = input()
    if tmp =="":
        break
    
```
AppleScriptでMacのシャットダウン時にファイルを削除する

年に一度のお祭りなのに小ネタ記事で恐縮ですが、Macをシャットダウンした時に所定のフォルダ内のファイルを削除したいという件があり、やってみました。
AppleScriptって存在は知っていたもののしみじみ使ったのは初めてのような気がします。

## やりたいこと

* シャットダウン時に本当に削除してよいかの確認ダイアログを出す
* 「はい」を選ぶと容赦なくフォルダ内のファイルを削除（ゴミ箱にも残さなくてよい） 

## ステップ1（Automator版）
シャットダウン時というのがややこしそうだったので、まずは手動で動かす方法をやってみました。
Automatorでサクッとできました。

- Automatorで新規→アプリケーションを選ぶ
- ワークフローで「確認を求める」を選ぶ
- ワークフローで「シェルスクリプトを実行」を選ぶ
- 保存した、.appファイルを実行すると動作します
<img width="667" alt="貼り付けた画像_2019_08_29_21_55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32552/b3628a59-0f28-88b1-5a96-fca09a791094.png">

なんとなく流れはつかめましたが、今回やりたいこととはちょっと違うのでこれはこれでおいといて、ステップ2に進みます。

##ステップ2（AppleScript版）

[この記事](https://dev.classmethod.jp/client-side/applescript-logout-sound-off/)をみて、AppleScriptを使うとアプリケーションが終了する時のイベントをフックすることができることがわかったので、それを応用してみました。
AppleScriptはろくに書いたことがなかったので、見よう見まねで書いてみました。

### AppleScriptからアプリケーションを作る

スクリプトエディタを起動して、保存しようとすると、ファイルのフォーマットを以下から選ぶことができます。

- スクリプト
- スクリプトバンドル
- ★アプリケーション
- テキスト

その他の選択肢の使いみちはよくわかっていませんが、今回はアプリケーションを選び、実際のコードを書いていきます。

### アプリケーション終了時にダイアログを出す
アプリケーション終了時に発火する`on quit`というイベントがあるのでそれを利用します。
`with icon xxx`でダイアログにアイコンを表示させることができます。
今回は削除するよ！！というダイアログなので、cautionにしました。

```applescript
--アプリケーション終了時に呼ばれる
on quit
display dialog "メッセージ内容" buttons {"はい", "キャンセル"} default button "キャンセル" with icon caution
end quit
```

### OKした場合とキャンセルした場合の分岐
```applescript
if button returned of result is "はい" then
--はいを選んだ時
else if button returned of result is "キャンセル" then
--キャンセルを選んだ時
end if
```
### OKしたときはコマンド叩く

```applescript
do shell script "/bin/rm -rf ~/download_dummy1/*; /bin/rm -rf ~/download_dummy2/*"
continue quit
```

キャンセルを押した時に、シャットダウンされてしまうとファイルが削除されないことになるため、今回はキャンセルを押したらシャットダウンされて欲しくありません。
そこでキャンセルしたときは、なにもしないようにしました。
なにもしないということはこのアプリも終了しないため、永遠にシャットダウンされません。
削除してもいい状態にしてリトライしてもらい、かならず削除してもらうというフローにしたかったため
このようにしています。

```applescript
else if button returned of result is "キャンセル" then
--ここの分岐ではなにもしない
end if
```
## 完成形
```applescript
on quit
	display dialog "ダイアログに表示するメッセージ" buttons {"はい", "キャンセル"} default button "キャンセル" with icon caution
	
	if button returned of result is "はい" then
		do shell script "/bin/rm -rf ~/download_dummy1/*; /bin/rm -rf ~/download_dummy2/*"
		continue quit
	else if button returned of result is "キャンセル" then
		--なにもしない（シャットダウンもキャンセルされる）
	end if
end quit
```

##参考にさせていただいた記事

https://dev.classmethod.jp/client-side/applescript-logout-sound-off/
http://acknowledge.sblo.jp/article/44449396.html
http://mirror.informatimago.com/next/developer.apple.com/ja/technotes/tn2065.html
http://piro.hatenablog.com/entry/2016/11/19/180405
https://mac-tegaki.com/trouble-shooting/applescript-app-ask-permission-every-time.html

---
[:christmas_tree: FORK Advent Calendar 2019](/advent-calendar/2019/fork)
:arrow_left: 3日目 [Teleportでのクラスタ管理（GCP編）](/shuhei4009/items/d6ec14c68f2b221abf59) @shuhei4009
:arrow_right: 5日目は @nogutea さんよろしくお願いします
FungusのLocalizationで日本語を取り扱う方法

#Fungusを使った複数言語対応
Fungusとは、会話イベントをGUIで作成可能なUnityアセットです。このアセットでは、ローカライズを手軽に行うことができる仕組みが取り入れられています。基本的な使い方は、以下の公式動画をご参考にしてください。
[13 Fungus localisation](https://www.youtube.com/watch?v=kBIXOwfaaaU)

ここで、SayダイアログやMenuダイアログに日本語を入力し`Export Localization File`を行った後、Excelで開くと文字化けが起きます。今回はその対処法を記述します。

#UTF-8を用いた対処法
文字化けの原因は、文字コードが異なるためです。そのため、UTF-8に指定してcsvファイルを出力します。この際、bom付きのUTF-8にすることで、Excelでスムーズにcsvファイルを読み取ることができます。
Assets/Fungus/Scripts/Editorにある`LocalizationEditor.cs`を開きます。60行目付近にある
`public virtual void ExportLocalizationFile(Localization localization)`の中に、追記を行います。

```LocalizationEditor.cs
public virtual void ExportLocalizationFile(Localization localization)
        {
            string path = EditorUtility.SaveFilePanelInProject("Export Localization File",
                                                               "localization.csv",
                                                               "csv",
                                                               "Please enter a filename to save the localization file to");
            if (path.Length == 0) 
            {
                return;
            }

            string csvData = localization.GetCSVData();
            
            ///
            /// 日本語用に追記
            var encoding = new UTF8Encoding(true);
            ///
            
            File.WriteAllText(path, csvData, encoding);
            AssetDatabase.ImportAsset(path);

            TextAsset textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
            if (textAsset != null)
            {
                localization.LocalizationFile = textAsset;
            }

            ShowNotification(localization);
        }
```

主な変更点は`var encoding = new UTF8Encoding(true);`を追加した点と、`File.WriteAllText(path, csvData, encoding);`のように第3引数を与えた点です。

変更を保存した後、再度`Export Localization File`ボタンをクリックすることで、bom付きUTF-8でcsvファイルが出力され、Excelでそのまま編集が行えます。
puppeteerとjestとvue

#目次
* ゴール
* 経緯
* 構成
* 準備
* さいごに

## ゴール
vueでpuppeteerをつかってテスト実行してみる

## 経緯
特にないんですが、仕事で結合試験の効率化でpuppeteerを使うという話があって
しかもjestとも連携できるそうなので、これはvueとも連携できるんじゃないか
というのを思いついたわけです。

## 準備
どういう環境でやるのか
`vue` `vuex` `vueRouter` `vuetify` `typescript`

とりあえず、こんな感じでプロジェクト作成
![vuecreate_puppeteer-ts.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95247/e0ee06de-d28a-6216-91e9-a8d783db1958.png)

### vue-plugin-jest-puppeteer
かなり試行錯誤しながら自力で設定する事ができなく途方にくれていたところで
都合の良いプラグインを発見。速攻でインストール
https://github.com/kaizendorks/vue-cli-plugin-jest-puppeteer

```terminal
vue add jest-puppeteer
```

### vuetifyを追加
jest-puppeteerの前にインストールすると、pluginsフォルダが消えてなくなったので
順序に気をつける（気のせいかもしれないです）

```terminal
vue add vuetify
```

### テスト実行
jest-puppeteerをvue add追加すると
package.jsonのscriptsに以下がついかされるので

```
"test:e2e": "jest --config=jest.e2e.config.js --runInBand",
```

実行するだけです

```
yarn test:e2e
```

ひとつ問題点がありまして
テストの中でyarn serveでローカルサーバーを起動するようになっているんですが
エラーになってしまいます。

解決策としては、いまのところ
あらかじめローカルサーバーを起動しておく以外に見つかっていません。

## 残課題
ローカルサーバーが起動していない状態で、実行ができるようにする。
githubのリポジトリのリンクを貼っておく

## さいごに
使い所はありそうな感触はあったので、積極的に実務で使っていきたいと思います。

はじめてのQiitaの記事を書いてみて、アウトプットすることの大事さと難しさを実感しました。
ありがとうございました。
あと、時間ギリギリになってしまって、すいません。
Macにssh接続しようとするとConnection refusedと表示される

# 環境
- MacBook Pro (13-inch, 2019, Four Thunderbolt 3 Ports)
- macOS Mojave 10.14.6

# 発生した問題
- macからmacにssh接続しようとしたが"ssh: connect to host xxx.xxx.xxx.xxx port 22: Connection refused"と表示される

# 対処法
システム環境設定 > 共有 > リモートログインにチェック

# 終わりに
初めはIPアドレス間違え、ファイアウォールを疑いましたが単純なミスでした
Extendを使う

##Extendって何に使うやつ？
* セレクタのプロパティを他のセレクタにコピーができる。
* Extendは参照先がCSSのセレクタになっており、参照元のセレクタのプロパティを書き換えた時に連動して書き換わってしまうので慎重に扱う。

##SCSSでかく
```scss
//extend参照元
.hoge {
  width: 10px;
  height: 10px;
  .add {
    display: inline-block;
  }
}

//extendを使う対象
.target {
  @extend .hoge;
  display: block;
}
```

##CSSにすると…
```css
.hoge, .target {
  width: 10px;
  height: 10px;
}

.hoge .add, .target .add {
  display: inline-block;
}

.target {
  display: block;
}
```


##使い道について

Mixinでだいたい片付けてしまうので、
「この場合はMixinよりExtendの方が使いやすいよ！」
てのがあればコメントしていただけると助かります…！
Firebaseのrobots.txtをドメイン単位で振り分けてみる

# 免責

- Sparkプランの上でやったことなので、上位プランならもうちょっとスマートな方法があったかもしれません
- `firebase.json`の設定次第ではもっとスマートな方法があったかもしれません
- やったことのログがメインとなります

# 何をやったか

`Firebase`で運用しているWebサイトの`robots.txt`を、`Firebase Hosting`ではなく`Cloud Functions`を使って、ドメインごとに別の内容を配信するようにしました。

## 動機

自サイトを`Firebase`で運用しています。 静的コンテンツの配信なら`Firebase Hosting`が一番楽ですが、ここを利用すると最初に次のドメインが割り当てられます。

* `{PROJECT_ID}.web.app`
* `{PROJECT_ID}.firebaseapp.com`

カスタムドメインを使いたい場合も割と簡単で、`Firebase`のコンソール上で指示に従ってドメインを登録すれば割とあっさり運用可能になります。便利ですね。
ただ、ちょっと困ったことがあって、**デフォルトのドメインを無効化出来ない**っぽいです。[^1]

すると、こんな事件が起きます。

<img width="504" alt="スクリーンショット 2019-12-03 18.54.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6805/fac36a48-1de1-367d-a344-8fe90fb743c6.png">

デフォルトドメインもクロールされてる...！？

動作確認込みでデフォルトドメインも使ってたとは思うのですが、これは何かカッコ悪い気がします。
というわけで、

* カスタムドメインでは、サイトマップなどの情報を提供できる`robots.txt`を配信
* デフォルトドメインでは、せめてbot等によるクロールをしないでもらうための`robots.txt`を配信

という対応を取ることにしました。

# `Firebase Hosting`や`firebase.json`ではダメなのか？

とりあえず、現時点では以下のような理由で「なんかダメっぽい」と仮置きしています。

## ホスティング環境が分断できてない

カスタムドメインもデフォルトドメインも同じホスティングコンテンツを参照するようになってます。
そのため、配置できる`robots.txt`は1個だけという判断をしています。
~~マルチサイト？結局ドメインが増えちゃうので問題解決にならないんじゃないかなと思ってます~~ [^2]

## `firebase.json`は？

`firebase.json`はリクエストに対する振る舞いが結構柔軟なのですが、ドメインによる振る舞い分岐を見つけられていません。
今のところは、多分出来ないんじゃないかなという判断をしてます。

# Cloud Functionsで賄う

というわけで、苦肉の策として「`/robots.txt`だけは`Cloud Functions`で配信する」という方針を取ることにしました。

## 実コード

```typescript:index.ts
import * as functions from 'firebase-functions';

const robotsAllow = `
sitemap: https://example.com/sitemap.xml
`

const robotsDisallow = `
User-agent : *
Disallow : /
`

export const ROBOTS_TXT = functions.https.onRequest((req, res) => {
  const host = req.header('X-Forwarded-Host');
  const robotsTxt = host === 'example.com' ? robotsAllow : robotsDisallow;
  res.type('txt')
    .set('Cache-Control', 'public, max-age=7200, s-maxage=3600')
    .send(robotsTxt.trim())
    .end();
});
```

## やったことの分割整理

### 複数の`robots.txt`を用意する

ファイルに持たさたりするなど、いくつかパターンが有りましたが、ワンソースで雑に解決したかったので、
「`robotsAllow`にカスタムドメイン向けのテキスト」「`robotsDisallow`にデフォルトドメイン向けのテキスト」と、
変数で管理するようにしました。

### アクセスしてきたドメイン名で`robotsTxt`を決定

`Cloud Function`のHTTPトリガー処理はリクエストヘッダーとして`X-Forwarded-Host`を受け取ります。
この中身がまさに「アクセスしてきたドメインが何か」を持っているため、この中身をベースに「どちらのrobots.txtを配信するか」を決定します。

### レスポンスする

`res`オブジェクトを使って、粛々と中身をレスポンス。追加で次のことをしています。

* MIMEタイプを変えるために、`type()` を呼び出し [^3]
* 頻繁に関数を呼び出しされるのもあれなので、とりあえず`Cache-Control`で多少はキャッシュしてもらう
* `robotsTxt`の中身は先頭と末尾に改行がいるので、`trim()`で整形

# 振り返り

リライト設定だしHostingがCDN相当の振る舞いをしてくれたりするので、つい`Cloud Functions`で利用しがちです。
ただ、コストを考えたほうがいいとは思いつつ、「最小限の労力で必要十分な結果を得る」にはこれぐらいの感覚で利用してよいのかなとも思いました。


[^1]: 無効化出来るに越したことはないので、情報募集中
[^2]: TODO
[^3]: これをしないばあいは、`text/html`になります
cargo publishできないRustプロジェクト

# はじめに
Rustのプロジェクトを[crates.io](https://crates.io)で公開するときに使うコマンドが`cargo publish`です。このコマンドはコンパイルが通るかどうかなどいくつかのチェックをし、ソースコード一式のアーカイブを作成し、crates.ioにアップロードするまでをまとめてやってくれます。
ここで「いくつかのチェック」と書いた通り、コンパイルが通るからと言って`cargo publish`できるとは限りません。また、crates.io側にもチェックがあります。この記事ではコンパイルが通るけど`cargo publish`できないRustプロジェクトについて紹介します。

# `[depencencies]`の不備
これは一番よく知られていると思いますが、`[dependencies]`は全てcrates.ioに登録されたクレートをバージョン指定で参照している必要があります。
以下の例はすべてNGです。

```Cargo.toml
[depencencies]
hoge = "*"
hoge = {path = "./hoge"}
hoge = {git = "https://github.com/..."}
```

ちなみにRust1.39からgitリポジトリへのdependencyでもversion指定されていればOKになったようです。

# アーカイブが大きすぎる
現状crates.ioの制限で、アーカイブの最大サイズは10MBになっています。圧縮後で10MBなのでそうそう越えることはないでしょう。ただ、一部の巨大なクレートは数MBあったりするので、絶対越えないということはなさそうです。過去のIssueを見ていると、どうしても越えそうなら連絡すれば個別に制限を緩めてくれるようですが、現在もその運用なのかは不明です。

# build.rsがsrcディレクトリを変更する
build.rsがRustのソースコードを生成するようなケースで生成先をsrcにしてはいけません。
["Case study: Code generation"](https://doc.rust-lang.org/cargo/reference/build-scripts.html#case-study-code-generation)に書かれている通り、targetディレクトリに生成して、`include!`マクロで取り込むようにしましょう。

# フォルダへのシンボリックリンク

特定のプラットフォームでトラブルになるためだと思われますが、フォルダへのシンボリックリンクは禁止のようです。
ファイルへのシンボリックリンクはいまのところOKのようです。

# 特殊なファイル名
まず、UTF-8でないファイル名はダメです。例えばWindows環境でのCP932エンコードされた日本語ファイル名とかですね。さらにいくつかの記号入りファイル名もチェックされます。これらのチェックはサポートする全プラットフォームで正しくアーカイブを展開できるようにするためです。
ただ、UTF-8の日本語ファイル名などは通ってしまいます。なんとなくまずい環境もありそうですが…。

# 特殊なクレート名
昔nulクレートを公開したらWindows環境が壊れた、という事件がありました。Windowsではnulは特殊なファイル名でありクレート用のnulディレクトリが作れなかったためです。そのためnulやcomなどWindowsで特別な意味を持つクレート名はcrates.ioで弾かれます。
被写体の大きさに関わらず被写体全体が写るためのカメラの設定

![camera.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/66eff828-c7a3-fb87-836a-86d0e17bde4b.png)

このように被写体の大きさがバラバラでも、被写体の全体を写すための方法を紹介します。

# 概要

![図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/8822769c-945d-6264-d6c7-f257d7f842f0.png)
tanθ = y÷x
θ = artan(tanθ)
求まったθをカメラの画角として設定します。
このように**カメラと被写体の距離**と**被写体の高さ**から**カメラの画角**を求めます。

# コード

```C++
Camera camera;   //カメラ
float y;   //被写体の高さ
Vector3 camraPos;   //カメラの座標
Vector3 objectPos;   //被写体の座標   

//上の図でいうところのxを求めます
float x = cameraPos.x - objectPos.x;
//y/xでタンジェントを求めます
float tanθ = y / x;
//求まったタンジェントをアークタンジェントにかけてθを求めます
float θ = atanf(tanθ);
//θをカメラの画角に設定します
camra.SetViewAngle(θ)
```
Unityで2つのベクトルの向きが同じになるように回転させる

#はじめに

右手と左手間のベクトルに合うようにいい感じにコントローラを回転させています。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">むにむに <a href="https://t.co/5VYClMBWod">pic.twitter.com/5VYClMBWod</a></p>&mdash; がとーしょこら@VRChat (@gatosyocora_vrc) <a href="https://twitter.com/gatosyocora_vrc/status/1193425441022824448?ref_src=twsrc%5Etfw">November 10, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これはUnityでスクリプトからオブジェクトを回転させるときに
そのオブジェクトが持つベクトルとあるベクトルの向きを同じになるように回転させました。

たまに使うので備忘録です。

#サンプルコードとイメージ図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/513d3de7-fa2d-da92-a885-870732358b20.png)

p3とp4のベクトルの向きがp1とp2のベクトルの向きに合うようにp3とp4を持つオブジェクトを回転させます。

```csharp:VectorRotationSample.cs
    // Vector3 p1, p2, p3, p4;
    // GameObject target;
    Vector3 refVec = (p1 - p2).normalized; // これと同じになるように
    Vector3 vec = (p3 - p4).normalized; // これを動かす(p3, p4はtargetに含まれる任意の2点)
    Quaternion rot = Quaternion.FromToRotation(refVec, vec);

    target.transform.rotation = rot * target.transform.rotation; // 左から掛ける
```

#関連文献
[【Unity】Quaterion API解説](https://www.f-sp.com/entry/2017/08/11/194125)
結婚式用忌み言葉チェッカー作ったよ

<a href="https://qiita.com/advent-calendar/2019/kuso-app">クソアプリ Advent Calendar 2019 6日目の記事です。</a>

#作ったくそアプリ
<a href="https://basterbaster.com/taboo_word_checker/">結婚式用忌み言葉チェッカー</a>です。
![Peek 2019-12-03 21-13.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317462/b2186c1d-a6ae-be36-58ae-10d143f449bd.gif)

<ul>
<li>チェックしたい言葉入力する</li>
<li>文章チェックボタンクリック</li>
<li>チェック結果を確認する</li>
<li>黄色背景をクリックすると、言い換え前のもの、言い換え理由がでます</li>
</ul>

#望み
結婚式準備の喧嘩を少なくしたいね！
上司になったとき粗相をなくしたいね！

#前置き
結婚式をしましたが、準備が多く大変です。時間のかかる準備の一つに招待状の作成とスピーチ原稿の推敲があります。
結婚式にはを相応しくない言葉(忌み言葉)があり、忌み言葉を回避する必要があります。
世の中のツールでは忌み言葉を発見できますが、言い換えを示してくれない＆理由を示してくれないので作りました。

#技術的なお話
Django+jQuery+Bootstrap4で作りました。
※Vue.jsとか使ってみたかったですが、この程度ですと逆にめんどくさくなりそうなので、使い慣れたjQueryを使いました。

##言い換え部分の実装
###辞書作成
対象の言葉、言い換える言葉、引っかかった理由をまとめたTSVファイルを作成しました。

```TSVの一部
たびたび	よく	重ね言葉
しばしば	よく	重ね言葉
くれぐれ	十分に	重ね言葉
ご多忙	ご多用	死を連想させる言葉
多忙	多用	死を連想させる言葉
```
###言い換え実装

入力をうけとったあとの処理はこんな感じです。

```python

import MeCab
from django.utils import html


def getmecabresult(text):
    text = html.strip_tags(text)
    imi_word = {}
    imi_wordlist = []
    with open("imiword.tsv", "r") as f:
        for imi in f:
            item = imi.strip().split("\t")
            imi_wordlist.append(item[0])
            imi_word[item[0]] = {"replace": item[1], "reason": item[2]}

    mecab = MeCab.Tagger("-Owakati")
    mecab.parse('')

    word_list = text.split("\n")
    resultlist = []
    count = 1
    word_obj = {}
    for word in word_list:
        node = mecab.parseToNode(word)
        while node:
            word = node.surface
            word_obj["word"] = word
            word_obj["replace"] = ""
            word_obj["reason"] = ""
            word_obj["istaboo"] = False
            for iw in imi_wordlist:
                if word.find(iw) != -1:
                    word_obj["replace"] = imi_word[iw]["replace"]
                    word_obj["reason"] = imi_word[iw]["reason"]
                    word_obj["istaboo"] = True
                    count += 1
                    break
            node = node.next
            resultlist.append(word_obj.copy())
        resultlist.append({"word": "\n", "replace": "", "reason": ""})
        data = {"resultlist": resultlist, "count": count}
    return data


```
<ul>
<li>入力したテキストをmecabにて言葉毎にわける</li>
<li>分けた言葉を、予め登録しておいた言葉と比較して、チェックする</li>
<li>もろもろ返却する</li>
</ul>

###おまけ
「クソアプリ」は１つの単語としてmecabで認識されたため、記事中は「くそアプリ」表記となってます

###20191214追記
Edge、IEだと403エラーになる問題修正しました。
問題出た場合はTwitterまでコメントいただけますと幸いです。
ReactくんさぁHooksとか言ってるけど、で？どうやってAPIから値持ってくんの？

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の三日目の記事です。

今回はReactでRestAPIなどから値を取ってくるのに、関数型コンポーネントでどーやってAPIから値取ってくんの？

componentDidMountなんてないよ？

componentDidUpdateなんてないよ？

ってなりますよね、僕はなります。

## 結論から言ってクレメンス

**useEffectを使うンゴ**

React Hooks にある、useEffectを使用します。

## useEffectってなんぞや

関数コンポーネントで副作用を実行するためのフックで、classコンポーネント時のcomponentDidMount,componentDidUpdate,componentWillUpdateの3つにあたります。

## じっそー

```jsx
useEffect(() => {
// ここでAPIをたたく
},[])
```

useEffectの第一引数が、実行する関数で、第二引数が何が変化したときにuseEffectを実行するかを決めるものとなっています。
ここでは空配列を指定しています、空配列を指定することでコンポーネントが配置される前(componentDidMount)でのみuseEffectを実行するといったことができます。

```jsx
useEffect(() => {
// ここでAPIをたたく
},[hoge])
```

これでhogeが変更された時に反応してuseEffectが実行され、APIを再度叩くことができます。

このようにしてきっちりバックエンドとフロントエンドを分離した際に再描画のタイミングを指定してAPIを再び指定することができます。
enumを利用して複数の識別子を受け付けるAPIを呼び出す

userIDやUUIDを同じパラメータとして扱い、サーバー側でよしなに判別するAPIを呼び出す時にどのように書けば良いかを考えていきます。

`GET /v1/users/{user_identity}`

このAPIのuser_identityは次のようにuserのidでもUUIDでも呼び出すことができます。

`GET /v1/users/123456`
`GET /v1/users/AAAAA-BBBB-CCCCC-DDDD`

このAPIを呼び出すために２つのメソッドを定義しました。

```swift
func fetchUser(byID id: Int) {
  request(url: "/v1/users/\(id)")
}

func fetchUser(byUUID uuid: String) {
  request(url: "/v1/users/\(uuid)")
}
```

内部の処理は同じなので、次のように一つのメソッドにまとめてみます。


```swift
func fetchUser(by id: Int? = nil, uuid: String? = nil) {
    if id == nil && uuid == nil {
        fatalError()
    }
    if id != nil && uuid != nil {
        fatalError()
    }
    if let id = id {
        request(url: "/v1/users/\(id)")
    } else if let uuid = uuid {
        request(url: "/v1/users/\(uuid)")
    }
}
```

`fetchUser`は、idかuuidを埋めれば適切にapiを呼ぶようになりました。
ただし、idとuuidはどちらか一つを与えるようにしなくては`fatalError`が発生します。

```swift

fetchUser(uuid: userUUID) //OK
fetchUser() // Crash
fetchUser(by: userID, uuid: userUUID) // Crash
```

あなたは実装者なのでこのパラメータの与え方のルールを知っていますが、他の開発者は中のコードを読むか、あなたが書いたコメントを読むか、はたまた間違えて呼んでクラッシュするのを確認しないと、気がつくことは出来ません。
不正な呼び出しをコンパイルの時点で気が付けない事も良くないですね。

そこで、Swiftの強力なenumを利用します。

```swift

enum UserIdentity {
    case id(Int)
    case uuid(String)
}

func fetchUser(by identity: UserIdentity) {
    switch identity {
        case .id(let id):
            request(url: "/v1/users/\(id)")
        case .uuid(let uuid):
            request(url: "/v1/users/\(uuid)")
    }
}

fetchUser(by .uuid(userUUID))

```

このようにenumで識別子を管理する事で、`fetchUser`を呼ぶには必ず任意の識別子を一つ指定する制約が生まれました。
間違えた呼び方をしてビルドすることはもう出来ません。

----

おまけ

今回のケースでは、APIのパスをenumが生成することで次のように書く事もできます。


```swift
enum UserIdentity {
    case id(Int)
    case uuid(String)
}

extension UserIdentity {
    var path: String {
      switch identity {
        case .id(let id):
          return "/v1/users/\(id)"
        case .uuid(let uuid):
          return "/v1/users/\(uuid)"
      }
    }
}

func fetchUser(by identity: UserIdentity) {
    request(url: identity.path)
}

fetchUser(by .uuid(userUUID))
```

メソッドの内部実装をシンプルにする事で、可読性が上がり処理が追いやすくなります。
これが正解かはプロジェクトの状況に寄りますが、可読性の高いコードを追求してみましょう。
Hyperoptを使って関数最適化をしてみる

#はじめに
Hyperoptはハイパーパラメータの自動最適化フレームワークです。主に機械学習のハイパーパラメータチューニングのために使用されるようです。

#準備
まずはライブラリをインストールしましょう。
<font color="red">pip install hyperopt</font>でインストールできます。

#実験
今回は

```math
x^2+y^2+z^2
```
の最小化問題を最適化していきましょう。

##目的関数の定義
はじめに目的関数を定義しましょう。

```python
# 目的関数を設定
def objective_hyperopt(args):
    x, y, z = args
    return x ** 2 + y ** 2 + z ** 2
```

##最適化実行
最初に最適化するパラメータの探索空間を設定しましょう。
そして、fmin()を使って探索を開始します。引数のmax_evalsで探索回数を設定しましょう。

```python
# hyperoptで最適化実行
def hyperopt_exe():
    space = [
        hp.uniform('x', -100, 100),
        hp.uniform('y', -100, 100),
        hp.uniform('z', -100, 100)
    ]

    # 探索の様子を記録するためのオブジェクト
    trials = Trials()

    # 探索開始
    best = fmin(objective_hyperopt, space, algo=tpe.suggest, max_evals=500, trials=trials)
```

最終的に結果を知りたい場合は以下を追加しましょう。

```python
    # 結果を出力する
    print(best)
```

探索中の情報はtrialsオブジェクトから取り出しましょう。以下を追加することで各試行でのパラメータや目的関数値を表示できます。

```python
    # 探索過程を調べる
    for i, n in zip(trials.trials, range(500)):
        vals = i['misc']['vals']
        result = i['result']['loss']
        print('vals:', vals, 'result:', result)
```
##コード
今回したコードは以下のようになります。

```python
# -*- coding: utf-8 -*-
import hyperopt
from hyperopt import hp
from hyperopt import fmin
from hyperopt import tpe
from hyperopt import Trials
import matplotlib.pyplot as plt

# hyperopt用の目的関数を設定
def objective_hyperopt(args):
    x, y, z = args
    return x ** 2 + y ** 2 + z ** 2

# hyperoptで最適化実行
def hyperopt_exe():
    # 探索空間の設定
    space = [
        hp.uniform('x', -100, 100),
        hp.uniform('y', -100, 100),
        hp.uniform('z', -100, 100)
    ]

    # 探索の様子を記録するためのオブジェクト
    trials = Trials()

    # 探索開始
    best = fmin(objective_hyperopt, space, algo=tpe.suggest, max_evals=500, trials=trials)
    # 結果を出力する
    print(best)

    epoches = []
    values = []
    best = 100000
    # 探索過程を調べる
    for i, n in zip(trials.trials, range(500)):
        if best > i['result']['loss']:
            best = i['result']['loss']
        epoches.append(n+1)
        values.append(best)
        vals = i['misc']['vals']
        result = i['result']['loss']
        print('vals:', vals, 'result:', result)

    # グラフを描画
    plt.plot(epoches, values, color="red")
    plt.title("hyperopt")
    plt.xlabel("trial")
    plt.ylabel("value")
    plt.show()

if __name__ == '__main__':
    hyperopt_exe()
```


#結果
今回の実験結果の図は以下のようになりました. 
早い段階で収束してきていますね。
<img width="400" alt="hyperopt.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319132/00408b2d-9121-6e96-168c-039158753b0d.png">

#参考サイト
[Hyperoptを使った、関数の最適化](http://nonbiri-tereka.hatenablog.com/entry/2015/07/14/233051)
[Python: Hyperopt で機械学習モデルのハイパーパラメータを選ぶ](https://blog.amedama.jp/entry/hyperopt)
SSH ポートフォワーディング時に Bad local forwarding specification エラーでハマった話



SSH ポートフォワーディングについては下記記事がわかりやすいです。
[SSH ポートフォワーディング とは](https://qiita.com/mechamogera/items/b1bb9130273deb9426f5)

## 再現した環境
- macOS Mojave / Catalina
- OpenSSH_7.9p1, LibreSSL 2.7.3


## エラーでハマる



いつものように下記コマンドを叩いた。

```
ssh -L ローカルのポート番号:接続したいサーバ:接続したいサーバのポート番号
```

しかし、エラーが出て、動作しなかった！

```
Bad local forwarding specification 'ローカルのポート番号:接続したいサーバ:接続したいサーバのポート番号'
```

スペースが足りなかったり、余分なスペースが入ると出るエラーらしい（[参考](https://blog.csdn.net/liulqx/article/details/95467252)）が、
確認しても間違いが見つからなかった。


## 原因
Mac のデフォルトのメモ帳からコマンドをコピペして、そのままコマンドラインに貼り付けていたから。
形式が勝手に変わってしまうから？
本当の原因は不明...

尚、メモ帳のコマンドをコピーして、 Slack などに一度ペーストし、更に Slack にペーストしたコマンドをコピーしてコマンドラインにペーストすると、動作する。（なぜ...）

何度も使うコマンドを Mac のデフォルトのメモ帳に保存しておくことがあるが、動作しないこともあるので注意するべきなのかもしれない。
RSpec+Capybaraの書き方などについて初心者が書いてみた。

## はじめに
私がテストコードを書くときに、意識していたことをわかりやすく、まとめられたらいいなって思います。これからテストコード書く人の参考にしていただけたら、幸いです。

## ユーザーの視点に立ってみる
まず、ユーザーの視点に立ってみて、ユーザーがどのようにアクセスしてくるのか、どのボタンを押すのか、その行為によって、どのような結果を帰ってきて欲しいのか、をしっかり考えます。私は、よくわからなくなることがあるので、紙に書いてわかりやすくまとめたり、口に出しながらやったりしています。ユーザーは何もデータがまだない状態でやっていることを忘れないようにしていました。

## 実際に書いてみたコードを読み、ユーザーの動きをシミュレートする
自分で、書いたコードが本当に考えていたユーザーの動きと一致しているのかどうかを、しっかり確認していきます。細かいところで、まちがえたりしていることがあるので、気を付けましょう。

## テストを実際にやってみる
テストを実際にやってみると、自分があっていると思っていた部分が間違えていることがあるので、すべてのテストが通るまで、間違えている部分を修正しましょう！

## リファクタリング
同じことを何回もする場合は、その部分を関数化したりすると読みやすさがあがります！

## やっておいてよかったこと
今回は、Ruby on Railsの開発だったので、テストをするたびに、データベースの中身が増えて大変でした:sweat_drops:　でも、[データベースクリーナー](https://blog.tamesuu.com/2019/06/02/260/)を使って、毎回データのないクリーンな状態から始められたので、とてもよかったです。

## さいごに
わたしは、師からTDD(テスト駆動開発)を教えていただきました。TDDをする前は、小さなバグやバグが起きる原因を探すのが大変でしたが、TDDを始めたことにより、バグの発見や、正しくコードが動くように書きなおすことが早くできるようになりました。ぜひ、みなさんTDDやってみてください:bangbang:
フラッシュメモリー(rom)のテーブル参照について、


Arduino Atmega328や168はフラッシュメモリー（rom）とramに分かれます。

Arduino コンパイラの場合

const 修飾子をつけてもなぜかRomに配置されません。

このあたりをgoogleっても昔の書き込み方式のページがヒットして
コンパイルエラーになります。(prog_int16_tなど.)

#1.インクルード宣言

 #include < avr/pgmspace.h >　//この宣言が重要


#2.データの定義
const 型　　テーブル名[要素数] PROGMEM = { xxx,yyy,zzz };

例
const byte 　bRomTable[] PROGMEM = {　0x01,0x02,0x04,0x08 };
const word 　wRomTable[] PROGMEM = {　0x100,0x2000,0x4000,0x8000 };


#3.読み出し部
pgm_read_byte(アドレス);
pgm_read_word(アドレス);

例:
a=pgm_read_byte(bRomTable+i);
b=pgm_read_word(wbRomTable+i);
を用いて読み出しましょう。

以上
Arudino カレンダー3日目でした。
nvm チートシート

## 前書き

この記事は オープンロジアドベントカレンダー2019の3日目です。
みなさんはNode.js のバージョンマネージャーは使っていますか？
私は[nodebrew](https://github.com/hokaccha/nodebrew) をずっと利用していたのですが、LTSを入れるコマンドが存在せず、
使い勝手の悪さを感じていたので、最近は [nvm](https://github.com/nvm-sh/nvm) というバージョン管理マネージャに乗り換えました。

使い方については、 GitHubの Readme と `nvm --help` の出力結果を読めばそれで十分なのですが、その都度、英語を読むのは面倒なので、以下に個人的によく使うであろうものを取捨選択してチートシートとしてまとめておきます。
本稿での nvm のバージョンは v0.35.1 です。
`.nvmrc` については別の方の記事を参照してください。本稿では言及しません。

## チートシート

### 前提
- 間違ったオプションや文字列を入力したら、`nvm --help` の内容を表示される。
    - `nvm` と打つだけでも `nvm --help` の内容が表示される。
- 出力結果に色がつくものは `--no-colors` オプションをつけるとプレーンテキストで出力される。
- バージョン指定する際に、オプションに `--lts` で最新のLTS を指定できる。（2019年12月現在はv12の最新バージョン)
- 特定のLTSを指定したい場合は、`--lts=<LTS name>` で 指定できる。
  - `--lts=carbon` -> v8の最新
  - `--lts=dubnium` -> v10の最新
  - `--lts=erbium` -> v12の最新

 
### 基本

**ヘルプを表示する**

```sh
$ nvm --help
```

**nvmのバージョンを表示する**

```sh
$ nvm --version
```

**インストールされているNode.jsのバージョンを表示する**

```sh
$ nvm version <version>
```
バージョンを指定しない場合は `nvm current` と同じ挙動

**現在利用しているNode.jｓのバージョンを表示する**

```sh
$ nvm current
```
バージョンを指定しない場合、現在の Node.jsのバージョンを表示し、バージョンを指定した場合はローカルにインストールされている最新のバージョンを表示する

**指定バージョンのNode.js をインストール**

```sh
$ nvm install <version>
```
指定したバージョンのNode.js を ダウンロードしてインストールして利用するバージョンを切り替える。 

**すでにインストール済みの指定したバージョンのNode.js から node_modules を引き継いてインストール**

```sh
$ nvm install <version> --reinstall-packages-from=<version>
```

**デフォルトパッケージをスキップして指定したバージョンのNode.jsをインストール**

```sh
$ nvm install <version> --skip-default-packages
```

**指定したバージョンのNode.jsをインストールした後にそのNode.jsで利用できる最新のnpmをインストール**

```sh
$ nvm install <version> --latest-npm
```


**指定したNode.js のバージョンをアンインストール**

```sh
$ nvm uninstall <version>
```
**指定したNode.jsのバージョンを利用する**

```sh
$ nvm use [--silent] <version>
```              
`--silent` オプションを利用すると実行結果が表示されない。 



**インストールされているNode.jsの一覧を出力**

```
nvm ls [<version>]
```
バージョンを指定した場合は指定したバージョンがすべて表示される

**リモートに登録されているNode.jsのバージョンの一覧を出力**

```
nvm ls-remote [<version>]
```

**現在利用しているNode.jsのバージョンでの最新のnpmへのアップグレード**

```sh
nvm install-latest-npm
```

**バージョン指定したグローバルのnpmバッケージを現在のバージョンにインストール**

```sh
nvm reinstall-packages <version>
```

**指定したNode.jsのバージョンのインストール先のパスを表示する。**

```
nvm which [current | <version>]
```

**指定したNode.jsのバージョンでコマンドを実行する**

```
nvm exec [--silent] <version> [<command>]
```
`--silent` オプションを利用すると実行結果が表示されない。


**引数付きで指定バージョンのNode.jsを実行**

```
nvm run [--silent] <version> [<args>]
```  
`--silent` オプションを利用すると実行結果が表示されない。

### 便利な使い方

**最新のLTSをインストールして、現在利用しているNode.jsのパッケージもインストール**

```sh
nvm install "lts/*" --reinstall-packages-from=current
```
これでLTSを最新にしたときに現在グローバルにインストールされている node_modulesも手軽にインストールできます。

## 参考リンク
[GitHub/nvm-sh/nvm#usage](https://github.com/nvm-sh/nvm#usage)
[GitHub/nvm-sh ヘルプコマンドの実装](https://github.com/nvm-sh/nvm/blob/master/nvm.sh#L2347)