OmniAICreator/Qiita-1.07M huggingface dataset:
VSCode Settings Syncの使い方（GitHub TokenもGist Idも不要）

公式や多くの紹介記事では、GitHub TokenやGist Idが必要と書いてありましたが、実際には不要で少し混乱したので、設定方法を紹介します。

# 初回

ExtensionsパネルからSettings Syncをインストール
<img width="1403" alt="スクリーンショット 2019-09-19 21.13.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/e77fa274-928a-c416-e3e5-0073f4432ae0.png">

Welcome to Settings Syncというタブが開くので、LOGIN WITH GITHUBをクリック
<img width="1403" alt="スクリーンショット 2019-09-19 21.22.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/acf59ccd-ef2a-9c17-101f-18176878a32e.png">

Authorize shanalikhanをクリックして、OAuth applicationに追加
<img width="583" alt="スクリーンショット 2019-09-19 21.25.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/d310e17a-9bf4-d3a7-51b5-78feea05818d.png">

VSCodeに戻るとGistを選ぶ画面が開いている。初めて使う場合はSKIPを選択
<img width="1403" alt="スクリーンショット 2019-09-19 21.25.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/e3bf5de9-e43a-9802-f095-3f6c437074cc.png">

EDIT CONFIGURATIONを見ると、アクセストークンが自動的に追加されている
<img width="1403" alt="スクリーンショット 2019-09-19 21.26.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/58a9c02a-593b-63d0-2897-81618a031a3e.png">
<img width="1403" alt="スクリーンショット 2019-09-19 21.27.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/b7a27e10-97ff-925e-499e-4a168ee1589f.png">

コマンドパレット（command + shift + p）からSync: Update/Uploaded Settingsを選択
　<img width="1403" alt="スクリーンショット 2019-09-19 21.30.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/5ee513a4-8fad-ad7d-7be0-02972fd80be1.png">

Gistに設定がアップロードされる
<img width="758" alt="スクリーンショット 2019-09-19 21.32.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/7dd28d5b-7408-14c7-5df1-edd3592cae22.png">

# 他のマシンから設定をダウンロードする場合

Settings Syncをインストール、GitHubにログイン後、既存のGistを選択
<img width="1403" alt="スクリーンショット 2019-09-19 21.32.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/1efa62fc-18b8-fc4c-7d9f-dd85808b7daa.png">

コマンドパレットからSync: Download Settingsを選択
<img width="1403" alt="スクリーンショット 2019-09-19 21.51.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499615/2e034143-cded-e013-dc46-3e8dc7287bc3.png">

# 最後に

設定で手こずったものの、使えるようになるとめちゃ便利！

# 参考
[Settings Sync (Visual Studio Marketplace)](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync)
ShellScript 変数 に 格納 されている 文字数 を出力する

# 目的

- ShellScriptで変数の中に格納された文字列の文字数を表示する方法を知る。

# 書き方の例

- 変数には任意の文字列が格納されているものとする。
- ターミナルに変数の文字を出力したいので`echo`コマンドの後に紹介する処理を記載する。
- 下記にShellScriptの処理を記載する。

``` shell
echo ${#変数名}
```

# 具体的な例

- 変数`string`に文字列`Hellow`を格納する。
- 下記にShellScriptの処理を記載する。
※`>`はターミナルの出力を表す。

``` shell
string="Hellow Japan"
echo ${#string}
>12
```
素早くAWSのSwitchRole画面を開くツール「switcher」

