OmniAICreator/Qiita-1.07M huggingface dataset:
LinuC 202「セキュアなDNSサーバーの実現」を見てBIND9をchroot監獄にした

「2.08.3 セキュアなDNSサーバーの実現」の出題内容については以下をご参照ください。
Version 10.0になって少々内容が変更されているようです。

LinuCレベル2 202試験（Version 10.0）出題範囲 | LPI-Japan
https://linuc.org/linuc2/range/202.html

LinuC レベル 1、レベル 2 の出題範囲改定について
https://linuc.org/docs/linuc_ver10.pdf

## この記事のアジェンダ
- bind-chrootをインストール
- namedを停止してnamed-chrootを起動

*前提条件として、既にnamedでゾーンの設定をしている

## bind-chrootをインストール

namedをchroot監獄にするためには、bind-chrootをインストールする。

+ bind-chrootをインストール

```
# yum install bind-chroot
```

+ 2020年8月時点ではCentOS7だと9.11.4-16.P2.el7_8.6が最新版っぽい
   - 最近BIND9の深刻めな脆弱性が公開されてたのは記憶に新しい...

```
# rpm -qa | grep bind | sort
bind-9.11.4-16.P2.el7_8.6.x86_64
bind-chroot-9.11.4-16.P2.el7_8.6.x86_64
```

## namedを停止してnamed-chrootを起動

+ namedを停止して自動起動も無効にする

```
# systemctl stop named
```

```
# systemctl disable named
Removed symlink /etc/systemd/system/multi-user.target.wants/named.service.
```

+ named-chrootを起動して自動起動を有効にする

```
# systemctl start named-chroot
```

```
# systemctl enable named-chroot
Created symlink from /etc/systemd/system/multi-user.target.wants/named-chroot.service to /usr/lib/systemd/system/named-chroot.service.
```

+ named-chrootのプロセス起動確認
   - named, named-chrootどちらも起動したままだと、namedプロセスが2つ存在し、設定再読み込みが効かなくなるなど事故ると思われる。

```
# ps -efH | grep named
named    22610     1  0 12:20 ?        00:00:00   /usr/sbin/named -u named -c /etc/named.conf -t /var/named/chroot
```

+ /var/named/chroot配下に必要なファイルが配置されていることを確認
   - bind-chrootがスクリプトで自動的に必要なファイルを配置してくれる模様

```
# ls /var/named/chroot/
dev  etc  run  usr  var
```

+ 試しにAレコードを追加してみる
   - ファイル編集する時は直のファイル(/var/named/chroot配下でないファイル)で編集すればよさそう

```
# vim /var/named/example.com.db
```

+ 設定ファイルとゾーンファイルのテスト

```
# named-checkconf -z /var/named/chroot/etc/named.conf
```

↓こういうやり方もできる

```
# named-checkconf -z -t /var/named/chroot /etc/named.conf
```

+ 設定ファイルとゾーンファイルの再読み込み

```
# rndc reload
server reload successful
```

digで名前解決テストして問題なければok.
チョコボールのキャラメル味とピーナッツ味を分類するAIツールを作ってみたの巻



記事をご覧くださりありがとうございます！
初めまして。AI/IoT分野のプロフェッショナルを目指して修行中の、たつのぶです。🐉
今回は、皆さんが知っているであろう、チョコレート菓子チョコボールの
キャラメル味とピーナッツ味をAIで判別してみたことをまとめた記事です。
実際には、Kerasを使って深層学習(ディープラーニング)をやってみました(^▽^)/
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/67a78638-5136-527c-2a80-c206f157fae8.jpeg" width=30%>　　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/12d32cde-7e52-ce02-4e8a-0c35b0066386.jpeg" width=30%>


#作ったもの
チョコボール画像を選択すると、
任意のフォルダに**(キャラメル味とピーナッツ味どちらなのか判別した)結果**をテキストファイルで書き出してくれるツール
その名も、チョコボールドラゴンというものです！（個人的にネーミング気に入ってる(笑)
![teki.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/4737dc27-a38c-2b68-cf1c-b9dcd01e49ec.png)

#学習用(訓練)データ
 - チョコボールのキャラメル味画像(15枚)
 - チョコボールのピーナッツ味画像(15枚)

# 評価用データ
➡したの実際の評価に使った画像を見てもわかる通り、人間の目では判別するのは難しいです(笑)
さて、AI君はどれくらい判別する能力があるのでしょうか？？
#### キャラメル味画像(5枚)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/9eca2dbe-62cf-025d-e03f-b6f9f701ff96.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/cc8024bf-6665-0160-95e2-34dc55573501.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/8947fa1e-4d01-80e5-4f2e-5f7ef81385ee.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/fd6ba3ab-f04a-b3fa-e0c2-51872077e35c.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/de03f511-ea75-562c-75ba-3766b9f13600.jpeg" width=30%>
#### ピーナッツ味画像(5枚)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/e266d66d-3ba0-a4f3-24a3-bc84b3c07eb4.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/3c9e2022-46c6-fccd-cfaa-aa2059eae8d5.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/1688bcd7-800e-82d7-20f0-bce10fb73d18.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/68922a81-fb23-f5da-9721-a2fd312bb4e4.jpeg" width=30%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/d78aac7c-84ac-67f2-a73b-1d2012187fc0.jpeg" width=30%>

#モデル作成と評価
![ほげ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580405/b24c969e-7ba6-bc18-ed60-41138b90586d.png)


➡5回モデル構築をして、評価用データを使って自作画像分類ツール(チョコボールドラゴン)で確認。
➡「loss(正解とどれくらい離れているかという数値。0に近づくほど正解に近い)」
と「accuracy(正確性。100%に近いほど正解に近い)」を眺めてみると、
理論的には、**lossが小さく、accuracyが高いほど良い結果が得られる**らしいですが、
理論通りにはいかず、モデル番号「5」のものが一番正解率の高いモデルとなった。

|モデル番号  | loss |accuracy  |  実際の正解率 |
|---|---|---|--- |
|1  |0.386 |0.875 | 60% |
|2  |7.689 |0.5  | 50% |
|3  |0.054 |0.75  |50% |
|4  |0.863 |0.5  |50% |
|**5**  |**0.546** |**0.625** |**90%** |

#ソースコード
(今後githubに乗っけます)

#参考URL
https://ailog.site/2019/08/01/keras1/

#最後に
うーむ。一番いいモデルデータを使って評価したら**90%の精度で判別**してくれました😃
なかなかの判定結果で満足です。
自分なりに構築して検証しましたが、訓練用入力画像データの前処理は十分なのか不明です(笑)
ぜひ、プロフェッショナルな方がいたら、コメント欲しいです。

この記事をご覧になった方。
身の回りにある画像を用いた、機械学習・深層学習は面白いので、ぜひ機会があったら
試してみてください。とても面白いですよ～
それでは✋
Github PackagesをDocker Registoryとして使う


## tl;dr

- Github Packages は Docker Registry として利用でき、リポジトリと同一の権限管理ができて便利である。
- タグは `docker.pkg.github.com/USER/REPOSITORY/IMAGE:TAG` となり、リポジトリに複数のイメージを登録できる。
- 公開リポジトリであってもアクセストークンの登録が必要である。 `docker login https://docker.pkg.github.com -u <User Name> --password <Access Token>`

## 実際どんな感じになるか

Github Packages を使うと、成果物のリソースの管理が Github Repository の管理と一致するため、非常に便利です。
Github Packages は Docker Registry としても使える機能を持っています。
すなわち、Github Repository の権限管理の Docker Registry として使うことができる。

以下のようなイメージの名前の docker registry として使えます。リポジトリに複数のイメージを格納できます。

`docker.pkg.github.com/USER/REPOSITORY/IMAGE:TAG`

![2020-08-16-12-31-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3413/90b9b9d5-7c07-3970-65e0-fc18b8f7260b.png)


![2020-08-16-12-32-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3413/3714051b-4564-39f8-1a61-2c43cbbd4338.png)

## ローカルの docker コマンドで使う

docker コマンドで github package にアクセスするには、公開リポジトリの公開パッケージであったとしても、必ず Personal Access Token を使ってログインすることが必要です。
加えて、Personal Access Token には、以下の権限が必要です。

- docker pull する場合 "read:packages"
- docker push する場合 "write:packages"

以下のコマンドでログインを行います。

```
docker login https://docker.pkg.github.com -u 74th --password <Access Token>
```


このリポジトリの nginx の例

```
docker run --rm -it -p 80:80 docker.pkg.github.com/74th/try-github-container-registry/nginx:latest
```

## Github Action でビルドする

