OmniAICreator/Qiita-1.07M huggingface dataset:
ポリゴンモデルをHOUDINIでポイントクラウドにしてTouchDesignerで描画する

#はじめに
ポイントクラウドは主に3Dスキャンをする際に得られるポイントのみの3Dデータです。
今回はテクスチャ付きのポリゴンモデルデータから以下のようなポイントクラウドを生成し、TouchDesignerで描画してみたいと思います。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Houdiniでもろもろ素材を作りTouchDesignerでレンダリングしました<a href="https://twitter.com/hashtag/Houdini?src=hash&amp;ref_src=twsrc%5Etfw">#Houdini</a> <a href="https://twitter.com/hashtag/TouchDesigner?src=hash&amp;ref_src=twsrc%5Etfw">#TouchDesigner</a> <a href="https://t.co/f2V3RuEolD">pic.twitter.com/f2V3RuEolD</a></p>&mdash; ツミキルーム\Takashi Kawamura (@tsumiki_room) <a href="https://twitter.com/tsumiki_room/status/1321152457985015809?ref_src=twsrc%5Etfw">October 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##使用するポリゴンモデル
ポジションとともにカラーも取り出したいのでUVベースでマッピングされたテクスチャ付きのポリゴンモデルを用意します。

今回は地球を用意しました。
![Earth.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/b3f69987-66f4-a685-5b9b-a0d72f1a8ab9.png)

##HOUDINIで色付きポイントクラウドを作る
HOUDINIでの仕上がりはこんな具合です。
![pT1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/924bc9d2-368c-998d-0cd6-495b41a699a8.png)

ネットワークはこんな感じ。
![nodes.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152366/e2a0da75-d968-467e-2bef-663150517bd3.png)

###1.File
モデルデータを読み込んでいます。
UVを保持できるデータ形式なら何でもいいです。