AWSのスイッチロール用URL生成ツール[switcher](https://github.com/reireias/switcher)を作ったら意外と好評だったのでご紹介です。

<a href="https://github.com/reireias/switcher"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/reireias/switcher.png" width="460px"></a>

![switcher.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/9e125dbd-bf00-8a90-35cd-979584636c69.gif)

[リリースページ](https://github.com/reireias/switcher/releases)から各OS用のバイナリが取得できるので、お試しください。

## モチベーション
現職では、プロダクトごとにAWSアカウントを分けて管理を行っています。
また、プロダクトによっては本番環境とステージング環境でアカウントを分けるようにプロダクトもあります。


このようにAWSアカウントを複数使用する状況では、ユーザー管理をどう行うか工夫が必要です。

愚直にアカウント毎にユーザーを作成してしまうと、ユーザーの管理が煩雑になってしまうし、多くのアカウントを使い分けるSRE等はMFAの管理が大変なことになってしまいます。

そこで、よく用いられる運用方法としては、大本となるAWSアカウントに各エンジニアのIAMユーザーを作成し、
各プロダクト側でSwitch Roleの権限を付与する、という形があります。

この運用方法であれば、ユーザーは1対のID/Passと1つのMFAデバイスの設定でマネジメントコンソールへアクセスが可能です。

### 課題
しかし、2、3個程度のAWSアカウントであれば、ブックマークやドキュメントにSwitchRole用のURLを記述しておけば十分なのですが、
SREのように何十個もAWSアカウントを切り替える必要がある場合、ブックマークを作成するだけでも大変です。

## switcher
そこで、[switcher]()というCLIツールを作成しました。


なぜ、CLIツールなのかというと、AWSアカウントを多数使うSRE等は総じてTerminalを常に開きTerminal中心の生活を送っているからです。

### 特徴
`~/.switcherrc.json` という設定ファイルにSwitchRole用のアカウント情報を記述します。

```json:~/.switcherrc.json
[
  {
    "name": "roleA",
    "roleName": "roleA",
    "account": "99999999",
    "color": "red"
  },
  {
    "name": "roleB",
    "roleName": "roleB",
    "account": "88888888",
    "color": "blue"
  }
]
```

SwitchRole時には切り替え後に表示される名前や色を指定できるので、それらも指定できるようにしてあります。


### 実装に関して
golang製です。

[ktr0731/go-fuzzyfinder]()というインクリメンタルサーチ機能をgolangから簡単に利用できるライブラリを同僚から教えていただいたので、これを活用しています。

以下に実装の一部抜粋を記載します。

こんな感じで第一引数に渡した配列に対して、インクリメンタルサーチが実現できます。
第二引数にはサーチ対象となる文字列を返す関数、
第三引数にはプレビューに表示する文字列を返す関数を指定することができます。

```go
	index, err := fuzzyfinder.Find(
		accounts,
		func(i int) string {
			return accounts[i].Name
		},
		fuzzyfinder.WithPreviewWindow(func(i, w, h int) string {
			return fmt.Sprintf(strings.Repeat("\n", h-10)+"%s\n\naccount:  %s\nroleName: %s\ncolor:    %s",
				accounts[i].Name,
				accounts[i].Account,
				accounts[i].RoleName,
				accounts[i].Color)
		}))
	if err != nil {
		log.Fatal(err)
	}
```


### その他
今回は後学のために、golang製CLIツールのディレクトリ、パッケージ構成のベストプラクティスを模索しながら作成してみました。

- Go Moduleを利用した依存ライブラリ管理
- goreleaserを利用した複数環境のバイナリ生成 + GitHubへのリリース
- gobumpを利用したセマンティックバージョンのインクリメント
- Makefileを利用した依存管理、ビルド、リリース作業のタスク定義

自分の中でのgolang製CLIツールのベストプラクティスが固まったので、GitHubの[テンプレート機能](https://help.github.com/ja/articles/creating-a-repository-from-a-template)用にリポジトリを用意しました。

<a href="https://github.com/reireias/golang-cmd"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/reireias/golang-cmd.png" width="460px"></a>

他人が直接このリポジトリをテンプレートに使うことはできませんが、forkしたリポジトリならテンプレートに指定できるので、気になった方は試して見てください！

## おわりに
快適なAWSライフを！
イニシャライザとは

##イニシャライザ（initializer：初期化子）とは？

イニシャライザとは、クラスが初期化された時やインスタンスが生成された時に、その直後に変数を初期化します。
イニシャライザは、クラス変数ならクラスが初期化される時に実行され、インスタンス変数ならインスタンスが生成された時に実行します。

##イニシャライザ（initializer：初期化子）とは？

クラスのロード時、クラス変数を初期化するためにしようします。
クラス変数はインスタンス化しなくても存在し、使える変数ですから初期化が必要です。
通常は初期化の代入で行われますが大量の要素を初期化しなければいけないような場合にも有効です。

##イニシャライザの種類

イニシャライザには
・スタティックイニシャライザ
・インスタンスイニシャライザ
の2つがあります。
【TypeScript】Webスクレイピングのやり方

## 関連

- [【Go】Webスクレイピングのやり方 \- Qiita](https://qiita.com/kou_pg_0131/items/dab4bcbb1df1271a17b6)

## 準備

今回使用するモジュールはこちら

- ~~`request`, `request-promise-native`, `@types/request-promise-native`~~
~~HTTPリクエスト送信~~
(2020/06/22 追記)こちらのライブラリは既に deprecated になっているので、他の代替ライブラリの仕様を検討してください。代替ライブラリの例としては「[Alternative libraries to request · Issue \#3143 · request/request](https://github.com/request/request/issues/3143)」をご参照ください。



- `chardet`, `@types/chardet`  
文字コード判定
- `iconv-lite`  
文字コード変換
- `jsdom`, `@types/jsdom`  
HTMLパーサ

```bash
$ npm i request request-promise-native @types/request-promise-native chardet @types/chardet iconv-lite jsdom @types/jsdom
```

## サンプルコード

```typescript
import * as request from 'request-promise-native';
import * as chardet from 'chardet';
import * as iconv   from 'iconv-lite';
import { JSDOM }    from 'jsdom';

const main = async () => {
  const url = 'スクレイピングしたいページのURL';

  // HTTPリクエスト送信
  const option = {
    url: url,
    encoding: null
  };
  const response = await request.get(option);

  // 文字コード判別
  const encoding = chardet.detect(response)!.toString();
  if(!encoding) throw new Error();

  // 文字コード変換
  const html: string = iconv.decode(response, encoding);

  // HTMLパース
  const jsdom = new JSDOM(html);
  const document = jsdom.window.document;

  // スクレイピング
  // ここからはquerySelectorとかgetElementByIdとかお馴染みのメソッドで好きなだけスクレイピングしちゃってください
  const elm = document.querySelector('hogehoge');

  // ...
};
main();
```

## 参考

- [Node.jsでウェブスクレイピングする色々な方法 - Qiita](https://qiita.com/ledsun/items/0965a60f9bdff04f2fa0)
- [node.jsでrequestを使ってeuc-jpのサイトをスクレイピング時に注意する事 - Qiita](https://qiita.com/mapyo/items/4e9f99e6aa72236a215b)
Pythonの当たり前

# 構文エラーは、例外としてキャッチできるのか？
```:テストコード
try:
    while True print('Hello world')
except:
    print("シンタックスエラーをキャッチできた")
```
本来は、while True<ココ>に、コロン(:)が入る。
コロンないので、構文エラーになる。

```:出力結果
File "c:\HOS\RD\python入門\syntaxerror.py", line 2
  while True print('Hello world')
```
となり、例外はキャッチできない。
Pythonはインタプリタで1行ずつ処理するので例外がキャッチできても良いかと思ったが、構文解析に成功しない限りは、一行ずつの実行にならないので、例外処理ではキャッチできないのだろうと思った。
Sassのメリット [備忘録]

Sassのメリット
Sassには以下のようなメリットがあります。

・記述の簡略化ができる
・プログラムのような処理ができる
・複数のCSSファイルを1つにまとめることができる
・同じ値を使い回すことができる

Sassのネスト構造
SassではCSSをネスト(入れ子)して記述することができます。ネストして記述することで深い階層になっても親子関係がわかりやすい、親要素を複数記述しなくて済むといったメリットがある。

パーシャル
パーシャルとは、分割したSassファイルのことです。ファイルを分割することで、機能や内容ごとに管理ができるようになります。一つのファイル に全てのスタイルを書くと膨大な記述になり、可読性が悪くなります。一定のルールでファイルを分割して開発することで変更・修正がしやすくなります。

・パーシャルファイルを作成するには、ファイル名を_（アンダースコア）から始めます。パーシャルファイルを読み込むには、@import ファイル名と記述します。


また、mixinという機能を使用することで、同じスタイルをまとめることもできます。

 mixin
mixinとは、まとまったスタイルを定義することができる機能です。
変数は値を定義するものでしたが、mixinはスタイルを定義するものです。
mixinを利用することで、何度も同じスタイルを記述する必要がなくなります。
mixinを定義するには、@mixin mixin名() {}のように記述する。

 変数
Sassでは、変数を使用することができます。
何度も使用する値を変数を定義することで、変数名で何度も使用することができます。
変数を定義するには、$変数名: 値;のように記述します。
TABLEの主キーをuuid型に変更した際にNo route matchesのエラーが出た。

# 環境
- Rails 5.2.3
- psql (PostgreSQL) 11.4
  
# 事象
 - DBに登録したユーザーのレコードを取得するURLにアクセスした。
 - 画像のとおり、No route matchesのエラーが表示された。
 
<img width="814" alt="スクリーンショット 2019-09-19 19.49.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99046/72200c50-1ef5-ec72-6b50-c22fb2d0e04c.png">


# 原因
テーブルの主キーの型をbigintからuuidに変更したのに、テーブルのcolumn name、routes.rbを修正しなかったため。
<img width="685" alt="スクリーンショット 2019-09-19 19.52.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99046/a088af73-bd34-eed0-4aee-d0718da0016f.png">



# 対応
①該当テーブルのcolumn nameをuuidに変更

```
class RenameHogeModelPrimaryKey < ActiveRecord::Migration[5.2]
  def change
    rename_column :hoges, :id, :uuid
  end
end
```
②対応するモデルに主キーがuuidであることを記述

```
class Hoge < ApplicationRecord
  self.primary_key = "uuid"
```

③routes.rbにてparamをidからuuidに変更した

```
resources :hoges, param: :uuid
```
バリデーション出来ないうんこ

7つのサンプルでjQueryを学ぼう！
https://ozpa-h4.com/2012/11/07/jquery-lecture/

https://www.sejuku.net/blog/52234

【jQuery入門】ページ遷移やPOSTで値渡しを行う方法まとめ！
でも使ってるのはjsだよね？
https://www.sejuku.net/blog/52234

使いやすいクローム
https://www.buildinsider.net/web/chromedevtools/01#page-2



おやすいですよcodeprep
タダで使えるプロゲートみたいなもん。最高。でも3年後には・・・
https://codeprep.jp/
【Onsen UI】popPage()をした後の画面を操作する方法

# 概要
popPage()をした後に、遷移後の画面を取得できず混乱したため、解決策をメモ
pushPage()に関する記事はたくさんあるのに...

# 問題点
popPage()をした後に戻った先の画面が取得できない
# 解決策
popPage()の後に発生するイベント、"postPop" を利用
リファレンスの最後に載っていた https://ja.onsen.io/v2/api/js/ons-navigator.html

具体的には、JavaScriptに以下の EventListener を追記

```
document.addEventListener('postpop', function(event){
  var newPage = event.enterPage;
  alert(newPage.id);
})
```

# サンプルコード
Navigator のリファレンスにコピペしてもテストできます

```html:html
<ons-navigator swipeable id="myNavigator" page="page1.html"></ons-navigator>

<template id="page1.html">
  <ons-page id="page1">
    <ons-toolbar>
      <div class="center">Page 1</div>
    </ons-toolbar>

    <p>This is the first page.</p>

    <ons-button id="push-button">Push page</ons-button>
  </ons-page>
</template>

<template id="page2.html">
  <ons-page id="page2">
    <ons-toolbar>
      <div class="left"><ons-back-button>Page 1</ons-back-button></div>
      <div class="center"></div>
    </ons-toolbar>

    <p>This is the second page.</p>
  </ons-page>
</template>
```

```javascript:js
document.addEventListener('init', function(event) {
  var page = event.target;

  if (page.id === 'page1') {
    page.querySelector('#push-button').onclick = function() {
      document.querySelector('#myNavigator').pushPage('page2.html', {data: {title: 'Page 2'}});
    };
  } else if (page.id === 'page2') {
    page.querySelector('ons-toolbar .center').innerHTML = page.data.title;
  }
});

//  追記は以下だけ
document.addEventListener('postpop', function(event){
  var newPage = event.enterPage;
  alert(newPage.id);
})
```
MayaPlugin C++ MPlug 接続先

日本でMayaPluginでC++で開発してる人工１００人もいない説を提唱します。

でmellとかPyとかだとノードリストみたいなのとれるけどC++だとどうやるの？

この記事見に来てるということはなんらかの方法でプラグは取得できた前提で話ます。
GetConnectionListみたいな関数はない

```c++:plugTest.cpp

MPlug　plug = どこかのプラグ
MPlugArray plugArray;

if (plug.connectedTo(plugArray, true, false))
{
　std::string distName = parray[0].name().asChar();
　if (distName.find("skinCluster") != std::string::npos)
　{
     // スキンクラスターつながってる！ということはジョイント接続確認ができる
  }
}
```

はい。プラグはどこから取ってくるかわ目的によって違うので抽象的にしました。
MSelectionListでもコールバックでもメッシュからでもとれると思います。

要の関数は　connectedTo　こいつ

connectedTo（取得するプラグ配列、出力側か、入力側か）

というメソッドです。なのでプラグが繋がってる先をみたいのならば第２引数をTrueにすれば繋がってるリストが帰ってきます。
適当に文字列判定しましたがそんなに軽い処理でないのでMFnTypeとかで判定したほうが良いと思います。

世のMayaでプラグインつくってる人はどこで情報を得ているのでしょうか。ガンバリオンさんの自作レンダーをつくろう！的なやつぐらいしかちゃんとしたの無くないですか？

あとはCEDEC漁るかリファレンスを穴があくまで読むかサンプル読み漁るかぐらいかないの辛い！
AWS S3にAngularアプリをデプロイする手順

**背景**

Angularアプリを作成したので、Webで起動できるようにしてみたかった
Angularアプリ自体はすでに作成している前提として進めていきます

**ざっくり手順**

1. Angularアプリ資源を作成する

2. S3バケットを作成する

3. 資源をアップロードする

4. S3を静的ウェブホスティングするように設定する

   

###  Angularアプリ資源を作成する

1. Angularアプリを作成する

2. ターミナルでAngularプロジェクトのディレクトリに移動し、 `ng build --prod`コマンドでビルドを行う

   プロジェクト配下に/distフォルダが生成され、アプリ資源一式が格納される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/928078ce-7054-1efc-9310-edffa57229cb.png)

   

###  S3バケットを作成する

1. Amazon S3コンソールにアクセスする

2. バケットを作成する

   1. ダッシュボードで**[バケットを作成する]**を選択する
   2. リージョン内で一意なバケット名を付け、適当なリージョンを選択し次に進む
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/ef548113-31e4-4c67-3577-b94e4f52fab5.png)

   3. バージョニングの設定を行えるが、すべて無効のまま次に進む
   4. S3のバケットのアクセス許可を設定できるが、デフォルトのまま次に進む
   5. **[バケットの作成]**を選択をするとバケットが作成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/4edb59db-4ca6-82e0-95e2-ff91fd05aa23.png)


      

### 資源をアップロードする

1. 作成したS3のバケット名を選択してバケットに移動する

2. ビルドして生成された「/dist」フォルダ以下の資源をバケットにドラック&ドロップしアップロードする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/85ceb14b-eedb-9433-bcf0-fab887542a9a.png)
   

### S3を静的ウェブホスティングするように設定する

1. S3の**[アクセス権限]**タブを選択する

2. **[ブロックパブリックアクセス]**を選択して、[編集]からパブリックアクセスをすべてブロックのチェックを外す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/92e6e10e-b482-354b-1dec-fba891d29907.png)


3. **[バケットポリシー]**を選択する

4. バケットポリシーエディターで下記のように設定する 


   ```
    {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Sid": "PublicReadGetObject",
               "Effect": "Allow",
               "Principal": "*",
               "Action": "s3:GetObject",
               "Resource": " arn:aws:s3:::angular-test-backet/*"
           }
       ]
   }
   ```
各設定項目に関しては以下の通り

   - version:使用するポリシー言語のバージョンを指定する。2012-10-17バージョンが最新らしい

   - statement:このポリシーのメイン要素、以下の要素のコンテナになる

    - sid:複数のステートメントを区別するためのステートメントID
    - Effect:AllowまたはDenyを使用して付与、あるいは拒否するアクセス許可設定を指定する
    - Principal:アクセスを許可するアカウント、ロールを指定する
    - Action:ポリシーで許可あるいは拒否するアクションのリスト
    - Resource:アクションが適用されるリソースのリスト
 
今回はリソースをARN(Amazonリソースネーム)で指定している
 S3バケット一覧画面にて、ARNを取得したいバケットにチェックを入れるとポップアップが表示され、バケットのARNを取得することができる
今回は取得したARNをResourceに貼り付け、末尾に「/* 」を付加して全リソースへのアクセス許可を付加している。　
 5.　バケット内の**[プロパティ]**タブを選択し**[Static website hosting]**を選択する。
 6. インデックスドキュメントに**[index.html]**を入力して保存する。
 7. もう一度**[Static website hosting]**を選択し、画面上部に表示されているエンドポイントURLにアクセスするとS3に保存したWebアプリが表示される。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298390/564c3d5f-659d-8398-19a7-7c75a5034295.png)
[EWS]オンプレ/O365ハイブリッド環境での会議作成API実行時のエラー

# 背景
- EWS Managed APIを使用して会議作成（Appointment.Save())を行うと「SMTP アドレスに関連付けられたメールボックスがありません」エラーが発生
    - 英語メッセージだと`smtp has no mailbox associated with it`、例外は「`ServiceResponseException`」
- Exchangeサーバへの接続(認証）は問題なし
- EWSの他API（空き時間検索）は正しく実行できている

# 原因

- Exchangeに接続するユーザ（ExchangeServiceインスタンスを生成する際に指定するユーザ）がO365ユーザだったため。同様の権限を持つオンプレユーザにしたところあっさり解決しました。

こんな原因なら認証や他のAPIも失敗すればいいのに・・・。ちなみにどういう理屈でエラーになっていて、なぜ解決したのかを説明できるMicrosoftのドキュメントやネット上の技術記事はなし。

# 感想

今回、久しぶりにMicrosoftプロダクトを使った開発に携わりましたが、かなり~~苦痛~~微妙でした。

この問題はその一部ですが、不毛な時間をかな～～り費やしました。20年プログラミングやってますが最大の苦痛でした。誰かが同じ思いをしないで済めば幸いです。

以下は愚痴w

プログラムそのものには問題がなく環境の問題だとは思いつつ、絶対はないので、色々と調査と試行錯誤しました。
オープンソースのプロダクト（Apache,MySQL,Rails,...)でも当然、色々と問題が出るのですが、違いはそのときの情報の量と質。
まず量の面ですが、感覚的にはMicrosoftプロダクト（今回だとEWS）の情報量はOSS系プロダクトの１０分の１にも達しません。
質の面でも同じで、今回の同様のエラー（＝エラーメッセージが同じという意味）に悩まされているQ&Aは（英語圏だと）そこそこあるもののほとんどがオープン状態。
それらには、Microsoft社員からの回答を含めてさまざまな対処方法が記載されていましたが、結局、どれも違ってました。

これって「落とし穴が多すぎるプロダクト」という事ですよね。
しかも「原因は違うのに同じエラーメッセージ」という事ですよね。

こうなってくると、自力解決しかありませんが、MSプロダクトは中身がブラックボックスなのでお手上げです。

今回、解決できたのは、（問題切り分けの過程で見つかったものですが）偶然でありほぼ「運」です。

ちなみに[Microsoft公式のExchangeブログ](https://blogs.technet.microsoft.com/exchangeteamjp/2016/07/22/troubleshooting-in-a-hybrid-deployment-freebusycalendar-lookup/)には「`ハイブリッド環境で発生する問題は要因が非常に多岐にわたるため、残念ながら確実なトラブル シューティング方法やステップのようなものがありません`」だそうで、社内でもお手上げな様子が伺えます。

有償かつクローズドなプロダクトでこれって酷くないですか？

少し好意的に見れば、おそらく「クラウドファースト」のかけ声の元「セールス優先」でアーキテクチャの検討もなにも置き去りでAzure ADやOffice365との統合を要求されたのかなと。つまり開発現場は被害者。

ちなみにEWS Manged APIの後継として推奨されているGraph APIも公式ドキュメントに嘘が書いてあったり、機能しないプロパティが用意されていたり、チュートリアルがビルドもできなかったり、SDKの日付データが文字列（しかも変数名はdateTime)だったりでかなり微妙でした。

EWSはバージョンが2.2で問題が枯れてるのかドキュメントに書いてあることに嘘はなく、期待する結果を返してくれました。ただ、洗練されていないというのは感じました。（たとえば、空き時間検索において、空き時間候補と各出席者のFree/Busyの紐付けは、空き時間と各出席者の予定を全部突き合わせるプログラムを独自に記述しないとだめ。Graph APIでは最初から紐付いている。）

昔から言われていることですが、MicrosoftのプロダクトはVersion 3 が一般的な Version 1 なのでしょうね。

# おまけ（Microsoftプロダクト依存の開発で直面するであろう苦痛）

オープンソース主体のWEB系開発と比べるとMicrosoft系プロダクトを利用した開発は以下の苦痛を伴うのかなぁと思います。
大半のWeb系エンジニアは最初の問題だけで退散すると思われます。笑

- いまだ（2019年9月）にIE(Internet Explorer）対応を期待される。
- 基本的に有償プロダクトで構成されているので同じ環境を構築するのが（コスト的に）困難 => 本番でしか顕在化しない問題多数。
- 上記の派生で、本番環境の管理者権限はないので権限が必要なAPIや認証でつまづいた時にクイックに権限付与したり試行錯誤できない。（１分で終わる作業のためにやりたいことやその理由を提出して付与されるまで１日待って、といった流れになるのでとにかく時間がかかるし、集中も途切れるので生産性が悪すぎる。）
- トラブルシューティング時に有用な情報がほぼない。例外情報が貧弱で問題を絞り込めない。実装が公開されていないのでお手上げ
- MS公式ドキュメントに不備（パラメタが必須なのか？指定しない場合のデフォルト値は？）・嘘が多い  ※特にバージョン１プロダクト
- GUIベースなのでデプロイを自動化するのが難しい。（一応、PowerShellってあるけど・・）
- WEB標準を無視したMicrosoft独自仕様が多い → スキルの可搬性が低い。技術者として市場価値が高まらない。（こうしてMSプロダクトを避ける人が増えれば対応できる人材が減って、相対的に需要は高まる という考え方もできる。）

なおVSCodeは好きです。^^
async/await で非同期パタトクカシーー

async関数を2つ呼び出すと、内部のawaitが交互に処理されます。

ということで、お約束の[パタトクカシーー](https://ja.wikipedia.org/?curid=1842)。
https://jsfiddle.net/Lhankor_Mhy/8q2k69o1/

```js
let r = "";
let パタトクカシーー = async(str)=>{
  for ( let x of str ){
    let s = await x;
    r = r + s;
  }
}
パタトクカシーー("パトカー");
パタトクカシーー("タクシー").then( ()=>alert(r) );
```

この記事は、この質問にインスパイアされました。
[JavaScript - javascriptのasync/awaitの挙動の得体・仕組みが分からない｜teratail](https://teratail.com/questions/212743)
Python 3.7でdictが順序を保存するようになって良かったとしみじみ思う

Python 3.7から（非公式には3.6から） `dict` がキーの順序を保証するようになりました（`collections.OrderedDict`相当の動作になった）。

今更ながら「`dict` が順序を保存するようになって良かったナァ」とシミジミ感じているので、その気持ちをダンプします。

# 良かったこと

例えば pandas でデータ集計をした時に `DataFrame`のカラム名を日本語に直した上で順序も入れ替えたい、なんてことはあるでしょう。

Python 3.7以降では、こんな風に辞書を１つ書けばOK。

```python
import pandas as pd

df = pd.DataFrame(...) # 何処かから DataFrame を取得済みとする。カラムは "age", "name", "salary"

# カラムの順序を "name, age, salary" にした上で、日本語に置き換えたい
mapper = {
    "name": '名前',
    "age": "年齢",
    "salary": "年収",
}

output = df[mapper.keys()].rename(columns=mapper)
#      名前  年齢    年収
# 0    Alice  21   100
# 1      Bob  32  1200
# 2  Charlie  43  2300
```

Python 3.5 では、辞書の順序が保存されないので、カラムの順序が入れ替わってしまうかもしれません。

```python
#      名前    年収  年齢
# 0    Alice   100  21
# 1      Bob  1200  32
# 2  Charlie  2300  43
```

カラムの順序を保存するには、別途順序を表すリストを用意するか・・・

```python
mapper = {
    "name": '名前',
    "age": "年齢",
    "salary": "年収",
}

keys = ["name", "age", "salary"]

output = df[keys].rename(columns=mapper)
```

順序を保証する `OrderedDict` を使うしかありませんでした。

```python
from collections import OrderedDict

mapper = OrderedDict([
    ("name", '名前'),
    ("age", "年齢"),
    ("salary", "年収"),
])

output = df[mapper.keys()].rename(columns=mapper)
```

でも、リストを別に用意するのはDRYじゃありません。

`OrderedDict`はDRYではあるんですが、見た目が「マッピング」っぽくありません。カッコが多くて書くのも面倒だし、`from 〜 import 〜` も必要です。

Python 3.7 なら、DRYで見やすい辞書リテラルを、何のデメリットも無く使えるのです。やったね！

# 良かったこと・その２

今までも `OrderedDict` という「順序が保持された辞書」があったのですが、
所詮は[普通にclass文で定義された](https://github.com/python/cpython/blob/3.7/Lib/collections/__init__.py#L81)普通のクラスにすぎません。組み込み型ではないのです。

なので、printfデバッグの際など、不細工なものを見ることになります。

```python
from pprint import pprint
from collections import OrderedDict

# この辞書はYAMLファイルか何かから読み込んだと思いねえ
d = OrderedDict({"name": "Alice", "age": 21, "salary": 100, "foo": 1000})

# printfデバッグしてみよう
pprint(d, width=30)

# OrderedDict([('name',
#               'Alice'),
#              ('age', 21),
#              ('salary', 100),
#              ('foo', 1000)])

# うげげ！？
```

もちろん `dict` なら全く問題ありません。

```python
d = {"name": "Alice", "age": 21, "salary": 100, "foo": 1000}

# printfデバッグしてみよう
pprint(d, width=30)

# {'age': 21,
#  'foo': 1000,
#  'name': 'Alice',
#  'salary': 100}

# 見やすい！
```

# 良かったこと・その3

こんな議論を見たことがないでしょうか？

> 「YAMLを読むとき、キーがファイルに書かれた順序通りになるようにできませんか？」
> 「Pythonの`dict`は順序を保存しないので無理です」
> 「なら`OrderedDict`を使えばいいじゃないですか」
> 「`OrderedDict`を返して既存のクソコードが動かなくなったらどうするんですか！？」
> 「YAMLも順序を保存しないのが仕様である！`OrderedDict`は人類の堕落につながる！！」
> 「じゃあ、間をとって`OrderedDict`を返す `ordered_dict=True` というオプションを追加しましょうか」
> 「毎回`ordered_dict=True`と書くのダルいので、デフォルト設定を上書きできませんか？」
> 「いいこと思いついた！ `dict_class` という引数で辞書のクラスを変えられるようにしよう！」
> 「それ`OrderedDict`以外に使う機会あるんですか？」

まあ、自転車置き場の議論です。

でも、組み込みの `dict` が最初から順序を保存していれば、こんな議論はそもそも不要なのです。やったね！

# むすび

みなさんも、ぜひ `dict` の順序保証をご活用ください。

`OrderedDict` よ、今までありがとう。そしてさようなら！！
初心者からマークアップをはじめて約4年間、効率よくコーディングする為に意識していること

コーディングをしたいと思い仕事にしてから約4年、ずっとwebサイトを作り続けてきました。
下りてきたデザインデータを元にマークアップしデータ納品ということをしていますが、制作の際に効率よくコーディングする為に意識していることをまとめたいと思います。

## 意識していること

### 頭で設計をイメージ

まずはデザインをしっかり見て、どのような設計にするのかを**頭でイメージ**をすること。
webサイトは更新がつきものなのでベストな設計なんてものは存在しないと思いますが、よりベターな設計は何かをしっかり頭で想像することが重要だと考えています。

設計なんてまだわからないという状態だとしても、
どうhtmlを書いて、どうcssでレイアウトして、どういうアニメーション・演出を盛り込んで...
などを頭で描ききれればスムーズなマークアップができると思います。

イメージが湧かない場合は、このタイミングである程度実装方法を調べておくことをおすすめします。

### ふわっとしたまま実装を進めない

- ここにアニメーションは入れようかな
- 画像にしちゃうか、htmlで組むべきか
- これも共通モジュール？
...etc

どんなに頭でイメージしていても、コーディングの最中にはじめのイメージからそれるケースも多々あります。
そのときは、必ず**立ち止まって自分の中で設計を固め直す**ことをおすすめします。

これを随時行わないと、ぐちゃっとしたコードになってしまい、死に目を見ます。（幾度となく経験してきた）

### 記述はわかりやすく

シンプルでわかりやすいコードが一番いいと思います。
ですが、記述している時は常に「命名が長くなってしまっている」「コメントアウトかいた方がいいか」など悩みがちだったり、
時間に追われていたりします。

その時の個人的な優先度は、**わかりやすさ > コードの綺麗さ**です。
わかりやすくて綺麗が一番いいですが、そこのバランスに悩むくらいならわかりやすさを取るべきだと考えます。

もちろん時間が許す限り綺麗にしたいですが、なかなか時間がない時が多いです。
そんな時はわかりやすさを優先した方がトータル的に速いです。

## まとめ

- 頭でコーディングのイメージを固める
- 詰まったときは後回しにしない
- 記述はわかりやすさを優先

上記意識することで、トータル的な作業時間は格段に減りました。
感覚的には、頭で考える時間と手を動かす時間は五分五分くらいのときが一番スムーズな気がします。
結局は急がば回れということですね。
bash触ってる時によくやること

## bash触ってる時によくやること

### 大量のファイルをコピーしてる時の進捗を表示したい
```bash
while true
do
  date
  ls -1 input/ | wc -l 
  sleep 5
done
```

出力イメージ

```bash
Thu Sep 19 10:25:49 UTC 2019
331
Thu Sep 19 10:25:54 UTC 2019
332
```

ちょっと見やすく？以下のような感じにしてもいいですね。

```bash
while true
do
  DATETIME=$(date +%Y%m%d_%H%M%S)
  FILECOUNT=$(ls -1 input/ | wc -l )
  echo "count: ${FILECOUNT}, time: ${DATETIME} "
  sleep 5
done
```

出力イメージ


```bash
count: 347, time: 20190919_103048 
count: 347, time: 20190919_103053 
count: 348, time: 20190919_103058 
```

とめる時はctrl + c してください。

### ファイルのサイズをざっくり知りたい時

```bash
$ ls -lha
total 856K
drwxr-xr-x 1 root root 4.0K May 12 15:35 .
drwxr-xr-x 1 root root 4.0K Apr 26  2018 ..
-rw-r--r-- 1 root root  12K May 12 17:43 alternatives.log
drwxr-xr-x 1 root root 4.0K May 12 17:43 apt
-rw-r--r-- 1 root root  35K Apr 26  2018 bootstrap.log
-rw-rw---- 1 root utmp    0 Apr 26  2018 btmp
-rw-r--r-- 1 root root 407K May 12 17:43 dpkg.log
-rw-r--r-- 1 root root  32K Apr  8 23:37 faillog
-rw-r--r-- 1 root root 2.9K May 12 17:43 fontconfig.log
-rw-rw-r-- 1 root utmp 286K Apr  8 23:37 lastlog
-rw------- 1 root root  63K Apr  8 23:37 tallylog
-rw-rw-r-- 1 root utmp    0 Apr 26  2018 wtmp
```

hオプションが単位をつけてくれます。

```bash
$ ls -ltr | grep 'G'
```

とかしてもいいですね

### ディレクトリのサイズをざっくり知りたい時

容量逼迫した時の領域を特定するのによく使ってました。

```bash
$ du -h /var --max-depth=1
4.0K    /var/tmp
928K    /var/backups
20K     /var/spool
4.0K    /var/opt
4.0K    /var/local
3.0M    /var/log
4.0K    /var/mail
553M    /var/cache
13G     /var/lib
13G     /var
```

df -h とセットで使うことが多いですね。
該当の領域に cdしてdu、
値の大きいディレクトリにまたcdしてdu
。。。。でどこのディレクトリにやばいファイルがあるか特定したりします。

max-depthが階層を決めるオプションです。


### ファイル数の多いディレクトリで最近更新されたファイルをざっくり見たい時

```bash
$ ls -ltr | tail
-rw-rw-r-- 1 root utmp      0 Apr 26  2018 wtmp
-rw-rw---- 1 root utmp      0 Apr 26  2018 btmp
-rw-r--r-- 1 root root  35330 Apr 26  2018 bootstrap.log
-rw------- 1 root root  64064 Apr  8 23:37 tallylog
-rw-rw-r-- 1 root utmp 292292 Apr  8 23:37 lastlog
-rw-r--r-- 1 root root  32032 Apr  8 23:37 faillog
drwxr-xr-x 1 root root   4096 May 12 17:43 apt
-rw-r--r-- 1 root root   2960 May 12 17:43 fontconfig.log
-rw-r--r-- 1 root root 416661 May 12 17:43 dpkg.log
-rw-r--r-- 1 root root  11742 May 12 17:43 alternatives.log
```

trオプションで時刻順、かつ一番下がもっとも最近の物に並んでくれます。


### 詳細な時刻を取得する
lsにfull-timeオプションをつけると、時刻を秒以下まで表示してくれます。

```bash
$ ls --full-time
total 4739260
drwxr-xr-x 2 root root 97505280 2019-09-20 11:19:12.917880914 +0000 dir_1
drwxr-xr-x 2 root root 97665024 2019-09-20 11:19:16.170149789 +0000 dir_2
```
【質問】FirebaseのStorageにおけるダウンロードURLについて

FirebaseのStorageでは、ファイルをダウンロードする方法として、ダウンロードURLという公開用のURLを取得する方法があります。

これはユーザー認証を受けずにファイルをシェアするためのものということです。

調べてみた限り、このURLはファイルをアップロードすると、ファイルごとに必ず生成されているようです。

URLはこんな感じのものです

https://firebasestorage.googleapis.com/xxxxx/abc.jpg?alt=media&token=xxx-yyyy-zzz

気になったのは、このURLを一旦受け取ると、ファイル名の部分を適当に変えることで、他のファイルも閲覧できてしまう点です。もし通し番号のようなファイル名にしていた場合は簡単に閲覧できてしまいます。

Storageのセキュリティルールで認証ユーザーのみアクセスできるようにしていても、このURLを知っている場合は閲覧できてしまいます。

これは問題なんじゃないかと思って調べてみると、下記のようなやり取りを見つけました。
https://stackoverflow.com/questions/41789457/firebase-storage-share-download-url-a-security-risk

ここでは問題ないという話で終わっているのですが、なぜ安全と言っているのかが理解できませんでした。
公開URLに対してはセキュリティルールはなんの効力もないようですし、URLの最後にくっついているtokenパラメータは消してもアクセスできます。

これは本当に問題ないと言えるんでしょうか？
どなたか解説いただけますでしょうか。
AWS RDSのMariaDBにおいて、データベース名にハイフン使いたい場合の対処

# tl; dr
MariaDB(Mysql)のデータベース名にハイフンを入れたい場合は、`CREATE DATABASE`を直接たたこう。
その際に、データベース名はバッククォートでくくろう。
AWS RDSのGUIでは「-」が禁止文字になっている。

#説明
AWS RDSのGUIでは、データベース名にハイフンが許可されていない。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211196/40e8be95-2a2c-65f6-6edb-35669f0214ea.png)

じゃあ直接、`CREATE DATABASE`を直接たたいてみようと思ったが、構文エラーとなった。

```
MariaDB [(none)]> create database test-test;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-test' at line 1
```

調べてみた結果、ハイフンを含める場合はバッククォートが必要だった模様。
修正して書き直してみるとうまくいった。

```
MariaDB [(none)]> create database `test-test`;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> show databases like 'test%';
+------------------+
| Database (test%) |
+------------------+
| test-test        |
+------------------+
2 rows in set (0.00 sec)
```

# 環境差異がある場合
解消のために、データベース名変更対応をを行った。
`RENAME DATABASE`は使えない（はず）なので、以下のように対応しました。

1. 正しい名前で`CREATE DATABASE` を実行
2. mysqldumpにて、誤ったデータベースから、データをエクスポート
3. mysqldumpにて、正しいデータベースに、2.のデータをインポート
4. 誤ったデータベースをDROPする

#備考 
確信はないが、昔はAWS RDSのGUIでは「-」は許可されていたように思う。
根拠は、同じ手順でRDBを作っていたのに、データベース名に環境差異が出ていたため。
途中で「-」を禁止文字にしたため、こうなったという考察。
Ansibleのwith_dictが書いた順番に実行されないとき

# Ansibleでのループ使用時の注意
## with_dictはvarを書いた順番通りに実行されるとは限らない
with_dictはハッシュ値の順番でループを実行するので、書いたvarsが上から順番に実行されるわけではない


```:vars
dicts:
  2:
  1:
```

このようなvarsがあったときに以下のplaybookを実行する。
(with_dictで指定した値はitemという名前になる)

```:playbook.yml
- hosts: localhost
  tasks:
    - debug: msg="{{ item }}"
      with_dict: "{{ dicts }}"
```
実行結果は以下のようになる

```:result
TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => (item={'key': 1, 'value': 'None'}) => {
    "msg": "1"
}
ok: [localhost] => (item={'key': 2, 'value': 'None'}) => {
    "msg": "2"
}
```
varsに書いた通りであれば、2 -> 1となるはずだが、1 -> 2の順番で実行されていることが分かる。
書いた通りの順番で実行したい場合はwith_itemsを使用すればよい。


```:vars
items:
  - 2
  - 1
```

```:playbook
- hosts: localhost
  tasks:
    - debug: msg="{{ item }}"
      with_items: "{{ items }}"
```

```:result
TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => (item=2) => {
    "msg": 2
}
ok: [localhost] => (item=1) => {
    "msg": 1
}
```
書いた通りの順番で実行されていることが分かる。

フォルダ作成のときなどに、親子関係があって順番が前後することでPlaybookがコケてしまうことがあるので、そういった場合はwith_itemsを利用すると解決する。
未経験からエンジニアへ、独学８ヶ月間の挑戦

# 自己紹介
このブログでは、未経験から８ヶ月間の独学でエンジニア転職を成功させるため、
時々学んだ内容のアウトプットや進捗の記録をしていきます。


まずは簡単に身分をお明かしたいと思います。
#### 職務経歴
2016年4月　　某公立大学卒業後、国立大学法人一般事務職に就職する。
2017年2月　　退職後、ビジネスホテルにて1年程フロントスタッフを経験。
　　　　　　　外国人への接客経験から、インバウンド関連の営業職に興味を持つ。
2018年4月　　某エンターテイメント系大企業へ転職。
　　　　　　　インバウンドに向けた営業や企画・マーケティングを経験し、現在就業中。
2019年6月　　Youtube動画をきっかけにIT業界に興味をもち、mac book Airを購入。
2019年7月　　エンジニアへの転職を目指して本格的に勉強をスタート。
#### 趣味
一人旅（ヒッチハイク・JR乗り継ぎ旅・琵琶湖自転車一周など）、筋トレ、プログラミング、
音楽（ダンスミュージック・R&B・その他洋楽全般）、野球・サッカー観戦、硬式テニス
#### 9月19日時点での習熟度
Progate　→　HTML＆CSS(3周)、Ruby(2周)、Ruby on Rails(1周)、
　　　　　　　Git・Command・SQL・Sass(1周)
Rails Tutorial　→　第1章〜第8章(1周)

#### **◉今後の短期目標◉**
〜9月20日　Rails Tutorial 2周目4章まで終わらせる。
〜9月30日　Rails Tutorial 2周目14章まで一気に終わらせる。
〜10月10日　Twitter模倣したWebアプリ1つ制作。
〜10月20日　オリジナルWebアプリ制作。
〜10月31日　オリジナルWebアプリ第二弾制作。


こんな感じで頑張っていきますので、応援よろしくお願いいたします。
お名前.comでドメイン取得、ConoHaでDNS設定したら反映されなかった話(「名称」がサブドメインだった)

ConoHaのDNSにドメイン登録したけどうまく行かず、最終的に解決したものの結構「ポカン」な内容で、検索しても中々出てこない理由だったので残しておきます。

僕のような初学者がハマってしまった時に少しでも参考になれば嬉しいです。


# 背景
ConoHaのVPSを借りてDjnagoのアプリケーションを設置、お名前.comで取得したドメインを使いたい。Conoha側で設定したけどいつまで経っても名前解決しない・・・

# 手順・試した事
以下の記事を参考にさせていただきました。単純なので間違えるはずはないと思っていたら、僕のポカミスでした。（※参考記事自体は全く間違っていません。読み違えている僕が悪いです。）

<手順>
・[ご利用ガイドDNS（GeoDNS）を使う](https://support.conoha.jp/v/geodns/)
・[お名前.comでドメインを取得してConoHaで公開するまで](https://qiita.com/sugra511/items/3b05423d4adeeec5cdd4)

<試した事>
・3日程度待つ（浸透までに時間がかかる）
・お名前のNSの登録順を変えてみる
・お名前のNS名の後に何故か「.」が付くので消す（自動で付くものだった）
・Who isをちゃんと登録しているかお名前で確認
　https://teratail.com/questions/53458
・nslookupで8.8.8.8で探してみる
etc.

⇒コンソールでチェック。該当なしの通知。

```bash

$ nslookup　ドメイン名
$ nslookup ドメイン名 ネームサーバー

** server can't find ドメイン名: NXDOMAIN
```

# 凡ミス 「名称」部分を修正
結論、ConoHaのこの「名称」部分を”www”で登録していたが、これがサブドメインの登録のことだったっぽい。ということでココを「@」にしたら無事反映されました。（何も入力しなくても良いみたい）
@はこのドメインのことを指す記号らしい。（理解度が低くてすみません）

![スクリーンショット_2019-09-16_23_07_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244525/5c3a0a7e-8819-fd7d-4fca-2e398c88d74d.png)

![スクリーンショット_2019-09-17_23_30_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244525/b443d86a-81c8-f4c0-50c8-99655c2f0ca3.png)

もちろん`www.ドメイン`を使いたい場合は`www`登録ですが。

TTLやタイプは調べて理解していましたが、「名称」というのが何を意味しているのか分からず`www`の有り無しどちらも登録してくれるのかな？程度に流していたのが良くなかったですね。

同じ状況の人がいればご参考に。
無料の時系列データまとめ#1


最近，時系列データを用いた予測，クラスタリングや異常検知の手法検討を始めたため，無料で入手できる時系列データベースをまとめました．
二次利用ができるかどうか等は，それぞれのデータの規約をご確認ください．

# 脳波の時系列データ
2015年のkaggleのコンペディションで, 脳波から人の動作を予測するものがありました．
脳波データと動作のイベントデータが存在するため， 時系列予測だけではなくクラスタリングや異常検知の例にも使えます．
十分に学習可能なデータ量があり，多次元の時系列データであることも良い点です．

**コンペのリンク** : [https://www.kaggle.com/c/grasp-and-lift-eeg-detection/](https://www.kaggle.com/c/grasp-and-lift-eeg-detection/)

kaggleへの登録とコンペへの参加をするとデータが入手できます．

# UEA & UCR Time Series Classification Repository

時系列データのクラスタリングように整備されたデータベースです．
データの中には，

1. 心電図のデータ
1. 自動車やロボットのセンサーデータ
1. デジタルペンを使って書くときのモーションデータ

など，様々なデータがあります．

学習データが少ない場合があるので，注意が必要です．

**リンク**：http://www.timeseriesclassification.com/dataset.php

# 為替データ（注文もできます）

時系列解析を始めた人が一度は夢見るのはFXでいい予測をして，お金をもうけることだと思います．
OANDAというFX業者がAPIを公開しています．
そのAPIを使って為替データを取得しましょう!!
さらに，このAPIを使って，python上で注文もできます．

1. OANDAでデモ口座を登録する(本当にお金を動かしたい人は正式な口座を開設してください．)
2. デモ口座のacount IDとaccess_tokenを取得
3. pip install oandapyV20
4. pythonを使ってデータを取得

登録とかはほかサイトを引用してください．

[こことか](http://discexuno.wp.xdomain.jp/machine-learning/how_to_use_oanda_rest_v20_api/)

以下はデータ取得のサンプルコードです．
為替の時系列データが，指定した間隔ごとにcsvファイルとして出力されます．

```python

from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments
import pandas as pd

# 取得したアカウントIDとアクセストークンで書き換えてください．
accountID = '***'
access_token = '***'

# api開始
api = API(access_token=access_token)

# 取得したい為替リストの指定
instrument_list=["USD_JPY","EUR_JPY","GBP_JPY","CAD_JPY","ZAR_JPY","TRY_JPY","CHF_JPY","AUD_JPY","NZD_JPY"]

# 取得したい時間間隔の指定
time_length_list = ['M1','M5','M10','M15','M30','H1','H2','H3','H4']

# データ取得関数
def get_market_df(params):
    df_list = []

    for instrument in instrument_list:
        r = instruments.InstrumentsCandles(instrument=instrument, params=params)
        api.request(r)


        data = []
        for raw in r.response['candles']:
            data.append([raw['time'], raw['mid']['o']])

        df = pd.DataFrame(data)
        df.columns = ['time', instrument]
        df.time = pd.to_datetime(df.time)
        df[instrument] = df[instrument].map(float)

        df_list.append(df)

    df = df_list[0]
    for i in range(len(df_list)-1):
        df = pd.merge(df,df_list[i+1],on = 'time',how='inner')

    return df

# データの取得と保存
for time_length in time_length_list:
    params = {
        "count": 5000,
        "granularity": time_length
    }

    df = get_market_df(params)
    df.to_csv(time_length + '.csv')

```


# その他

時系列データベースの推移が↓でまとめられています．
面白い．

https://techlife.cookpad.com/entry/timeseries-database-001
[Rust] docs.rsのビルド環境が変わります

# はじめに
[docs.rs](https://docs.rs)は[crates.io](https://crates.io)で公開されたRustのクレートのドキュメントを生成・ホスティングしてくれるサービスです。このdocs.rsでドキュメントを生成する環境が変更されるということで以下のアナウンスが出ています。変更タイミングは2019/9/30です。

[**Upcoming docs.rs changes**](https://blog.rust-lang.org/2019/09/18/upcoming-docsrs-changes.html)

詳細はリンク先を見ていただければいいのですが、簡単なまとめと新環境でのビルド確認方法について書いておきます。

# 新ビルド環境のまとめ

* ビルドはDockerイメージ（[rustops/crates-build-env](https://hub.docker.com/r/rustops/crates-build-env)）内で行われる
* 実行時間は最大15分（ターゲットプラットフォーム毎）
* メモリ使用量は最大3GB
* ビルド中のネットワークアクセス禁止
* ビルド中の`target/`以外のディレクトリへの書き込み禁止

これまで依存ライブラリ不足などでビルドに失敗した場合は、メンテナが手動でサーバにインストールするなどで対応していたようですが、Dockerイメージにすることでそのあたりを運用しやすくするということだと思われます。

ネットワークアクセス禁止と書き込み禁止はたいていのクレートには関係ないと思いますが、`build.rs`でいろいろやっている場合は影響があるかもしれません。

# 新環境でのビルドを試す

Dockerイメージになったことで、手元でもdocs.rsと同じ環境でビルドできるようになります。


まず以下のようにDocker環境に入ります。

```console
$ docker pull rustops/crates-build-env
$ docker run --rm --memory 3221225472 -it rustops/crates-build-env bash
```

Docker内ではRustのインストール、gitリポジトリのクローン、ビルドを行います。
（Rustは最新のnightlyが使われるようです）

```console
# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain nightly -y
# source $HOME/.cargo/env
# git clone https://github.com/dalance/sv-parser
# cd sv-parser/sv-parser
# cargo fetch
# time cargo doc --no-deps
```

依存クレートのfetchにかかる時間は15分制限には含まれないようなので、まず`cargo fetch`で依存クレートを取得してから時間を測ります。最後の`cargo doc`の実行時間が15分を超えなければOKです。

手元で一番大きなクレート（[sv-parser](https://github.com/dalance/sv-parser)）で試してみました。[Tokei](https://github.com/XAMPPRocky/tokei)でソースコードのサイズを測ったところRustのコードで4万行ほどです。

```
-------------------------------------------------------------------------------
 Language            Files        Lines         Code     Comments       Blanks
-------------------------------------------------------------------------------
 Markdown                1           89           89            0            0
 Rust                  182        44469        39673          811         3985
 SystemVerilog           4           31           26            0            5
 TOML                    8          154          136            0           18
-------------------------------------------------------------------------------
 Total                 195        44743        39924          811         4008
-------------------------------------------------------------------------------
```

リリースビルドだと10分近くかかりますが、docだけなら3分ほどでした。
（実行環境はXeon Gold 6134 @ 3.20GHz）

```
 Documenting sv-parser v0.1.4 (/sv-parser/sv-parser)
    Finished dev [unoptimized + debuginfo] target(s) in 2m 55s

real    2m55.417s
user    3m49.382s
sys     0m14.006s
```

docs.rsで使われているCPUが何なのか分かりませんが、15分あれば十分なようです。
Pythonのターミナル出力に色付けする。


coloredlogsというモジュールを使用する。

```py
pip install coloredlogs
```

# 単純なPRINTの色付け

```py
import logging
import coloredlogs

class bcolors:
    # https://godoc.org/github.com/whitedevops/colors
    BGRED = '\033[41m'
    BGGREEN = '\033[42m'
    BGYELLOW = '\033[43m'
    BGBLUE = '\033[44m'
    BGMAGENDA = '\033[45m'
    BGCYAN = '\033[46m'
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    MAGENDA = '\033[95m'
    CYAN = '\033[96m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
    

logger = logging.getLogger()
coloredlogs.install(level='DEBUG', logger=logger)

print(bcolors.BLUE + "------- Colored STDOUT Test -------" + bcolors.ENDC)
```

これで色付けされて出力されるはず。部分的な色付けも可能。

# loggerとの組み合わせ
loggerと組み合わせて、ファイルに書き込みつつ、標準出力にも出す。

```py
import logging
import coloredlogs

coloredlogs.CAN_USE_BOLD_FONT = True
coloredlogs.DEFAULT_FIELD_STYLES = {'asctime': {'color': 'green'},
                                    'hostname': {'color': 'magenta'},
                                    'levelname': {'color': 'black', 'bold': True},
                                    'name': {'color': 'blue'},
                                    'programname': {'color': 'cyan'}
                                    }
coloredlogs.DEFAULT_LEVEL_STYLES = {'critical': {'color': 'red', 'bold': True},
                                    'error': {'color': 'red'},
                                    'warning': {'color': 'yellow'},
                                    'notice': {'color': 'magenta'},
                                    'info': {},
                                    'debug': {'color': 'green'},
                                    'spam': {'color': 'green', 'faint': True},
                                    'success': {'color': 'green', 'bold': True},
                                    'verbose': {'color': 'blue'}
                                    }

logger = logging.getLogger(__file__)
coloredlogs.install(level='INFO', logger=logger, fmt='%(asctime)s : %(message)s', datefmt='%Y/%m/%d %H:%M:%S')
handler = logging.FileHandler('output.log', 'w', 'utf-8')
handler.setFormatter(logging.Formatter('%(asctime)s : %(levelname)s : %(message)s', datefmt='%Y/%m/%d %H:%M:%S'))
logger.addHandler(handler)

logger.error("This is ERROR!")
logger.warning("This is WARNING.")
logger.info("This is INFO.")
logger.debug("This is DEBUG..")  # Not Printed
```

DEFAULT_FIELD_STYLES、DEFAULT_LEVEL_STYLESを変更することで、特定の部分やログのレベルの色を変更することが可能。

デフォルト値などは以下のリンクを参照。
https://coloredlogs.readthedocs.io/en/latest/api.html#id24

# 課題
## 色+太字(color and bold)も可能らしいが、できない。

```py
print(bcolors.BLUE + bcolors.BOLD +"------- Colored STDOUT Test -------" + bcolors.ENDC)
```

ただの青になる…

```py
BOLDBLUE = '\033[1;94m'
print(bcolors.BOLDBLUE + "------- Colored STDOUT Test -------" + bcolors.ENDC)
```

ただの青になる…

```py
>>> RED = '\033[91m'
>>> BOLD = '\033[1m'
>>> ENDC = '\033[0m'
>>> print(RED+'TEST'+ENDC)
TEST
>>> print(RED+BOLD+'TEST'+ENDC)
TEST
```

ここだと表現できないが、インタープリタで上記ならOK。調査中。

## 出力を標準出力にしたい
coloredlogs.installを行うとデフォルトではstderrがハンドラとして自動的に追加されるらしい。
そのため、正確にはこれは標準エラー出力に出ていると思うのだが、stream=sys.stdoutを指定すると、コンソール実行の場合うまく色がつかない…。調査中。
【2019年度版】Seleniumで最近のEdgeのUIテストをしようとして色々モヤッとした話

## 背景
Webアプリを開発してた
対象ブラウザに Edge が入ってた
Selenium を使ってUIテストを自動化したいとなった

## 問題点
Aさんの環境で動いていたSeleniumによるUIテストが、なぜか私の環境でエラーになる。
エラー内容

```
OpenQA.Selenium.WebDriverException : A exception with a null response was thrown sending an HTTP request to the remote WebDriver server for URL http://localhost:65382/session. 
The status of the exception was UnknownError, and the message was: An error occurred while sending the request. 
Unable to read data from the transport connection: 既存の接続はリモート ホストに強制的に切断されました。
```

What's?

## 原因
自分のPCにインストールされているEdgeのバージョンと、
Seleniumで使われているEdge用のWebDriverのバージョンが違うことで上記エラーが発生していた。
参考記事：https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/17578227/

## 解決方法
「じゃあ、自分のPCのEdgeのバージョンと、Seleniumで使われているEdge用のWebDriverのバージョンを揃えよう」
ということでサクッと対応しようと思ったが、

#### やり方が分かりにく過ぎてモヤッとした・・・

自分のPCにインストールされているEdgeと同じバージョンのEdge用WebDriver を手に入れる方法を紹介します。

① MicrosoftのWebDriver置き場から、自分のPCのEdgeのバージョンに合ったものをダウンロード
　https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188038/7cc22b74-4a6b-5ce6-2959-3ddc47927d54.png)

　自分のPCのEdgeのバージョンの確認のしかた
　https://support.microsoft.com/ja-jp/help/4027011/microsoft-edge-find-out-which-version-you-have
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188038/ba35f92c-4bce-70d5-363e-3c75ec708708.png)


　ここで、同じバージョンが見つかった方（Edge17以下）、無事入手できました。
　見つからなかった方（Edge18以上）、次へ進んで下さい。


② Windowsに追加された機能でインストールして入手する
　https://blogs.msdn.microsoft.com/osamum/2018/10/04/new-feature-of-edgehtml/ 
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188038/58a648a4-77cf-e9d4-f922-53618fb39d09.png)

　上記のように、Windowsの「設定」⇒「アプリ」⇒「アプリと機能」⇒「オプション機能」を開いて、
　機能の追加で、Microsoft WebDriver を選択してインストール
　
####　保存されたMicrosoftWebDriver.exe が、C:\Windows\System32 の直下に置いてあります。
　※フォルダじゃなくてファイルなので注意
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188038/a0d9a5b4-1c2f-55a7-6213-9002f0204b53.png)

それをSelenium実行フォルダ下にコピーするなり、パスを通すなりする。
※既にEdge17用等のWebDriverが配置されていたら置き換えること

#### これで通るようになりました。

なんでこんな解りにくいところに置いてあるんだ・・・。

参考になったら「いいね」を押していただけると嬉しいです。
最近のWindowsにおいて、SeleniumでEdgeのテストをしようとしてモヤッとする人が減ることを祈っております。
Uncaught SyntaxError: Unexpected token N in JSON  の解決方法

エラー発生時のコードは以下の通りである。

```js
let data = JSON.parse(yourString);
```

解決方法は、NaNをnullに変えるだけである。
解決方法を以下に示す。

```js
let data = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
```

## 参考
https://stackoverflow.com/questions/15228651/how-to-parse-json-string-containing-nan-in-node-js
更新(API)があるLPページをS3とCloudFrontに移した話

# はじめに
よくあるAPIサーバとStaticコンテンツサーバの構成を廃止して、S3とCloudFrontに移行してコスト削減をした話

# 背景
世の中には商品などのリリースを出すためのLPサイトが無数にあるのではないでしょうか。
自分が担当していたLPサイトもよく見る下記のようなシステムで動いていました。冗長構成は省きます。
![music-old.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210/ac1e5abe-0cb4-aedf-b041-8b4d4798468d.png)

説明すると、
商品情報はMySQLに保存され、登録・更新があるので管理ツールからデータを追加・更新出来ます。管理ツールで登録されたデータはフロントのAjaxから呼び出されAPIサーバ経由で配信されます。

ただ、上記システムだとEC2やMySQLがいるためインフラコストが多大にかかっていました。そこで、更新(API)があるLPページをS3とCloudFron(CF)に移設した際のtipsを説明します。

# 目指したシステム構成
S3+CloudFrontのシンプルなLPサイト
![music-new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210/2efdd534-46cf-ab8e-6f18-572b5094f4cd.png)


# tips
- staticコンテンツをS3に配置
- APIで配信していたJSONデータをS3に配置しメタデータを付与
- S3をCFで配信
- (おまけ)PCとSPの切り替えはLambda@Edgeでコントロール

## staticコンテンツをS3に配置
1. S3にstaticコンテンツ配置
2. ROOT配下のディレクトリもindex.htmlを参照させたいとき  
　　[Webホスティングの設定](https://qiita.com/dogwood008/items/a92abae789f4b0466f38#s3で静的webページをホスティングする) を参考にする。  
　　http://domain/hoge/ を /hoge/index.html で配置している場合は↑を設定するのが簡単。

## APIで配信していたJSONデータをS3に配置しメタデータを付与
1. APIで返していたJSONデータをJSONファイルに書き出す  
　　curlなどを使ってshellで回してJSONを保存すのが良い
2. JSONファイルをS3に配置
3. JSONファイルのメタデータに  `Context-Type:application/json; charset=utf-8`  付ける

![S3_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210/f8902b69-9f15-ea22-53d4-37ffbd10309e.png)


## (おまけ)PCとSPの切り替えはLambda@Edgeでコントロール
今まではNginxでUAを見てURIの先頭の `/pc/` と  `/sp/` をコントロールしていました。
これをS3+CF環境で実現するためにLambda@Edgeを利用して、URIのコントロールを実現しました。

CloudFronｔのビュアーリクエスに下記Lambda@Edgeを仕込むと  `/` をUAを見て判断してくれます。 

```python
##python##
import json

sp_list = [
  'Android',
  'iPhone',
  'iPad'
]

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']
    ua = headers['user-agent'][0]['value']
    
    # 書き換え対象
    if request['uri'] in ['/', '/index.html', '']:
        for sp in sp_list:
            if sp in ua:
                request['uri'] = '/sp/'
                return request
        request['uri'] = '/pc/'
        
    return request
```

## 今回話さなかったこと
新たなデータを登録したい時はJSONを作る必要がありますが、頑張ってください。

# まとめ
EC2とMySQLで作られたシステムを
S3とCFのみを使った簡潔なシステムにリプレイス出来、運用コストを大幅に削減できました。
Rubyの基礎まとめ

Rubyのデータ型とか条件分岐、繰り返しとか基礎of基礎をまとめていきます。

##### 背景
railsを使用しアプリを作成するのに集中してしまいそもそものRubyの基礎を最近疎かにしてしまっているため。
どこでも使う、絶対使うことであるので備忘録としてまとめていきます。

##データ型
データがどのようなデータかを区別するためのもの。
例えば「１」というオブジェクトがあったとき、それは数字としての１なのか文字列としての"1"ですかと分かりません。それを判断するためのデータ型
##### 文字列
文字列は「""」もしくは「''」で囲むことによって定義する。

```ruby:hoge.rb
puts "hello world"
puts 'hello world'

puts "こんにちは"+"ゴリラさん"
# +で連結が可能
```

#####数値
「""」や「''」を使わずそのまま数字を入力し定義する。
数字を文字列として扱うか数値として扱うかで処理が異なる

```ruby:hoge.rb
puts 1
puts 1 + 1
puts "1" + "1"
#実行結果
１
２
１１
```

#####変数
データを格納するための領域　~~ex.おもちゃをしまっておくおもちゃ箱~~
**scivola様からいただいたコメントを基に追記（2019/9/20）**
>　Rubyにおいて、ひとつのオブジェクトが複数の変数に代入された状態があるため箱であると説明がつかなくなる。
よって変数とは名前のついた札であり、代入とは札とオブジェクトを紐づけるという認識。

[変数に関し参考させていただいたURL]([title](http://...))

変数名 = オブジェクト
で定義する

```ruby:hoge.rb
hello = "こんにちは"
puts hello
#実行結果
こんにちは

puts "#{hello}佐藤さん"
#実行結果
こんにちは佐藤さん
```
変数を文字列内に含む場合は#{変数}で囲む。変数だけでなく計算式も展開することができる。これを式展開という。
この時は文字列を「""」で囲む。「''」の場合展開がされないので注意。

#####配列
複数のオブジェクトを一括で管理すために使う
配列名（複数系） = [1,2,3,4]

```ruby:hoge.rb
names = ["佐藤", "鈴木", "田中"]
puts names
puts names[0]
puts names[2]
#実行結果
佐藤
鈴木
田中
佐藤
田中
```

配列は前から0,1,2...というように０からインデックス番号が振られている。その番号を指定することで配列内の任意の番号を取り出すことができる。

#####ハッシュ
名前、年齢など複数の値を格納するために用いられる。
ハッシュはrailsで様々登場してくるので理解が必要。

```ruby:hoge.rb
user = {name: "田中", age: 21}
puts user[:name]
puts user[:age]
#実行結果
田中
２１
```
「name:」をキーという。「:name」の書き方をシンボルと言い、キーを呼び出す際に使われる。

##　条件分岐とか繰り返し処理とか

#####条件分岐（if式）
条件分岐とは、指定した条件によって成り立つか否かによって処理が変化すること。
「もし〇〇なら××を行う」といった感じ。Rubyにおいてif式が用いられる。

```ruby:hoge.rb
if 条件
 処理内容
end

age = 21
if age >= 20
  puts "あなたは成人しています"
end
#実行結果
あなたは成人しています
```

**条件に当てはまらない場合の処理、複数の条件の場合**
条件に当てはまらない場合の処理を追加する場合はelseを用いる
複数の条件を指定する場合はelsifを用いる

```ruby:hoge.rb

age = 18
if age >= 20
  puts "あなたは成人しています"
 else
  puts "あなたは成人していません"
end
#実行結果
あなたは成人していません

num = 5
if num == 4
  puts "数字は４です"
 elsif num == 5
  puts "数字は５です"
 else
  puts "数字は４でも５でもありません"
end
#実行結果
数字は５です
```

#####繰り返し処理（eachメソッド、while式）
処理をループして行いたいときに用いられる。
繰り返し処理にはfor式、eachメソッドがある。今回はfor式は割愛し、よく使われるeachメソッドを書いていく。
while式は条件を伴った繰り返し処理の際に使用される。

```ruby:hoge.rb

配列.each do |変数|
 実行したい処理
end

names = ["佐藤", "田中", "鈴木"]
names.each do |name|
 puts name
end

#実行結果
佐藤
田中
鈴木

#ハッシュを使った繰り返し処理
users = [{name: "佐藤", age: 21}, {name: "田中", age: 18}]

users.each do |user|
 puts "名前は#{user[:name]}で#{user[:age]}歳です"
end

#実行結果
名前は佐藤で21歳です
名前は田中で18歳です

```

while文

```ruby:hoge.rb
while 条件式 do
 実行したい処理
end

num = １
while num <= 5
 puts num
 num += 1
#実行結果
1
2
3
4
5
```

##最後に
以上Rubyにおける基礎of基礎となるデータ型や条件分岐、繰り返し処理をまとめました。

##追記・編集
2019/9/20:
変数に関して、#{変数}の展開に関して、if, each, whileに関して追記および編集修正
Android QからバックグラウンドでActivityの起動に制限が設けられた

## はじめに
僕が担当させて頂いているAndroidアプリにて、Android Qの端末でとある問題が発生していたため発見しました。

## 変更内容
この記事に書いてある通りです。
https://developer.android.com/preview/privacy/background-activity-starts?hl=ja

Android Qからは、上記URLに書いてある"Activityの起動が許可される条件"の内、1つまたは複数の条件が満たされないとActivityが起動できなくなります。
Goで扱うやつら（go.mod / go.sum / Makefile）って何なの？

#はじめに
Go言語の初学者の方へ！

- go.mod
- go.sum
- Makefile

って知ってますか？

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_77401_fa94ce08-da06-0dad-60be-68f5f4f9d359.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233118/e7ab6670-504d-c62c-5d9e-0b2d1ccfc173.gif)
Gifのソース：https://qiita.com/nkitgamesake/items/7e45309a180e1a905337


これらを知ることで開発が分かりやすくなるかも知れないので、誰かのお助けになることを祈って、今日も記事を書いてみます！

#go.mod って何？
モジュールの依存関係を管理するファイルですね！

モジュールとは？
>ソフトウェアのモジュールの場合、プログラム全体を構成する機能ごとのひとまとまりのことを指し、プログラムモジュールとも呼ぶ。
モジュールの集まりがアプリケーションなどになる。

モジュール：https://kotobank.jp/word/%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-9341

詳細：https://qiita.com/propella/items/e49bccc88f3cc2407745
元ソース：https://github.com/golang/go/wiki/Modules#modules


#go.sumって何？

依存モジュールのチェックサムの管理をしてるファイルですね！

チェックサムとは？
>データの信頼性を確認するためのチェック方法のひとつ。データを送受信する際、正しくデータが送信できたかどうかの確認に使われる。

チェックサム：https://kotobank.jp/word/%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%B5%E3%83%A0-5718

このサイトいわく、go.sum は githubに追加しない方が良いみたいですね！
https://medium.com/@ponde_m/go-1-11-4-%E4%BB%A5%E4%B8%8A%E3%81%A7-go-modules-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82%E8%A7%A3%E6%B1%BA%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89-checksum-mismatch-c5528eaebd72

#Makefileって何？

プログラムのビルド作業を自動化するツールですね！

こちらのサイトを参考にしてください！
https://qiita.com/seihmd/items/42996d5abb14badf775e

#まとめ

今回の疑問は３つのファイルに関してでした！

- go.mod ： モジュールを管理するファイル
- go.sum ： 依存モジュールのチェックサムの管理をしてるファイル
- Makefile ： プログラムのビルド作業を自動化するツール

これらについて気になる人は更に調べてみてください！