OmniAICreator/Qiita-1.07M huggingface dataset:
ChatworkとGoogleAppsScript連携


#やりたいこと
GoogleAppsScriptを使ってチャットワークにメッセージを送りたい！

#構成
- Chatwork
- GoogleAppsScript
    - chatwork-client-gas

#１. Chatworkのアクセストークンを取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/5f7ac61a-9eb4-bf03-b94f-d4d2342aac13.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/dc151181-f578-11b1-44a0-c0ee4a99f184.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/31bc4835-d70a-b6b9-fbe9-5303b55f3856.png)

#２. チャットワークのAPIを使ってメッセージを送る
GoogleAppsScriptを使ってチャットワークへメッセージを送るには「**chatwork-client-gas**」が必要です。
下記リンクからプロダクションコードを取得します。

[chatwork-client-gas](https://github.com/cw-shibuya/chatwork-client-gas)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/3ad6ffa4-90f8-a128-8063-cd14853ded8b.png)

GoogleAppsScriptに下記コマンドを入力

```
function myFunction() {
  var client = ChatWorkClient.factory({token: '取得したトークン'});
  var message = 'テストメッセージ送信';
  client.sendMessageToMyChat(message);
}
```

#３．実行
実行時、認証が出ますがOKを押して実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/36b1ef62-79f0-8ad4-3c8c-47248399ac19.png)

問題なければメッセージがチャットワークへ送れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634739/c1571229-4fbb-a365-e95c-4f38c8d9f617.png)


これを使えばカレンダーの通知等をチャットワークで通知するような仕組みもできそうですね。
fcgi コマンドでターミナルから php-fpm(FastCGI)の動作を確認する


以下の記事とほぼ同じ内容ですが、Mac OS X で確認したときのメモ。