`${{ secrets.GITHUB_TOKEN }}`でアクセストークンが得られるので、これを使うように[Build and push Docker images](https://github.com/marketplace/actions/build-and-push-docker-images)の Github Action を組みます。

```yaml
name: docker-build

on:
  push:
    branches:
      - master

jobs:
  build:
    name: build
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Build and push Docker images
        uses: docker/build-push-action@v1.1.0
        with:
          registry: docker.pkg.github.com
          username: 74th
          password: ${{ secrets.GITHUB_TOKEN }}
          dockerfile: ./Dockerfile
          repository: 74th/try-github-container-registry/nginx
          tags: latest
```
PM（プロダクトマネージャ）について調べてみた

# はじめに
こちらの[イベント](https://codezine.jp/article/detail/12590)をふと目にすることがあり、
登壇者の豪華さ、内容に興味が沸いたので参加してみました。
こちらはその備忘録です。

![スクリーンショット 2020-08-16 12.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/aeb2bf95-2e60-349a-7695-97b31438a786.png)

一番印象に残ったのは、「manageとはなんとかする　という意味もある」という一言でした。
（若干精神論的にも聞こえましたが、マネージャ・リーダーという役職の人に結局求めるのはこれになってしまうよなぁと..なんとかしたあとの結果に対しては考察が必要（良いこと、改善することをきちんと振り分ける）だと思うけど、結局なんとかしようとしないとちゃんとしたものが残らないので）

# その後やったこと
その後、こちらの連載記事を一通り読みました。
また、こちらのNoteもいくつか読ませていただきました。

- [「プロダクトマネジメントの基本を学ぼう」連載一覧](https://codezine.jp/article/corner/816)
- [TablyのNote](https://note.com/tably)

ちなみに一番知りたかったのは、「プロジェクトマネージャとプロダクトマネージャの違い」ですが、
この図が一番分かりやすかったです（解説しているページは[こちら](https://codezine.jp/article/detail/12288?p=2)）

![12288_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384422/3a51f3d1-1544-8de4-482b-829befaade62.png)

自分の理解を簡単に残すと、プロダクトの一部がプロジェクト。
実際、受託開発で関わるのはプロジェクトになるし、プロジェクトを成功させるだけでも大変だけど、
プロダクト全体のことを考えるプロダクトマネージャの発想や意識は必須だよなぁ。
（受託開発だとプロダクトマネージャにはならないけど、プロダクトへの意識は顧客と仕事をする上で必須になるので）

# 所感とまとめ
受託開発という流れがある程度続くうちはプロジェクトマネージャという言葉が続くだろうし、
いきなり何もかもは変わらないのかなと思う。
ただ、日本の企業がいずれ自社製品のプロダクトマネジメントをするようになると、
当初のプロジェクトを中心とした発想は徐々に変わっていくのかなぁと思う。
（少なくとも今回のセミナーの開催者や参加している方は変えていきたい意識なのかなと思った）
その時にプロダクトマネジメントの視野・視座が必要にはなるんだろうなぁ。
Raspberry PiのCPU温度をPrometheus+Grafanaで可視化する

Raspberry Pi4が熱い。やけどしそうです。
CPU温度をGrafanaで可視化してみます。

* 2020/8/16時点のRaspberry Pi OSは`Debian Buster`がベース
* Busterのリポジトリに登録されている`prometheus-node-exporter`のバージョンは0.17.0。
* Busterの次のバージョン`Bullseye`のリポジトリにはバージョン1.0.1があり、これを使うとCPU温度の値が取れる

PrometheusとGrafanaのインストールについては、以前書いた「[PrometheusとGrafanaでRaspberry Piを監視](https://qiita.com/moritalous/items/76730e99b2842be87208)」を参照ください。

# バージョン1.0.1のprometheus-node-exporterをインストール

1. https://www.debian.org/distrib/packages#search_packages でprometheus-node-exporterを検索
2. 検索結果の`prometheus-node-exporter パッケージ`の`bullseye (testing)`をクリック
3. ページ下部にある`prometheus-node-exporter のダウンロード`のarm64かarmhfを選択
4. `ftp.jp.debian.org`で始まるリンクをクリックし、debパッケージをダウンロード
5. `sudo dpkg -i prometheus-node-exporter_[バージョン]_[アーキテクチャ].deb`でインストール

# Grafanaで可視化

CPU温度は`node_thermal_zone_temp`というメトリクスで取得されています。
私はCPUの周波数と合わせて、こんな感じで可視化してみました。

![スクリーンショット (175).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/33e2f325-6f37-f9fd-673f-adeb6c8f54bd.png)

熱い
Optimizing OpenCVをCMakeでビルドする時のエラーの対処

# はじめに
OpenCVをインストールしようとした際，最適化版があることを知らず，普通にビルドしてしまったのですが，
オプションを指定で最適化版をインストールできるということだったのでそちらをインストールしようと思います．

しかし，再度ビルドしようとしたらエラーが出てしまったので，その解決方法を自分用にメモしておきます．

# CMakeオプション
```bash
cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
    -D ENABLE_NEON=ON \
    -D ENABLE_VFPV3=ON \
    -D BUILD_TESTS=OFF \
    -D OPENCV_ENABLE_NONFREE=ON \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D BUILD_EXAMPLES=ON ..
```

# エラー
```bash
CMake Error at cmake/OpenCVCompilerOptimizations.cmake:477 (message):
  Required baseline optimization is not supported: VFPV3
  (CPU_BASELINE_REQUIRE=;VFPV3;NEON)
Call Stack (most recent call first):
  cmake/OpenCVCompilerOptions.cmake:268 (include)
  CMakeLists.txt:688 (include)
```

# 解決方法
依然のビルドと競合しているので，CMakeCacthを削除します．

```bash
rm CMakeCache.txt
```

あとは再度上記のオプション付きで`cmake ..`をすればできるはずです．
PYNQ > PYNQ-Z1 > ビルトインUSB UARTのピン > MIO14とMIO15 | MIOとは > MicroBlazeのBlock Designでは割り当てできない

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
PYNQ v2.5 Image
Vivado v2019.1 (64-bit)
```

### 概要

PYNQ-Z1に搭載のUSB UART(J14)をMicroBlazeだけのBlock Designに使用検討した。
使用できないようだ。
関連情報をここに記載しておく。

### USB UART > MIO14とMIO15 

PYNQ-Z1 Board Reference Manual(Revised April 13, 2017)には以下の図がある(p5)。
![コメント 2020-08-16 122951.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/248b9286-b841-1b11-a76f-67a02d1fe2aa.png)

MIO14とMIO15ピンがUSB UARTのRX, TXになっていると理解した。

### 回路図

PYNQ-Z1の回路図(pynq-z1_sch.pdf)で確認をした。

![コメント 2020-08-16 123153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/7395435f-8fa7-48cd-c6ab-5b414fbd247c.png)

IC20FのPS_MIO14_500とPS_MIO15_500が対応するピンのようだ。

- PS_MIO14_500 (C5) : UART_TXD_IN (USB UARTのRX)
- PS_MIO15_500 (C8) : UART_RXD_OUT (USB UARTのTX)

ピンとしてC5, C8が対応しているようだ。

### MIOとは


- [ZYBO (Zynq) 初心者ガイド (3) PSのGPIOでLチカ](https://qiita.com/iwatake2222/items/39d2ed00fa88a1204fce)
    - @iwatake2222 様
    - 情報感謝です

> ZynqはPSとPLから構成されます。PSにはCPUのほかにUART、I2C、GPIO等のペリフェラルがハードマクロIPとして搭載されています。これら専用のピン(IO)が用意されています。それがMIO(Multiplexed IO)です。ピン毎にどの機能に割り当てるかを選ぶことが出来るので「Multiplexed」となっています。STM32などのマイコンと同じです。

> このMIOはPS専用です。...

PS専用のピン。そのためPLのI/O Portsでは選択できないと理解した。


### MicroBlazeのBlock Designでは割り当てできない

https://qiita.com/7of9/items/32de37874cde4aa27be4#forum%E3%81%AE%E6%83%85%E5%A0%B1
でも見つけた情報にて、C14/D11のピンがPL用には使えないとあった。

PYNQ-Z1の場合は前述のように`C5`, `C8`が該当のピンになるのだろう。
VivadoでRun Synthesis後にI/O Portsウィンドウにて`C5`をAXI UART LiteのTXピンに指定しようとしたところ「`C5 are invalid placements.`」となった (forumの記載と同じ状況だった)。

ビルトインのUSB UARTはPLから使えないということなのだろう。
kotlin&Java:特定のフラグメントのみツールバーを表示しない方法

#はじめに
Android開発で特定のフラグメントのみツールバーを表示しない実装に今後も遭遇することが予想されるため、備忘録を含め下記にまとめさせていただきます。

## kotlinの場合
```kotlin:kotlin
//隠したい
(activity as AppCompatActivity?)!!.getSupportActionBar()!!.hide()

//表示したい
(activity as AppCompatActivity?)!!.getSupportActionBar()!!.show()
```

## Javaの場合
```kotlin:Java
//隠したい
((AppCompatActivity)getActivity()).getSupportActionBar().hide();

//表示したい
((AppCompatActivity)getActivity()).getSupportActionBar().show();
```

以上となります。

今回参考にした記事です。
より詳細に記載がりますので、よろしければご参照ください。(Javaです。)
https://stackoverflow.com/questions/29128162/android-hide-toolbar-in-specific-fragment

ご参考になれば幸いです。
AtCoder Beginner Contest 175 Task A - Rainy Season の鮮やかな解答(Python)

## 経緯
A問題なので楽勝かと思いきや、自分はパッと鮮やかな解答が思いつきませんでした。
（時間がかかるのも嫌なので結局、8通りの場合分けをベタ書きするというセンスないコードを提出してしまいました、無念……。）

ヒントを得ようと上位者のSubmissionを眺めていると、itertoolsを使用した鮮やかな解答が多く見られましたが、最近Pythonを触り始めた私にはgroupbyがチンプンカンプンでした。今回、理解したので内容を記しておきます。

## 問題
>AtCoder 町の、ある連続した$3$日間の天気の記録があります。天気の記録は長さ$3$の文字列$S$で表され、$i(1\leq i\leq 3)$日目の天気は$i$文字目が'S'のとき晴れ、'R'のとき雨でした。
天気が雨である日が連続していた最大の日数を求めてください。
>
制約
$\left| S \right| = 3$
$S$の各文字は'S'または'R'である

要求は非常にシンプルですが、単純に'R'の個数で判定すると'RSR'のパターンでNGとなります。

## しょぼい解答
拡張性が皆無な書き方をすれば以下のようになります。ゴリ押しですね。

```python:しょぼい解答
s = input()
if s == 'RRR':
  res = 3
elif s =='SRR':
  res = 2
elif s =='RSR':
  res = 1
elif s =='RRS':
  res = 2
elif s =='RSS':
  res = 1
elif s =='SRS':
  res = 1
elif s =='SSR':
  res = 1
else:
  res = 0
print(res)
```

## 普通の解答
おそらくこの程度が期待されているコードだと思われます。

```Python:普通の解答
s = input()
if 'RRR' in s:
    res = 3
elif 'RR' in s:
    res = 2
elif 'R' in s:
    res = 1
else:
    res = 0
print(res)
```
## 上位者の解答例
[morio__](https://atcoder.jp/users/morio__)さんという方が下記のようなコードを[提出](https://atcoder.jp/contests/abc175/submissions/15907417)されていました。
黄コーダーの方で、Pythonで最速の開始36秒でのACということで完全にレベチです。

```python:#15907417
from itertools import groupby
res = 0
s = input()
for k, v in groupby(s):
    if k == 'R':
        res = max(res, len(list(v)))
print(res)

```

汎用性が非常に高くて美しいですね。
指定するキーの部分を書き換えるだけで常に与えられた文字列の中の最長の連続数を取得できます。
コードとはかくあるべきと感じます。

## groupbyについて
groupbyの公式ドキュメントです。
[itertools.groupby(iterable, key=None)](https://docs.python.org/ja/3/library/itertools.html#itertools.groupby)

多次元入力に対して任意のカラムでグルーピングも出来るようですが、今回は1次元配列で見てみます。
こんな挙動のようです。

```Python
# itertoolsからgroupbyをインポート（itertoolsには他にも便利なツールがたくさんありました）
from itertools import groupby

# groupbyする1次元配列
mylist = [0,0,0,1,1,2,2,2,1,1,1]

# groupbyはイテラブルでkeyとgroupが返る
for key, group in groupby(mylist):
  # groupの各要素をリストにキャストして出力
  print(key, list(group))

# 出力
# 0 [0, 0, 0]
# 1 [1, 1]
# 2 [2, 2, 2]
# 1 [1, 1, 1]
```
`groupby`で得られる`group`はあくまでイテラブルな'オブジェクト'なので、扱う際にはリストにキャストしてあげないといけないみたいです。

ちなみに`group`の型を`type(group)`で出力すると`<class 'itertools._grouper'>`でした。

## 理解した内容
キーが'R'のグループに対し、`len(list(v))`でグループの要素数を取得していき、最大のものを出力しているということですね。
非常に鮮やかで勉強になりました。自分ももっと精進します。
Portable Docker環境でWebDAVを使う

# 概要

WebDAVを使って、WindowsのエクスプローラーからUSBメモリ内のLinuxのファイルにアクセスする環境を作ります。

# なぜWebDAV

Windowsのエクスプローラーで仮想化PCのLinuxのファイルにアクセスしたいときは仮想PC独自の共有フォルダ設定かsambaを使うのが一般的だと思うのですが、Qemuにはフォルダ共有機能が(実質)なく(Linux側でsamba実行するだけっぽい)、設定が凄まじく面倒そうだったのと古いsambaは設定しないとWindows10からアクセスできないのでWebDAVにしてみた。

ftpdは立てるのは簡単だけど(管理者権限なしで)ドライブに割り当てるのは無理そう。これが簡単にできるのならftpのほうがいいんだけど…。

# Dockerコンテナ

おそらく需要の関係で公式のコンテナは存在しないようなので、基本的には[公式のApache使用httpdコンテナ](https://hub.docker.com/_/httpd)をベースにデフォルト無効のWebDAVを有効にして各種設定を行うDockerfileを作るのがセオリーのようです。

それは面倒なので[bytemark/webdav](https://hub.docker.com/r/bytemark/webdav/)を使います。2020年8月現在、一番使われているWebDAVコンテナで、必要な項目を環境変数で設定できるように工夫しているようです。

自分でDockerfileを作る場合は[この記事](https://qiita.com/kxn4t/items/dd20bc65aff0ff9b0f2c)が参考になりそうです。


# composeファイル

[USBメモリ内のLinuxにサーバーを立てる想定](https://qiita.com/riafeed/items/c7729dc84191e93f0f3d)なのでセキュリティガン無視の方向で。

ANONYMOUS_METHODS: ALLですべてのメソッドで認証なし匿名アクセスができるようになります。それでも認証方式をDigestに、かつ適当にでもユーザー名とパスワードを設定しておかないとWindowsからアクセスしてもエラーになるようです。

volumeで[任意のディレクトリ]:/var/lib/dav/dataと設定すると[任意のディレクトリ]がWebDAVでアクセスしたときのルートフォルダになります。

```yaml
webdav:
  image: bytemark/webdav
  container_name: webdav
  restart: always
  ports:
    - "80:80"
  environment:
    AUTH_TYPE: Digest
    USERNAME: user
    PASSWORD: abcdefgh
    ANONYMOUS_METHODS: ALL
  volumes:
    - /root:/var/lib/dav/data
```

これをLinuxのどこかのディレクトリにおいて```docker-compose up -d .```するとWebDAVサーバーが起動します。

composeファイルを使わない場合は、

```bat
docker run -d -p 80:80 --name webdav --restart=always -e AUTH_TYPE=Digest -e USERNAME=user -e PASSWORD=abcdefg -e ANONYMOUS_METHODS=ALL -v /root:/var/lib/dav/data bytemark/webdav
```

# Windowsからアクセスする

設定に問題なければエクスプローラーのアドレスバーに

```bat
\\localhost@80\DavWWWRoot
```

とするとLinux側のファイルやフォルダが表示されるはずです。


# ドライブに割り当てる

SUBSTを使えば管理者権限なしでWebDAVフォルダーを任意のドライブレターに割り当てることができます。

上記のUNCパスではうまくいかないソフトウェアでもドライブレターを割り当てればうまくいくことがあります。
実際、VisualStudioCodeではUNCパスでフォルダを開こうとしても通りません(全く関係ないフォルダを開きます)が、ドライブレターを割り当てればうまくいきます。

エクスプローラーで一度開いている場合はsubstだけでドライブ割り当てできますが、初めて開く場合は一度net useコマンドを使って接続しておく必要があります。net useでドライブを割り当てることもできますが管理者権限が必要です。

```bat
net use \\localhost@80\DavWWWRoot
subst Z: \\localhost@80\DavWWWRoot
```

タイトルバーには切断されたネットワーク ドライブと表示されますが、接続されているようです。

batに記述する場合はwebdavサーバーの起動に時間がかかっているとnet useに失敗するので、成功するまで数十秒～1分間隔で再接続するようにしておいたほうがいいと思います。

```bat
:NETUSE
timeout 30 /nobreak
net use \\localhost@80\DavWWWRoot
if %ERRORLEVEL% NEQ 0 goto NETUSE
subst Z: \\localhost@80\DavWWWRoot
```
【CloudTrail】機能の有効化

## CloudTrailとは

AWSのAPIリクエストの履歴をJSON形式で保存するロギングサービス

- 機能を有効化すると、IAMユーザー・AWSサービスのアクションが全て記録される

- ログデータはKMSを使って暗号化され、gz形式でS3に保存される

## 1. 証跡を作成する
<img width="1440" alt="スクリーンショット 2020-08-02 23.35.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/df92a227-5c4b-848d-4d7a-dfc1b5236a4c.png">

## 2. 証跡属性を選択する
![スクリーンショット 2020-08-16 12.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/4e18dd5a-1f4e-7d63-d990-f64793f719d2.png)
![スクリーンショット 2020-08-16 12.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/c373e45d-6eb3-6477-9d6b-bf75e2f09990.png)

## 3. ログイベントを選択する
![スクリーンショット 2020-08-16 12.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/105d9e26-8227-5fc4-f446-3fe018e220d5.png)
![スクリーンショット 2020-08-16 12.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/7c45a841-4c7e-fcf7-057a-6a685ee3f1ae.png)

### 作成完了
![スクリーンショット 2020-08-16 12.12.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/d604f693-4932-d62f-da7d-9435e5168731.png)
【CocoaPods】CocoaPodsインストール・セットアップ方法



【CocoaPodsとは？】
CocoaPodsはライブラリ管理ツールです。
ライブラリとは、プロジェクトの拡張機能として存在し、機能をプロジェクトに埋め込むことができます。



【CocoaPodsのインストール方法・手順】
①Launchpadを開く→アプリケーションが並んだ画面に移動すると思います。
![スクリーンショット 2020-08-16 10.58.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/b6465fc6-d0e0-3a10-309e-2a680d732ae8.png)
その中に「ターミナル」というアプリケーションがあるので、開きましょう。
![スクリーンショット 2020-08-16 10.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/4b1223ae-0a79-8445-2bb3-feca2665db67.png)
「ターミナル」開くと白い画面が出てきます。(人によって画面の色が違う場合がありますが機能に差異はありません)
![スクリーンショット 2020-08-16 11.09.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/0f6feaeb-4bdc-ceac-5177-084078169200.png)

②コードを入力していく
下記のコードを入力してEnter押します。
```　sudo gem install cocoapods　```
![スクリーンショット 2020-08-16 11.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/c2ea86ff-67b5-70a1-a6c6-f70ffff28f76.png)
自分のMacのパスワードを要求されていますので、入力してEnter
※入力する際、表示されないので注意です。
![スクリーンショット 2020-08-16 11.12.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/de49ef26-7bdc-8ada-ae1f-4a03861bf17a.png)


このような画面が出てきたらインストール完了になります。
![スクリーンショット 2020-08-16 11.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/e8d069dc-d656-a9cf-ad88-84bcb6f88c64.png)


最後にセットアップしていきます。下記のコードを入力してEnter押します。
``` pod set up ```
![スクリーンショット 2020-08-16 11.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678283/74430ea6-ac7a-7e9d-6172-54a66ff81d2c.png)


これでCocoaPodsのインストール・セットアップ完了しました。
Rubyの基本基礎

初めまして。タクミです。エンジニアとしてのアプトプット力を高めるためはじめました。よろしくお願いします。

Rubyとは何か？
その前にここで、そもそもプログラミングとは何か、基本的な用語の意味を学ぶ

 プログラミング
コンピュータが実行する処理の手順をまとめたデータをプログラムと呼び、
このプログラムを作成・記述していく作業のことをプログラミングと呼ぶ。

 プログラミング言語
プログラミングを行うために使用する言語のこと。
対して、私たち人間が日常会話で使用する言語は、自然言語と呼ばれる。

日本語や英語などの自然言語は、人間同士がコミュニケーションを行うためのものであり、
プログラミング言語は、人間がコンピュータに処理をお願いするための言語。

Ruby（プログラミング言語）
Rubyはプログラミング言語の1つです。記述がシンプルでわかりやすいため気軽に楽しくプログラミングでき、しかも実用的です。大きなWebアプリケーションから小さなプログラムまで、さまざまなソフトウェアを作ることができる。

→ Ruby 公式サイト
https://www.ruby-lang.org/ja/

Rubyプログラム実行の手順

１、ファイルを作成
２、ファイルにプログラムを記述
３、ファイルを指定してプログラムを実行

rubyでHello Worldと出力するにはVScodeにこのように書きます。

```ruby/helloworld.rb
1　puts "Hello World"

```

ターミナルではこのように書きます。

```ターミナル
# カレントディレクトリを確認
% pwd
/Users/ユーザー名/ruby

# ディレクトリの中身を確認
% ls
helloworld.rb

# Rubyファイルを実行
% ruby helloworld.rb
```

以下が実行した画面です。

```ターミナル
takumi@takuminoMacBook ~ % cd ruby
takumi@takuminoMacBook ruby % pwd
/Users/takumi/ruby
takumi@htakuminoMacBook ruby % ls
helloworld.rb	
takumi@takuminoMacBook ruby % ruby helloworld.rb
Hello World
```

以上です。これからも続けていきます！読んでいただきありがとうございました。
git add . と git add -A と git add -u の違いはなんぞや？

# gitとは？
gitとは、プログラムソースなどの変更履歴を管理する分散型のバージョン管理システムのことです。

# git add
git add は指定したファイルをインデックスに登録してコミット対象にするコマンドのことです。

```git:ターミナル 
$ git add ファイル名

#例
$ git add index.html
```

ファイル名には、*を使ったワイルドカードによる指定もできます。

```git:ターミナル 
$ git add *.rb   #カレントディレクトリの全ての.rbファイルをadd
```

# git add -u と git add -A と git add.
git add にオプションを追加することによってまとめてコミット対象にすることができます。

###git add -u
```git:ターミナル 
$ git add -u
```
git add -u は**バージョン管理されていて、変更があった全てのファイル（変更されたファイル、削除されたファイル）**がaddされます。
※バージョン管理されていないファイルや新しく作られたファイルはaddされません。

###git add -A

```git:ターミナル 
$ git add -A
```

git add -A は**変更があった全てのファイル（変更されたファイル、削除されたファイル、新しく作られたファイル）**がaddされます。

###git add .

```git:ターミナル 
$ git add .
```

git add . は**今いるディレクトリ以下の変更があった全てのファイル**がaddされます。

```git:
#例 
 sample_app
 ├── dir1
 └── dir2
```

例えば、上の図のように dir1 と dir2 という2つのディレクトリがある場合に dir1 にいる状態で git add . を実行すると、dir2 で行われた変更は add されません。

# 簡略図

||新しく作られた<br>ファイル|変更された<br>ファイル|削除された<br>ファイル|
|---|:---:|:---:|:---:|
|git add -u|×|○|○|
|git add -A|○|○|○|
|git add .|○|○|○|

# 参考

[git add -u と git add -A と git add . の違い](https://note.nkmk.me/git-add-u-a-period/)
Colaboratoryで日本語フォントを画像に入れる

1. Colabのローカルにフォントを入れる
2. OpenCVで画像読み込み
3. PILでフォント描画
4. OpenCVで画像表示


こちらを参考にさせて頂きました。
Watlab | Pythonで画像に日本語文字を入れる方法
https://watlab-blog.com/2019/08/25/image-text/
Google Colaboratoryに好きなフォントを入れてmatplotlibとかで使う方法
https://qiita.com/nkay/items/b2d50349a3f5d38df45b

```python:font.py
#フォントをColabローカルにインストール
from google.colab import drive
drive.mount("/content/gdrive")
!cp -a "gdrive/My Drive/font/" "/usr/share/fonts/"

from PIL import Image, ImageFont, ImageDraw
import cv2
import numpy as np
from google.colab.patches import cv2_imshow

# 画像に文字を入れる関数
def img_add_msg(img, message):
    font_path = '/usr/share/fonts/meiryo.ttc'           # Colabのフォントへのパス
    font_size = 100                                     
    font = ImageFont.truetype(font_path, font_size)     # PILでフォントを定義
    img = Image.fromarray(img)                          # cv2(NumPy)型の画像をPIL型に変換
    draw = ImageDraw.Draw(img)                          # 描画用のDraw関数

    # テキストを描画（位置、文章、フォント、文字色（BGR+α）を指定）
    draw.text((50, 50), message, font=font, fill=(255, 255, 255, 0))
    img = np.array(img)                                 # PIL型の画像をcv2(NumPy)型に変換
    return img                                          # 文字入りの画像を返す

img = cv2.imread('/content/gdrive/My Drive/hoge/huga.jpg', 1)     # 画像読み込み
message = 'ハローワールド'                                           # 画像に入れる日本語
img = img_add_msg(img, message)                        

# 画像表示
cv2_imshow(img)

```
はい、と。
![img](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216609/8e60a159-2039-c158-abcd-bc367b1e43ed.png)
heokuデプロイ→コード変更後更新されない

#現象
rails tutorial3章
1.sample_app作成後
config/routes.rbの内容を下記に変更(rootを'application#hello'から'static_pages#home'に変更)
  >root 'static_pages#home'
  get  'static_pages/home'
  get  'static_pages/help'
  get  'static_pages/about'
end>

2.git commit → git push heroku master後
ページを再度開いたが、開いたページがroot 'application#hello'のまま

#原因
heroku masterにpushできていなかった
→作業ブランチがローカルのstatic-pagesのままgit push heroku masterを実行していた

#解決方法
現在の作業ブランチから Heroku の master ブランチへpushする。
git push heroku static-pages:master

#参照
https://techacademy.jp/magazine/6401#sec4
iOSの「ショートカット」アプリを使って休暇申請メールを自動作成にしてみた話

# はじめに
ちょっとした息抜きで「ショートカット」アプリで自動化を取り入れてみた話
日々の細々とした作業は少しでも軽減していきましょう。

## 本編
ボタン押下と日付選択だけで休暇申請メールが自動で作成されるようにしてみました。

### 休暇予定日の入力設定
まず、休暇を申請する日付を入力できるようにしましょう。
「スクリプティング」>「通知」>「入力を要求」を選択し、以下のように設定します。

入力値はマジック変数「**休暇予定日**」と定義します。

|項目|設定|備考|
|---:|:--:|:---|
|質問|日付|入力要求時のメッセージを任意に設定|
|入力の種類|日付||

### 休暇種別の入力設定
休暇種別の内容を入力できるように設定をします。
テキストはマジック変数「**休暇種別**」と定義します。

#### 休暇種別を定義
まず休暇の種類を定義します。
「スクリプティング」>「リスト」>「リスト」を選択します。

今回は以下のように、一般的な全休・午前休・午後休を定義しました。
会社の制度に応じて任意に設定してください。

|項目|設定|
|--:|:--|
|1|全休|
|2|午前休|
|3|午後休|

#### リストから選択するよう設定
定義したリストから選択できるように設定します。
「スクリプティング」>「リスト」>「リストから選択」を選択し、以下のように設定します。

|項目|設定|
|---:|:--:|
|リスト|**休暇種別**|

### テキストの作成
メールタイトルおよび本文を作成するように設定します。

#### タイトル
タイトルの設定をテキストを設定します。
「書類」>「テキスト」>「テキスト」を選択し、以下のように編集します。

作成したテキストはマジック変数「**タイトル**」と定義します。

```text:作成したいテキスト
【勤怠】 ○年○月○日(○)
```
○の部分はマジック変数「**休暇予定日**」を下記のようにフォーマットして使用します。

|出力項目|入手|日付フォーマット|カスタムフォーマット|備考|
|---:|:---|:---|:---|:---|
|○ 年|日付|カスタム|yyyy|年
|○ 月|日付|カスタム|M|月
|○ 日|日付|カスタム|d|日
|(○) |日付|カスタム|EEE|曜日

#### 本文
本文も同様にテキストを設定します。
「書類」>「テキスト」>「テキスト」を選択し、以下のように編集します。

作成したテキストはマジック変数「**本文**」と定義します。

```text:作成したいテキスト
下記、休暇(△)を申請します。
○月○日(○)
```
△,○の部分は以下のようにマジック変数を使用します。

|出力項目|マジック変数|種類|日付フォーマット|カスタムフォーマット|備考|
|---:|:--:|:---|:---|:---|:---|
|(△)|**休暇種別**|テキスト|-|-|リストから選択した休暇種別
|○ 月|**休暇予定日**|日付|カスタム|M|月
|○ 日|**休暇予定日**|日付|カスタム|d|日
|(○) |**休暇予定日**|日付|カスタム|EEE|曜日

### メール作成
メールの作成設定を行います。
「共有」>「メッセージ送信」から「**メールを送信**」を選択し、以下のように編集します。

|項目|設定|備考|
|---:|:---|:---|
|メッセージ|**本文**|マジック変数|
|宛先|送信先のメールアドレス||
|件名|**タイトル**|マジック変数|
|作成シートを表示|On|作成したメールを確認後、手動で送信。Offで自動送信|

## 実行結果
#### 休暇予定日の入力
![input-date.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/c7128e4e-d70a-e96d-6e21-0f5a003a01ae.jpeg)

#### 休暇種別の入力
![input-shubetsu.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/13a03ca0-45cf-d97e-c7c4-94fcc65c59cc.jpeg)

#### メール作成
![mail.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338551/a3595b5f-6baf-aa46-31e1-a0174f65b466.jpeg)

# おわりに
無事に自動化することができました。
「ショートカット」アプリはWebリクエストを実行できたり、SSH接続でスクリプトを叩けたりもするようです。
PlayFrameworkのevolutionsをテストに適用しようとしたらテーブルが作成されずハマった件

## 事の発端
PlayFrameworkを使っていて、DBアクセスの部分のテストを書こうと思ったとき、既にevolutions自体は使っていたのでテストコード用のスキーマを同じように作りたいなぁ、と思って、
https://www.playframework.com/documentation/ja/2.4.x/ScalaTestingWithDatabases
を参考に、
`conf/evolutions/hogedb`
にevolutionsファイルを設置、以下のようなテストコードを実行すれば、evolutionsが動いてテーブルができるはず！と思ったけれど何も起きない・・・


```scala:HogeSpec.scala
// テストコード
class HogeSpec extends PlaySpec with HogeTestHelper {
  withHogeDatabase { database =>
    Evolutions.applyEvolutions(database)
  }
}
```

```scala:HogeTestHelper.scala
// テストコードで使うヘルパー
trait HogeTestHelper {
  def withHogeDatabase[T](block: Database => T) = {
    Databases.withDatabase(
      driver = "com.mysql.cj.jdbc.Driver",
      url = "jdbc:mysql://hogehoge:3306/hoge_test?allowPublicKeyRetrieval=true&useSSL=false&characterEncoding=UTF8",
      name = "hogedb",
      config = Map(
        "user" -> "hoge",
        "password" -> "hoge"
      )
    )(block)
  }
}
```

## 解決方法は見つけたけれど・・・
IntelliJでコードを書いていて、ふとevolutionsファイルを設置したフォルダを右クリックしたら、
`Rebuild evolutions.hogedb`
なるものがメニューにあったので、クリックした後にテストを実行したら、狙い通りにテーブルができました！
はいいのだけれど、これがIntelliJ固有の問題なのか、他に解決策があるのかよくわからずです。
【AWSアカウント】サインインリンクの変更

## やること
IAMユーザーのサインインリンクをカスタマイズし、設定したエイリアスをIAMユーザーのログイン時に使用出来るようにする

## 1. サインインリンクをカスタマイズする
デフォルトでは数字の羅列となっている部分を変更する
<img width="1440" alt="スクリーンショット 2020-08-02 23.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/2df51c51-4578-6fee-cdda-9986bf9ec0ae.png">

## 2. アカウントエイリアスを入力する
![スクリーンショット 2020-08-16 11.35.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/48b50dd0-a902-5bd8-043f-ed4ef8680198.png)

### 変更完了
![スクリーンショット 2020-08-16 11.33.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/ae033268-79f5-d78c-7a33-98b667f7de4e.png)

### アカウントエイリアスを利用してのログインが可能になる
<img width="350" alt="スクリーンショット 2020-08-02 23.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/cfd4c578-cd31-99c6-a7fd-7cf18eb323f0.png">
Rails APIでbooleanが勝手にcastされバリデーション通過するのを防ぐ

# 事象

Rails APIでboolean型のカラムに対しcreate, updateした際、boolean以外の型は弾くようにしたい

```powershell
$ rails -v
Rails 6.0.3.2
```

```powershell
$ rails g model Post body:text opened:boolean
```

```ruby:app/models/post.rb
class Post < ApplicationRecord
  validates :opened, inclusion: { in: [true, false]}
end
```

こうすれば本来、boolean以外は弾かれる、はずが…

```powershell
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "moge"}'
{"status":"success","data":{"id":1,"body":"hoge","opened":true,"created_at":"2020-08-16T01:31:14.277Z","updated_at":"2020-08-16T01:31:14.277Z"}}
```

booleanのopenedカラムに対し"moge"を指定

期待： booleanじゃないのでエラーになり弾かれる
実態： エラーにならず、trueにcastされsaveされる

```powershell
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "0"}'
{"status":"SUCCESS","data":{"id":2,"body":"hoge","opened":false,"created_at":"2020-08-16T01:31:28.498Z","updated_at":"2020-08-16T01:31:28.498Z"}}
```

期待： booleanじゃないのでエラーになり弾かれる
実態： エラーにならず、falseにcastされsaveされる

どうやら値がキャストされた状態で渡ってしまう模様

# 対策

カスタムバリデーションを作る

```ruby:app/validators/boolean_validator.rb
class BooleanValidator < ActiveModel::EachValidator
  def validate_each(record, attr, _value)
    before_value = record.send("#{attr}_before_type_cast")
    record.errors.add(attr, "is invalid") unless %w[true false].include?(before_value.to_s.downcase)
  end
end
```

```ruby:app/models/post.rb
class Post < ApplicationRecord
  validates :opened, boolean: true
end
```

※カスタムバリデーションを実装した後はRailsサーバを再起動すること

# 結果

```powershell
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "moge"}' 
{"status":"error","data":{"opened":["is invalid"]}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "0"}' 
{"status":"error","data":{"opened":["is invalid"]}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "true"}'
{"status":"success","data":{"id":3,"body":"hoge","opened":true,"created_at":"2020-08-16T02:25:18.211Z","updated_at":"2020-08-16T02:25:18.211Z"}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "false"}'
{"status":"success","data":{"id":4,"body":"hoge","opened":false,"created_at":"2020-08-16T02:25:30.700Z","updated_at":"2020-08-16T02:25:30.700Z"}}
```

期待した通り、trueとfalse以外は弾かれるようになりました

# 参考

[Railsでboolean型のカラムのvalidationを行い型が異なる場合エラーとして返す方法
](https://qiita.com/k-shimoji/items/13c51b4719cf1eb1f117)
上記URLで実装すると、rubocopにいろいろ引っかかるので今回の記事を書いています
フォーム内容をKEYにして、一致するカラムに回答内容を反映する

```

const insertReport = (e) => {
  if(e.namedValues['key']) {
  const key = e.namedValues['key'];
  const information = e.namedValues['information'];

  const Sheet = SpreadsheetApp.opennById('ID).getSheetByName('SHEET_NAME');
  const data_range = Sheet.getRange(1,1).getDataRegion().getValues();
  const criteria_column = data_range.map((data) => data[0]);
  // ここでkeyをtoString()にするのがポイントです。これがないとindexOfが検索値として認知してくれません
  const is_match_row = 
criteria_column.indexOf(key.toString()) + 1;
  // SET_COLUMNには、値をセットしたい列の番号をセットします
  Sheet.getRange(is_match_row, SET_COLUMN).estValue(information);

  }

}


```
【AWSアカウント】パスワードポリシーの適用

## パスワードポリシーとは
IAMユーザーのパスワード要件や必須の更新期間の指定、パスワード変更権限の有無等の設定

## 1. パスワードポリシーを設定する
![スクリーンショット 2020-08-16 11.14.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/2c4fe744-d2fe-912a-0911-42cc7c4bc1ac.png)
![スクリーンショット 2020-08-16 11.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/855f5d75-9a08-0623-7fb8-fcca938a6670.png)

## 2. パスワードポリシーの詳細設定をする
設定を変更する項目にチェックを付け、適用
<img width="1440" alt="スクリーンショット 2020-08-02 23.06.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/620242b0-7fc1-ae0a-4c99-95be2a61fb6d.png">

### 設定完了
![スクリーンショット 2020-08-16 11.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/40235a83-c424-46d7-5101-6c8365915d76.png)
PYNQ > ビルトインUSB UART > VivadoのI/O Portsでの指定がわからない > forum:そもそも指定できない (代わりにPMOD USB UARTを使う)

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
PYNQ v2.5 Image
Vivado v2019.1 (64-bit)
```

### 概要

- MicroBlazeの実装を試そうとしていた
- UART出力についてUSB UARTを使用しようとしたが、そもそもピンがわからない
- 調べたところ、USB UART自体はピンを指定できない
    - 代わりとしてPMOD USB UARTを使うというフォーラム回答があった

### 試そうとしたもの

- [Vivadoでmicroblaze](https://fpgafpga.jimdofree.com/%E3%83%9B%E3%83%BC%E3%83%A0/vivado%E3%81%A7microblaze/vivado%E3%81%A7microblaze-%E5%B0%8E%E5%85%A5%E7%B7%A8/)
    - Himawari様
    - 情報感謝です

テキストと画像で丁寧に書かれている。
一方で、制約ファイルの記載がなく、よくわからなかった。
USB UARTでのシリアル出力用のピン設定をどうしているのか不明だった。

### forumの情報

- [USB-UART Bridge pins? ](http://zedboard.org/zh-hant/node/13331)

上記によると

- C14/D11はあるけどZynq PSと直接接続用
    - PL用には使えない
- 代わりとしてPMOD USB-UARTを使うという手がある
    
PMOD USB-UARTの製品としては以下のようなものがあるようだ。
https://www.avnet.com/shop/us/products/digilent/pmod-usb-uart-3074457345625232705/

PMODでシリアル出力するのであれば、手持ちのFTDIアダプターを使えばよさそうに思った。


### 不明点

- [PYNQ > XSDK > I2C通信 > MLX90632のEEPROM Versionを読む](https://qiita.com/7of9/items/51b2912f95d588da3b5a)

上記ではUSB UARTでの出力(`I2C configuration done.\n`)がUSB UARTに出力されている。
MicroBlazeではなくZynqを使っているという違いはある。

このあたりはまだ学習不足である。
【AWSアカウント】IAMユーザーへの権限付与

## やること
個々のIAMユーザーに対して、適切な権限を付与する

## 1. アクセス権限を追加する
「アクセス管理 ＞ ユーザー ＞ IAMユーザー」からアクセス権限の追加を行う
![スクリーンショット 2020-08-16 11.04.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/925b6e68-040a-c6d5-bc5a-bfba35d7440a.png)

## 2. ポリシーをアタッチする
許可するアクセス権限を選択し、アタッチする
（今回は管理者としてのアクセス権限を付与）
![スクリーンショット 2020-08-16 11.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/e6a0b614-49de-4014-3e69-9631d7a9dfa5.png)
DockerでPostgreSQLとOwnCloud

前回：[VMのgitlabをコンテナへ（ついでにバージョンアップ 12.0.3→13.2.4）（ついでにdocker-compose）](https://qiita.com/F_clef/items/5855a5eb8090f96fdd99)
これはそろそろDockerを使えるようになりたい筆者の試行錯誤の軌跡です。

# DBとownCloudをVMからDockerコンテナへ移行
前回は、VMのgitlabをDockerコンテナに移行しました。
![Untitled(6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/bc66e507-7671-1d98-a334-3f5cf49b27af.png)

今回は、VMサーバー群のアプリケーションのうち、postgreSQLとownCloudをDockerコンテナに移行して、*Resource*を閉じます。
![Untitled(7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/d8fedbab-cdae-3495-2646-74576ffe5733.png)

# コンテナの構成
docker-compose.ymlは以下のようにしました。

```yml:docker-compose.yml抜粋
    db:
        image: postgres:9.6.19
        environment:
            POSTGRES_USER: psql
            POSTGRES_PASSWORD: xxxx
        volumes:
            - /home/fclef/docker/server/db/data:/var/lib/postgresql/data
            - /home/fclef/docker/server/db/init:/docker-entrypoint-initdb.d
            - /home/fclef/docker/server/db/backup:/tmp/backup
        ports:
            - 5432:5432

    owncloud:
        image: owncloud:latest
        restart: always
        volumes:
            - /home/fclef/docker/server/owncloud:/var/www/html
        ports:
            - 51080:80
```
PostgreSQLのイメージを`latest`に指定すると、owncloudの初期化でエラーが出ました。
PostgreSQLを9.6以前のバージョンにする必要があるようです。
参考：[Install fails on pg 10.5](https://git.cloudron.io/cloudron/owncloud-app/-/issues/13)

# PostgreSQLのバックアップとリストア
参考：[PostgreSQLのbackup, restore方法まとめ](https://qiita.com/rice_american/items/ceae28dad13c3977e3a8)

## バックアップ
バックアップしたいデータベース名を指定して実行します。

```console
$ pg_dump <database> > <buckup file>
```

## リストア
リストアもコマンドは簡単です。

```console
psql <database> < <buckup file>
```
ただし、リストア前にデータベースを作成しておく必要があります。
そこで、バックアップファイルに対応するデータベースを作成してリストアするシェルスクリプトを作成しました。

```bash:1_init.sh
files=`ls -1 /tmp/backup/*`
for file in ${files[*]}; do
    database=`echo ${file} | sed -r 's@.*/(.*).backup.sql@\1@g'`
    echo "init ${database}."
    psql -c "create database ${database};"
    psql ${database} < ${file}
done
```

このスクリプトを`/docker-entrypoint-initdb.d`にマウントします。
このディレクトリ下にある`.sql`ファイル及び`.sh`ファイルはコンテナ起動時に実行してくれます。
ファイル名の先頭に数字を付けておくと、数字順に実行してくれます。

# ownCloudのセットアップ
nginxのコンテナからowncloudのコンテナへのリバースプロキシを設定してアクセスすると、
初期セットアップの画面が開きます。
※スクショし忘れたので拾い画です。
![](https://www.avoiderrors.com/wp-content/uploads/2019/01/Auto-Install-ownCloud-5.jpg)

ログインID,パスワード設定枠の下にある「ストレージとデータベース」というラベルをクリックするとデータベースの詳細設定ができるので、
PostgreSQLを選択して各種項目を入力します。
最下部のDBのホスト情報については、PostgreSQLコンテナのサービス名とポート番号を入力すればOKです。
上記ymlファイルなら、"db:5432"と入力します。

# ownCloudのアップロード上限設定
初期設定では、1ファイルあたり数百MBまでしかアップロードできません。
ownCloudコンテナ側はすでに大きいファイルを受け入れる設定がされているので、リバースプロキシ側で制限を緩めてあげるだけです。

```nginx:nginxコンテナのowncloudリバースプロキシ設定
client_max_body_size 10G; # これを追記
```

# ownCloudのバックアップとリストア
ownCloudのバックアップとリストアの方法は調べてもよくわかりませんでした。
少ししかアップロードしているファイルがなかったので、データディレクトリのファイルを直接コピーしてアップロードしました。
正攻法を知っている方がいらっしゃったら教えていただけると幸いです。

大きく詰まることなく、調べながらでも数時間で終えることができました。
VMセットアップに比べると劇的スピードです。。
Dockerすげぇと今日も思ったのでした。

次回：[DockerでGhost](https://qiita.com/F_clef/items/f0587bd69f12f8ef29a7)
objectをforEachしたい→Mapを使うという手もあるよ

# object.forEachと書きたいが…

Objectは直接forEachできないため、以下のように書く必要がある。

```javascript
Object.keys(obj).forEach(key=>{/*keyを使った処理*/})
```

これでもいいのだが、連想配列にはObjectだけでなくMapも利用できるので、試してみよう。

# Map型を使った場合
Mapを使った場合は以下のように書ける。

```javascript
map.forEach((value, key)=>{/*keyとvalueを使った処理*/})
```

Map.prototypeから直接forEachが生えているので、若干短く書ける。
他にもMap型から直接使えるメソッドがあり、

```javascript
map.keys() //keyを列挙するイテレータを取得
map.values() //valueを列挙するイテレータを取得
```
などが該当する。

ちなみに、for文で処理することも可能。

```javascript
for (const [key, value] of map) {
  //keyとvalueを使った処理
}
```

# ObjectとMapの相互変換
以下のようにして相互に変換できる。

```javascript
//Map→Object
const obj = Object.fromEntries(map.entries())
//Object→Map
const map = new Map(Object.entries(obj))

//ちなみにMap→Arrayは
const array = [...map]
//Array→Map
const map = new Map(array)
```

Object.entries/Object.fromEntriesというドンピシャな関数が用意されているので、有り難く使わせてもらおう。

# 余談
そのうち`map.map((val, key)=>…)`なんて登場するんじゃないかと思っていたが、どうも`[...map].map(([key, val])=>…)`で済むらしい。

# 参考文献

[MDN Map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map) - ObjectとMapの比較
[MDN Map.prototype.forEach()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach)
【AWSアカウント】IAMユーザーの作成

## なぜ作成するのか？
ルートアカウントは利用している全サービスとリソースに対して全操作が行える強い権限を持つ
→ 適切な権限を付与したIAMユーザーで通常の構築・運用作業を行うことがベストプラクティス

## 1. IAMユーザーを作成する
![スクリーンショット 2020-08-16 10.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/45f76c0e-ec95-2ecf-9e2d-f82353afb29f.png)

## 2. ユーザー詳細を設定する
![スクリーンショット 2020-08-16 11.00.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/756e7510-c436-4081-9bb7-2f3ad146f6ee.png)

# 3. グループを作成する
<img width="1440" alt="スクリーンショット 2020-08-02 22.37.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/5ac8b89d-50cd-5cb1-215c-34407ab4f900.png">

自身を管理者としたグループを作成する
<img width="1440" alt="スクリーンショット 2020-08-02 22.39.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/258b9d89-85df-a943-c5f6-c96e0538753b.png">

## 4. タグを追加する
<img width="1440" alt="スクリーンショット 2020-08-02 22.45.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/1e77bfaf-9432-aeea-eac2-b12e15b04772.png">

### 作成完了
![スクリーンショット 2020-08-16 11.01.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/4cb7aacc-0bc2-9726-be79-976824c6c46b.png)
【Blender】  2.82で背景を変える方法 2選

# 動作環境
本記事の動作環境は以下の通りです。
 
| 項目             |               環境 |
|:-----------------|:------------------|
| OS               |         Windows 10 | 
| Blender          |               2.82 |

#背景を変える方法

ワールドの背景もオブジェクトのテクスチャと同様にシェーディングで編集することが可能。
背景を変える方法は主に以下の2通り。

- hdr画像を割当てる
- 単色 or グラデーションを割当てる

#hdr画像を割当てる

以下の方法でhdr画像を割当てる。


1. 以下のサイトからお好みのhdr画像を取得する (補足：容量が大きいほうが解像度が高い)
    [https://hdrihaven.com/hdris/](https://hdrihaven.com/hdris/)
   
1. ワールドプロパティ>カラー>環境テクスチャ>開く から取得した画像を割当てる

![hdr_setting.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/909e8a0b-ea5c-d025-43f0-7260488151ab.png)



補足：シェーダーエディターから同様の操作をすることも可能。詳細は後述の単色 or グラデーションを割当てるとほぼ同じ。

![hdr_setting2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/3fb34bbe-3d87-c9d9-5099-1e7ea2cce50d.png)


#単色 or グラデーションを割当てる

シェーダーエディターを使用して以下の方法で背景を変更する。

1. シェーダーエディターを開く
1. データタイプをワールドに変更
1. オブジェクトのシェーダーと同じようにシェーダーノードを編集していく

![shadar_editor.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/789bd9ff-e897-e93a-1386-906a5dac620b.png)


###単色の例

単純に色を変更するだけ。

![shader_node_mono_color.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/49a02fbe-9164-826c-2a2c-31c5d0419bc8.png)


###グラデーションの例

shift + a で以下のノードを追加

- カラー > 色相/彩度
- コンバータ > カラーランプ
- テクスチャ > グラデーションテクスチャ
- ベクトル > マッピング
- 入力 > テクスチャ座標

下図のように結線し、任意に設定を変える。

![shader_node_gradation_color.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/c34ab38d-f72e-15e8-017a-0b46f9bd6774.png)


#蛇足：テキトーなpngをテクスチャに設定すると…

以下のようなテキトーなpngをテクスチャにすると、不思議な世界に、、、

<img width="200" alt="backgrond.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/53636986-7a49-6bf4-0e0f-24820e47b900.png"> &emsp; &emsp;![snake_foot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682933/4204d73f-adb2-6b11-5e15-a65a490c5d3d.gif)


#参考
以下、シェーダーノードの公式サイト

[https://docs.blender.org/manual/ja/2.82/render/shader_nodes/index.html](https://docs.blender.org/manual/ja/2.82/render/shader_nodes/index.html)
_と__について

メモ程度に記載します。

## 「_関数」について

Pythonには事実上のPrivate属性が無いですが、_で関数を内部用に定義できる

```module/func.py
def _func():
  return something
```

```module/__init__.py
from .module import func
```

上記の場合、

```test.py
from module import *

print(func._func())
```

```
ImportError: cannot import name 'func' from 'module.func'
```

from M import * 　では一つのアンダースコアで始まる関数はインポートされません
しかし、

```module/func.py
class Net():

  def _func(self):
    return 'something'
```

```module/__init__.py
from .module import Net
```

上記の場合、

```test.py
from module import *

print(Net()._func())
```

呼び出せる。

つまり、`import *` の呼び出しの`__init__.py`で、

```module/__init__.py
from .module import _変数
```

という記述ができない為。

※重要
import *の記述でなければ、_func()は使用できる

## 「__関数」について

上記で説明した機能も勿論、合わせ持ち、ネームマングリング機構を呼び出す。
本来、ネームマングリング機構は
親クラスと子クラス間での名前衝突を避ける目的の為のもの。

```module/func.py
class Net():

  def __func(self):
    return 'something'
```

```module/__init__.py
from .module import Net
```

上記の場合、

```test.py
from module import *

print(Net()._Net_func())
```

_Net_func()の呼び出しに変わり、擬似的にprivate属性を作成できる

## 「\_\_関数\_\_」について

magic methodになる。

`__init__`や`__call__`、`__iter__`等既存のmagic methodがある。
これによって、クラスを綺麗に書ける。
普段の開発では自分で新しく定義しないようにする。
vue.js コンポーネントを作成する

コンポーネントは再利用可能なvueインスタンス。
何度も使うコードをコンポーネント化して再利用が簡単にできる。
受け取ったデータを処理して返すなどの処理もできるが、今回は文字を登録しておくだけ。


#コンポーネントファイルの作成
child.vue などの名前でコンポーネントファイルを作成する。
複数作っていくことになるのでプロジェクト内の/componentsフォルダに保存しよう。

```vuejs:child.vue
<template>
    <p>text here</p>
</template>

```

#コンポーネントの呼び出し
呼び出し元は"親コンポーネント"、呼び出される側は"子コンポーネント"と呼ばれる。

親側でまずはどんなコンポーネントがあるのか登録する必要がある。
コンポーネント登録の方法はグローバルとローカルの2種類。
## グローバル登録
main.jsに書きの記述で登録する。
`import`で外部ファイル（Child.vue）を読み込み、
`Vue.component()`で登録される。

```js:main.js
import Child from './components/Child.vue'
Vue.component('Child', Child);
```

## ローカル登録
親となるコンポーネントファイルの`<script>`タグ内で登録する。
こちらでも`import`で読み込み。
`export default {}`のコンポーネントプロパティに登録する。

```vuejs:parent.vue
<script>
import Child from "./components/Child"
export default{
  components: {
    Child
  },
};
</script>
```

#呼び出し
親コンポーネント側で、HTMLタグと同様の記述で呼び出し、ページに表示される。

```vuejs:parent.vue
<template>
<div>
  <Child></Child>
</div>
</template>
```


コンポーネント間でのデータのやり取りはまた別の記事で。
javascriptの標準入力

##javascriptで標準入力からデータを受け取る

・標準入力からデータを受け取る

例）「hello」というデータが渡される

```javascript
process.stdin.resume();
process.stdin.setEncoding('utf8');

var lines = []; ; //標準入力から受け取ったデータを格納する配列
var reader = require('readline').createInterface({　//readlineという機能を用いて標準入力からデータを受け取る
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (lines) => {　//line変数には標準入力から渡された一行のデータが格納されている
   lines.push(lines);　//ここで、lines配列に、標準入力から渡されたデータが入る
});
reader.on('close', () => {　//受け取ったデータを用いて処理を行う
  console.log(lines)　//helloが出力される
}

```

##受け取ったデータの処理

●整数化する
例）「1」が標準入力から与えられている場合

```javascript
(...)
reader.on('close', () => {　//受け取ったデータを用いて処理を行う
  var n = parseInt(lines[0]); //「1」を整数として処理できるようになる
}
```

●データをコンマで分解する
例）「1,2」「3,4」というデータが与えられた場合

```javascript
(...)
reader.on('close', () => {　//受け取ったデータを用いて処理を行う
 var Arr1 = lines[0].split(',') //Arr1配列に「1」「2」が格納される
 var num_Arr1 = Arr1.map(function(str){
        return Number(str);  //num_Arr1配列内に、Arr1配列を整数化したものを格納
});

 var Arr2 = lines[1].split(',')　//Arr2配列に「3」「4」が格納される
 var num_Arr2 = Arr2.map(function(str){ //num_Arr2配列内に、Arr2配列を整数化したものを格納
        return Number(str);)
});
}

```
※[map()メソッドとは](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map )
> map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します

●応用編
※Teratailで質問した際にいただいた回答をQiitaでまとめています
https://teratail.com/questions/256288

```javascript
(...)
reader.on('close', () => {
lines.map(e => e.split(',')).flat().map(e => +e);
})
```
・上記のコードで行っていること
①「e」（elementの略）という仮配列に、「1,2」「3,4」をコンマで分割した値をいれる。
※e配列の中身：[[1 2][3 4]]

②[.flat()メソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) を用いて配列の深さを揃える
※e配列の中身:[1 2 3 4]

③mapメソッドを用いて、e配列に整数化したe配列を代入する
単項算術演算子 (+、-、++、--) はすべて、必要に応じてオペランドを数値に変換するという特性がある為、「(e => +e);」という処理で整数化を行える。

↓
mapメソッドによって以上の処理をした中身がlines配列に代入される。
lines配列の中身は
[1 2 3 4]に更新される。
GASを使ってオートフィルする

# 説明
  reference_rangeにはパターン生成の参照元となる範囲を指定します。
  effect_rangeには、パターンが影響する全体（その際、範囲はreference_rangeも含まれている必要があります）を指定します。

```
  const Sheet = SpreadsheetApp.openById('YOUR_SPREAD_ID).getSheetByName('YOUR_SHEET_NAME');
  const last_row = Sheet.getLastRow();
  const reference_range = Sheet.getRange(1,1,last_row, 1);
  const effect_range = Sheet.getRange(1,1, last_row + 1, 1);
  reference_range.autoFill(effect_range, SpreadsheetApp.AutoFillSeries,DEFAULT_SERIES);

```
【AWSアカウント】MFAの設定

## MFAとは
**Multi-Factor Authentication**（**多要素認証**） の略

アカウントへのログイン時に、利用者のユーザー名とパスワードに加え、利用者が所有するAWSのMFAデバイスから発行されるワンタイムパスワードの入力が必要になる

## 1. MFAを有効化する
<img width="1440" alt="スクリーンショット 2020-08-02 22.04.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/2a2c3734-e74c-8537-83ce-52dd7ec8c2d1.png">
![スクリーンショット 2020-08-16 10.36.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/c7528d28-070d-b8c9-53c4-1404657fa588.png)

## 2. MFAデバイスタイプを選択する
スマートフォンやタブレットにアプリケーションをインストールして使用する「**仮想MFAデバイス**」を選択
<img width="1440" alt="スクリーンショット 2020-08-02 22.13.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/8f5adb5d-d138-ca5e-c115-0d7d7c9ed901.png">

## 3. 「Google Authenticator」をインストールする
MFAに使用するアプリケーション
<img width="318" alt="スクリーンショット 2020-08-02 22.29.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/bca6500e-bd02-cad6-0ed5-8bbe3bf93bb9.png">

## 4. MFAを割り当てる
Google AuthenticatorでQRコードを読み取り、MFAコードを2つ入力
<img width="1440" alt="スクリーンショット 2020-08-02 22.22.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/d9861f60-5c60-114a-5564-5e9258de0fa0.png">

### 割り当て完了
![スクリーンショット 2020-08-16 10.15.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/41cec541-61bf-58cd-3eec-5f1ccfcf04b3.png)
フォームで送信した内容を任意のスプレッドシートに反映する

# 前提
  ひとつのスプレッドシートに複数のフォームが紐づいていることを想定しています。そのため、if文で、反映したいフォームにしかない質問内容が存在するか否かを判定しています。

```

const insertData = (e) => {
  if (e.namedValues(['KEYWORD']){
    const keyword = e.namedValues['keyword'];
    const information = e.namedValues['information'];
    const spread_id = 'YOUR_SPREAD_ID';
    const sheet_name = 'SHEET_NAME';
    const SpecificSheet = SpreadsheetApp.openById(spread_id).getSheetByName(sheet_name);
    const last_row = SpecificSheet.getLastRow();

    SpecificSheet.getRange(last_row + 1, 1).setValue(keyword);
    SpecificSheet.getRange(last_row + 1, 2).setValue(information);
  }
}

```