###2.transform
サイズや位置の微調整をしています。
大きすぎたり、座標が中心からずれている場合はバウンディングボックスの座標を取得するなどしてあらかじめ調整しておきましょう。
中心座標などの取得方法はこちら→[エクスプレッションクックブック](https://www.sidefx.com/ja/docs/houdini/ref/expression_cookbook.html)

###3.scatter
メッシュの表面にポイントを散らすノードです。
Options > Force Total Count
でポイント数を調整します。
先ほどの地球の画像は30万ポイントです。
ポリゴンの頂点座標をもとにポイントクラウドを作成することもできますが、
よくできたモデルであればあるほど不必要な頂点が削り取られて全体の頂点数に偏りが出るものです。
ポイントクラウドの粗密を避けるためにScatterはとても重要な工程です。

###4.attribute from Map
UVをもとに貼られたテクスチャからカラーのアトリビュートを作成します。
Texture Mapでテクスチャ画像を参照しましょう。

###5.attribute delete
不必要なアトリビュートを削除します。
PとCd以外を削除しましょう。

###6.sort
ポイントのID順を整理します。
Point Sortで任意のSort方法を選びます。
今回はByYでY軸の下から上へと並べています。

###7.書き出す
・sort以降のOPを右クリック>save>geometry を選択します。
・Save geometryで.plyファイルを書き出します。
[.ply拡張子について](https://ja.wikipedia.org/wiki/PLY_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%BD%A2%E5%BC%8F)#:~:text=PLY%E3%81%AFPolygon%20File%20Format,%E3%81%9F%E3%82%81%E3%81%AB%E8%A8%AD%E8%A8%88%E3%81%95%E3%82%8C%E3%81%9F%E3%80%82)
.plyは3dスキャンによく使われる形式で、座標やカラーなどさまざまなアトリビュートを保持することが可能です。


　
以上でHOUDINIでの作業はおしまいです。
##TouchDesignerでポイントクラウドを描画する
あとは.plyデータをpoint File in TOPで読み込むだけです。
HOUDINIで書き出したファイルをTouchDesignerにドラッグ＆ドロップしてみてください。
勝手にpoint File in TOPが生成されたと思います。

なお、TouchDesignerでの作業は以下のリンク先が詳しいです。そちらを参考にしてください。

　[ポイントクラウドを扱う-Toyoshi Morioka](https://note.com/toyoshimorioka/n/na8b33b9bf8c3?magazine_key=m5328d8af9465)

##まとめ
HOUDINIはとても便利なツールです。
ぜひみなさん使ってみてください。
AWS AmplifyでPythonのFunctionをCI/CDするとbuildに失敗する問題の対処方法

題名の通り、AWS AmplifyでPythonのFunctionをCI/CDするとbuildに失敗する問題に遭遇しました。

## 結論(対処方法)

ビルド設定のamplify.ymlに以下を追記することでbuildを通すことができました。

```yml
version: 1
backend:
  phases:
    build:
      commands:
        # ここから追記 >>>
        - export BASE_PATH=$(pwd)
        - yum install -y gcc openssl-devel bzip2-devel libffi-devel python3.8-pip
        - cd /opt && wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz
        - cd /opt && tar xzf Python-3.8.2.tgz 
        - cd /opt/Python-3.8.2 && ./configure --enable-optimizations
        - cd /opt/Python-3.8.2 && make altinstall
        - pip3.8 install --user pipenv
        - ln -fs /usr/local/bin/python3.8 /usr/bin/python3
        - ln -fs /usr/local/bin/pip3.8 /usr/bin/pip3
        - cd $BASE_PATH
        # <<< ここまで追記
        - '# Execute Amplify CLI with the helper script'
        - amplifyPush --simple
```

## 発生した問題

CI/CDのビルドフェーズにて、下記のようにPython3.8以上が必要な旨が出力されています。

```bash
2020-10-27T19:21:49.678Z [INFO]: python3 found but version Python 3.7.4 is less than the minimum required version.
                                 You must have python >= 3.8 installed and available on your PATH as "python3". It can be installed from https://www.python.org/downloads
                                 You must have pipenv installed and available on your PATH as "pipenv". It can be installed by running "pip3 install --user pipenv".
2020-10-27T19:21:49.679Z [WARNING]: ✖ An error occurred when pushing the resources to the cloud
                                    ✖ There was an error initializing your environment.
2020-10-27T19:21:49.687Z [INFO]: init failed
2020-10-27T19:21:49.688Z [INFO]: Error: Missing required dependencies to package tatamifmmusiclibrary7312699f
                                 at buildResource (/root/.nvm/versions/node/v10.16.0/lib/node_modules/@aws-amplify/cli/node_modules/amplify-provider-awscloudformation/src/build-resources.js:30:11)
                                 at process._tickCallback (internal/process/next_tick.js:68:7)
2020-10-27T19:21:49.699Z [ERROR]: !!! Build failed
2020-10-27T19:21:49.699Z [ERROR]: !!! Non-Zero Exit Code detected
2020-10-27T19:21:49.699Z [INFO]: # Starting environment caching...
2020-10-27T19:21:49.700Z [INFO]: # Environment caching completed
```

## 原因

Amplify CLIで `amplify add function` してランタイムにPythonを選択すると、内部的にはPython 3.8が選択されるようです。
一方、CI/CDで使用するAmazon Linux2でインストールされるPythonは3.7.4のため、バージョンの不一致が起こってしまいます。

## 解決のヒント

経験上、Amplifyの問題はGitHub Issueにあがっているケースが多いです。
本件も以下Issueにて既に議論がされていました。


[Amplify can't find Python3.8 on build phase of CI/CD #595](https://github.com/aws-amplify/amplify-console/issues/595)

カスタムイメージを作成した人もいるようですが、あまり非公式なイメージは使いたくないので、多少buildに時間がかかってもPython 3.8をインストールしたほうが良いと判断しました。
いずれAmazon Linux2でインストールされるPythonのバージョンが上がると思うので、暫定対処で良いでしょう。
【Obsidian】Template機能の使い方

# １．はじめに

## 「Obsidianって何？」という方へ
こちらのページを参考にしてください。
- https://qiita.com/koKekkou/items/f1f684f0d7dadb658d02

# ２．関連する設定

## エディタ
- Show frontmatter

## プラグイン
- Templates
- Slides

## ホットキー
-  Insert template

## プラグイン/Templates
- 設定内容を確認して、必要なら調整する。

# ３．操作の例

1. Open new Zettelkasten noteを```Ctrl+N```で実行。
2. メモ（note）のタイトル欄に、タイトルを追記。
3.  Insert templateを```Ctrl+I```で実行し、その後は不要な行を削除。そして編集。
- ```Ctrl+N```、 ```Ctrl+I```は「ホットキー」で設定済み。

# ４．サンプル

## frontmatter
```
---
title: 
insert: {{date}} {{time}}
update: {{date}} {{time}}
type: note
---
#論点
#人物 
#言葉 
#ライフハック 
#00総論
#情報科学
#哲学
#歴史
#社会科学 
#技術工学
#産業
#言語学
#文学
from: {{URL}}

---
```
- 「不要なものは、挿入後にVIM操作で行削除を行う」を前提に作成。
- タグキーワードは図書分類を参考にしています。

## 書く内容が「5つから選ぶ」タイプ
```
- 項目名1：→○選択A、○選択B、○選択C、○選択D、選択E
- 項目名2-1：→選択A
- 項目名2-2：→選択B
- 項目名2-3：→選択C
- 項目名2-4：→選択D
- 項目名2-5：→選択E
```
- 「不要な行や文字を削除する」という前提で作る。
 
# 以上
IAMのイベントを検知して処理する(EventBridge→SNS→Lambda)

少し前に以下の記事を書きました
https://qiita.com/kaikusakari/items/06b47a45de30107a2ab1

単独アカウントでIAMのイベントを取得する場合のケースでしたが、クロスアカウント環境下でIAMのイベントを集約して検知したい場合の手段になります。

前の記事に記載した通り、IAMのイベントは「us-east-1」リージョンにEventBridgeを作らないと取得できません。（他にもConfigを使うなど取得する手段はありますが、EventBridgeがお勧めです）

## 想定環境
・「ap-northeast-1」を主に使っている
・クロスアカウント
・1つのアカウントにログやイベントを集約して監視専用のアカウントとする

## 準備するもの
**イベント送信先**
ログ集約アカウント
・「ap-northeast-1」でLambdaを作り、イベントを検知してチャットアプリに通知する
・「us-east-1」から「ap-northeast-1」のLambdaをCallするためのSNSトピックを作成する
・「us-east-1」で各アカウントからIAMのイベントを受け取る用のイベントバス+ルールを作る

**イベント送信元**
各アカウント
・「us-east-1」でIAMイベント取得用のルールを作る

## 構築（イベント送信先）
**Lambda**
Lambda(Node)の実装例

```javascript:index.js
exports.handler = async (event) => {
  const json = JSON.parse(event.Records[0].Sns.Message);
  console.log("account " + json.account);
  console.log("eventName " + json.detail.eventName);

    const response = {
        statusCode: 200,
        body: JSON.stringify('account ' + event.account + ' ' + event.name),
    };
    return response;
};
```

**SNSのトピックを作成**
上記Lambdaの名前をサブスクライブに指定する

**EventBridge（イベントバス）**
送信元アカウントの12桁数字を入力する

**EventBridge（ルールの作成）**
イベントパターンのイベント名に「Create*」のような指定はできません。

```json:eventpattern
{
  "source": [
    "aws.iam"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "iam.amazonaws.com"
    ],
    "eventName": [
      "CreateUser",
      "CreatePolicy"
    ]
  }
}
```

## 構築（イベント送信元）

**EventBridge（ルールの作成）**
ターゲットにイベント送信先のイベントバスを指定します

```json:eventpattern
{
  "source": [
    "aws.iam"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "iam.amazonaws.com"
    ],
    "eventName": [
      "CreateUser",
      "CreatePolicy"
    ]
  }
}
```

## 結果
CreateUser、CreatePolicyのイベント発生時にLambdaが動くのでチャットアプリなりに通知して適宜監視するなど利用できるかと存じます。
（EventBridgeはCloudtrail経由のため実際の操作から10分程度遅れて通知を受け取ることになります）
Helm パッケージアップデート方法

Datadog の k8s へのデプロイに Helm を使っている。

Datadog Helm Chart のアップデート方法をメモしておく。


### Datadog Helm Chart のバージョンを確認できる場所

[Tags · DataDog/helm-charts](https://github.com/DataDog/helm-charts/tags)

2020年10月27日時点での最新バージョン
`datadog-2.4.30 `


### 現在デプロイされてる chart のバージョン確認

```
$ helm list -n {Namespace}

NAME      	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART         	APP VERSION
datadog-v1	{Namespace}	36      	2020-10-15 21:50:01.152307 +0900 JST	deployed	datadog-2.4.24	7
```


### ローカルの helm リポジトリのバージョン確認

※ ここをコマンドラインでサクッとスマートに確認できるやり方が知りたい・・😓

```
$ cat $HOME/Library/Caches/helm/repository/datadog-index.yaml | grep version | head
      version: =2.8.11
    version: 2.4.20
```

[kubernetes - Where are helm charts stored locally? - Stack Overflow](https://stackoverflow.com/questions/62924278/where-are-helm-charts-stored-locally)


### 現在ローカルにインストールしている Helm リポジトリ一覧

```
$ helm repo list

NAME            	URL
datadog         	https://helm.datadoghq.com
ingress-nginx   	https://kubernetes.github.io/ingress-nginx
stable          	https://charts.helm.sh/stable
external-secrets	https://external-secrets.github.io/kubernetes-external-secrets/
```

### Helmのパッケージであるチャートを検索

```
helm search repo datadog
NAME                    	CHART VERSION	APP VERSION	DESCRIPTION
datadog/datadog         	2.4.30       	7          	Datadog Agent
datadog/datadog-operator	0.1.2        	0.3.1      	Datadog Operator
stable/datadog          	2.3.42       	7          	DEPRECATED Datadog Agent
```


### アップデートコマンド
```
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "datadog" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
```


### アップデートされたことを確認

```
$ cat $HOME/Library/Caches/helm/repository/datadog-index.yaml | grep version | head
      version: =2.8.11
    version: 2.4.30
```


### K8s 環境にデプロイしてみても、アップデートされることを確認

```
$ helm list -n {Namespace}

NAME      	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART         	APP VERSION
datadog-v1	{Namespace}	44      	2020-10-28 02:49:37.980447 +0900 JST	deployed	datadog-2.4.30	7
```

### `helm diff` コマンドでリリース間の差分を確認

```
$ helm diff revision datadog 1 2

（〜中略〜）

-     chart: "datadog-2.5.1"
+     chart: "datadog-2.6.2"

（〜中略〜）

-     helm.sh/chart: "datadog-2.5.1"
+     helm.sh/chart: "datadog-2.6.2"

（〜中略〜）
```

### `helm uninstall {helm 名}` コマンドで helm アンインストール

```
$ helm uninstall {helm 名}
```


### Datadog サポートチケットへログ等々を送るコマンド

```
# Datadog Cluster Agent の場合
kubectl exec <POD_NAME> -it datadog-cluster-agent flare <CASE_ID>

# Datadog Agent の場合
kubectl exec <POD_NAME> -it agent flare <CASE_ID>
```
to_sメソッドについて。

#to_sメソッドの説明
**数値が持つメソッドです。数値を文字列に変換してくれます。
ちなみに、 to_sのsの意味は「string(文字列)」です。**
以下の例を見てください。

```java:【例】irb
# 数値「20」にto_sメソッドをつけて実行
irb(main):001:0> 20.to_s
=> "20"
```

to_sメソッドによって、文字列"20"が実行結果になっています。

それでは、文字列と数値を連結させて、
"i am 20 years old."を表示しましょう。

#irbで以下のコードを実行しましょう

では、実際にターミナルでto_sメソッドを試してみましょう。

```java:ターミナル
# to_sで数値を文字列に変換し、連結
irb(main):001:0> "i am " + 20.to_s + " years old."

# 続けてこのように表示されれば成功
=> i am 20 years old.
```

「はじめから文字列<font color="Red">"20"</font>を用意すればよかったのでは？」と思うかも
しれません。しかし、足し算した結果を文字列として利用したい場合など、
数値を文字列に変換する<font color="Red">**to_sメソッド**</font>を利用する場面は多くあります。
この方法は必ず覚えておきましょう。

反対に文字列を数値に変換するメソッドもあります。それがto_iメソッドです。これは文字列がもつメソッドです。
to_iメソッドについては、次回説明させていただきます。

#まとめ

**to_sメソッドとは、数値を文字列に変換するメソッド。**

#####以上。
JavaScriptでGETパラメータ（URIクエリ）を取得する方法（コードスニペット）

サンプルのクエリ：

```
?a=0&b=2&a=1&d[]=0&d[]=1&こんにちは=hoge=piyo
```

## 値にイコールが含まれてることと配列を考慮しない

```js
const $_GET = Object.fromEntries(decodeURIComponent(location.search).slice(1).split('&').map(prop => prop.split('=')));
```

結果：

```json
{
  "a": "1",
  "b": "2",
  "d[]": "1",
  "こんにちは": "hoge"
}
```

## 配列を考慮しない

```js
const $_GET = Object.fromEntries(location.search.slice(1).split('&').map(prop => {
    const data = prop.split('=');

    return [data[0], decodeURIComponent(data.slice(1).join('='))]
}));
```

結果：

```json
{
  "a": "1",
  "b": "2",
  "d[]": "1",
  "こんにちは": "hoge=piyo"
}
```

## 配列も考慮する

```js
const $_GET = (query => {
	const dataSet = {};

	for (const data of query) {
	    const key = data[0];
	    const val = decodeURIComponent(data.slice(1).join('='));

	    if (!key) {
	        continue;
	    }

	    if (key.endsWith('[]')) {
	        const _key = key.slice(0, -2);

	        dataSet[_key] ??= [];
	        dataSet[_key].push(val);

	        continue;
	    }

		dataSet[key] = val;
	}

	return dataSet;
})(location.search.slice(1).split('&').map(prop => prop.split('=')));
```

結果：

```json
{
  "a": "1",
  "b": "2",
  "d": [
    "0",
    "1"
  ],
  "こんにちは": "hoge=piyo"
}
```
React とか いろんなところ で役に立つ三項演算子

# React とか いろんなところ で役に立つ三項演算子

三項演算子とは以下のようなもの

```js
isflag ? console.log("いいよ") : console.log("ダメだよ");
```

if 文だと

```js
if (isflag) {
  console.log("いいよ");
} else {
  console.log("ダメだよ");
}
```

## 何が役に立つの？

三項演算子は、非常にスマートに書ける。
しかし、見にくい

コードが見にくくなってしまう。

という問題があるらしい

## 使いどころ　アロー関数

js には、アロー関数というのがある。

```js
() => console.log("アロー関数");
```

map や Object.key などでよく私は、使います。
ここで、if 文を書くとします。

```js
const a = [1, 2, 3, 4, 5];
a.map((data) => {
  if (data == 2) {
    console.log(data);
  }
});

// ====log=====
// 2
```

2 が表示されます。
こういった書き方よりもこう書いたほうがコードが見やすいと思います。

```js
a.map((data) => (data == 2 ? console.log(data) : null));
```

## まとめ

コードは書いていると、長くなります。
長いコードをスクロールするのも大変だと思っています。

条件式をしたとしても表示するかしないか、出力するかどうか
などで数行分書くのは、大変です。

React などでは、状態によって表示するかどうかを決める時があります。そういったとき IF 文なのか三項演算子なのかは、好みによります。

私は、単純な処理なら三項演算子を使います。
好みです！！
Amazon CloudWatch Logsにおける任意のログストリームページのURLを動的に生成する

## はじめに
CloudWatch Logsと言えば、AWSを使っている人は必ずと言っていいほどお世話になるログ管理のサービスです。
サービス自体はシンプルでとても便利なんですが、なぜかURLがちょっと特殊な作りになっていて、僕自身、任意のログストリームページのURLを動的に生成しようとしたとき「ん？これどうなってんの・・・？」とはじめは戸惑いました。

ちょっとしたTips程度ですが、同様のことで悩んでいる人がいるかもなので記事にしておきます。


## CloudWatch LogsのURL構造はどうなっているか

URLは以下のようになっています。
ちなみに`hoge-lambda`というLambdaを実行したときのログストリームのものです。

```
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups/log-group/$252Faws$252Flambda$252Fhoge-lambda/log-events/2020$252F10$252F27$252F$255B$2524LATEST$255D542bf48a98944249b069342e12861b99
```

分かりやすくするために、以下のようにURLを分解してみます。
こうすると`定型部分 + ロググループ名 + 定型部分 +　ログストリーム名`の構造になっていることが分かります。

```
1. 定型部分
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups/log-group/

2. ロググループ名
$252Faws$252Flambda$252Fhoge-lambda

3. 定型部分
/log-events/

4. ログストリーム名
2020$252F10$252F27$252F$255B$2524LATEST$255D542bf48a98944249b069342e12861b99
```


## ロググループ名・ログストリーム名はURLエンコードされている

次に、ロググループ名とログストリーム名に注目します。
コンソール画面から正しいロググループ名とログストリーム名を引っ張ってきてそれぞれを比較してみます。

```
正しいロググループ名
/aws/lambda/hoge-lambda

URLに含まれているロググループ名
$252Faws$252Flambda$252Fhoge-lambda
```

```
正しいログストリーム名
2020/10/27/[$LATEST]542bf48a98944249b069342e12861b99

URLに含まれているログストリーム名
2020$252F10$252F27$252F$255B$2524LATEST$255D542bf48a98944249b069342e12861b99
```

上記を見比べると、それぞれ以下のように変換されていることが分かりました。 
しかし、この変換をするようなエンコード方式ってどんなだろう・・・となります。

```
/ -> $252F
[ -> $255B
$ -> $2524
] -> $255D
```

これ、**実はURLエンコードを2回実施されている**んです。
途中経過も含めると以下のように変換されています。

```
　　 1発目    2発目
/ -> %2F -> $252F
[ -> %5B -> $255B
$ -> %24 -> $2524
] -> %5D -> $255D
```

つまり、CloudWatch Logsで使われているURLは以下のように作られていることが分かります。

`定型部分 + URLエンコードを2回実施したロググループ名 + 定型部分 +　URLエンコードを2回実施したログストリーム名`


## まとめ
重要なのは、**ロググループ名とログストリーム名の部分のみをURLエンコード×2回実施すればいい**という点だけです。
ここさえ抑えておけば、あとは定型部分と結合するだけで動的にURLが生成できるので簡単ですね。

CloudWatch LogsのSubscription Filterなどを使ってログ監視を実装するのはよくあるユースケースかと思いますが、アラート通知する内容に生成したログストリームページのURLを埋め込んであげると、エラー発生時のログ確認が素早くできるようになるので個人的にオススメです。
ElixirでABC162のA,B,C問題を解いてみる！

# はじめに

- [Elixir](https://elixir-lang.org/)でやってみました


# 問題
- [AtCoder Beginner Contest 162](https://atcoder.jp/contests/abc162)
- A〜Cまで解いてみます
- 今回は[Doctests](https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-with.html#doctests)を書いていません

# 準備
- [Elixir](https://elixir-lang.org/)をインストールしましょう
    - 手前味噌ですが、[インストール](https://qiita.com/torifukukaiou/items/d04d0273749c41eb50af#0-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)等ご参考にしてください
- プロジェクトを作っておきます

```console
$ mix new at_coder
$ cd at_coder
```

# [問題A - Lucky 7](https://atcoder.jp/contests/abc162/tasks/abc162_a)
- 問題文はリンク先をご参照くださいませ :bow:

```elixir
defmodule Main do
  def main do
    IO.read(:line) |> String.trim() |> String.contains?("7") |> if(do: "Yes", else: "No") |> IO.puts
  end
end
```

- [提出](https://atcoder.jp/contests/abc162/submissions/17687750)の際にはモジュール名は`Main`にしておいてください
- :tada::tada::tada:
- この調子で以下、B問題、C問題を解いていきます

# [問題B - FizzBuzz Sum](https://atcoder.jp/contests/abc162/tasks/abc162_b)

```elixir
defmodule Main do
  def main do
    n = IO.read(:line) |> String.trim() |> String.to_integer()
    1..n |> Enum.reduce(0, fn i, acc -> if rem(i,3) == 0 or rem(i,5) == 0, do: acc, else: acc + i end) |> IO.puts()
  end
end
```

- [提出](https://atcoder.jp/contests/abc162/submissions/17687605)の際にはモジュール名は`Main`にしておいてください
- :tada::tada::tada:


# [問題C - Sum of gcd of Tuples (Easy)](https://atcoder.jp/contests/abc162/tasks/abc162_c)
- 問題文はリンク先をご参照くださいませ :bow:


```elixir
defmodule Main do
  def main do
    k = IO.read(:line) |> String.trim() |> String.to_integer()
    list = for i <- 1..k, j <- 1..k, do: Integer.gcd(i, j)
    1..k |> Enum.flat_map(fn i -> Enum.map(list, & Integer.gcd(&1, i)) end) |> Enum.sum |> IO.puts
  end
end
```


- [提出](https://atcoder.jp/contests/abc162/submissions/17693015)の際にはモジュール名は`Main`にしておいてください
- タイムアウトになるかなあと心配しましたがセーフ(1689 ms)でした
- [Integer.gcd/2](https://hexdocs.pm/elixir/Integer.html#gcd/2)は最大公約数(The greatest common divisor)を計算してくれます


# Wrapping Up :qiita-fabicon: 
- A〜Cは自力でいけました！ :smile:
- 問題みてiexでちょっとためして行けそうだったので`Main`モジュールをこさえて人間コンパイル? のみ通して直接提出してみました
    - それで今回は[Doctests](https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-with.html#doctests)は書いていません
        - 言い訳にはならない?
    - コンパイルエラーださずに`AC`取れました
- Enjoy [Elixir](https://elixir-lang.org/)!!! :fire::rocket::rocket::rocket:
csvのグループ分けと最小値の取得（pandas）


## この記事の内容

- csvファイルをいくつかのグループに分けて処理する

##まえがき
卒業研究の過程で、そこそこ大きめのcsvファイルを処理する必要があった。具体的には、id列の値にしたがって行をグループ分けし、各グループの中でdistance列が最小の行を取得するという作業。以下ではその時に用いた手法を記す。

##本題
コードは以下の通り。

```python
import pandas as pd

data = pd.read_csv("元データファイルへのパス")
df = pd.DataFrame(columns=data.columns)
###これが最終的な出力ファイルになる。列名はdataと同じで、この段階では空の状態。

dic = {}

for name,group in data.groupby('id'):
   dic[name] = group

list = dic['id'].unique()

for i in list:
   k = dic[i]
   l = k['distance'].idxmin()
   m = data.iloc[l:l+1,:]
   df = df.append(m)

df.to_csv("保存したいディレクトリのパス")

```
もっと簡潔なコードがあるような気がするが…
元データの列名を引き継いだDataFrameの作成や、ある列の値が最小となる行番号の取得など、結構いろいろな場面で役立つ。
【MySQL】外部キー制約を一時的に無効にする

# 目的
開発環境やテスト環境でデータの操作上、
外部キー制約を一時的にしたい

# 方法
無効にする

```
SET FOREIGN_KEY_CHECKS = 0
```

有効に戻す

```
SET FOREIGN_KEY_CHECKS = 1
```
日付時刻をpickerで入力できるvue-datetime

こんな感じで、日付と時刻のpicker入力が実装できます。

[![demo](https://raw.githubusercontent.com/mariomka/vue-datetime/v1.x/demo/demo.gif)](http://mariomka.github.io/vue-datetime)

Vuetify.jsにdate pickerとtime pickerはありましたが、2つを同時にできるものはなかったので探してみたところ、**[vue-datetime](https://github.com/mariomka/vue-datetime)** というものがありましたので、有難く使わせていただきます。

# 使用方法

vue-datetimeをインポート

```
import { Datetime } from 'vue-datetime'
import 'vue-datetime/dist/vue-datetime.css'
```

componentsに追加

```
components: {
     datetime: Datetime
},
```
datetimeタグにtypeで「datetime」を指定すると使用できる。
dateやtimeを指定すると片方だけの使用も可能です。

```
<datetime v-model="○○" type="datetime"></datetime>
```

### ラベルのつけ方

```
<datetime v-model="○○" type="datetime" input-id="startDate">
   <label slot="before" for="startDate">ラベル名</label>
</datetime>
```

### その他パラメータ

Parameter | Type | Default | Description
--------- | ---- | ------- | -----------
v-model (*required*) | ISO 8601 `String` | - | Datetime.
type | `String` | `date` | Picker type: date, datetime or time.
input-id | `String` | `''` | Id for the input.
input-class | `String`, `Array` or `Object` | `''` | Class for the input.
input-style | `String`, `Array` or `Object` | `''` | Style for the input.
hidden-name | `String` | `null` | Name for hidden input with raw value. See #51.
value-zone | `String` | `UTC` | Time zone for the value.
zone | `String` | `local` | Time zone for the picker.
format | `Object` or `String` | `DateTime.DATE_MED`, `DateTime.DATETIME_MED` or `DateTime.TIME_24_SIMPLE` | Input date format. Luxon [presets](https://moment.github.io/luxon/docs/manual/formatting.html#tolocalestring--strings-for-humans-) or [tokens](https://moment.github.io/luxon/docs/manual/formatting.html#formatting-with-tokens--strings-for-cthulhu-).
phrases | `Object` | `{ok: 'Ok', cancel: 'Cancel'}` | Phrases.
use12-hour | `Boolean` | `false` | Display 12 hour (AM/PM) mode
hour-step | `Number` | `1` | Hour step.
minute-step | `Number` | `1` | Minute step.
min-datetime | ISO 8601 `String` | `null` | Minimum datetime.
max-datetime | ISO 8601 `String` | `null` | Maximum datetime.
auto | `Boolean` | `false` | Auto continue/close on select.
week-start | `Number` | auto from locale if _weekstart_ is available or `1` | First day of the week. 1 is Monday and 7 is Sunday.
flow | `Array` | Depends of *type* | Customize steps flow, steps available: time, date, month, year. Example: ['year', 'date', 'time']
title | `String` | `''` | Popup title.
hide-backdrop | `Boolean` | `false` | Show/Hide backdrop.
backdrop-click | `Boolean` | `true` | Enable/Disable backdrop click to cancel (outside click).
Swift初心者　Xcodeでのデバッグ術メモ

#概要
この記事はプログラミング初心者である筆者の備忘録です。
随時追記予定。


#Swiにおけるデバッグ方法まとめ
- Break pointとは
- LLDBコマンド
- ビューデバッガ
- 参考

#Break pointとは
テスト中にbreake point を設定した行で処理を止めてくれる。
これを利用すると、1行ずつデバッグができる。
設定するには、下の画像のようにエディタ左端の数字をクリックするとチェックが付き設定できる。
![スクリーンショット 2020-10-27 23.58.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695350/d2606224-1e3e-76d4-2a30-a6174c8a6204.png)

このまま実行すると下の画像のようにBreak pointで処理が停止し、デバッグエリアが出てくる。
デバッグエリアでコマンドを利用したりして色々デバッグができる。
![スクリーンショット 2020-10-28 0.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695350/dbb18186-10f6-229b-bbb0-d07a5fdc0c85.png)

#LLBDコマンド
LLBDとはソフトウェアデバッガの1つ（たぶん）。
デバッグエリアのコンソール画面でコマンドを打ち込んでデバッグを行う。

###poコマンド
おそらくprint objectの略だと思われる。

```
po <変数>
```
で指定した変数の値を出力できる。便利である。
![スクリーンショット 2020-10-28 0.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695350/8e1b802b-5fbd-a668-34a1-0a9306820f3b.png)
###expressionコマンド
```
expression <変数> = <値>
```
で指定した変数に任意の値を代入できる。poコマンドと組み合わせれば、いちいちビルドし直すことなくprintデバッグが可能。うれしい。
![スクリーンショット 2020-10-28 0.18.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695350/1d703e0c-1be4-4317-1260-ffffbdec07c0.png)
#ビューデバッガ
Xcode標準装備のView Hierarchy行う。直訳するとビューの階層。アプリ上のViewの階層構造を把握できる。
![スクリーンショット 2020-10-28 0.22.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695350/9aa7a2a1-ac6a-5c8b-27d9-294550aa93f7.png)
上の画像中の赤丸で囲ったボタンをクリックすると起動する。
実はまだ使ったことがないのでここからは追々追記することにする。
#参考
https://developer.apple.com/videos/play/wwdc2018/412
PdfSharpでPDFを結合する

[本記事は、自分サイトのこの記事と同一内容です。](https://hagiayato.github.io/my-site/jekyll/update/2020/11/27/PdfSharp-merge.html)
<h1>はじめに</h1>
PDFを結合するプログラムを日本語で調べると、出てくる多くはiTextSharpを使う方法です。
これでもいいのですが、無料版のライセンスがAPGLであり商用ソフトを作る場合には支障をきたします。
そこで今回は、MITライセンスのpdfSharpを用いてPDFを結合してみます。<br/>
※ライセンスの違いは以下の記事を参照
　「オープンソースライセンス、どれなら使っても良いの？？」@fate_shelled
　https://qiita.com/fate_shelled/items/a928709d7610cee5aa66
<h1>準備</h1>
まずはC#のプロジェクトをvisual studioで作成します。
次にそのプロジェクトにPdfSharpをインストールします。<br/>
　１．プロジェクト　＞　NuGet パッケージの管理を開く
　２．検索欄に"pdfSharp"を入力する
　３．右側"インストール"ボタンをクリックする

<h1>コード実装</h1>
いよいよコードを実装します。
まずはライブラリをコードにインポートします。

```C#
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
```
つついて実際に処理を実装します。
１．結合後PDFのオブジェクトを作成

```C#
// PDFオブジェクト作成
PdfDocument document = new PdfDocument()
```
２．結合するPDFを開く

```C#
// file：結合するファイルのパス
// PdfDocumentOpenMode.Import：PDFを読み取りモードで開く
// 結合するPDFオブジェクトを作成
PdfDocument inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import)
```
３．結合するPDFの全ページを結合後PDFに追加する

```C#
// 頁全件ループ
foreach (PdfPage page in inputDocument.Pages)
{
    // PDF頁を追加
    document.AddPage(page);
}
// 結合するPDFを閉じる
inputDocument.Close();
```
４．２，３を結合するPDFの数だけ繰り返す
５．PDFを保存し閉じる

```C#
// PDF保存
document.Save(selectedPath);
// PDFを閉じる
document.Close();
```
このようにして実際に作成したコードは以下の中の関数"pdfMerge"です。
https://github.com/HagiAyato/PDFmerger/blob/main/PDFmerger/IOpg.cs<br/>
以下補足
・結合するファイルのパスはListにまとめておき、foreachを回して上記処理２～４を繰り替えすのがおすすめです。
・PDFオブジェクト作成時はusing句を使うことで、確実に処理終了時の解放ができます。
・例外処理(try-catch等)もお忘れなく。
<h1>ライセンス表記</h1>
PdfSharpはMITライセンスのライブラリで、使用する際はライセンスの表記が必要です。
ソースコード中やreadmeなどにライセンス表記を入れましょう。

```C#
/*
 * PdfSharpライセンス表記
 * Creator of PDFsharp is empira Software GmbH
 * Kirchstrase 19 53840 Troisdorf Germany
 * http://www.empira.de
 * PDFsharp (R) is a registered trademark of empira Software GmbH
 * Released under the MIT license
 * http://www.pdfsharp.net/PDFsharp_License.ashx?AspxAutoDetectCookieSupport=1
 */
```
【Java】DBマイグレーション（Flyway）

DBマイグレーション（スキーマ管理）ライブラリであるFlywayを利用する。
以下のような目的で利用する。
・DBの定義やその変更に関する情報を一箇所で管理する。
・その情報に基づき最新のDBの状態を自動で再現する。

# MavenプロジェクトでFlywayを利用するための設定

```:pom.xml
<dependency>
  <groupId>org.flywaydb</groupId>
  <artifactId>flyway-core</artifactId>
</dependency>
```

# SpringBootの設定ファイルを修正（application.yml）
SpringBootはデフォルトで、flywayが起動時に自動実行される。

```:
flyway:
  baseline-on-migrate: true
  baselineVersionAsString: 0.0.0
  baseline-description: Initial
```

# テーブルの定義ファイルを追加
以下フォルダにsqlファイルを追加する。
src/main/resources/db/migration/

・マイグレーションファイル
管理対象のスキーマに適用する変更内容を記述したSQLファイル
以下の規則で作成する。
V{version}__{description}.sql

例）
V0_0_1__createTable.sql

・リピータブルマイグレーションファイル
ビュー、プロシージャ、ファンクションなどのオブジェクトのマイグレーションを行いたい場合に使用する。
以下の規則で作成する。
R__{description}.sql

例）
R__createView.sql

# 公式サイト
https://flywaydb.org/
RESTAPIとは

## RESTAPIとは
> RESTful API(REST API)とは、Webシステムを外部から利用するためのプログラムの呼び出し規約(API)の種類の一つで、RESTと呼ばれる設計原則に従って策定されたもの。RESTそのものは適用範囲の広い抽象的なモデルだが、一般的にはRESTの考え方をWeb APIに適用したものをRESTful APIと呼んでいる。

RESTful APIでは、URL/URIですべてのリソースを一意に識別し、セッション管理や状態管理などを行わない(ステートレス)。同じURLに対する呼び出しには常に同じ結果が返されることが期待される。

また、リソースの操作はHTTPメソッドによって指定(取得ならGETメソッド、書き込みならPOSTメソッド)され、結果はXMLやHTML、JSONなどで返される。また、処理結果はHTTPステータスコードで通知するという原則が含まれることもある。

引用：[IT用語辞典 e-Words](http://e-words.jp/w/RESTful_API.html)

## RESTの設計原則

■RESTの4つの設計原則
1. セッションなどの状態管理を行わない。(やり取りされる情報はそれ自体で完結して解釈することができる(ステートレス))
2. 情報を操作する命令の体系、インターフェースが予め定義・共有されている。（HTTPのGETやPOSTメソッドなど）
3. すべての情報は汎用的な構文で一意に識別される。（URLやURIなど）
4. 情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができる。（HTTPステータスなど）

リソースに対してURLが対応づけられる。（そのため、URLが名詞的になることが多い）

RESTfulについてよくわからない方はこの記事の ```RESTなAPIとそうではないAPIの例```を参照にしてください
[0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)

これらの原則に則ったWebサービスをRESTfulなサービスといいます。
それぞれについてもう少し説明していきます。


## メリット/デメリット

### メリット
* アプリケーションの中のリソースがURIで示せる。
 - アドレス欄に入力すれば、そのリソースを参照できる。どのリソースを操作しているのか明確
* URIに規則が生まれることで、利用する開発者が楽になる
* ステートレスにすることで、スケーラビリティが向上
 - アクセスの集中に耐えやすい構造にできる
* 統合の相対的な容易さ
 - 標準的なデータフォーマット(XMLやJSON)を扱うことで、他システムとの連携が容易になる
 - RESTに基づいたWebアプリでは、インタフェースが固定されている為互換性の問題が発生しない

### デメリット
* 設定するREST設計をしやすいAPIフレームワークを選定する必要性。APIフレームワークの選定がREST設計に合っていないとURIの設定・変更難しくなり、コードが汚くなりうる

## URI設計について

```
// 悪い例
https://~~~/api/getUsers/nakamura
// 良い例
https://~~~/api/users/nakamura
```

RESTでは一つのリソースに対してアドレス指定可能なURIが用意されていることが推奨されています。
URI設計はリソースに対してディレクトリ構成模すとシンプルかつ直感的にサービスの指定が行えます。
URIはあくまでもリソースを示すべきなので名詞のみで構成されることが原則です。```/api/getUsers```ではなく```/api/users```とします。

## インターフェースの統一
RESTで用いられるHTTPメソッドは下記のようにCRUD操作と対応付けられます。

|処理 | HTTPメソッド | CRUD操作 |
| :--: | :--: | :--: |
|登録 | POST | CREATE |
| 取得 | GET | READ |
| 更新 | PUT | UPDATE |
| 削除 | DELETE | DELETE |

RESTではURIで表されたリソースに対して各HTTPメソッドで操作を行います。
以下のようなURI設計が一般的です。

```
登録 POST    /users/userId/events
取得 GET     /users/userId/events/eventId
更新 PUT     /users/userId/events/eventId
削除 DELETE  /users/userId/events/eventId
```
登録処理はInsert処理であるためIDの設定をする必要がありません。
取得、更新、削除はレコード指定してCRUD操作を行う必要があるためIDをURIに付与します。

## HTTPステータスコード
REST APIではリソースへのアクセス結果をHTTPステータスコードとして返します。クライアント側は、HTTPステータスコードを基に処理のハンドリングを行います。

以下に代表的なものをいくつか記載しておきます。

| コード | メッセージ | 説明 |
| :-- | :-- | :-- |
| 200 | OK | 成功 |
| 201 | Created | 作成成功（POST） |
| 204 | No Content | 成功だが、返すリソースはなし |
| 400 | Bad Request | 汎用エラー |
| 401 | Unauthorized | 認証エラー |
| 403 | Forbidden | 権限エラー |
| 404 | Not Found | 該当リソース無し |
| 405 | Method Not Allowed | メソッド未対応 |
| 409 | Conflict | リソースなどの衝突（作成時など） |
| 500 | Internal Server Error | サーバーエラー |

## 参考
[REST入門 基礎知識](https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa)
[【Spring BootでREST API】#1 イントロダクション](https://b1tblog.com/2020/03/13/spring-rest-1/)
[0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)
【Java】パスワード生成（Pasay）

パスワードポリシー実施ライブラリであるPasayを利用する。
設定可能なルールセットを使用してパスワードを生成することができる。

# MavenプロジェクトでPasayを利用するための設定

```pom.xml
<dependency>
    <groupId>org.passay</groupId>
    <artifactId>passay</artifactId>
    <version>1.6.0</version>
</dependency>
```

# 大文字小文字英数字混合の8桁のパスワードを生成するコード

```:Password.java
public class Password {

    public static String generate() {
        List<CharacterRule> rules = Arrays.asList(
                  new CharacterRule(EnglishCharacterData.UpperCase, 1),
                  new CharacterRule(EnglishCharacterData.LowerCase, 1),
                  new CharacterRule(EnglishCharacterData.Digit, 1)
            );
        PasswordGenerator generator = new PasswordGenerator();
        String password = generator.generatePassword(8, rules);
        return password;
    }
}
```

# テストコード

```:PasswordTest.java

public class PasswordTest {

    @Test
    public void testGenerate() {
        String password = Password.generate();
        assertTrue(password.length() == 8);
        assertTrue(password.matches(".*[a-z].*"));
        assertTrue(password.matches(".*[0-9].*"));
        assertTrue(password.matches(".*[A-Z].*"));
    }
}
```
RaspberryPiにZABBIX Serverをインストール

#概要
[公式サイト](https://www.zabbix.com/jp/download?zabbix=5.0&os_distribution=raspbian&os_version=10_buster&db=mysql&ws=apache)に乗っている方法ではインストールできなかった為、自分が成功したパターンを記録しておきます。
初投稿です。

```
OS: Raspberry Pi OS 8.0
Zabbix: 5.0LTS
DB: MySQL
Web server: Apache
```
#障壁と解決方法
障壁となった部分:
・mysqlがインストールできない
>解決方法:mariadb-serverをインストール

・mysql用のテーブル定義ファイルがダウンロードできない。

>解決方法:別マシンでダウンロードして転送

これ以下は最初からインストールする場合の操作を記述します。

#リポジトリの登録
この辺は公式サイトのまま進めましょう

```
wget https://repo.zabbix.com/zabbix/5.0/raspbian/pool/main/z/zabbix-release/zabbix-release_5.0-1+buster_all.deb
```
```
dpkg -i zabbix-release_5.0-1+buster_all.deb
```
```
apt update
```

#パッケージのインストール
```
apt install zabbix-server-mysql zabbix-frontend-php zabbix-apache-conf zabbix-agent
```
mysqlが見つからない為、mariadb-serverを追加でインストール

```
apt install mariadb-server
```
#mariadbの設定
以下のコマンドでmariadbを起動

```
systemctl start mariadb.service
```
mysqlコマンドでローカルホストに実行中のmariadbにログイン。パスワードはデフォルトで"password"

```
sudo mysql
```
zabbix用のデータベースを作成する。

```
mysql> create database zabbix character set utf8 collate utf8_bin;
mysql> create user zabbix@localhost identified by 'password';
mysql> grant all privileges on zabbix.* to zabbix@localhost;
mysql> quit;
```
テーブル定義などを行うファイルを解凍し、mysqlにパイプするコマンドが乗っているが、

```
zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix
//ファイルが見つからない為動かない
```

自分の環境だとcreate.sql.gzがダウンロードされなかった為、別のマシン(debian)でパッケージインストールを行い、そこでダウンロードされたファイルをSCPでコピーした。


コピーが終わったら、コピー先のフォルダで以下を実行

```
sudo zcat create.sql.gz |sudo mysql zabbix
```
これでZabbixに必要なテーブルが定義された。

#Apacheの設定

```
sudo nano /etc/zabbix/apache.conf
```

で設定ファイル編集

```
php_value date.timezone Europe/Riga
とある部分を見つけ
php_value date.timezone Asia/Tokyo
に変更し、保存(日本時間の場合)
```

以下のコマンドで zabbix-server zabbix-agent apache2を開始、ついでに自動起動有効化

```
systemctl restart zabbix-server zabbix-agent apache2
systemctl enable zabbix-server zabbix-agent apache2
```

Apacheが起動するので、ブラウザから以下のアドレスへアクセス
http://{アドレス}/Zabbix
例) http://localhost/Zabbix


#ブラウザで初期設定
基本的に次へ次へで大丈夫ですが、Zabbixのデータベースに設定したパスワードは入力が必要です。
Zabbixアカウントのログイン画面が出たら成功です。以下の情報でログインできます。
ID:Adimin
Pass:zabbix(デフォルト)
![スクリーンショット 2020-10-27 23.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829293/43bfedf4-9fe3-a037-2f4f-3703d55a112a.png)
ダッシュボード画面:
![スクリーンショット 2020-10-27 23.49.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829293/0d5013d9-9c12-26af-2821-760f9d61c6ac.png)

#あとがき
公式サイトのようにうまくいけば一番なのですが、障壁が多かった為、記録として投稿しました。
ホストの登録や、Zabbix-senderの使い方などは改めて記事にしたいと思います。
GRUBとは

## 勉強前のイメージ

Linuxのブートローダー
GRUB、新しい方がGRUB2？

## 調査

### GRUBとは

GNU GRand Unified Boot loader の略
システム起動時にロードするインストール済みのオペレーティングシステム(OS)、カーネルを選択できるプログラム

### そもそもブートローダーとは？

1. 電源を入れるとBIOSがマスターブートレコード(MBR)を見に行く
2. マスターブートレコード(MBR)の中のブートローダーを見て、パーティションテーブルを参照
3. パーティションテーブルからブートセクタがわかり、ブートセクタの中にOSプログラムがあるのでそれを読み込み、OSが起動する

この流れで行くと、2の「マスターブートレコード(MBR)の中の `ブートローダー` を見て、パーティションテーブルを参照」 
ここに、ブートローダーが出てきます。
OSを起動する前の処理にブートローダーが出現します。

以下はCentOSのブートローダーの画面になります。

![無題 - ペイント 2020-10-26 16.09.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/34103086-13ba-c4db-a950-0816dac274f1.png)


### GRUBの種類

- GRUB Legacy(バージョン0.9x系)

GRUB Legacy は上流のメンテナンスがなく、サポートも打ち切られている
`grub-install` コマンドでインストールすることが出来るが、何もなければGRUB2を使うことが推奨されている

- GRUB 2(バージョン1.9x系)

GRUB Legacyの後継
BIOS、UEFIからのブートが出来る
GRUB Legacyよりブートが速い

### GRUB Legacy と GRUB 2 の違い

- 設定ファイルの書式が変更
- GRUB2は設定を複数のファイルに分散して保存するようになった
- GRUB2では UEFIファームウェア をサポートするようになった
	- これによって、2TB以上の大容量のドライブをサポート出来るようになった

### 設定ファイル

- GRUB Legacy
	- /boot/grub/grub.conf or /boot/grub/menu.lst

- GRUB 2
	- /etc/default/grub と /etc/grub.d
	- update-grubコマンドを実行して /boot/grub/grub.cfg を生成する

## 勉強後のイメージ

もう何も考えなくても多分普通にOSインストールしたらGRUB 2なんだと思う。
CentOS7ではデフォルトGRUB2だとあったし。
昔、ubuntuで2TB以上のHDD入れるときに詰まった記憶がある、あれがGRUB Legacy。

## 参考

- [E.2. GRUB](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/installation_guide/s1-grub-whatis)
- [マスターブートレコード (MBR)](https://wa3.i-3-i.info/word15557.html)
- [旧BIOSを進化させたUEFI、その基本を解説（前編：役割と概要）](https://www.pc-koubou.jp/magazine/1257)
- [GRUB Legacy](https://wiki.archlinux.jp/index.php/GRUB_Legacy)
- [GRUB](http://www.pasokuma.net/linux/os/linuxstructure/grub.html)
- [a. ブートローダ](http://www2.it-shikaku.jp/top30.php?hidari=101-02-02.php&migi=km101-02.php&bk=1)
GitHubプライベートリポジトリのCloneでremote: Repository not found.

GitHubのプライベートリポジトリをCloneしようとした際に、以下のようなエラーが出ました。
解決したので共有します。

```console
$ git clone https://github.com/username/dummy.git
Cloning into 'dummy'...
remote: Repository not found.
fatal: repository 'https://github.com/username/dummy.git/' not found
```

# 解決策：Gitbashのバージョン更新、ユーザ名の指定
普段はWindowsで作業をしており、Git for WindowsのGit Bashを使用していましたが、
長らくアップデートをしていなかったのが主な原因だったようです。

```console
# アップデート前
$ git --version
git version 2.23.0.windows.1

# アップデート後
$ git --version
git version 2.29.0.windows.1
```

アップデート後に、ユーザ名を指定して実行することでCloneすることが出来ました。

```console
$ git clone https://username@github.com/username/dummy.git

パスワードが聞かれるので応答する。
```

※Gitをアップデートせずにユーザ名を指定してもCloneはできませんでした
※ユーザ名を指定しなかった場合はnot foundのままでした。


#Git for Windowsのアップデート方法
Git for Windowsのアップデートは、以下のコマンドで実行できます。

```
$ git update-git-for-windows
```

同様のエラーが出てしまい他の方法を試してもClone出来ないという方は、
アップデートしてみるのも良いかもしれません。

今回は以上です。


# 参考
[Git Bashを手動でアップデートする方法【Git for Windows】](https://onoredekaiketsu.com/manually-update-git-bash/)
[私家版 Git For Windowsのインストール手順](https://opcdiary.net/technical/programming/%E7%A7%81%E5%AE%B6%E7%89%88-git-for-windows%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86/)
dein.tomlをdein_lazy.tomlに分ける

# `dein.toml`を`dein_lazy.toml`に分けた

## `dein.toml`とは
`dein.vim`で導入するプラグインをtoml形式でまとめたもの

導入するプラグインをまとめているだけなら1つのファイルでいいじゃないかとも思うが、vimの起動時にtomlの読み込みを行うため、記述量が増えると起動が遅くなる。
そこで、起動時に必ずしも必要ではないプラグインを遅延読み込みさせることで起動をできるだけ早くしようというのが`dein_lazy.toml`である。(`vimrc`で読み込みを行うときにファイル名指定をしているので必ずしも`dein.toml`か`dein_lazy.toml`というファイル名である必要はないみたい)


## 実際に分けてみる

分ける前の`dein.toml`は以下のようになっていた

```toml:dein.toml(before)
[[plugins]]
hook_add = '''
    augroup colorcshemeSetting
        autocmd!
        autocmd VimEnter * ++nested colorscheme night-owl
        autocmd Colorscheme * highlight Normal ctermbg=none
        autocmd Colorscheme * highlight NonText ctermbg=none
        autocmd Colorscheme * highlight LineNr ctermbg=none
        autocmd Colorscheme * highlight Folded ctermbg=none
        autocmd Colorscheme * highlight EndOfBuffer ctermbg=none 
    augroup END
'''
repo = 'haishanh/night-owl.vim'

[[plugins]]
repo = 'vim-jp/vimdoc-ja'

[[plugins]]
repo = 'cocopon/vaffle.vim'

[[plugins]]
repo = 'prabirshrestha/vim-lsp'

[[plugins]]
repo = 'mattn/vim-lsp-settings'

[[plugins]]
repo = 'mattn/vim-lsp-icons'

[[plugins]]
repo = 'prabirshrestha/asyncomplete.vim'

[[plugins]]
repo = 'prabirshrestha/asyncomplete-lsp.vim'

[[plugins]]
repo = "markonm/traces.vim"

[[plugins]]
repo = 'cespare/vim-toml'

[[plugins]]
hook_add = '''
let g:rufo_auto_formatting = 1
'''
repo = "ruby-formatter/rufo-vim"

[[plugins]]
repo = "tpope/vim-endwise"

[[plugins]]
repo = "mindriot101/vim-yapf"

[[plugins]]
hook_add = '''
let g:shfmt_extra_args = '-i 4 -ci -bn -s'
let g:shfmt_fmt_on_save = 1
'''
repo = "z0mbix/vim-shfmt"
```

これのうち言語設定関連のものを`dein_lazy.toml`に分離させた

```toml:dein_lazy.toml
[[plugins]]
on_ft = 'toml'
repo = 'cespare/vim-toml'

[[plugins]]
hook_add = '''
let g:rufo_auto_formatting = 1
'''
on_ft = "ruby"
repo = "ruby-formatter/rufo-vim"

[[plugins]]
repo = "tpope/vim-endwise"
on_ft = "ruby"

[[plugins]]
on_ft = "python"
repo = "mindriot101/vim-yapf"

[[plugins]]
hook_add = '''
let g:shfmt_extra_args = '-i 4 -ci -bn -s'
let g:shfmt_fmt_on_save = 1
'''
on_ft = ["sh", "bash"]
repo = "z0mbix/vim-shfmt"
```

(tomlの各キーの順番はフォーマッタでソートされているようで`repo`が後ろに来ている)


おそらく言語設定だけではなく他のプラグインも移せるものがあるだろうが、今回はこの程度にしておく。

起動時間はそもそもそんなにプラグインを入れていたわけではないので大した変化はなかった。しかし、チリツモで今後重くなることを防いだと考えれば無意味ではないと思う。
【2020年上半期】プログラミング学習歴６ヶ月　参考にした技術書１０選

#:tangerine:はじめに

私は、全くの**初心者**なので最初から何か目標を持って

始めた**タイプ**ではありません(*^^)v

なので・・・

私の場合は、まずHTML5・CSS3から進めてみました！

今日に至るまでの学習を振り返ると、それぞれの学習には繋がりがあることに気づきました！

そこから、ある言語や領域に興味を持ち始め・・・

今は**AWSでサーバー構築の技術向上**と**Webアプリケーションの習得**に専念しています！

それでは、紹介します:blush:

#独学で進めてきた参考書:pencil2:（2020年４月～10月）
##:point_up:プログラミング学習の導入は、やはりHTML5とCSS3
[タイトル] **HTML5&CSS3しっかり入門教室 ゼロからよくわかる、使える力が身につく。**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/80f7b053-b4a2-27e5-7ff4-eecf759fabd1.png)

##:point_up:webサイトに動きをつけてrichするには、 Java Script
[タイトル] **本当によくわかるJavaScriptの教科書　はじめての人も、挫折した人も、基礎力が必ず身に付く**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/ae60a7c3-ac66-154b-a9f3-30ee2732968b.png)

##:point_up:学習を進めていくと、サーバーサイドの言語に踏み込み　PHP
[タイトル] **よくわかるPHPの教科書　【PHP7対応版】**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/28e19c0c-638a-2ef6-5913-d1b60d0a61ed.png)

##:point_up:PHPと言えば、世界で圧倒的なシェアを誇る　Wordpress
[タイトル] WordPress Perfect GuideBook 5.x対応版
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/8206b84c-c4e0-7690-ba85-f8de41ff9ac3.png)

##:point_up:サーバーサイド言語の学習を進めるとフレームワークという便利な機能に気づき　Django（２冊）
[タイトル] **動かして学ぶ！Python Django開発入門**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/682e9f0e-8abe-db68-b64e-719ca4ff8c8e.png)

[タイトル] **Djangoのツボとコツがゼッタイにわかる本**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/285b3bab-57b9-5a20-a21e-cffb0e853c22.png)


##:point_up:いよいよOSの学習に突入　ソフトウェアの縁の下の力持ちといえば Linux（２冊）+αネットワーク
[タイトル]　**Linux標準教科書**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/5ab2bdf8-6b6a-a59d-6ec5-90cadf5cd6e1.png)

[タイトル]　**イラストでそこそこわかるLinux コマンド入力からネットワークのきほんのきまで**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/2bcf43a6-597f-f332-67aa-740720a764ba.png)

##:point_up:Linuxを勉強しているとデータベースの存在を知り　MySQL
[タイトル] **3ステップでしっかり学ぶ MySQL入門**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3ae52f12-2c10-61bf-d542-7536b4cb2618.png)

##:point_up:ここまでくるとインフラ関連の技術に興味を持ち　AWS
[タイトル] **図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書**
　　　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/64227b10-9465-d84e-480f-b97d8ddd7295.png)

#:tangerine:最後まで読んで頂きありがとうございました！
なんとなく始めたプログラミング学習も

継続して進めていけば自分の興味のある分野に気づき、

何を作りたいのかが少しずつ明確になってきました(^^♪

以上です。
【pytorch】tensor 型の確認

pytorchの使い方の確認のため書く。
#is_tensor
torch.is_tensor(obj)のobjがtensorならTrueを返す。

```
>>> import torch
>>> a=torch.tensor([[0, 1], [2, 3], [4, 5]])
>>> a
tensor([[0, 1],
        [2, 3],
        [4, 5]])
>>> torch.is_tensor(a)
True
>>> torch.is_tensor(1)
False
```
#is_storage
torch.is_storage(obj)のobjがPyTorch storage objectならTrueを返す。
PyTorch storage objectが何を示しているかはまだ勉強中。

```
>>> torch.is_storage(a)
False
>>> torch.is_storage(1)
False
```
#is_complex
torch.is_complex(obj)のobjが複素数ならTrueを返す。
__注意__
以下のコードで__cfloat__が原因でエラーになるときがある。それはpytorhのバージョンを上げることで解決できる。
[https://pytorch.org/](https://pytorch.org/)でpytorchのバージョンを上げられる。

```
>>> b=torch.rand((3,3), dtype=torch.cfloat)
>>> b
tensor([[0.1955+0.3707j, 0.5087+0.8311j, 0.2987+0.4621j],
        [0.5064+0.7313j, 0.9797+0.8714j, 0.0260+0.7468j],
        [0.1468+0.5747j, 0.9827+0.3058j, 0.8373+0.9638j]])
>>> torch.is_complex(a)
False
>>> torch.is_complex(b)
True
>>> torch.is_complex(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: is_complex(): argument 'input' (position 1) must be Tensor, not int
```
#is_floating_point
torch.is_floating_point(obj)のobjがfloatならTrueを返す。
objがcfloatならFalseである。

```
>>> c=torch.rand((3,3), dtype=torch.float)
>>> c
tensor([[0.7839, 0.8118, 0.8087],
        [0.4022, 0.0625, 0.7638],
        [0.3203, 0.0413, 0.3117]])
>>> torch.is_floating_point(a)
False
>>> torch.is_floating_point(b)
False
>>> torch.is_floating_point(c)
True
>>> torch.is_floating_point(1.0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: is_floating_point(): argument 'input' (position 1) must be Tensor, not float
```
Vagrantでホスト名を設定する。

### 環境
Vagrant 2.2.10
centos7
Mac OS Catalina 10.15.6
apache 2.4.6

### vagrant-hostupdaterインストール
```
$ vagrant plugin install vagrant-hostsupdater
```

### Vagrantfileに設定する
```
config.vm.network :private_network, ip: "192.168.3.10"
config.vm.hostname = "ホスト名"
```

### vagrantをリロードする
```
$ vagrant reload
```
パスワードを求められるので入力する。
その後、Vagrantfileで指定したホスト名に、ブラウザでアクセスできるようになる。
/etc/hostsファイルを確認すると、ホスト名の情報が入力されている。
オブジェクトを個々の属性に展開する ...演算子の使い方




### オブジェクトを個々の属性に展開する ...演算子

####MyAttributes.js

```
import React, {Component} from 'react';

export default class MyAttributes extends Component {
  render(){
    return(
      <ul>
        <li>名前：{this.props.name}</li>
        <li>年齢：{this.props.age}</li>
        <li>性別：{this.props.gender}</li>
      </ul>
    );
  }
}
```

####index.js

```
const attr = {
  name: "田中",
  age: "31",
  gender: "male",

ReactDOM.render(
  <MyAttrbutes {...atr} />,
  document.getElementById("root");
);
```
忘れないうちに、フリマアプリの機能とポイントまとめ

#はじめに
　作成していたフリマアプリのようなものが一段落したので、まとめておく。完全に自分用。

##実装した機能

###ユーザー管理
deviseというGemを使用。
RSpecを用いてテストコードを記述。Fakerでテスト用データをFactoryBotに記述。
GimeiというGem、日本語版のFakerを使用。
正規表現。
エラーエラーハンドリングをrenderメソッドを使って表示。
###商品の出品機能
ActiveHash導入。
ActiveStorageを導入して、画像を保存できるように。
Fakerの日本語対応を使って、テストコード記述。
JSを使ってブラウザ上でリアルタイムに利益等を計算。
###商品の一覧表示
if文の条件文にexists?メソッドで、テーブルにデータが無いときと処理を分岐。
###商品の詳細表示機能
ActiveHashのnameを表示（@変数名.model名.name名）
###商品の削除機能
before_actionで同じ処理をまとめる。
###商品の編集機能
newアクションと同じフォームにまとめる。
###商品購入機能
商品と購入者の組み合わせをパラメーターから取ってくるため、mergeメソッドを使う。
APIの導入（PAY.JP）を使ってクレジットカード決済の導入。JSでtokenをレスポンス。
tokenをmerge。
購入済みにsold outを表示。
`<% if @item.purchase %>`を使って条件分岐。
Vue.jsならではの、いろんなやり方の画像プレビュー方法

#ref属性から画像を取得して、表示する

```javascript:
// refからアップロード
input(type="file", ref="file", @change="leftSetImage")
v-img(:src="image.source")
```

```javascript:
// refから一時的なURLに変換して取得
leftSetImage() {
  const files = this.$refs.file;
  const fileImg = files.files[0];
  if (fileImg.type.startsWith("image/")) {
    this.image.source = window.URL.createObjectURL(fileImg);
  }
},
```


#イベントオブジェクトから画像を取得して、表示する

###一時的なURLでプレビュー表示

```javascript:
// イベントオブジェクトからアップロード
input(
  type="file",
  @change="setImageLeft($event)"
)
v-img(:src="office.left_image.image", type="submit")

```

```javascript:
// イベントオブジェクトから、一時的URLに変換して取得
setImageLeft(e) {
  const file = (e.target.files || e.dataTransfer)[0];
  this.LeftUploadedImage = file;
  if (file.type.startsWith("image/")) {
    this.office.left_image.image = window.URL.createObjectURL(file);
  }
},
```

#base64に変換して、プレビュー表示

今までのやり方だと、ブラウザを放置して更新したり、そのデータを画像を保存したりした時の再表示の動作ができなくなるということが起きる。

base64に変換する場合は、そのような事象は起きない。

```javascript:
// イベントオブジェクトからアップロード
input(
  type="file",
  @change="setImageRight($event)"
)
v-img(:src="office.right_image.image", type="submit")

```

```javascript:
// イベントオブジェクトから、base64に変換して取得
setImageRight(e) {
  const file = e.target.files[0] || e.dataTransfer.files;
  const reader = new FileReader();
  reader.onload = (e) => {
    this.office.right_image.image = e.target.result;
  };
  reader.readAsDataURL(file);
},
```
Light Sailで作ったWordPressの右下からBitnamiのロゴを消す。



![screenshot-2020-10-27-233225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145707/19d689e6-9ad2-c32d-304d-dde1db4e7a08.png)

ここを押して、以下コマンドを実行。

非表示。

```terminal
sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1
```

apache再起動

```terminal
sudo /opt/bitnami/ctlscript.sh restart apache
```

あとは、再度サイトを確認。


参考：https://qiita.com/MosamosaPoodle/items/24ae64627820e557790b
Set-ClipBoardという取り回しのいいコマンド

## PowerShellで出力する方法
いくつか方法があるし、いくらでも方法があるけれど、主たるところは以下の２種類か。

- 標準出力でそのままコンソール上に出力する
- Out-File でファイルを出力する

最近、もうひとついい方法

- Set-ClipBoard でクリップボードに直接出力する

## クリップボードに出力するメリット

貼り付けでテキストエディタに出力できるので、Out-Fileとそれほど取り回しは変わらない。
Tabで区切って、Excelやスプレッドシートに貼り付けるとそのままファイル化できる、というメリットもある。
もちろん、そのままメールやチャットソフトに貼り付ける、などもできるだろう。

## Set-ClipBoardの例文

例えば、以下の構文でカレントフォルダにあるファイルのフルパスと最終更新日時を取得することができる。

```PowerShell
$tmp = Get-ChildItem -Path . -Recurse | ? { $_.LastAccessTime -gt "2020/04/01" } | ft -autosize -property FullName, LastWriteTime | Out-String -Width 4000
$tmp | Set-ClipBoard
```

以下のコマンドだとCSV化することができる

```PowerShell
$tmp = Get-ChildItem -Path . -Recurse | ? { $_.LastAccessTime -gt "2020/04/01" } | select Fullname,  LastWriteTime | ConvertTo-Csv
$tmp | Set-ClipBoard
```

クリップボードなのでメモリに出力されるし、そのまま色々なメディアに持っていくことができるので、一度テキスト出力するよりも早く取り回しがいい。

活用しがいのあるコマンドだ。
fatal error Adafruit_TCS34725.h: No such file or directory　の解決方法


M5Stackに[カラーセンサーユニット](https://www.switch-science.com/catalog/5218/)をつけて、スケッチ例をコンパイルしたら、

スケッチ例の場所：　
ファイル >> スケッチ例 >> M5Stack >> Unit >> Color

こんなエラーが出た。

```
fatal error: Adafruit_TCS34725.h: No such file or directory
「SD.h」に対して複数のライブラリが見つかりました
compilation terminated.
使用済：C:\Users\tatsu\OneDrive\ドキュメント\ArduinoData\packages\esp32\hardware\esp32\1.0.4\libraries\SD
未使用：C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\SD
exit status 1
Adafruit_TCS34725.h: No such file or directory
```

エラーメッセージ　”Adafruit_TCS34725.h: No such file or directory”　をそのままググると、[このサイト](https://arduino.stackexchange.com/questions/19624/trying-to-understand-compilation-error-message)で誰かが同じ悩みを投稿してた。


それに対する誰かの回答

>It looks like you're trying to get the Adafruit TCS34725 color sensor going. 
The official source of the library is in the Adafruit's GitHub repository for the TCS34725 and there is a link at the bottom of the README for how to install a library. 

<br>
つまり、ただライブラリをインストールすればいいだけのことらしい。

[この回答のリンク](https://github.com/adafruit/Adafruit_TCS34725)をたどっていくと、ライブラリの名前は<B>Adafruit TCS34725</B>と書かれている。

>To install, use the Arduino Library Manager and search for 'Adafruit TCS34725' 
and install the library


<BR>
早速、このとおり、Arduino IDEで、
ツール >> ライブラリの管理 >> "Adafruit TCS34725" を検索

[![Image from Gyazo](https://i.gyazo.com/8ac3ef7719c624afd089185127e9799a.png)](https://gyazo.com/8ac3ef7719c624afd089185127e9799a)

インストール！

コンパイル！


エラーは出なくなった。
他のエラーも消えた。


<BR>