[php-fpm の動作確認](https://qiita.com/iitenkida7/items/eace6fae2b907e527a63)
[Directly connect to PHP-FPM](https://easyengine.io/tutorials/php/directly-connect-php-fpm/)

# やりたかったこと

+ nginx から FastCGI で php-fpm へ接続するテストをしたい
+ php-fpm のみの動作を確認したい
+ php-fpm は HTTP ではないので `curl` で確認できない

# 対応方法

`cgi-fcgi` というコマンドで FastCGI の確認ができるようなので使ってみる。
Mac OS X ならインストールは HomeBrew で可能。

[fcgi](https://formulae.brew.sh/formula/fcgi)


```bash
$brew install fcgi
```

実際に確認してみる。

```bash
$docker run -p 9000:9000 -d  php:7-fpm

# cgi-fcgi を利用した接続テスト
$REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000
X-Powered-By: PHP/7.4.6
Content-type: text/html; charset=UTF-8

# ログより接続を確認
$docker logs 187afd220bc3
[06-Jun-2020 08:25:09] NOTICE: fpm is running, pid 1
[06-Jun-2020 08:25:09] NOTICE: ready to handle connections
172.17.0.1 -  06/Jun/2020:08:25:16 +0000 "- " 200
```
Ubuntu18.04LTSで、apt-get update時にis not valid yet (invalid for another 6h 56min 10s). Updates for this repository will not be applied.エラーが出た時の解決方法

Ubuntu18.04LTSで、apt-get update時にis not valid yet (invalid for another 6h 56min 10s). Updates for this repository will not be applied.

```
$ sudo apt-get update
E: Release file for http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease is not valid yet (invalid for another 6h 56min 10s). Updates for this repository will not be applied.
E: Release file for http://us.archive.ubuntu.com/ubuntu/dists/bionic-updates/InRelease is not valid yet (invalid for another 6h 56min 22s). Updates for this repository will not be applied.
E: Release file for http://us.archive.ubuntu.com/ubuntu/dists/bionic-backports/InRelease is not valid yet (invalid for another 6h 56min 48s). Updates for this repository will not be applied.
```

時刻がずれている事が原因のため、時刻を補正して解決


# 参考
[Windows10とのデュアルブートでUbuntu18.04をいれていて、firefoxは使えるが、端末上でコマンドパッケージをダウンロードしようとしても接続エラーとなり、ダウンロードできません。](https://forums.ubuntulinux.jp/viewtopic.php?id=20171)
[Ubuntu 18.04LTSで # apt update 失敗 → 設定変更により、修正完了](https://kunpu1306.hatenablog.com/entry/2018/10/14/095340)
[Ubuntuでの時刻同期について](https://www.yokoweb.net/2018/05/14/ubuntu-18_04-timesyncd/#toc1)
[Ubuntuで時刻同期の設定 (timesyncd.conf)](https://qiita.com/tukiyo3/items/c847d443a6d977083de9)
[時刻合わせにNTPdではなくsystemd-timesyncdを使うようにした話](https://science-as-a-candle-in-the-dark.hatenablog.com/entry/2018/10/24/200604)
[Mac のターミナル上で OS の時刻情報を確認・変更する方法](https://gotohayato.com/content/121/)
Ubuntu で Git の最新を使う

# git の バージョン

git をインストールすると、Ubuntu 20.04 の場合は、2.25.1 が入ります。(Ubuntu 18.04 は、2.17.1) 

```bash
$ sudo apt install git
$ git version
git version 2.25.1
```

最新のGitを使いたい場合は ppa をリポジトリに追加すればOKです。

# PPAを追加して git を更新する

ここでは、stable 版の ppa をリポジトリに追加していきます。

```bash
$ sudo add-apt-repository ppa:git-core/ppa
$ sudo apt update
$ sudo apt upgrade
```



# 現時点の最新

```bash
$ git version
git version 2.33.1
```
最新版 git 2.33.1 が無事入りました。






## トラブルシューティング
### ERROR: '~git-core' user or team does not exist. が出る場合

```bash
$ sudo add-apt-repository ppa:git-core/ppa
Cannot add PPA: 'ppa:~git-core/ubuntu/ppa'.
ERROR: '~git-core' user or team does not exist.
```

プロキシー環境下の場合に発生することがあります。
環境変数 http_proxy や https_proxy を引き継ぐようにするため sudo に -E オプションを渡すと良いです。

```bash
$ sudo -E add-apt-repository ppa:git-core/ppa
```


# 参考
* https://launchpad.net/~git-core/+archive/ubuntu/ppa
デュアルブートPCの物理ボリュームをOS間で共有する。

## 要約
デュアルブート環境でWindowsとLinux双方から扱える物理ボリュームの設定をします。
NTFS指定， Fast Bootをオフにすること。

## 環境
2つの物理ボリュームにWindows10， Xubuntuを別々にインストール済み。 ブートローダはgrub2。
物理ボリュームを1つ追加してデータを双方のOSで共有したい。

## フォーマット
基本的にボリュームのフォーマットはWindows上から行うことをおすすめします。
ファイルシステムはNTFSを指定しましょう。 ほとんどのLinuxディストリビューションでは最初からNTFSマウントに対応しています。

### 完了？
一応これで両OSから認識されるようになりますが， Linux上からの書き込みがロックされてしまいます。

### 原因
WindowsのFastBoot機能によってデバイスの状態がロックされてしまうことが原因です。 この状態でLinuxから無理に書き込みを行うとWindowsの起動に失敗する可能性もあります。

## FastBoot(高速スタートアップ)の無効化
コントロールパネルの [ハードウェア設定->電源オプション->電源ボタン設定] 内の [現在利用可能ではない設定を変更します] を選択することで， [高速スタートアップを有効にする] のチェックを外します。

## 完了
再起動し， 両方のOSからボリュームを操作できることを確認しましょう。
Ubuntu18.04LTSでSambaサーバの起動時にFailed to start Samba SMB Daemon

Failed to start Samba SMB Daemon

Ubuntu18.04LTSでSambaサーバの起動に失敗

```
[1]: Starting Samba SMB Daemon...
 systemd[1]: smbd.service: Main process exited, code=exited, status=1/FAILURE
 systemd[1]: smbd.service: Failed with result 'exit-code'.
 systemd[1]: Failed to start Samba SMB Daemon.
```

以下のconfファイルの記述に失敗していただけでした。。
記述を見直して解決

```
/etc/samba/smb.conf
```

#参考
[フルアクセスの共有フォルダ作成](https://www.server-world.info/query?os=Ubuntu_16.04&p=samba)
[sambaが起動しない](https://www.run-the-earth.com/archives/11864)
[技術メモ] クッキーとセッションの違い


主にステートフル(※)な通信を実現するためにそれぞれ利用されます。

※ステートフルとは
システムが現在の状態を表すデータなどを保持しており、その内容を処理に反映させる方式。
 同じ入力に対する出力が常に同じとは限らず、内部の状態次第で変わることがある。

##クッキー
サーバーからクライアント側に付与する情報（セッションID）の仕組み

##セッション
サーバー側に保存される一連の操作や通信のこと

詳しくはこちら
↓　↓　↓
http://ohs30359.hatenablog.com/entry/2015/09/04/235027
1e18はlong long型の変数に格納する

##結論
`long long a = 1e18;`
と書きます。

##起きたこと
変数aが1e18を超えるか判定する文を書きたかった。
`if(a > 1e18)`
みたいに書いたのですが、aに`1000000000000000001`が入った時にうまく分岐ができていないことに気づいた。

##原因
`typeid(1e18).name()`で調べたところdoubleと返された。
`1e18`は浮動小数点数であり、doubleの精度が大体15桁であることからこのようなことが起きたと考えられる。

`1000000000000000000`と書けばこんな事例が発生することはないのだが、見にくいため書かない方が良いと思う。
`1e18`と書いてlong longの変数に入れてあげるのが良いと考えた。

##コード

```cpp

#include <iostream>
using namespace std;

int main()
{
    long long a = 1e18;
    long long b = 1000000000000000000;
    long long e = 1000000000000000001;

    cout << typeid(1e18).name() << endl;

    cout << "1e18を変数に入れない" << endl;

    cout << (1e18 < e) << endl;
    cout << (1e18 > e) << endl;
    cout << (1e18 == e) << endl;

    cout << "1e18をlong long型の変数にいれる" << endl;

    cout << (a < e) << endl;
    cout << (a > e) << endl;
    cout << (a == e) << endl;

    return 0;
}

```

##参照
[浮動小数点数型と誤差](https://www.cc.kyoto-su.ac.jp/~yamada/programming/float.html)
シェルスクリプトで変数に値が格納されているか判定する際に間違いやすいこと...


変数に値が格納されているか判定する際は以下のようにすることが多いが、

```shell:test.sh
#!/bin/bash -x

HOGE="hoge"
if [ -n "$HOGE" ]; then
    echo "correct" # こちらに分岐するのが正しい
else
    echo "wrong.."
fi

HOGE=""
if [ -n "$HOGE" ]; then
    echo "wrong.."
else
    echo "correc" # こちらに分岐するのが正しい
fi
```

```
$ bash test.sh
correct
correct
```

if文に空白忘れやダブルクオーテーション忘れがあると分岐を間違うので注意

```shell:test.sh
#!/bin/bash -x

# 空白忘れ...
HOGE="hoge"
if [ -n "$HOGE"]; then
    echo "correct" # こちらに分岐するのが正しい
else
    echo "wrong..."
fi

# ""ダブルクオーテーション忘れ...
HOGE=""
if [ -n $HOGE ]; then
    echo "wrong..."
else
    echo "correct" # こちらに分岐するのが正しい
fi
```

```
$ bash test.sh
wrong...
wrong...
```

システム障害に繋がりかねない...
root権限を使用するための簡単な設定方法

　　　　　　ラズパイを扱っていく上でルート権限は必要不可欠。
　　　　　　設定しておかないと本当に詰むことだってありますよ！

# 　　設定方法

```ruby:pi@raspberrypi:~
＄ sudo passwd
新しい UNIX パスワードを入力してください:
新しい UNIX パスワードを再入力してください:
passwd: パスワードは正しく更新されました
```
######　　　　※注意

　　　　　　打ち込んだパスワードは表示されません！
　　　　　　間違いのないようにしてくださいね。

`この情報は役に立ちましたか？
　- [x] はい`
DynamoDBのRead操作まとめ（Node.js）

## 概要

使っててよくわからなくなったのでまとめます。

Python用のドキュメントですけど基本はここを参照してます。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html

検索範囲は `get_item` < `query` < `scan` なので、いかにして`scan`を使わないようにするかがテーブル設計のミソになります。

## get_item

主キーを指定して値を抜いてきます。
複合主キーを指定している場合は両方指定する必要があります。

値は取れないか1個取れるかの二択。

```js
    const result = await dynamo.get_item({
      TableName: YOUR_TABLE_NAME,
      Key:{
        'group_id': groupId,
      },
    }).promise();

    if (!result.Item) {
      return []
    }

    const members = result.Item.members.values;
```

## query

主キーのうちパーティションキーのみを指定してデータを抜いてきます。
ソートキーで絞り込みをかけれるのがミソ。

```js
    const result = await dynamo.query({
      TableName: YOUR_TABLE_NAME,
      ExpressionAttributeValues: {
        ":group_id": groupId
      },
      KeyConditionExpression: "group_id = :group_id"
    }).promise();

    const memberIds = result.Items.map(record => record.member_id);
```

## scan

データを全部ぶち抜いてきます。
一応Filter構文を使えば絞り込みはできますが、全部走査かかるので最終手段。

(後で書く)
dockerチュートリアル 使ってみた

こんにちは、sonmasayoshi14です。都内のベンチャーでサーバサイドエンジニアやっております。プログラミング始めてから2年2ヶ月ほど。
とりあえず、毎週なにかしらをqiitaに書くということを目標にやっています。

もう2年も経っているのに、dockerというものについて何も知らない！
ということで、とりあえずチュートリアル触ってみました。詳しい人いれば教えてくれると踊ります。

チュートリアル 
https://docs.docker.com/get-started/

1.動画を見る
2.dockerとは 
dockerはアプリケーションをビルド、実行、共有するためのプラットフォームであるらしい。そして、それはコンテナとともに行われるようだ。

```
Fundamentally, a container is nothing but a running process, with some added encapsulation features applied to it in order to keep it isolated from the host and from other containers. One of the most important aspects of container isolation is that each container interacts with its own private filesystem; this filesystem is provided by a Docker image. An image includes everything needed to run an application - the code or binary, runtimes, dependencies, and any other filesystem objects required.
```

- dockerはrunnning process
- ホストや他のコンテナから隔離されている
- それぞれのコンテナはprivateなファイルシステムを持っている(Docker imageによってもたらされているらしい)
- docker imageは全てを含んでいる。
  - code,binary,runtimes,dependencies, and any other filesystem objects required

- 仮想マシンとの違いは? 
  - 仮想マシンはゲストOSを動かして、その上でアプリケーションを動かす
  - dockerはOSはhostのものをそのまま使う。カーネルもhostとシェアして使う

なるほどなぁ(白目)

3.dockerのsetup
PCにアプリケーションをダウンロードするだけ。

4.ビルドしてみる
githubからサンプル用の物を引っ張ってきた。

tagをつけてビルド！

```
docker build --tag bulletinboard:1.0 .
```

imageを指定して、コンテナを動かしてみる！

```
docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0
```

publishはhostないのportとdocker内のportを両方指定できる。
detachaはbackgroundで動かすoption

localhost:8000にアクセスしたら、ブラウザにform(サンプル用のもの)が表示された！

コンテナを止めたい時はdocker stop、コンテナを削除したい時はdocker rmだ！

5.docker hubにpushしてみよう！
docker loginして、docker pushすればimageをpushして管理できる。
いつでもpullもできるよ！


ということで、buildとコンテナの実行と共有ができることはわかった。もうちょい簡単なコードないかなぁ。
おすすめの入門法があれば教えてください！
【python】listの中身を左にローテートするプログラム

#【python】listの中身を左にローテートするプログラム

自分用のメモです。


▼設問

- listの中身を指定された整数分、左側に回転させる。


[URL](https://www.hackerrank.com/challenges/ctci-array-left-rotation/problem)


▼sample input

```python:
a=[1,2,3,4,5]
d=4
```

▼sample output

```python:
[5, 1, 2, 3, 4]
```

▼my answer

```python:
def rotLeft(a, d):
    c = a[d:]
    d = a[0:d]
    return c+d

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    nd = input().split()
    n = int(nd[0])
    d = int(nd[1])
    a = list(map(int, input().rstrip().split()))
    result = rotLeft(a, d)
    fptr.write(' '.join(map(str, result)))
    fptr.write('\n')
    fptr.close()
```


<br>
##ハマったこと
extendメソッドでlistを結合したところ、戻り値がNoneになった。

```python:
a=[1,2,3,4,5]
c =a[4:]
d =a[0:4]

print(c.extend(d))

#Noneになる。
```

ググった限り、extendメソッドでも結合できそうだったのに、、

理由がわかりましたら教えていただけると嬉しいです。
Nginx経由でCVE-2018-17082脆弱性を攻撃する手法に関する個人的なメモ

以下は、特に公表を目的としない個人的な備忘録であるが、公開のメモであるので、もちろん指摘やコメントなどは歓迎する。
PHPの脆弱性 CVE-2018-17082 についてYouTube動画を制作するために、この脆弱性についてあらためて調べているが、Nginxをキャッシュサーバーにしている（リバースPROXYとしてNginxを使っている）場合の挙動についてきちんと調べていなかったので調べ直した。主に以下の記事に関係する。

[PHPの脆弱性 CVE-2018-17082 によるキャッシュ汚染についての注意喚起](https://blog.tokumaru.org/2018/09/cve-2018-17082-cache-poisoning.html)

ブラウザ　&lt;--> リバースプロキシ(Nginx) &lt;--> Apache2 + PHP という構成を前提としている

今までの調査で、Nginxが挟まっている場合攻撃が刺さらないことは判明しているが、なぜ刺さらないかを追っかけきれていなかった。

NginxとApacheの間の通信をキャプチャするには、tcpdumpを使うのが一般的だろうが、ちょっと面倒くさいなと思っていたところ、Apacheのリクエストを調べるだけならApacheの代わりにNetcatを使えば簡単じゃねと思いたち、さっそくやってみた。
徳丸本VMではApacheは88ポートで動いているので、以下のコマンドでApacheを停止してNetcatで88ポートで待ち受ける。

```
$ sudo systemctl stop apache2
$ sudo nc -l -p 88
```

この状態で、Nginxに以下のリクエストを送信する。

```
GET http://example.jp/31/31-001.php HTTP/1.1
User-Agent: Mozilla/5.0
Content-Length: 44
Transfer-Encoding: chunked
Host: example.jp

5 <script>alert('Hacked')</script>
ABCDE
0

```

Content-LengthヘッダとTransfer-Encodingヘッダを重ね打ちするのが、HTTP Request Smuggling(HRS)の攻撃手法である（[参考動画](https://www.youtube.com/watch?v=VUBR1rVAquw)）。ちなみに、チャンク長5の後の文字列はRFC 7230ではChunk Extensionsという扱いになると思う（参考: [Chunk Extensions](https://tools.ietf.org/html/rfc7230#section-4.1.1)）。
だが、Netcat側の表示は下記となる。

```
$ sudo nc -l -p 88
GET /31/31-001.php HTTP/1.1
Host: example.jp
X-Real-IP: 192.168.56.1
X-Remote-Addr: 192.168.56.1
X-Forwarded-For: 192.168.56.1
Connection: close
Content-Length: 5
User-Agent: Mozilla/5.0

ABCDE$
```

NginxはHTTPリクエストのContent-Lengthヘッダを無視し（これはRFC的に正しい挙動）て、Transfer-Encoding: chunkedを正しく解釈しているが、ApacheへのリクエストはContent-Length形式に変更している。リクエストの意味は同じなので、これでよいわけだ。
では、Transfer-Encoding: chunkedなリクエストを送信するにはどうすればよいか調べてみると、Nginxの設定として以下を指定すればよいことがわかった。

```
proxy_request_buffering off;
proxy_http_version 1.1;
```

参考: [Module ngx_http_proxy_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering)

これを指定して同じHTTPリクエストを投げるが、挙動はまったく変わらない。そうか、Nginxはリクエストをすべて受け取り終わっているから、Transfer-Encoding: chunked形式を使う必要がないのだ。
それでは、というわけで、途中までHTTPリクエストをNginxに投げてみる（読者むけ注記: ここからがハイライトです）。

```
GET http://example.jp/31/31-001.php HTTP/1.1
User-Agent: Mozilla/5.0
Content-Length: 41
Transfer-Encoding: chunked
Host: example.jp

5 <script>alert('Hacked')</script>
ABCDE
```

すると、目論見通り、Chunked Encodigが終端されていないので、NginxはApacheにChunked Encodingのリクエストを投げる

```
$ sudo nc -l -p 88
GET /31/31-001.php HTTP/1.1
Host: example.jp
X-Real-IP: 192.168.56.1
X-Remote-Addr: 192.168.56.1
X-Forwarded-For: 192.168.56.1
Connection: close
Transfer-Encoding: chunked
User-Agent: Mozilla/5.0

5
ABCDE
```

だが、二重の意味で攻撃には至らないことが分かった。

- Content-Lengthが削除される（RFC的には正しい挙動）
- チャンク長の後のscriptタグ(Chunk Extensions)が削除される

攻撃のためには、どちらも欠かせないのだが、両方消されてしまうので、Nginx経由での攻撃は見込みがないと判断した（あっけないエンディング）。
VSCode にPython仮想環境を追加する

# はじめに
venvで作成した仮想環境が，Visual Studio Codeの"select interpreter"で表示されずつまづいたのでメモしておきます。

## 前提
- macOS Catalina 10.15.5
- Visual Studio Code 1.45.1
- Python 3.8.2

# Pythonの仮想環境作成
Pythonの仮想環境作成にはvenvを使用しました。最新のPythonであれば標準で実装されています。詳しくは[こちら](https://docs.python.org/ja/3/library/venv.html)。

仮想環境を作ります。将来的に複数の仮想環境を用意することを想定して，"python_envs"というフォルダを用意して仮想環境をまとめました。機械学習と画像処理用の環境なので，名前は"mlcv"です。

```
python3 -m venv python_envs/mlcv
```

# VSCodeの仮想環境読み込み先を設定
"python_envs"に作った仮想環境をVSCodeが自動で読み込むよう設定します。
``command + ,`` で設定画面を開き，"venv folders"と検索します。

![Screen Shot 2020-06-06 at 17.02.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281326/a4235fdd-1aef-ae50-7d94-87fe1bad7d01.png)

"Add Item"をクリックし，"python_envs"のパスを入力して完了。

![Screen Shot 2020-06-06 at 17.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281326/74a254a5-58cd-74e4-772b-5a2419f135e5.png)

``shift + command + p``でコマンドパレットを開き，"select interpreter"を実行するとPython環境の一覧が表示されます。一番下に先程作成した仮想環境"mlcv"が追加されました。
【プログラミング初心者】Swift練習問題~繰り返し１~ 回答例

以下で投稿した問題の回答例です。
https://qiita.com/euJcIKfcqwnzDui/items/f87eea73729284757711

#練習問題
##練習問題１
### 回答例
```swift
func printTexts(texts: [String]) {
    for text in texts {
        print(text)
    }
}
```
### 解説
引数として受け取った`texts`を１つずつ取り出し、取り出した`text`を`print()`で出力しています。

##練習問題２
### 回答例
```swift
func printTexts(texts: [String]) {
    var index = 0
    while index < texts.count {
        print(texts[index])
        index += 1
    }
}
```
### 解説
`index`を配列番号として定義しています。
1ループごとに`index += 1`し1ずつアクセスする配列番号を移動させていきます。
ループの継続条件は`index < texts.count`としています。
配列の要素数が３個の場合`texts.count == 3`です。
初回ループのとき`index == 0`なので`index < texts.count`、つまり「0 < 3」の結果はtrueとなり処理ブロックに入ります。
`index += 1`で`index`の値を更新します。
２回目のループは「1 < 3」、３回目ループは「2 < 3」となりtrue。
４回目ループでは「3 < 3」でfalseとなるためループ処理には入らず終了となります。

注意したいのは`index <= texts.count`としないことです。
「3 <= 3」はtrueなので４ループ目に入ります。
配列番号は0~[要素数 - 1]なので`texts[3]`は存在しません。
存在しない要素にアクセスするとクラッシュします。

##練習問題３
### 回答例
```swift
func printCombine(texts: [String]) {
    var combinedText = ""
    for text in texts {
        combinedText = combinedText + text
    }
    print(combinedText)
}
```
### 解説
最終的に表示する内容として`combinedText`を定義しています。
ループ処理の中で`combinedText = combinedText + text`として`combinedText`の値を更新していきます。
`text`が`["Hello", "World", "!"]`とすると
１ループ目で`combinedText`は「Hello」、２ループ目で「HelloWorld」...のように更新されています。

#応用問題
##応用問題１
### 回答例
```swift
func printLoop(text: String, loop: Int) {
    var index = 0
    while index < loop {
        print(text)
        index += 1
    }
}
```
または

```swift:別解
func printLoop(text: String, loop: Int) {
    for _ in 0..<loop {
        print(text)
    }
}
```
### 解説
応用と位置づけましたが【練習問題２】と内容は変わりません。

別解の方は`0..<loop`することで`[0, 1, 2, ..., (loop - 1)]`の整数配列を作っています。
その配列数の個数分ループを回しています。
取りだした値自体は使用しないので`_`としています。
Swiftではこちらの書き方が一般的です。

##応用問題２
### 回答例
```swift
func power(_ base: Double, exponent: Int) -> Double {
    var result = 1.0
    if exponent >= 0 {
        for _ in 0..<exponent {
            result = result * base
        }
    } else {
        let absoluteExponent = -exponent
        for _ in 0..<absoluteExponent {
            result = result / base
        }
    }
    
    return result
}
```
### 解説
べき乗の特性として指数の値が正、負、０によって計算の仕方がことなります。
そのため`if`文を使ってそれぞれ場合分けをしてあげます。
####exponentが0の場合
`exponent`が0の場合、数値の０乗は１なので`result`の初期値として１を入れています。
`exponent >= 0`はtrueとなり`if`の処理ブロックに入りますが、`0..<0`の要素数は０なのでそのまま`for`の処理ブロックには入らず`return result`となり１がそのまま返ります。
`if exponent == 0 { return 1 }`と明示的に処理を書いてあげてもOKです。

####exponentが正の場合
`exponent`が正の場合、べき乗は指数の数だけ元の値を掛けていくという計算なので`exponent`の回数掛け算を行ないます。

####exponentが負の場合
`exponent`が負の場合、指数の絶対値の回数分元の値で割るという計算になります。
従って`result = result / base`という処理になります。
`let absoluteExponent = -exponent`では符号を反転させています。
符号を反転させず`0..<absoluteExponent`とするとSwiftはクラッシュします。
符号を反転させず`exponent..<0`としてあげても正解です。
この場合`exponent..<0`は`[exponent, exponent -1, ..., -1]`という配列を返します。

#最後に
別の問題は以下に掲載しています。
また本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載も以下にまとめていますのでそちらも是非もご覧ください。
アジェンダ：https://qiita.com/euJcIKfcqwnzDui/items/0b480e96166e88945684
pydrive を使って 共有ドライブにアップロードする方法


個人 G Drive にアップロードする系を多かったものの、共有の G-Drive に関する記事はなかったので投稿しました。
初投稿。ウェイ。


## 必要なモノ
- GCP の OAuth ID / Password
	- GCPコンソールにアクセス
	- プロジェクトがなければプロジェクトを作成
	- API & Services > Credential
	- +Create Credentials > OAuth Client ID
	- Oauth Client ID を作成

- PyDrive
```
pip install PyDrive
```

- 以下のスクリプト `settings.yaml` を作業ディレクトリに置く

```settings.yaml

client_config_backend: settings
client_config:
  client_id: <ID>
  client_secret: <PASS>

save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json

get_refresh_token: True

oauth_scope:
  - https://www.googleapis.com/auth/drive.file
  - https://www.googleapis.com/auth/drive.install

```

## フォルダの作成
```test.py
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)

drive_id = "0XXXXXXXXXXXXXVA" #confirm from url
folder_id = "XXXXXXXXXXXXXXXXXXXXXXXXht" #confirm from url

directory = "workdir"

file_metadata = {
'title': directory,
'mimeType': 'application/vnd.google-apps.folder',
'parents': [{
  'id': folder_id,
  'kind': 'drive#fileLink',
}],
}
f = drive.CreateFile(file_metadata)
f.Upload(param={'supportsTeamDrives': True})
```

ここがミソ
`f.Upload(param={'supportsTeamDrives': True})`

## ファイルのアップロード
```test.py
file_name = "test.csv"
file_metadata = {
        'title': "filename_at_gdrive.csv",
        'mimeType': 'text/csv',
        'parents': [{
            'id': folder_id,
            'kind': 'drive#fileLink',
            }],
    }
f = drive.CreateFile(file_metadata)
# use SetContentFile for attach and upload
f.SetContentFile(file_name)
# always apply param when upload
f.Upload(param={'supportsTeamDrives': True})
```

## フォルダ・ファイル情報取得

```test.py
query_list = [
"title='{}'".format("2020.csv"),
"mimeType = 'application/vnd.google-apps.folder'",
"'{}' in parents".format(folder_id),
"trashed=false",
]
query = " and ".join(query_list)

# always specifiy team drive when accessing shared drive
file_list = drive.ListFile({
'q':query,
'supportsAllDrives':True,
'corpora': "teamDrive",
'teamDriveId': drive_id,
'includeTeamDriveItems': "true",
'supportsTeamDrives': "true",
}).GetList()
```



## 参考文献
|type|style|
|----|-----|
|gdrive api 方法|https://qiita.com/akabei/items/f25e4f79dd7c2f754f0e <br> https://python.keicode.com/advanced/pydrive.php|
|credentails|https://console.developers.google.com/apis/credentials?project=revcomm-common|
|folder id 取得方法|https://ploi.io/documentation/mysql/where-do-i-get-google-drive-folder-id#:~:text=Getting this folder ID is,be put in that folder.)|
|folder 配下 にファイルを格納する方法|https://developers.google.com/drive/api/v3/folder <br> https://stackoverflow.com/questions/46562255/python-upload-my-own-files-into-my-drive-using-pydrive-library| 
|support all drive|https://stackoverflow.com/questions/56452507/how-to-upload-file-to-group-drive-shared-drive-with-google-drive-api-v3|
|共有ドライバに格納する方法|https://github.com/gsuitedevs/PyDrive/issues/149|
|mimetype|https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types|
|gdrive query 取得方法|https://pythonhosted.org/PyDrive/filelist.html|
Linux でPDFの解像度や詳細情報を表示する方法（pdfinfo）

#Linux でPDFの解像度や詳細情報を表示する

MacなどではProperty を表示したらそのファイルの情報がみれ、もちろんPDFの詳細情報も確認でき解像度を表示させることが出来ます。

しかしながらLinuxだと標準状態ではそれが出来ないため今回はterminalからpdfinfoを用いて簡単に表示する方法を紹介します。

## 1. pdfinfo をインストールする。
```
sudo apt-get install poppler-utils
```
参照
https://github.com/howtomakeaturn/pdfinfo

## 2. 実行する
実行したいファイルのあるフォルダまで移動して
terminalから以下を実行します


```
pdfinfo 実行したいファイル名.pdf
```

とすると

![Screenshot_2020-06-06_17-05-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593429/25974dea-d5ec-7731-3bc8-6ade868ddba9.png)



と結果が表示されたら成功です！
[Angular勉強メモ]（１）プロジェクトを作ってみる

### Angularとは
　　Angular（アンギュラー）は、Googleと個人や企業のコミュニティによって開発されているTypeScriptベースのオープンソースのフロントエンドWebアプリケーションフレームワークである。

### 環境準備
 予めtypescriptの知識を持っていればいいです。

- Angular4
- angular/cli: 1.1.0
- nodejs: 12.10.0
- 開発IDE:WebStorm

### プロジェクトを作る
  今回はAngularとAngular Materialを活用してプロジェクトを管理するためのアプリを作ってみよう。
　まずは下記のコマンドの通り、Angualrプロジェクトを自動に作成します。

> ng new projectname
> 例：ng new tasker

以下のようにログを出力したら、正常に終ります。

```typescript:
......
Successfully initialized git.
Installing packages for tooling via npm.
Installed packages for tooling via npm.
Project 'tasker' successfully created.
```
### Angular Materialを導入
下記のコマンドで必要なAngular Materialを導入する。
> npm install --save @angular/material

### 起動
下記のコマンドでプロジェクトを起動する。
> ng serve

うまく起動すれば、localhost:4200経由でアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/32d20ead-59af-f9cb-b5a7-93079371f985.png)

### 最後に
最後まで読んでいただき、ありがとうございます。
ソースコードは[こちら](https://github.com/Hyman1993/tasker)でダウンロードできます。

参考：https://material.angular.io/guide/getting-started
キーペアのないEC2運用

# キーペアというネックポイント

EC2を作成すると、通常はキーペアを使用してSSH接続するかと思います

誰もが使用する22番ポートへの攻撃は、SecurityGroupでIPを絞るなどの対応ができますが
キーペアを紛失してしまうとあまりよろしくない。

AWSのSystemsManagerではセッションマネージャーというものがあり、
AWSマネジメントコンソールから、ブラウザ上でセッションを確立でき、いつも通りコマンドも叩けます。


# 方法
今回はPublicSubnetにあるEC2への、セッションマネージャによるアクセスをやってみます。
前提として、使用する **IAMユーザー** がSSM等の使用権限を持っていること
※マネジメントコンソールでSSMを操作する権限の話

![Public.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/770dbdca-7e67-1939-69ed-4ee05d65ff9c.png)


### 対象のEC2にRoleをアタッチ
EC2に最低限必要なポリシーは１つ
・AmazonSSMManagedInstanceCore


このIAMポリシーを持ったIAM Roleを作成したら、EC2にアタッチします。

①IAMRoleの作成画面へ
②Roleにアタッチするポリシーはデフォルトで存在する、
　**AmazonSSMManagedInstanceCore**　を選択
③EC2インスタンスの画面へ移動して、アクセスするEC2に対して、作成したRoleをアタッチ

### SSMで確認、セッション開始
Roleがアタッチされると、SystemsManager > マネージドインスタンス内にインスタンスが存在するので
この時点で準備OKかと思います。

**※出てこない場合、プロファイルが読み込まれていないので暫く待つか、再起動で表示されます。**

セッションを開始する場合はこの画面からも開始できますが
<img width="357" alt="スクリーンショット 2020-06-06 15.40.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/8f120d19-f106-2fdf-85ae-99c134c8ade0.png">

EC2インスタンス画面からも接続可能です。↓
<img width="417" alt="スクリーンショット 2020-06-06 15.41.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/91cf7577-a5ba-0bd5-67f2-eeffe3266cfd.png">
「接続」から↓
<img width="697" alt="スクリーンショット 2020-06-06 15.41.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/2a06b87e-c589-0791-3b64-5a461f2e7593.png">







# 注意点など

### Networkingの観点
今回はPublicSubnet、つまりインターネットゲートウェイがルーティングされた環境のインスタンスへの接続を実行しました

![Public0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/25fbc9c4-e6f6-2392-a2c9-37302282244c.png)


よりセキュアにしたい場合は、VPCエンドポイントがルーティングされたSubnetの用意が必要です

![Private2(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/447c6e1a-b7d0-84ab-091b-f08204e27e1b.png)

VPCエンドポイントは、AWSネットワークからインターネットに出ずにアクセス先のAWSリソースへアクセスさせてくれる子なので
今回であればSSMまでのアクセスをAWSネットワーク内で完結してくれます。

VPCエンドポイントに登録するAWSサービス名は以下です
※詳細は時間あったらまた今後追記

```
com.amazonaws.region.ssm
com.amazonaws.region.ec2messages
com.amazonaws.region.ssmmessages
```

### コスト観点
EC2セッションマネージャーの使用でかかる追加料金はありません
https://aws.amazon.com/jp/systems-manager/pricing/

ただし、VPCリソースの料金はかかります。
例えばVPCエンドポイントの場合

```
VPCエンドポイントの料金目安、東京リージョン
・各AZのVPCエンドポイント料金：0.014USD/時間
・処理データ1GBあたりの料金：0.01USD/GB
サービス（エンドポイント）毎にかかる
接続の有無に関わらずエンドポイントの料金はかかる
```

あらかじめVPCリソースの料金は算出しておいたほうがいいですね。
（個人で使っていると、このエンドポイント料金は大きかった）


こう考えてみると、よりコストを意識（重視）する必要がある場合、予め存在する踏み台サーバーのSSHポートを閉じて、PublicSubnetの踏み台サーバーを経由したアクセスが無難そう。
スペックによるが、踏み台のEC2料金のほうが安い場合がある。。

ただ、あくまでセキュリティを重視すべきであれば、PrivateSubnetならVPCエンドポイントで構築したほうが良い。


### 監査観点
SSMはCloudTrailと統合されているため、APIコールのログが残ります。
CloudTrailはデフォルトで有効となっているので、確認できます

また、セッションマネージャーの画面から、監査ログ等を取得する設定も可能
<img width="1338" alt="スクリーンショット 2020-06-06 16.24.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/c7747fed-91b6-e13e-9bf0-ba90115d6587.png">


# まとめ

セッションマネージャーを使うメリットがたくさんある
・**キーペアが不要**のため、管理する危なっかしいものが減る
・ブラウザでアクセスできるから、WindowsサーバーもRDPであることを意識しなくても済む
・VPC Network環境によって使い分ける
・ログも残してくれる

お試しの場合
・IAMやVPCの勉強になる

以上です！ありがとうございました。

次はトラブルシューティングの記事とか書こうかなーと思っています
【プログラミング初心者】Swift練習問題~繰り返し１~

#練習問題
##練習問題１
引数に与えた`[String]`型の配列の内容全てを表示する関数`printTexts`を`for`文を使って作成してください。

```swift
func printTexts(texts: [String]) {
    for ...
    // 処理
}

let texts = ["Hello", "World", "!"]
printTexts(texts: texts)
```
```:実行結果
Hello
World
!
```
[回答例はこちら](https://qiita.com/euJcIKfcqwnzDui/items/1d50b0e67d7aff0bc66b#%E7%B7%B4%E7%BF%92%E5%95%8F%E9%A1%8C%EF%BC%91)

##練習問題２
引数に与えた`[String]`型の配列の内容全てを表示する関数`printTexts`を`while`文を使って作成してください。
※配列の要素数は`配列.count`で取得できます。

```swift
func printTexts(texts: [String]) {
    while ...
    // 処理
}

let texts = ["Hello", "World", "!"]
printStrings(texts: texts)
```
```:実行結果
Hello
World
!
```
[回答例はこちら](https://qiita.com/euJcIKfcqwnzDui/items/1d50b0e67d7aff0bc66b#%E7%B7%B4%E7%BF%92%E5%95%8F%E9%A1%8C%EF%BC%92)
##練習問題３
引数に与えた`[String]`型の配列の内容全てを連結して表示する関数`printCombine`を作成してください。

```swift
func printCombine(texts: [String]) {
    // 処理
}

let texts = ["Hello", "World", "!"]
printCombine(texts: texts)
```
```:実行結果
HelloWorld!
```
[回答例はこちら](https://qiita.com/euJcIKfcqwnzDui/items/1d50b0e67d7aff0bc66b#%E7%B7%B4%E7%BF%92%E5%95%8F%E9%A1%8C%EF%BC%93)

#応用問題
##応用問題１
第一引数に文字列、第二引数にループ回数を取り、指定したループ回数文文字列を出力する関数を作成してください。

```swift
func printLoop(text: String, loop: Int) {
    // 処理
}

printLoop(text: "HelloWorld!", loop: 3)
```
```:実行結果
HelloWorld!
HelloWorld!
HelloWorld!
```
[回答例はこちら](https://qiita.com/euJcIKfcqwnzDui/items/1d50b0e67d7aff0bc66b#%E5%BF%9C%E7%94%A8%E5%95%8F%E9%A1%8C%EF%BC%91)

##応用問題２
第一引数に整数、第二引数に指数を取り、累乗の計算した結果を返す関数を作成してください。
※指数が０、負の値の場合も考慮してください

```swift
func power(_ base: Double, exponent: Int) -> Double {
    // 処理
}

print(power(2, exponent: 10))
print(power(2, exponent: 0))
print(power(2, exponent: -1))
```
```:実行結果
1024.0
1.0
0.5
```
[回答例はこちら](https://qiita.com/euJcIKfcqwnzDui/items/1d50b0e67d7aff0bc66b#%E5%BF%9C%E7%94%A8%E5%95%8F%E9%A1%8C%EF%BC%92)

#最後に
別の問題は以下に掲載しています。
また本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載も以下にまとめていますのでそちらも是非もご覧ください。
http://naoyalog.com/
ScratchのプロジェクトをPythonに変換する

#初めに
なぜ、こんなことをしようと思ったのかというと、僕がScratchからPythonに切り替えた時ぐらいに、「ScratchからPythonに変えられないかな...」と思っていた。
それでPythonがわかってきて、UnityやC#をやっているときに、
「そういえば、ScratchからPythonに変えるやつないんかな...探してみよ」
「ないやん...」
「せや、自作したろ。」
という感じで制作を決意した。
#その一
##解析対象探し
まずはScratchのプロジェクトファイルをダウンロードしたときに.sb3ファイルが手に入る。sb3ファイルが解析できないと何もできない。なので「sb3ファイル 解析」と調べると、Scatchプロジェクトに使われている変数の名前などを表示するサイトに行き着いた。そのサイトは拡張子を.zipに変えてドラッグしてや。というので、これはもしやと思い拡張子を.zipに変えてみて、展開してみると、見るからに怪しそうなjsonが見つかった。そいつの中身を見てみると、明らかにブロックなどのことを書いている。とりあえずこれで解析対象のファイルが見つかった。
![projectj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559663/42a13e23-f05a-7d96-03d7-5b88c8753044.png)

##GUIを作る
その当時は配布したかったので、だれでも実行できるやつにしたかった。PythonTkinterで作ると、pythonをインストールしている人しか実行できないので、C#Formにして、GUI部分を作った。
![GUI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559663/60f2d4a1-3987-62d2-e312-af490789aa97.png)

##zip解凍
ZipArchive(C#)クラスを使えば何とかなった。
#その二
##json解析
C#でJson解析をしようとしても、なんかそれ専用のクラスを作らないといけなかったので、渋々PythonのJsonモジュールを使うことにした。あんなことやこんなことをして無事Jsonの解析は終わった。ちなみに、Pythonの実行を自動でするために、System.Diagnostics.Processを使って、実行することにした。
##書き込み
C#で書き込もうと思ったが、Json解析をpythonで済ましちゃっているのでpythonで書き込むことにした。しかし、書き込むファイルの場所と名前を指定しなくてはいけないので、 実行時に引数を入れて、そいつをsys.argvで読み込むことにした。あとはopen()してJson解析時のif地獄の中にwrite()してやればOK。
#最後に
これは配布すべきなのか?配布してしまったらこのツールに頼ってしまわれそうで怖い。(そもそもダウンロードする人がいるのか?)
一部のブロックには対応してない。これは**決して**面倒くさいというわけではなく、これ以上のことをしたいならPythonを使えということである。
#おまけ:手こずったところ
##Json解析
jsonファイルのブロック定義は一つのブロックごとに分けられている。一つの演算子も一つの塊になっている。つまり5+5+5+5+5という計算をするときには再帰関数を使ってした。しかしそれでは1000近くしかできないので、もっといい案あったら教えてください。
##書き込み
ずっとf文字列を完成間近まで知らなかった為、ずっと.format()を使っていた。C#の\$文字列みたいなのがあったらいいなと思ってググってみたら、f文字列があってfすげええってなってた。たぶんf文字列とか\$文字列とかの言い方が違う。
##スタック
ifとかforのブロックを抜け出した後に、elseとかその下のやつを書き込まないといけないのでそのelseや下のやつをリストに保存していて、呼び出すときは今の層-1していたんだけど、こんなやつ

```python
if True:
    if True:
        if True:
            if True:
                print("Hello")
    print("World")#-2されている。ってかand使えよ
```
とかあったので、ifの時の階層を一緒に保存することにした。
#本当に最後に
わけわからんところもあったと思いますが、ここまで見ていただいてありがとうございました。
#追記
~~公開しました~~。
~~https://www.axfc.net/u/4023085~~
Go でローカルにある JSON を読み込む

## やりたいこと
ローカルにある JSON を Go の構造体として読み込む

## ローカルにある JSON ファイル (sample.json)
```json

{
  "posts": [
    {
      "id": 1,
      "title": "Post 1"
    },
    {
      "id": 2,
      "title": "Post 2"
    },
    {
      "id": 3,
      "title": "Post 3"
    }
  ],
  "comments": [
    {
      "id": 1,
      "body": "some comment",
      "postId": 1
    },
    {
      "id": 2,
      "body": "some comment",
      "postId": 1
    }
  ]
}
```

## JSON を struct でどう読み込むか決める

```go
type Post struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
}

type Comment struct {
	ID     int    `json:"id"`
	Body   string `json:"body"`
	PostID int    `json:"postId"`
}

type Blog struct {
	Posts    []Post    `json:"posts"`
	Comments []Comment `json:"comments"`
}
```

## `Unmarshal` で構造体に変換
[json.Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal) で JSON を構造体に変換

```go
func main() {

	jsonFromFile, err := ioutil.ReadFile("./sample.json")
	if err != nil {
		log.Fatal(err)
	}

	var jsonData Blog
	err = json.Unmarshal(jsonFromFile, &jsonData)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(jsonData.Posts[0].Title)
}
```
最後に読み込めているか確認
`Post 1` と出力されれば成功。
【python】最も多い鳥の種類を求めるプログラム

#【python】最も多い鳥の種類を求めるプログラム

自分用のメモです。


▼設問

- 目の前を通った鳥の種類の番号(正の整数)を順番にlistにいれる。
- 最も多く目撃された鳥の種類を返す。
- ただし、複数の種類が同数回目撃された場合は、一番小さな種類の番号を返す。


[URL](https://www.hackerrank.com/challenges/migratory-birds/problem)


▼sample input

```python:
arr = [1,1,1,4,4,4,5,3]
```

▼sample output

```python:
1
```

▼my answer

```python:
def migratoryBirds(arr):
    x=0
    minType=0

    #各種類番号の数を数える
    for i in set(arr):
        if x<arr.count(i):
            x=arr.count(i)
            minType=i
        
     #目撃回数が同じ場合は、小さい種類番号を優先する
        elif x==arr.count(i):
            x=arr.count(i)
            if minType>i:
                minType=i
    return minType


if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    arr_count = int(input().strip())
    arr = list(map(int, input().rstrip().split()))
    result = migratoryBirds(arr)
    fptr.write(str(result) + '\n')
    fptr.close()
```


<br>
**・sightings**
目撃（動物）
Its id number will be added to your array of sightings.

You would like to be able to find out which type of bird is most common given a list of sightings.
ドラムマニア・コントローラをエレドラのパッドに改造したよ。

##マエセツ
最近、[1,000円で買える電子ドラム](https://nlab.itmedia.co.jp/nl/articles/2006/03/news116.html)が話題ですが、私もドラムを叩くのが趣味なので家に電子ドラム持ってます(でんでん太鼓じゃないほう)。でも家では場所をとるのでいつもは畳んであったり、アンプやコードをつないだりとちょっと面倒。
また音楽系のハッカソンがあるとミニマムセットでスーツケースにつめて持っていったりしてた（[たとえばこんな作品](https://twitter.com/i/status/648027811375005697)）のですがやっぱ重いです。[こんなん](https://www.amazon.co.jp/gp/product/B073FGT6YN/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)とかも買って[こんな風](https://youtu.be/G22Uvq-VMMA)に使ったりもしましたが、やっぱ強弱もつかないし、なんかしょぼい。
というわけで、常日頃コンパクトで持ち運び便利、家でも手軽につたける電子ドラムほしいなと思ってたところにハードオフのジャンクコーナーでこんなものあったので買ってはありました。(スタンドもフットコントローラも付いてなくてたしか300円ぐらいだったはず)
![p1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/5f450722-7fd5-c731-fa11-cbf5b6b26f45.jpeg)

#まずは分解
このままではPLAYSTATION2とソフトがないと動かないしまずは分解です。裏の14個のネジをはずすとこんな基板が出てきます。
![p2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/6d3e74ca-7d53-c87c-5926-4768643302d2.jpeg)
![p3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/aa246cd5-27c6-ff83-e9ce-2d06f02eb41a.jpeg)
基板の回路は使わないですが、SELECTとSTARTのボタンは後々なんか使えそうなのでそのために残します。
コードは使わないのではずします。ICなどに伸びる基板の配線をドリルでカット(図中の赤丸)して各パッドからの配線を外に引き出します。
![p5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/5484f22e-6d1b-cd1e-fd29-9a42de277040.jpeg)

#ドラムはハードウェアが命※
今回のパッドはスタンドがないので(あってもちゃちそう)ガッツリスタンドに固定できるように、これまたイシバシ楽器だかのジャンクで買ってあった取り付け治具を裏カバーにネジ止めします。
![p6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/2a702696-0027-07c8-9d5b-08483f75df7c.jpeg)
下穴あけてネジ切りしてこんな感じに取り付けました。
![p7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/033d767e-16e2-d890-8596-570de5e54d67.jpeg)
これで多少ハードにプレイしてもある程度耐えてくれそうです。

　　　※ドラム界隈ではスタンドなどの鳴り物を支えるパーツをハードウェアと呼びます。

#信号テスト
まずはSELCT、STARTボタンから。ここはただのゴムスイッチなのでテスターで抵抗値を測ります。
![p9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/298b993a-9212-7018-610f-ca3cab739c04.jpeg)
２つのボタンともOFF時は抵抗値∞、ON時は約13Ωでした。

次に各パッド。各パッドはオシロスコープをつないでスティックで叩いたときの波形を見ます。
![p10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/589774ea-1b5f-eda9-eeea-ab2bde6a21ae.jpeg)
いずれのパッドも同じぐらい(数V程度)のスパイク波形が観測されました。
各パッドは発砲素材で浮かした構造になっているので他のパッドを叩いてもほとんど反応しないのはさすが大量生産品です。

#実演
配線の先に標準ジャックをつけて電子ドラムのコントローラーにそれぞれぶっ刺したら完成。
でこんな感じ。
[ドラムマニアコントローラで電子ドラム演奏(動画)](https://www.facebook.com/shin.takeuchi.31/videos/3070131926410376/
)
![p11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/0b096189-cad8-a007-6bb3-f0d997e0a73e.png)


#まとめとこれから
そこそこのパッド数をコンパクトにまとめられた。
　→オシロではほとんど混信がないように見えたが電子ドラムにつなげるとそこそこ混信する。電子ドラムコントローラ側のパラメータ調整or前処理回路が必要かな･･･。
ハイハットコントローラとバスドラペダルは電子ドラムのままなのでやや重たい。
　→ 頑丈で軽いやつを自作したらいいのだけれども演奏性が落ちると本末転倒ｗ
今後はハッカソンなどでのコンピュータとの連携用に[このあたり](https://www.pinterest.at/pin/773493304728926684/)とか[このあたり](https://qiita.com/yasuraok/items/8ae995b7484e140b071f)を参考にしてUSB-MIDI化でもしよかと思ってる。(今のままでも電子ドラム使ってMIDI化できてるので+アルファを思いついたらやるかな)

で、その夜早速これとNETTODUETTOと使ってセッションしてみた。おもろかった。
![iwaoka.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567140/3be40e6a-2ef3-1ee9-67bc-725db6d0401b.png)
メモ：Expo sdk 37からEjectすると、firebaseのログイン状態とAsyncStorageの内容がクリアされる

(メモ）

Expo sdk37 & managed workflowのReact-native アプリを bare workflowでejectしたら、firebaseのログイン状態とAsyncStorageの内容がクリアされる問題に遭遇しました。

原因はExpo　managed workflow下で参照されるAsyncStorageのデータ保存場所と、Eject後のAsyncStorageの保存場所が異なることから発生する問題のようです。

https://github.com/expo/expo/issues/2805

また、FirebaseのAuth情報もAsyncStorageに保存される事から、ログイン状態も解除されます。

解消するには、現時点（2020/06)でissuesを参考にAsyncStorageの移行作業をする必要がありました。

また、FirebaseのAuth情報の移行には下記のQiita記事を参考にさせていただきました。

https://qiita.com/mildsummer/items/c7a8a6a68844242c135f

ありがとうございます！
助かりました！
【AWS】インスタンスストアとEBSの違いとは？

# はじめに
現在、AWS SAAの学習をしています。
その中でインスタンスストアとEBSの違いについて学びましたので、アウトプットします。

# インスタンスストアとは？

**別名、「エフェメラルディスク」**
EC2インスタンスに内蔵されているローカルストレージです。

**特徴**

- EC2の一時的なデータが保持され、EC2の停止・終了と共にクリアされる
- 無料で使用可能

このように、再起動をする度にデータがクリアされるストレージになります。
そのため、インスタンスストアは一時ファイル置き場として利用できるストレージになります。


# EBSとは？

**「Elastic Block Store」の略。**
EC2インスタンスにアタッチして利用できるブロックレベルのストレージサービス。

**特徴**

- インスタンスストアとは異なり、再起動してもデータが消えない。
- 1つのボリュームで最大16TB
- EC2をテンプレートにしてもEBSは保持可能
- スナップショットをS3に保存可能
- 別途、EBS料金が必要

OS/アプリケーション等のインストール先に適したストレージになります。

# 図にした場合

![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/c96238a4-de11-966b-0691-ac0d9abc827e.jpeg)


# まとめ

|  項目  |  内容  |  用途  |
| ---- | ---- | ---- |
|  インスタンスストア  | EC2インスタンスに内蔵されているローカルストレージ |  一時的なデータ置き場  |
|  EBS  |  EC2インスタンスにアタッチして利用できるブロックレベルのストレージ  |  OS/アプリケーションのインストール先  |


# 参考

[Amazon EC2 インスタンスストア](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/InstanceStorage.html)
[この１冊で合格！　AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集](https://www.amazon.co.jp/gp/product/B07VFFX6V1/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)
【python】指定した値で割り算できるペアを求めるプログラム

#【python】指定した値で割り算できるペアを求めるプログラム

自分用のメモです。


▼設問

- 正の整数の入ったlistが与えられる.（ar）
- listから整数を2つ抜きだし、合計値がk（正の整数）で割り切れるペアの数を求める.



[URL](https://www.hackerrank.com/challenges/divisible-sum-pairs/problem)


▼sample input

```python:
k=3
ar=[1,3,2,6,1,2]
```

▼sample output

```python:
5
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e9c3ade7-0d1d-097d-254d-2e37ed4fc8d2.png)


▼my answer

```python:
def divisibleSumPairs(n, k, ar):
    ans = 0
    
    for n,i in enumerate(ar):
        arr=[]
        arr =list(map(lambda x:(x+i)%k, ar[n+1:]))
        ans += arr.count(0)
    return ans

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    nk = input().split()
    n = int(nk[0])
    k = int(nk[1])
    ar = list(map(int, input().rstrip().split()))
    result = divisibleSumPairs(n, k, ar)
    fptr.write(str(result) + '\n')
    fptr.close()
```


<br>
#####考え方
- 組み合わせの全パターンを出す。
- 各要素をｋで割った余りを求める。
- 余り＝０となった数を足し上げる。

▼一度かけ合わせた組み合わせは除外。

```python:
for n,i in enumerate(ar):
    print(ar[n+1:])

#------------------
[3, 2, 6, 1, 2]
[2, 6, 1, 2]
[6, 1, 2]
[1, 2]
[2]
[]
```

**・map関数**
`map(関数,イテラブル)`

イテラブルの要素を一つづつ抜き出し、関数を実行した値を返す。

▼こんなときに使う
・listの各要素をそれぞれn倍したい。
・lambda式と一緒に使われることが多い。
　└ lambda式：関数(def)を一文で書いたもの

▼処理
for文と関数が組み合わさった処理。

▼注意点
出力値はmap型。
listが欲しい場合は、list()で変換する。

<br>
**・lambda式**
defで定義する関数の簡略版。
メソッド名をつけず、引数と処理を一文で記述する。

`lambda 引数:処理`

<br>
**・mapとlambda**
`map(lambda 変数:処理, イテラブル)`

イテラブルの要素を一つづつ抜き出し、lambdaの変数に入れ処理を実行。この処理を各要素に対し行う。


**・enumerate関数**
・for文で使う
・インデックス番号を抜き出す

`for 変数1, 変数2 in enumerate(イテラブル):`
　└ 変数１：インデックス番号が入る。
　└ 変数２：抜き出した要素が入る。

▼こんなときに使う
・forが何回目の処理か知りたい。


英語が見慣れないのと長いので、難しそうだが実際は単純。

通常のfor文：「for 変数2 in イテラブル」
　①index番号を入れる変数を追加（先方に書く）
　②イテラブルをenumerateで囲む。
csvファイルは『SmoothCSV』で編集しよう

皆さんはcsvファイルをどうやって開いていますか？

Excel？それとも、メモ帳などのテキストエディタでしょうか？

私も今まではそうでした。
でも、文字化けしたり、操作しにくかったりでイライラすることも多かったです。

そんなイライラから解放されたいあなたには、[『SmoothCSV』](https://smoothcsv.com/product)をオススメします。

##SmoothCSVは無料のcsv専用エディタ

SmoothCSVはcsvやtsvファイルを編集することに特化した無料ソフトです。

csvファイルは、コンマ区切りのデータですが、Excelやテキストエディタで閲覧したり編集する方が多いかと思います。
ですが、これには色々と問題があります。

##問題1. Excelの文字化け問題

csvファイルは結局はコンマ区切りの表データなのでExcelのような表形式で編集できると便利ですね。
なので、皆さんもExcelでcsvファイルを編集することも多いかと思います。

ですが、ここで必ずといっていいほどぶち当たる問題が**文字化け**です。
こんな悲惨なことになった方も多いと思います。

<img width="474" alt="mojibake.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/c25eee2d-afe0-1973-9f58-303bbd4a7381.png">

そして、Excelでcsvファイルを保存しようとすると毎回出るこの警告。

<img width="533" alt="excel_csv_warning.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/4acc12bb-ddb6-3ec6-2fee-c5d362cf190d.png">

こちとらわかっててcsv形式で保存しようとしてるのに、毎回出ます。正直、うっとおしいです。

##問題2. テキストエディタは編集しにくい
じゃあテキストエディタならいいかと言うとこれも問題です。
第一に見づらいです。列がきちんと揃っているわけでないので、どの列がどこに対応しているのかわかりにくい。
そして、列を編集/追加したいときに、1行ずつポチポチいじらないといけないです。
やってられません！

<img width="408" alt="csv_texteditor.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/2ed0cc83-545a-8819-782d-019e2aa3a829.png">

ここで**SmoothCSVの出番**です！

## SmoothCSVなら文字化け知らずで編集もしやすい

SmoothCSVは無料ソフトで下記からダウンロードすることができます。

SmoothCSV
https://smoothcsv.com/product

インストーラ版/Zip版のお好きな方をダウンロードします。
指示に従ってインストールしてください。

SmoothCSVでcsvファイルをこのようにExcelっぽい画面で表示されます。
文字化けもしていませんね。

<img width="493" alt="smoothCSV.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/56f96615-5976-b9d5-1f5a-b2614a31230f.png">

保存時に毎回互換性がないとかなんとか聞かれることもありません。
とても便利！
[Go] JSON レスポンスから CSV を作成する


## やりたいこと
JSON のウェブから取得して、ほしいデータだけを CSV に書き出す。

## 手順

### まずは、JSON の中身を確認する
[JSONPlaceholder](https://jsonplaceholder.typicode.com/) というサイトから色々な JSON 提供している。
今回は [ToDo](https://jsonplaceholder.typicode.com/todos) リストを使う。
それでは、JSON の中身を確認。

```json
[
  {
    userId: 1,
    id: 1,
    title: "delectus aut autem",
    completed: false
  },
  {
    userId: 1,
    id: 2,
    title: "quis ut nam facilis et officia qui",
    completed: false
  },
  {
    userId: 1,
    id: 3,
    title: "fugiat veniam minus",
    completed: false
  },
... と続く
```
ふむふむ。
`userId`、`id`、`title`、`completed` がワンセットでリピートしてるのね。

###  JSON と Go の構造を合わせて struct を作る
ネストがなくシンプルの構造だ。

```go
type ToDo struct {
	UserID int
	ID     int
	Title  string
	Body   string
}
```
JSON データは、この構造がスライス `[]ToDo` で表現されていることになる
### ウェブから JSON を取得する
GET リクエストして、問題なければレスポンス BODY を読む。

```go
	url := "https://jsonplaceholder.typicode.com/posts"
	res, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	if res.StatusCode != http.StatusOK {
		log.Fatal(err)
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
```
### `Unmarshal` でJSON → Go 構造に変換
`Unmarshal` の第2引数にはポインタを渡す 
そうしないとエラーになる
Ref: [Unmarshal](https://golang.org/pkg/encoding/json/#Unmarshal)

```go
	var jsonData []ToDo
	err = json.Unmarshal(body, &jsonData)
	if err != nil {
		log.Fatal(err)
	}
```

### CSV への書き込み
`UserID` はいらないので、CSV には出力しない。
どこでも利用する予定がなければ、`Unmarshal` で読み込まないこともできる。

```go
	csvFile, err := os.Create("./data.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer csvFile.Close()

	writer := csv.NewWriter(csvFile)

	for _, oneToDo := range jsonData {
		var row []string
		row = append(row, strconv.Itoa(oneToDo.Id))
		row = append(row, oneToDo.Title)
		row = append(row, oneToDo.Body)
		writer.Write(row)
	}

	writer.Flush()
```

## まとめ
読み込む JSON に合った `struct` ができれば、`Unmarshal` するだけだから簡単だ。
Access　tip集

#VBAで一行以上あるないかの判定

If DCount("フィールド名", "クエリ名") > 0 Then

#四則演算


*  [A]　\　[B]で割り算の商のみ表示
* [A]　/　[B]で割り算
* [A] Mod [B]で割り算の余りのみを表示


#日付/時間　操作

* DateAdd(単位, 時間, 日時)　yyyyとか、m,d,h,n,sで単位指定　
* DateAdd("ww", 2, #2017/5/10#)	2017/05/24	2017/5/10 の2週間後
* DateAdd("m",1,#2017/1/30#)	2017/02/28	2017/1/30の1カ月後、2月に30日がないので2月末日が返される
* DateAdd("ww", 2, Null)	Null	引数日時がNull値の場合、戻り値はNull値
* DateAdd("ww", Null, #2017/5/10#)	エラー	引数時間がNull値の場合、エラーになる

#オートナンバーを再走する
```
TableReNew ("テーブルA")
Function TableReNew(Spec)

    DoCmd.SetWarnings WarningsOn:=False

    Dim tableName
    Dim Newtable
    tableName = Spec

    DoCmd.CopyObject , "Newtable", acTable, tableName

    DoCmd.DeleteObject acTable, tableName
    DoCmd.Rename tableName, acTable, "Newtable"

    DoCmd.SetWarnings WarningsOn:=True
    
End Function
```
#Access　ファイルサイズ問題
- クエリを実行するだけでファイルは大きくなる。
- 他PCなどに転送する前に、「データベースの最適化・修復」をやる。
- それだけで膨れ上がったファイルサイズが最小のものになる。

#インポート定義を編集
クエリに直接、SQL文を直接入力すると参照して、編集できる。

```
SELECT MSysIMEXColumns.SpecID, SpecName, FieldSeparator,
FieldName, DataType, IndexType, SkipColumn
FROM MSysIMEXColumns INNER JOIN MSysIMEXSpecs
ON MSysIMEXColumns.SpecID = MSysIMEXSpecs.SpecID
ORDER BY MSysIMEXColumns.SpecID;
```
#VBA export
### テーブルエクスポート
```
    Dim Path As String
    Path = CreateObject("WScript.Shell").Specialfolders("Desktop") & "\" & "住所録.csv"
    
    DoCmd.TransferText acExportDelim, , "T_住所録", Path, True, ""
    
    MsgBox "エクスポートされました"
```
###クエリを外部にエクスポート
```
stDocName = "c:\data\abcexp.csv"
DoCmd.TransferText acExportDelim, , "abcexp", stDocName, False
```

#VBA inport
###VBAでエクセルをインポート
```
Private Sub Excel読み込みボタン_Click()
  DoCmd.TransferSpreadsheet acImport, , "商品管理テーブル", "K:\～\Accessに追加用商品管理データ.xlsx", True
  MsgBox ("Excelのデータを取り込みました。")
  Exit Sub
End Sub

```
AWS EC2インスタンスのボリュームを拡張する

Cloud9でボリューム不足を警告されるようになったので、容量を増やすことにした。
AWSのEC2->ボリューム から該当するインスタンスを選択してボリュームを変更。
今回は10GB→16GBに変更する。

####EC2でボリューム変更前
```
Developer:/proc/sys/vm $ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        483M   60K  483M   1% /dev
tmpfs           493M     0  493M   0% /dev/shm
/dev/xvda1      9.8G  9.5G  155M  99%
```

xvda1の使用率は99%。

```
Developer:/proc/sys/vm $ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  10G  0 disk 
└─xvda1 202:1    0  10G  0 part /
```
xvda1に10GB割り当てられている。

####EC2でボリューム変更後
EC2でボリューム変更後、xvdaに16GB割り当てられているが、xvda1は10GBのまま。

```
Developer:/proc/sys/vm $ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  16G  0 disk 
└─xvda1 202:1    0  10G  0 part /
```

xvda1に16GB割り当てないといけないらしい。

以下リンクに従ってパーティションの拡張を行う。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html#extend-linux-volume-partition

```
Developer:/proc/sys/vm $ sudo growpart /dev/xvda 1
CHANGED: disk=/dev/xvda partition=1: start=4096 old: size=20967390,end=20971486 new: size=33550302,end=33554398
```

無事変更された模様。

```
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  16G  0 disk 
└─xvda1 202:1    0  16G  0 part /
```

パーティション拡張できたので、ファイルシステムのサイズを変更する。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/extend-linux-file-system/

```
sudo resize2fs /dev/xvda1
```

その後、df -hでサイズを確認すると確かにファイルサイズが変更されている。

```
Developer:/proc/sys/vm $ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        483M   60K  483M   1% /dev
tmpfs           493M     0  493M   0% /dev/shm
/dev/xvda1       16G  9.5G  6.1G  62% /
```

使用率は62%。
Cloud9をリロードすると容量オーバーの警告が消えた。
C++によるプログラミング技法_関数の引数にbool型を使う代わりにenum型を用いる。

# 1.はじめに
初投稿です。転職し、一から新しい言語のC++を学習(現在約8か月経過)していった過程で学習した内容の**備忘録**及び、**似たような境遇**の方のお役に立てればと思い投稿しました。
2020/6/6 @yumetodoさんのコメントより修正(enumではなくenum classを用いる)

# 2.関数の引数にbool型を使う代わりにenum型を用いる。
以下のような関数

```FindString.cpp
std::string FindString(const std::string &text,
                      bool search_foward, bool case_sensitive)
```

上記関数は検索オプションとして、第2引数は検索方向、第3引数は大文字と小文字の区別をするbool型の引数を受け取る。この関数は以下のように用いる。

```UseFindString.cpp
result = FindString(text, true, false);
```

上記はこの関数の使用者からすると、最初のbool引数が検索の方向なのか、大文字小文字の区別フラグなのか忘れやすいポイントであり、余計なデバックに無駄な時間を費やす可能性がある。これの回避策の一例としてenum classを用いて書き換える方法がある。

```FindString.cpp
enum class SearchDirection
{
	FOWARD,
	BACKWARD
};

enum class CaseSensitivity
{
	CASE_SENSITIVE,
	CASE_INSENSITVE
};


std::string FindString(const std::string &text, 
                       SearchDirection direction, CaseSensitivit case_sensitivity)

```

上記のenum型の引数を用いた関数とbool型の引数の用いた関数の対比を以下に示した。

```Compare.cpp
auto result = FindString(test, true, fasle)                 //⓵　bool型引数を使用

auto result=FindString(test, SearchDirection::FOWARD, CaseSensitivity::CASE_INSENSITVE);    //⓶　enum型の整数値を用いた引数を使用

```
上記②は①と比べ、ユーザーが2つのフラグの順序を取り違えることがなくなり(誤ったフラグを指定するとコンパイルエラーになるため)、さらにコードが分かりやすくなる。

# 最後に
今回は一例として、enum型を用いたが、Ｃ＋＋２ａ以降では名前付き引数(他言語(JavaScript等)にある機能)が導入予定らしいので、そちらを使うのもいいかもしれない。