OmniAICreator/Qiita-1.07M huggingface dataset:
textlintを導入する


`textlint` の導入に関して調査したのでまとめてみた。

開発チームの規模、体制に関わらず、推敲、校閲するフローが抜けてしまう場面はしばしある。
結構場当たり的に各人がやってしまいがち。lintによる監視は、やはり重要そうです。
日本語力が低すぎの自分としても、今後自分が書くであろうすべての文章、すべての恥をこの際どうにかしたい。

# textlint とは

簡単にまとめると普通の文章に対してのlintツール。

https://github.com/textlint/textlint

# 導入

```zsh
# インストール
% npm i -D textlint

# 例として代表的な Rule Presets を一つ
% npm i -D textlint-rule-preset-ja-technical-writing
```

ルートに `.textlintrc` を作成し、ruleを記述。

```.textlintrc
{
  "rules": {
    "preset-ja-technical-writing": true
  }
}
```

以下を実行すると、`README.md` に対してtextlintが実行できるイメージ。
`markdown`と`txt`ファイルを指定できる。

```
% ./node_modules/.bin/textlint README.md
```

# Rules と Rule Presets

非常に多くのRuleが公開されている。以下辺りが参考になる。

- [Collection of textlint rule](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule)
- [日本語コミュニティ](https://github.com/textlint-ja)

## 使い方

まずは代表的な `Rule Presets` を試し、必要に応じて `Rules` を追加していくのが良さそうです。

- 参考: [Rule Presets: Japanese](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule#rule-presets-japanese)
- 参考: [Rules: Japanese](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule#rules-japanese)

日本語以外の言語も必要に応じて。

## ルール管理の支援

ここから実際に動かしながら、チューニングをしていく。
出てきた例外処理の追加などに、以下のような支援技術も必要。

- [textlint-rule-ng-word](https://github.com/KeitaMoromizato/textlint-rule-ng-word) : NGWordを登録する
- [textlint-rule-prh](https://github.com/textlint-rule/textlint-rule-prh) : 校正作業(表記ゆれ)用スペルチェッカー[prh](https://github.com/prh/prh)をtextlint上で動かす
- [textlint-filter-rule-allowlist](https://github.com/textlint/textlint-filter-rule-allowlist) : 許可リストを登録する

## `--fix` オプション

lintfix一発でバッっと対応したい場合は、対応しているものに限り `--fix` オプションが使える。
結構インパクトある変更が大量に出るので、使用の際は慎重に。

```
% ./node_modules/.bin/textlint --fix README.md
```


# そもそもどういうルールを入れるべきなのか

ツールの導入自体は非常に簡単だが、結局「どういうルールを設定すべきか」を考えるのが難しい。

当たり前だが高い国語の能力がいるだけではなく、言葉遣いのルールとは、どいういう語り方をするかであり、突き詰めていくと「人格」のデザインになる。つまり組織の場合は文化的背景や、ブランドパーソナリティの戦略へとつながっている。

この規模で検討するのであれば、さすがにtextlintの戦略を、単独のプロジェクトとして管理すべきように思われる。



※ SmartHRさんが企業での言葉使いを大切にし、校正ルールをオープンソース化している例が非常に参考になりました。

https://shanaiho.smarthr.co.jp/n/n881866630eda




# 個人用として、あえてのGlobalインストール

基本的にプロジェクト単位で導入するものですが、書き方を使い分ける必要がない個人用途の場合には、割り切ってGlobalインストールしちゃうのもありかもしれません。

```zsh

# Globalインストール
% npm i -g textlint

# ruleを必要に応じて
% npm i -g textlint-rule-preset-ja-technical-writing 

# .textlintrc 作成
% cd ~/.
% textlint --init

```

作成した `.textlintrc` に必要なルールを記述していく。

```.textlintrc
{
  "rules": {
    "preset-ja-technical-writing": true,
  }
}
```

これで、いつでも `textlint` が使えるように成りました。

```zsh

% textlint /path/to/README.md

```

あとは、回数をこなし `.textlintrc` の内容を磨いていくことになりそうです。
二重スリット実験での観測問題に対する疑惑

#始めに
光子や電子などを二重スリットを通して、スクリーンに到達したところで、
到達する量子の数は、二重スリットを起点として、二つの波の重ね合わせにあるという。
波に関して身近なところでは、ヘッドホンなどで外部から来るノイズの音波と逆位相の音波をヘッドホンなどが出力して、ノイズと逆位相の音波の重ね合わせで、ノイズの音がある程度は軽減される。自身でもノイズキャンセリング機能が付いているヘッドホンで確認している。逆に同位相の波であれば、強め合う事になる。量子力学でも同様の現象が二重スリットで確かめられる。
#干渉縞
個人的にレーザーポインターと自作スリットで、干渉縞らしき物が出現することは確認した。
![d1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466942/ab1a1558-ef85-a95a-973c-1fde056c9231.png)

粗雑な作りの二重スリットなどで、あまり良く分からないところがあるが、
縞が出来ている事は確認できた。
理想を言えば
![d2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2466942/e357262f-ef21-8d4c-3e38-f525bbb6cc56.png)

の様になるのが理想だが、先立つものが無い事もあり、実験の精度はよろしくないのが残念である。

#観測問題

量子が発信源からスクリーンまで到達するする間に「観測」を行うと、
量子の波動性は消滅して、干渉縞は消滅して、スリットの後ろだけに、
量子がスクリーンに到達するとなっている。
しかし、今回私が行ったやり方、スリットの前後で光の一部を遮る、
横から光を照射するなどを行ったが、干渉縞には変化がなかった。
実際、__実写__で二重スリット実験で干渉縞が現れる動画はいくつも見たが、
途中で__観測__を行って、__干渉縞が消滅する実写__の動画は見当たらなかった。アニメーションとかでそういうことが起きると説明している動画はいくつもあるが、__実写__のがないのは、本当はそう言うのは無いのではないかと言う疑惑を感じる。

#最後に

本格的に、きちんと電子を１個づつ発射するような二重スリット実験は、
数千万の予算がかかるらしいが、私には無理である。
本当に途中の__観測__によって干渉縞が消えるのであれば、
アニメーションとかで無く、__実写__で証拠を示して頂きたいものである。
Goで任意サイズの一時ファイルを作って送信

## 動機

ネットワークのパフォーマンス計測のために任意サイズのデータを送信したかったので、送りたいデータのサイズの一時ファイルを作って送信してみた。

## 実装

```main.go
package main

import (
	"flag"
	"io"
	"io/ioutil"
	"net"
	"os"
)

var size int64

func init() {
	flag.Int64Var(&size, "size", 1e9, "data size to be sent")
	flag.Parse()
}

func main() {
	conn, err := net.Dial("tcp", "localhost:8000")
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	file, err := ioutil.TempFile("", "")
	if err != nil {
		panic(err)
	}
	defer os.Remove(file.Name())

	if err := file.Truncate(size); err != nil {
		panic(err)
	}

	var offset int64 = 0
	buf := make([]byte, 1024)
	for {
		nr, errRead := file.ReadAt(buf, offset)
		if errRead != nil && errRead != io.EOF {
			panic(err)
		}

		offset += int64(nr)
		if _, err := conn.Write(buf[:nr]); err != nil {
			panic(err)
		}

		if errRead == io.EOF {
			break
		}
	}
}
```

## 参考資料
- [Create a temporary file or directory](https://yourbasic.org/golang/temporary-file-directory/)
- [How to create a 10MB file filled with "000000..." data in golang?](https://stackoverflow.com/questions/16797380/how-to-create-a-10mb-file-filled-with-000000-data-in-golang)
Chart.js 目盛りの最大値を揃える

js内で完結する場合は今回のような対応は必要ないと思いますが、
データ自体は別から持ってきて、目盛りのmax値も自動更新にしたい且つmax値を揃えたい場合に使いました。


↓最大値を何も設定せずに普通に作ったグラフ。
Aの目盛りの最大値が130,000、Bの目盛りの最大値が50,000となっています。
![img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/520008c5-f07f-8f2d-c336-ac0601bafe65.jpeg)

現時点でのコードは下記になります。

```js
const ctx = document.getElementById('myChart');
let myChart = new Chart(ctx, {
	type: 'line',
	data: {
		labels: ['2018年', '2019年', '2020年', '2021年', '2022年'],
		datasets: [{
			label: 'A',
			tension: 0,
			fill: false,
			data: [25000, 50000, 75000, 100000, 125000],
			yAxisID: 'y-axis-1',
			borderColor: '#1E90FF'
		}, {
			label: 'B',
			tension: 0,
			data: [10000, 20000, 30000, 40000, 50000],
			yAxisID: 'y-axis-2',
			backgroundColor: '#87CEFA',
			borderColor: 'transparent'
		}]
	},
	options: {
		tooltips: {
			mode: 'nearest',
			intersect: false,
		},
		responsive: true,
		elements: {
			point:{
				radius: 0
			}
		},
		scales: {
			yAxes: [{
				id: 'y-axis-1',
				type: 'linear',
				position: 'left',
				ticks: {
					min: 0,
					stepSize: 10000,
					callback: function(val){
						return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
					}
				},
				gridLines: {
					display: false,
				}
			}, {
				id: 'y-axis-2',
				type: 'linear',
				position: 'right',
				ticks: {
					min: 0,
					stepSize: 10000,
					callback: function(val){
						return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
					}
				},
				gridLines: {
					zeroLineColor: '#000',
					drawBorder: false,
				}
			}]
		}
	}
});
```
Aの方が目盛りの最大値が大きいので、今回はBをAに合わせていきます。
まずは、Aの目盛りの最大値を取得します。

```js
const yAxis1Index = myChart.controller.boxes.findIndex((u) => u.id === 'y-axis-1'); // 3
const yAxis1Max =  myChart.controller.boxes[yAxis1Index].max; // 130000
```
`myChart.controller.boxes`で取得できるもの↓
![img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/3f83e0e3-e07f-abc7-7e7b-69dce210e3e9.jpeg)

そこにいらっしゃったんですね
![img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/a27a80f8-3f5b-8eb9-f736-f26de90c1a7c.jpeg)

下記の記述を追加する。

```js
const yAxis2Index = myChart.options.scales.yAxes.findIndex((u) => u.id === 'y-axis-2');
myChart.options.scales.yAxes[yAxis2Index] = {
	ticks: {
		display: false, // 目盛りの値が重複してしまうので非表示にする
		max: yAxis1Max
	},
	gridLines: {
		display: false,
	}
};
myChart.update(); // グラフを更新
```
目盛りの最大値が揃うとこうなります。
![img04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1481042/c0ff4486-e23d-d80c-7e6c-9b451fa0bd60.jpeg)
sketchupでruby その20

#概要

sketchupでrubyやってみた。
練習問題やってみた。

#練習問題

お宅のぶどう園、見せて。

#写真

![budo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1ad5f97b-3d6b-4277-3d9d-b8e787cdb6d3.jpeg)


#環境

windows vista
sketchup 8

#サンプルコード


```
def loadtest2
   model = Sketchup.active_model
   entities = model.active_entities
   path = Sketchup.find_support_file "ki2.skp", "Plugins/"
   definitions = model.definitions
   componentdefinition = definitions.load path
   for x in 0..5 do
     for y in 0..1 do
       point = Geom::Point3d.new 200 * x, 300 * y, 0
       transform = Geom::Transformation.new point
       instance = entities.add_instance componentdefinition, transform
     end
   end
end




```

#実行手順

- pluginsにrbファイルを置く
- 起動時に読み込む
- rubyコンソールから呼び出す




以上。
パフォーマンスに影響を与えるポイントについて【TOP10】

##七、精度が高すぎるアニメーションクリップ――86％

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/3e7f4db9-4460-30ae-b8bf-02f5ac0aa296.png)


Unityのアニメーションクリップには、各フレームにある各アニメーション曲線の重要な情報が含まれていることがわかっています。多くのアニメーションアセットでは、重要な情報が浮動小数点数で高精度に記録されることがよくあります。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/8112ce8b-f84c-ab6b-a770-76609e97dea9.png)

 
アニメーションファイルの浮動小数点精度が高い場合、アニメーションクリップのパフォーマンスは一般により良く、より詳細になりますが、メモリに追加のコストが発生します。適切に精度を圧縮したら、表示効果は少し悪くなりますが、アニメーションクリップ数とフレーム数を考慮すると、結果としてメモリは非常に大きく節約できます。
 
精度を3〜4ビットに下げることをお勧めします。UWAの長年の実務経験に基づいて、アニメーションクリップの精度が3〜4ビットの場合、パフォーマンスへの影響を少なくして、メモリコストを効果的に減らすことができます。
 
したがって、UWAはこのルールを使用して、アニメーションの精度が高過ぎるアニメーションクリップを除外し、開発チームが効果とメモリのバランスを検討した後、ターゲットを絞った方法で精度を圧縮または保持します。 UWA Q＆Aの記事「アニメーションファイルの浮動小数点精度を下げる方法」を参照してください。
 
##八、役に立たないテクスチャサンプルを含むマテリアル――79％

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/5a9dc27b-b95c-08f0-65f2-2623976b30b4.png)


 
開発中に、開発チームは、実際に欲しい表示効果に応じて、マテリアル球に対しShaderの選択や交換を行います。Unity独自のメカニズム設定により、マテリアル球の使用Shaderを切り替えると、前のShaderのテクスチャサンプリング情報が自動的に保存されます。
 
このような処理が無視されると、パッケージが最終的にエクスポートするときに、実際には必要のないテクスチャがパッケージに取り込まれ、メモリの浪費を引き起こします。
 
この検出ルールにより、開発チームは、不要なテクスチャサンプリングを含むすべてのマテリアルを検索し、関連するテクスチャサンプリング情報を削除して、パッケージサイズを縮小し、スペースを節約できます。
 
##九、粒子数の上限が30を超えるパーティクルシステムーー79％

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/809c1a4b-1c77-1615-576c-d03c4f05da9f.png)


パーティクルシステムはUnityプロジェクトで非常に一般的であり、雨、雪、火などのさまざまな動的効果を生成するために使用できます。次の図は、Unityで「生まれた」ばかりのパーティクルシステムです。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1b5414eb-bcba-b7ba-4ab0-aa68383e411a.png)

 
ルールに示されているパーティクル数の上限は、コンポーネントが同時に持つことができるパーティクルの最大数を指します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/efcd8362-34ec-df65-57b3-355438764f36.png)


 
パーティクルシステムでは、適切な粒子数は、炎や落ち葉などの特殊効果の表現効果とつながります。パーティクルの数が多すぎると、大量のメモリが使用されるだけでなく、実際の操作中にCPUとGPUの計算にさらに圧力がかかります。
 
UWAエンジニアの経験と業界のビッグデータの統計分析に基づいて、一般には、パーティクルシステムの粒子数の上限は30を超えないと、良い表示効果が得られます
 
このルールにより、開発チームは実際の表示に基づいてパーティクルシステムのパーティクル数に妥当な上限を設定し、特殊効果のレベルを維持することを前提としてメモリとコンピューティングのコストを最適化できます。
 
##十、参照テクスチャサイズが256を超えるパーティクルシステム

――78％
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/c4f316ae-bc86-4d31-a2d2-901d06fe4f30.png)



 
パーティクルシステムでは、さまざまな特殊効果をあわせルために、テクスチャを参照してパーティクルを「ドレスアップ」します。
単一の粒子の場合、テクスチャサイズの増加は、パーティクル全体のパフォーマンスの向上にとってそれほど顕著ではない場合があります。業界のビッグデータの分析を通じて、UWAは、ほとんどのパーティクルシステムを使用する場合、256×256のテクスチャサイズでほとんどのパフォーマンス要件を満たすことができることを発見しました。
 
このルールにより、「大きな」テクスチャサイズを参照するパーティクルシステムを除外し、表示効果が大幅に変化しないパーティクルシステムを「スリム化」することができます。メモリと計算へのプレッシャーを軽減するだけでなく、これらのより重要なパーティクルシステムのために貴重なパフォーマンススペースを解放することもできます。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com
私の記事まとめ


## Deep Learning系


https://qiita.com/seiji1997/items/5899a8cb92e5f02b556a


## 備忘録系


https://qiita.com/seiji1997/items/2ede161d0191093a4717



## データ分析系

https://qiita.com/seiji1997/items/62a33f51c5d677fb586e
パフォーマンスに影響を与えるポイントについて【TOP6】

##四、空のテクスチャサンプルを含むマテリアル――91％

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/9bd46b12-1fe6-abbe-1247-ccde0af0235e.png)


Shadersを作成するときに、計算用にいくつかのテクスチャを宣言します。ただし、このShaderを使用してMaterialインスタンスを作成する場合、これらのテクスチャは不要であるか、過失のためにマテリアルにテクスチャを追加するのを忘れる可能性があります。その場合、Unityはデフォルトの「テクスチャ」をマテリアルに割り当てます。この状況は計算結果と表示効果に影響を与えませんが、Unityは引き続き関連する計算を実行するため、パフォーマンスの消耗を引き起こします。
 
したがって、このルールの検出を提供して、開発チームがテクスチャを必要としないマテリアルを見つけ、関連するテクスチャ宣言を削除またはコメントアウトして、Unityによる不要な計算を回避し、GPUへの圧力を軽減できるようにします。もともとテクスチャを追加する予定のマテリアルは、その構造をさらに最適化すると判断されます。
 
##五、OptimizeGameObjectsのAnimatorコンポーネントをオンにしていない――87％
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/057a430b-a0f8-92c0-c8d7-3d9d687deca5.png)



 
アニメーションシステムに関しては、Animationコンポーネントは古いバージョンのUnityのアニメーションシステムに対応し、Animatorは新しいアニメーションシステムMecanimに対応するコンポーネントであることがわかっています。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1a11a2d7-72c1-9e2a-251c-2d83e6bf1723.png)

 
Mecanimアニメーションシステムを使用して、対応するアセットのImport Settingsで「Optimize Game Objects」オプションを有効にできます。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ad5608c0-b3a9-cefc-56c7-f96685eb1e28.png)

 
選択されていない状態では、Unityはアニメーションクリップの処理時にTransformのレベル情報を削除しないため、スケルタルアニメーションの再生中に不要なCPU計算コストが発生します。
 ![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/8dfde299-2390-66c2-043e-f19267405904.png)

 
選択した後、Unityは関連する最適化を実行します。簡単に言うと、Transformコンポーネントのみを含むボーンノードはUnityによってインポートされません（ただし、Extra Transform Pathsで対応するボーン名を確認することで、目的のボーンノードを保持できます）。関連するボーン情報がavatarにマッピングされます。アニメーションシステムは、フレームごとにこれらのボーンノードの変換（GameObject）を更新する必要はありませんが、avatarのボーン情報を取得してスキンメッシュを更新し、アニメーションを表現します。これによって、CPU計算が節約でき、アニメーションのコストが削減されます。
 
ここで、UIのAnimatorコンポーネントはOptimizeGameObjectsの最適化アイテムをサポートしておらず、処理する必要がないことに注意してください。したがって、この部分のAnimatorは検出ルールで除外され、検出されなくなります。
 
##六、Scale曲線を含むアニメーションクリップ――86％

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ef8ba656-7d2f-8208-4f6d-0abe27453943.png)


 
Scaleスケーリングアニメーションは、オブジェクトの縮小と拡大を制御する役割を果たします。次に、Scale曲線の役割は、アニメーション内のオブジェクトの各フレームのスケーリング状況を記録することです。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/c434d0e4-2fba-b5c2-9f79-0e072e2b8c57.png)


 
多くの場合、インポートされたアニメーションアセットには、オブジェクトの空間位置変換のみが含まれます。つまり、Scale曲線の値は常に1です。したがって、アニメーションクリップの表示効果には影響しませんが、実際には曲線データ全体が存在し、不要なメモリの浪費につながります。
 
この不要なメモリ消費を回避するために、このルールを使用して、Scale曲線を含むこれらのアニメーションクリップを除外します。これは、開発チームがチェックするのに便利です。
 
以上がこれら3つの検出ルールの説明です。皆様の役に立てれば幸いです。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com
Apache Portable Runtimeの署名検証をする際に公開鍵を探した話

# はじめに

Apache のソースビルドをしようとしたときに、Apache Portable Runtime（APR）の署名、ハッシュ値の検証をした。
その際に、ドキュメントを見ても公開鍵が見当たらなくて困ったので記事にする。

今回検証したのは、`APR 1.7.0`です。

# 結論

- 鍵 ID `1E1F909911C78735`
- フィンガープリント `B1B9 6F45 DFBD CCF9 7401 9235 193F 180A B55D 9977`

の公開鍵を鍵サーバーから取得することで署名を検証できた。

# やったこと

https://apr.apache.org/download.cgi を見ながら、ソースコードをダウンロード。

```
$ curl -L -O https://dlcdn.apache.org//apr/apr-1.7.0.tar.gz
```

分離署名になっているため、署名ファイルもダウンロード。

```
$ curl -L -O https://www.apache.org/dist/apr/apr-1.7.0.tar.gz.asc
```

署名検証をしようと公開鍵はどれか探してみたが、見つからず...

とりあえず鍵 ID を確認

```
$ gpg --verify apr-1.7.0.tar.gz.asc apr-1.7.0.tar.gz

gpg: Signature made 2019年04月02日 02時56分25秒 JST
gpg:                using RSA key 1E1F909911C78735
gpg: Can't check signature: No public key
```

鍵サーバーを検索してみる

```
$ gpg --keyserver pgpkeys.mit.edu --search-keys 1E1F909911C78735

gpg: data source: http://pgpkeys.mit.edu:11371
(1)     William A. Rowe, Jr. <wrowe@apache.org>
        William A. Rowe, Jr. <wrowe@pivotal.io>
        William A. Rowe, Jr. <wrowe@vmware.com>
        William A. Rowe, Jr. <wrowe@rowe-clan.net>
        William A. Rowe, Jr. <william.rowe@springsource.com>
          4096 bit RSA key 193F180AB55D9977, created: 2008-04-09, expires: 2020-07-08 (expired)
```

メールアドレス「`wrowe@apache.org`」はそれっぽい。

https://httpd.apache.org/dev/verification.html#Validating によると、https://people.apache.org/keys/committer/ に Apache 開発者のフィンガープリントが公開されているらしい。

フィンガープリントを確認してみる。

```
$ gpg --fingerprint 1E1F909911C78735

pub   rsa4096 2008-04-09 [SC] [expired: 2020-07-08]
      B1B9 6F45 DFBD CCF9 7401  9235 193F 180A B55D 9977
uid           [ expired] William A. Rowe, Jr. <wrowe@rowe-clan.net>
uid           [ expired] William A. Rowe, Jr. <wrowe@apache.org>
uid           [ expired] William A. Rowe, Jr. <wrowe@pivotal.io
```

`B1B9 6F45 DFBD CCF9 7401 9235 193F 180A B55D 9977`を検索してみると、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352836/1369b09f-2698-79c4-2e4d-e03ec9dafe8c.png)

いた！

有効期限が切れているが、この公開鍵は本物の様。

署名検証をしてみると、、

```
$ gpg --verify apr-1.7.0.tar.gz.asc apr-1.7.0.tar.gz

gpg: Signature made 2019年04月02日 02時56分25秒 JST
gpg:                using RSA key 1E1F909911C78735
gpg: Good signature from "William A. Rowe, Jr. <wrowe@rowe-clan.net>" [expired]
gpg:                 aka "William A. Rowe, Jr. <wrowe@apache.org>" [expired]
gpg:                 aka "William A. Rowe, Jr. <wrowe@pivotal.io>" [expired]
gpg: Note: This key has expired!
Primary key fingerprint: B1B9 6F45 DFBD CCF9 7401  9235 193F 180A B55D 9977
     Subkey fingerprint: 41E0 4A4F 57D8 2401 C81F  4FED 1E1F 9099 11C7 8735
```

正しく署名を確認できた。

# さいごに

公開鍵の有効期限が切れてしまっているが、どこに報告すればいいのかハッキリわかっていない。（メーリングリストでいいのか？）
もし、適切そうな報告先がわかる方がいましたら教えていただけると幸いです。
忘備録（excel散布図グラフの書き方）


東京都のコロナ感染状況（対前週比）をピックアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524780/48a1fbb3-06f9-4bba-a9e2-819dfe40a8c2.png)

東京都の感染率（前週比）に関するグラフを作図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524780/c5883981-5528-c6ce-a8c2-0a7dc05c0b1a.png)

回帰曲線（２次式）　y=0.3622x＾2－12.48x＋207.35
の２次項と１次項の速度をグラフ化

感染率の減少には、１次項成分が大きく寄与しているのがわかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524780/60e047ce-102a-7359-ab6b-9c82f9d651c7.png)


ここで、横軸を経過日、折れ線グラフとして、感染率（先週比％）、２次項成分、１次項成分、和の４つのグラフを表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524780/bbf6ce0b-4672-e9f2-32d1-d671a022d571.png)

グラフデータの範囲を次のようにする。
=Sheet1!$C$2:$G$17

すると、以下の部分のグラフが出来上がる

横軸は、c2～c17まで　経過日
縦軸は、d2～f17まで　感染率（先週比％）
　　　　e2～e17まで　２次項成分
　　　　f2～f17まで　１次項成分
　　　　g2～g17まで　和


データソースの選択に於いて、チエックボタンを外すと表示をなくすことができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524780/af0429ce-c0a8-a166-6de0-d1e2f76e25dd.png)

横軸は、c2～c17まで　経過日
縦軸は、e2～e17まで　２次項成分
　　　　g2～g17まで　和
データが存在するか確認してから郵便番号検索

データが存在するか確認してから郵便番号をURLに入れると住所を出力するものを作りたいと思います。

具体的に描くと
データベースの接続に成功しました。 SELECT に成功しました。 北海道札幌市中央区旭ケ丘。　
というものです

まずは

```
$postnum=$_GET["post"]; // URLの末尾の数字

$link = mysqli_connect('ここはそれぞれの引数をいれる');
```
接続状況をチェックします
mysqli_connectとはMySQLサーバーへ接続をオープンにする

```
if (mysqli_connect_errno()) { //mysqli_connect_errno()は直近の接続コールに関するエラーコードを返す
 die("データベースに接続できません:" . mysqli_connect_error() . "\n"); //mysqli_connect_error直近の接続エラーの説明を返す
}
echo "データベースの接続に成功しました。\n";
```

dieはスクリプトを終了させる関数。引数に文字列を指定した場合は、スクリプトが終了する前に文字列を出力します。

```
$query = "select 住所.郵便番号 from ファイル名 where 郵便番号= '".$postnum."'";
//住所、郵便番号のところにはそれぞれのカラム名をいれる
```
ファイルに入っている郵便番号と$postnumが同じ、住所と郵便番号を取得する

```
if ($result = mysqli_query($link, $query)) {
//mysqli_query — データベース上でクエリを実行する

 echo "SELECT に成功しました。\n";

 foreach ($result as $row) {
   echo $row['住所']."<br>";
 }
}
mysqli_close($link);
```
という形になります。
git管理下からはずす手順

## 内容
git管理下にあるファイルを管理下からはずす手順

## 目次
- [ファイルを管理対象から除外する（ファイルは残す場合）](#ファイルを管理対象から除外する（ファイルは残す場合）)
- [ファイルごと削除する](#ファイルごと削除する)

## ファイルを管理対象から除外する（ファイルは残す場合）
```bash
# ファイルを管理対象からはずす
git rm --cached <ファイル名>
```
※ ファイルを残した場合は`.gitignore`に追記

## ファイルごと削除する
```bash
# ファイルごと削除
git rm <ファイル名>

#ディレクトリごと削除
git rm -r <ディレクトリ名>
```
windowsにgit-filter-repoをインストールする

:::note
2022-02時点になります
:::

## インストール

1. windowsのpython 3.10.x をダウンロード＆インストールする  
https://www.python.org/downloads/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/0d84f51f-1ebe-38ba-574e-2964768c5a2d.png)
1. git-filter-repo をダウンロードする  
https://github.com/newren/git-filter-repo/  
※ルートの「git-filter-repo」だけで大丈夫だと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/ddf9bcaf-fb2b-fd90-c53f-df3feec23222.png)
1. 「2」でダウンロードした「git-filter-repo」の一行目の記述を変更する  
#!/usr/bin/env python3  
↓  
#!/usr/bin/env python
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/0c06964e-73d5-399f-4578-bbd23fc20865.png)
1. gitのサブプログラムのパスを確認する  
確認コマンド: `git--exec-path`
1. 「3」で変更した「git-filter-repo」を「4」の位置にコピーする
1. コマンドを確認する  
`git filter-repo`
バッチ処理の設計における主な検討点

これまでの業務経験をもとに、バッチ処理の仕様で検討する必要がありそうな主な点をまとめてみました。あくまで参考程度なので、他にもいろいろあるとは思います。

## ◆バッチ実行時の入力パラメータ（あるのであれば...）

* 入力パラメータの数
* 入力パラメータの桁数
* 入力パラメータの型
* 入力パラメータの範囲

ジョブスケジューラ製品を使用する場合、その製品の特徴、制約を把握する必要があります。

## ◆実行契機、周期

いつ、何をトリガーにして実行を開始するのかの仕様を決めます。

## ◆入力ファイルの仕様

* 拡張子
* ファイルの内容項目
* 文字コード（テキストファイルの場合）
* ファイル名規則
* ファイルの生成契機
* ファイルの削除契機（貯めるとディスク容量を圧迫するので削除が必要な場合）
* 格納ディレクトリ（ディレクトリ構成）
* 入力ファイルなしの場合の挙動
* 入力ファイルが空の場合の挙動
* 入力ファイルが複数ある場合の読込順序
* 空行の扱い（テキストファイルの場合）
* 改行コード（テキストファイルの場合）
* 最大サイズ、最大行数
* ファイルのバックアップの有無、方法（NASへの保存とか）

## ◆出力ファイルの仕様

* 拡張子
* ファイルの内容項目
* 文字コード（テキストファイルの場合）
* ファイル名規則
* ファイルの削除契機（貯めるとディスク容量を圧迫するので削除が必要な場合）
* 出力先ディレクトリ（ディレクトリ構成）
* 出力ファイルが空の挙動の有無
* 出力ファイルがなしの場合の挙動の有無
* 改行コード（テキストファイルの場合）
* 最大サイズ、最大行数
* 出力先ディレクトリに既に同名ファイルがあった場合の挙動（上書きか異常終了か）
* ファイルのバックアップの有無、方法（NASへの保存とか）

## ◆中間ファイルの仕様（必要であれば...）
中間ファイルとは、ジョブとジョブの間などでデータを受け渡す目的で一時的に作成するファイルです。要求仕様を満たすために内部的に作成するものです。

## ◆業務量

* バッチ処理1回あたりの最大実行量
* 年間あたりの最大実行量

お客さん（発注者）しかわからないはずなのですが、お客さんもなかなか確定できないまま時間が経ちがちです。とりあえず概算で見積もって書いておく、くらいになりがちな気が。

## ◆データベース

* テーブル仕様（カラム、主キー、ユニークキー、AUTO INCREMENT、などなど）
* コミット単位の件数（100件ずつコミット？1000件ずつコミット？）
* コミット失敗時のリカバリ
* 「フラグ1」→「フラグ1」の更新を許容するか？（※１）
* 「フラグ1」→「フラグ0」への更新はありか？（※２）
* 削除は物理削除か論理削除か？（※３）
* 排他取得はwait?no wait?（※４）
* パーティショニング（※５）

（※１）仕様の問題として例えば「失効状態」→「失効状態」へのUPDATEは許容するか？という問題です。フラグは変わりありませんが、テーブルには大抵の場合、更新日カラムが存在するので、更新日をアップデートする必要があるか？という話です。

（※２）仕様の問題として例えば「失効状態」→「有効状態」へのUPDATEは許容するか？という問題です。不可逆的なテーブル更新がないかを確認する必要があります。

（※３）個人情報関係の場合、退会者のユーザ情報は保持しないことが原則なので物理削除になるかと思います。その他のデータに関してはディスク容量とも相談ということになるかと思います。

（※４）オンライン処理であればno waitが一般的でしょうけども、バッチ処理なら一定時間はwaitするのが一般的かと思われます。

（※５）テーブルデータが膨大になる時、性能向上のためパーティションに分けることが考えられます。まだ経験が浅いためなんとなくですが、100万レコード超えるテーブルなら検討を始めたい感じですかね。

## ◆ログメッセージ

* エラーメッセージ
* ワーニングメッセージ
* インフォメッセージ
* デバッグメッセージ

# その他備考

### ◆異常発生時の扱い
異常があった時点で処理を異常終了？OR 異常があっても続けて流す？
これは決めの問題であり、プロジェクトや顧客の考え方によると思います。
ただ、製造業や流通系だと、どの商品でエラーが起きたのか特定することが大事なので、異常があっても全件ループさせる傾向にある、と聞いたことがあります。

### ◆フレームワークの特徴、制約
バッチ処理は、オンライン処理よりもフレームワークの特徴、制約の影響を受けやすいと思います。
（独自フレームワークを使っているプロジェクトで、入力ファイルとしてcsvしか読み込めない、1度の実行で入力ファイルは複数読み込めない、という事例を経験したことがあります。）
プロジェクトで使用されているフレームワークの仕組みを理解することが肝要です。

### ◆性能問題
* バッチ処理はオンライン処理に比べて性能観点が常につきまとう印象です。
* マルチスレッド、マルチプロセス化の検討が必要なシーンはよくあると思います。
* SELECT文の改修はよくありがちなので、SQLの学習が特に重要な印象です。DMLは基本的に、登録（INSERT）抽出（SELECT）、更新（UPDATE）、削除（DELETE)の4種類に分けられますが、この中でぶっちぎりに難しいのがSELECT文。テーブル結合が何重にもされていると、Javaなどのプログラミング言語よりもデバッグの難易度が高いので、厄介です。
* 何万、何億単位のテーブルレコードを操作する場合、プログラミング言語側で改善しようとするより、少量の重いSQLを実行した方が基本的に速いです。
SQL実行ツールをつくる

タイトルの通りSQL実行ツールを作っていきたいと思います。

まずはHtmlから

```
<body cz-shortcut-listen="true">
  <form action="index.php" method="post">
    <label>
      SQL:
      <br>
      <textarea name="sql" rows="8" cols="80" style="margin: 0px; width: 560px; height: 92px;"></textarea>
    </label>
    <br>
    <input type="submit" name="exec" value="実行">
  </form>
  <table border="1" style="border-collapse: collapse">
```

次にPHP

```
  if (!empty($_POST["sql"])) { //$_POST["sql"]が空じゃない時
    $sql = $_POST["sql"]; //上のtextareaで入力されたもの
  
  $link = mysqli_connect('ここはそれぞれの引数を入れる');//mysqliに接続

  $result =  mysqli_query($link, $sql);
  if (is_bool($result)) { // is_boolは変数がブーリアン(true,false)であるかどうか調べる
    if ($result) {
      echo "成功しました";
    } else {
      echo "失敗しました";
    }
  } else {
    $first = true; // 初回フラグをtrueにしておく
    foreach($result as $row) {
      if ($first) {
        echo "<tr>";
        foreach($row as $key => $value) {
            echo "<th>".$key."</th>";// Table_in_?やフィールドの構成を表示する
        }
        echo "</tr>";
        $first = false; // $keyを表示したのでfalseにしておく
      }
      echo "<tr>";
      foreach((array)$row as $key => $value) {
        echo "<td>".$value."</td>"; //テーブル名やカラムを表示する
      }
      echo "</tr>";
    }
  }
  mysqli_close($link);
  }
  ?>
  </table>
郵便番号検索を作る

URLの数字で検索して住所を表示するものを作りたいと思います

郵便番号と住所が入ったファイルから郵便番号を検索して住所を表示するという仕組みです

fgetcsvを使った場合とfopenを使った場合の二種類を書きます

まずは共通のコード

```
$postnum = $_GET["post"];
// urlの末尾の数字

$fp = fopen("ここにファイルの名前", "r");
// fopen ファイルをオープンする "r"はテキストファイルの読み込み

$str = mb_convert_encoding($fp,"utf-8","sjis");
// mb_convert_encoding sjisからutf-8に変換する
```

次にfgetcsvを使った場合

```
while( !feof($fp) ) { 
// while文でCSVファイルのデータを1つずつ繰り返し読み込む
//feofはファイルポインタが終端に達したか確認する
    $data = fgetcsv($fp);
    //fgetcsvとはfopen “r”モードで読み込みしたcsvファイルのデータを配列にして出力する関数
    if (is_array($data)==false) { break; }
    //is_array 変数が配列かどうかを検査する
    if ($data[2] == $postnum) {// $data[2]に郵便番号が入っている
        echo mb_convert_encoding($data[6]."<br>","utf-8","sjis");
        //$data[2]つまり郵便番号と$postnumが一緒だった場合に$data[6](住所)を出力する
    }
}
fclose($fp); // fcloseはfoopenとセット
```

次にfopenを使った場合

```
while( !feof($fp) ) {
// while文でCSVファイルのデータを1つずつ繰り返し読み込む
//feofはファイルポインタが終端に達したか確認する
    $line = fgets($fp);
    //fgetsとはfopenでオープンしたファイルから一行分読み取る関数
    if (strlen($line)==0) { break; }
    //$strlenは$lineの文字列の長さを取得する
    //つまり文字がなくなったらbreakする
    $line = mb_convert_encoding($line,"utf-8","sjis");
    //$lineをsjisからutf-8に変換する
    $line = str_replace('"','', $line);
    //str_replaceでダブルクォーテーションを消す (ファイルの中は各項目ごとに,で区切られていてそれに""がついている　例ホッカイドウ","サッポロシチュウオウク","イカニケイサイガナイバアイ",")
    $data = explode(",", $line);
    //,ごとに$lineを分割する
    if ($data[2] == $postnum) {
        echo $data[6]."<br>";
　　　　//data[2](郵便番号)とurlの数字が同じだった場合にdata[6](住所)を表示する
    }
}
fclose($fp);
```

fgetcsv関数：ファイル内のデータの1行データ(csv形式)を配列データに変更して取得する。

while分を回す
fgetscsvで一行取得
if分でデータが配列かどうか検査する
データを出力

fgets関数：ファイル内のデータを1行ずつ取得する。

while文を回す
fgetsで一行取得
if文で文字列の長さが0になると停止するようにする
sjisからutf-8に変換
ダブルクォーテーションを消す
文字列を","ごとに分割する
データを出力

という違いがあります。
Gitのコミット絵文字prefix入力の辛さを改善する

# 前提
* コミットメッセージにprefixを入れるのはいいぞ
    * https://dev.to/puritanic/how-are-you-writing-a-commit-message-1ih7

# 背景
コミットメッセージのprefixに特定の文言を入れると、様々な良い効果が生まれ開発が捗る事が言われています。さらに、prefixを絵文字にすると、インフォグラフィック的にも視認性がよく良い効果が生まれるようです。
そしたら、コミットメッセージに[絵文字prefix](https://goodpatch.com/blog/beautiful-commits-with-emojis)([Githubで対応しているもの](https://www.webfx.com/tools/emoji-cheat-sheet/))を使ってみようとなるのですが、入力するのがだるいし、Typoしてコミット・Pushしてしまったら涙目です。
で、どうしようかというと、マルチバイト入力の強みを生かしてFEPに登録しようという試みです。

# やること
**マルチバイト言語を使用している強みでFEP(Google日本語入力とか)に辞書登録するだけ**

* [Githubで使える絵文字一覧](https://www.webfx.com/tools/emoji-cheat-sheet/)
* [Anglarスタイル](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type)に則った絵文字Prefixにする
* [Angular Git Commit Guidelines with Emojis](https://github.com/ellerbrock/conventional-changelog-angular-emoji)

|Type|登録|登録する文字列|意味|
|:---|:----|:---|:--|
|feat|ふぃ|`:sparkles:`| 新機能|
|fix|ふぃ|`:bug: `|バグフィックス|
|refactor|り|`:recycle:`|リファクタリング|
|perf|ぱ|`:rocket:`|パフォーマンス改善|
|test|て|`:rotating_light:`|テストコードの追加・修正|
|style|す|`:gem:`|コードの意味に影響しない変更|
|docs|ど|`:book:`|ドキュメントだけの変更|
|chore|ちょ|`:ticket:`|雑用|

これで、どの環境でコミットしてもEmoji Prefixが簡単に登録できる。
クラスを使って成績表を作る

タイトルの通りクラスを使って成績表を作っていきます

このような形にしたいと思います
![クラス表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612146/b8e5570a-8262-9589-0ee1-8dfe3e6fc486.png)

上が項目名になっていて横が人、そしてランクは点数が高い順になっています

まずはテーブルタグの中身を作ります

```
  <table>
    <tr>
      <th>生徒</th>
      <th>国語</th>
      <th>数学</th>
      <th>理科</th>
      <th>社会</th>
      <th>英語</th>
      <th>合計値</th>
      <th>ランク</th>
    </tr>
  </table>
```

続いてjavascript
まずはクラス宣言の部分

```
  class info {//クラス宣言
    constructor(total, name, NL, math, science, society, english) {//コンストラクター
      this.total = total;
      this.name = name;
      this.NL = NL;
      this.math = math;
      this.science = science;
      this.society = society;
      this.english = english;
    }
    getTotal() {//メソッド
      return this.total = this.NL + this.math + this.science + this.society + this.english; //すべてを足し合わせたもの
    }
    getName() {
      return this.name;
    }
    getNL() {
      return this.NL;
    }
    getMath() {
      return this.math;
    }
    getScience() {
      return this.science;
    }
    getSociety() {
      return this.society;
    }
    getEnglish() {
      return this.english;
    }
  }
```

続いてオブジェクトの作成します

```
　//オブジェクトの作成
  var a = new info(this.total, 'Aさん', 80, 70, 70, 50, 60);//コンストラクターのかっこの中の順番、つまりtotal, name, NL, math, science, society, englishの順に点数を入れていく
  var b = new info(this.total, 'Bさん', 60, 70, 40, 80, 60);
  var c = new info(this.total, 'Cさん', 60, 70, 70, 60, 60);
  var d = new info(this.total, 'Dさん', 80, 40, 40, 70, 70);
  var e = new info(this.total, 'Eさん', 70, 70, 70, 60, 70);

  var arr = [ //変数arrの中にはそれぞれのトータルを入れておく
    a.getTotal(),
    b.getTotal(),
    c.getTotal(),
    d.getTotal(),
    e.getTotal(),
  ];
```
という形です
画像がマウスカーソルを追いかける

タイトルの通り画像がマウスカーソルを追いかけるものを作りたいと思います。

まずは変数などの設定をします

```
var mga = "download.png";//mgaは画像でダウンロードしたもの

var ix=0, iy=0, mx=0, my=0;//ix,iyは画像の位置 mx,myはマウスカーソルの位置 最初は0に設定しておく

document.write("<img src="+mga+" id='img' style='position:absolute;'>");
```

ixとiyは画像が追いかけ始める最初の位置　この場合は左上端からになる

次にマウスカーソルの座標を取得します

```
function getMouseXY(e) {//getMouseXYはマウスカーソルの座標を取得する
  mx = e.pageX;//mxはマウスカーソルx軸を取得する
  my = e.pageY;//myはマウスカーソルのy軸を取得する
}
document.onmousemove = getMouseXY;
//onmousemoveはマウスカーソルの位置を取得する マウスカーソル＋が動くとイベントが発生する
```



```
function Run() {

if (mx > ix) {//mx(マウスカーソル)がix(画像)より大きい時ixを+3
  ix += 3; //3ずつ追いかける
} else if (mx < ix){//mx(マウスカーソル)がix(画像)より小さい時ixを-3
  ix -= 3; //3ずつ追いかける
}

if (my > iy) {//my(マウスカーソル)がiy(画像)より大きい時myを+3
  iy += 3;
} else if (my < iy) {//my(マウスカーソル)がiy(画像)より小さい時myを-3
  iy -= 3;
}

var ob = document.getElementById("img").style;

ob.left = ix+"px"; 
ob.top = iy+"px";
//obは上にあるimgのスタイルを動かす変数
//ob.leftというのは左からiy(数値)px
//ob.topは上からix(数値)px

setTimeout(Run,200);//0.2秒に一回動く 数を大きくするほど動く頻度が長くなる
}
Run();
```

これで完成です

スタイルを合わせたすべて


```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>サイト</title>

<style>
#img {
  width: 16px;
  height: 16px;
  border-radius: 50%;
}
</style>
</head>
<body>
<script>

var mga = "download.png";//mgaは画像でダウンロードしたもの

var ix=0, iy=0, mx=0, my=0;//ix,iyは画像の位置 mx,myはカーソルの位置

document.write("<img src="+mga+" id='img' style='position:absolute;'>");

function getMouseXY(e) {//getMouseXYはカーソルの座標を取得する
  mx = e.pageX;//mxはカーソルx軸を取得する
  my = e.pageY;//myはカーソルのy軸を取得する
}
document.onmousemove = getMouseXY;
//onmousemoveはカーソルの位置を取得する

function Run() {

if (mx > ix) {//mxがixより大きい時ixを+3
  ix += 3;
} else if (mx < ix){//mxがixより小さい時ixを-3
  ix -= 3;
}

if (my > iy) {//myがiyより大きい時myを+3
  iy += 3;
} else if (my < iy) {//myがiyより小さい時myを-3
  iy -= 3;
}

var ob = document.getElementById("img").style;

ob.left = ix+"px"; ob.top = iy+"px";
//obは上にあるimgのスタイルを動かす変数
//ob.leftというのは左からiy(数値)px
//ob.topは上からix(数値)px

setTimeout(Run,200);//0.2秒に一回動く
}
Run();
//setInterval(Run,200);
</script>
</body>
</html>
```

styleの#imgで画像の大きさを変更できます
Javascriptでカレンダーを3か月分作る

javascriptでカレンダーの三か月分を作っていきます。

![スクリーンショット 2021-12-08 152429.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612146/0932d3a9-26b8-7532-94de-3f7c1b1b16cf.png)

このような形に仕上げていきます。

まずは変数を設定します

```
  <div id="calendar"></div>

    <script>
      var weeks = ['日', '月', '火', '水', '木', '金', '土'] //weeksには文字列を入れておく
      var date = new Date() //現在の時刻を取得
      var calendarHtml = '' //空を作ってあとからここに追加していく
```

三か月分for文を回します

```
      for (var add_month=1; add_month<=3; add_month++) {
```

次に変数を設定します

```
        var year = date.getFullYear() //現在の年を取得
        var month = date.getMonth() + add_month; //getMonthは0~11で月を取得する 現在の月から三カ月　
        var startDate = new Date(year, month - 1, 1)//月の最初の日 
        var endDate = new Date(year, month,  0) //月の最後の日 来月の0日目つまり今月の最後の日になる
        var endDayCount = endDate.getDate() //月の最後の日を取り出す 日付の数字を取得する
        var startDay = startDate.getDay() //月の初めの曜日を取得
        var dayCount = 1
```

ここから表を作っていきます

```
        calendarHtml += '<table>' //テーブルタグを追加
        calendarHtml += '<caption>' + startDate.getFullYear() + '年' + (startDate.getMonth()+1) + '月' + '</caption>'//カレンダーの年と月の部分
        for (let i = 0; i < weeks.length; i++) { //weeksの数だけつまり曜日の数だけiを回す
            calendarHtml += '<th>' + weeks[i] + '</th>' //曜日を描写する
        }

        for (let w = 0; w < 6; w++) {//週の数は最大6週目まで
            calendarHtml += '<tr>'
  
            for (let d = 0; d < 7; d++) {//dは0から7まで増えていく
                if (w == 0 && d < startDay) {//最初の週でスタートデイ(月の初めの曜日)よりdが小さかったら<td>を増やしていく
                    calendarHtml += '<td></td>'//月の最初の日より前の空白を描写する
                } else if (dayCount > endDayCount) {
                  // 月末日以降は何もしない daycountは月末日まで
                } else {
                    calendarHtml += '<td>' + dayCount + '</td>'//daycountの分だけカレンダーに追加する
                    dayCount++
                }
            }
            calendarHtml += '</tr>'
            if (dayCount > endDayCount) {//daycountがenddaycountを超えると停止する
              break;
            }
        }
        calendarHtml += '</table>'
      }
```

for分を4回使うことになります

1つ目は3カ月回すためのもの

2つ目は曜日の表を作るためのもの
 
3つ目は週を月の最後まで回すもの

4つ目は1週間の日にちを最後まで回すためのもの

という形になっています
Phpからシンプルにslackにアラートを飛ばす（2022新方式版）

## はじめに
フレームワークはCodeIgniterを使っていますが、どんなフレームワークでもサービスとしてクラスを作って、どっかから呼べばできるはずです

## 下準備
slack側の準備はこれを見てください

https://qiita.com/YoshitakaOkada/items/94f66dffbf46294f7b20#slack%E5%81%B4%E6%BA%96%E5%82%99

## source
```php:app/Libraries/Slack.php
<?php

namespace App\Libraries;

class Slack
{
    private const TODAY = 0;
    private const TOKYO = 130010;
    
    /**
     * slackにメッセージを送ったあと、成功したら ok を返す
     * @param string $message
     * @return string
     */
    public function sendMessage(string $message): string
    {
        $url = env('slack.url');
    
        $post_fields = [
            "channel" => urlencode(env('slack.channel')),
            "text" => $message,
        ];
        
        $options = [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true, // 実行結果を文字列で返す
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS =>
                http_build_query(
                    ['payload' => json_encode($post_fields)]
                )
        ];
        $conn = curl_init();
        curl_setopt_array($conn, $options);
        $res = curl_exec($conn);
        curl_close($conn);
        
        return $res;
    }
    
    /**
     * メッセージのネタは「天気」にしましょう！
     * @return string
     */
    public function sampleMessage(): string
    {
        // PHPのcurlでSSL certificate problemが出る場合
        // https://tm23forest.com/contents/php-curl-ssl-certificate-problem
        $url = 'https://weather.tsukumijima.net/api/forecast/city/' . self::TOKYO;
        $conn = curl_init();
        $options = [
            CURLOPT_URL => $url,
            CURLOPT_HEADER => false,
            CURLOPT_RETURNTRANSFER => true, // 実行結果を文字列で返す
        ];
        curl_setopt_array($conn, $options);
        $res = json_decode(curl_exec($conn), true)["forecasts"][self::TODAY];
        curl_close($conn);
    
        return $res["date"] . PHP_EOL . $res["telop"];
    }
}
```

```php:tests/Tests/Libraries/SlackTest.php
<?php

namespace Tests\Libraries;

use App\Libraries\Slack;
use PHPUnit\Framework\TestCase;

class SlackTest extends TestCase
{
    
    public function testSampleMessage()
    {
        $service = new Slack();
        $expected = '2022-02-11' . PHP_EOL . '晴時々曇' . PHP_EOL . 'From PHP script';
        $this->assertEquals($expected, $service->sampleMessage() . PHP_EOL . 'From PHP script');
    }
    
    public function testSendMessage()
    {
        $service = new Slack();
        $this->assertEquals('ok', $service->sendMessage('あああ'));
    }
}
```
【Docker】コンテナをイメージにして配布する

## はじめに
本記事では、コンテナからイメージを生成する方法についてまとめます。

## コンテナの作成
今回は簡単なコンテナとして、c++のhello worldプログラムを使います。
ディレクトリ構成は以下のようにします。

docker-cpp/
　├ src/
　　├ CMakeLsits.txt
　　└ main.py 
　├ docker-compose.yml
　└ Dockerfile

各ファイルの内容は以下のようになります。

```Dockerfile:Dockerfile
FROM ubuntu:18.04

RUN apt-get update && apt-get -y upgrade && \
    apt-get install -y sudo && \
    apt-get install -y build-essential && \
    apt-get install -y vim && \
    apt-get install -y wget && \
    apt-get install -y unzip && \
    apt-get install -y git && \
    apt-get install -y libssl-dev

# コンパイラーのインストール
RUN apt-get install -y gcc && \
    apt-get install -y g++

# コンパイラーのパスをセット
ENV CC=/usr/bin/gcc \
    CXX=/usr/bin/g++

# CMakeインストール
RUN cd $HOME && \
    wget https://github.com/Kitware/CMake/releases/download/v3.17.1/cmake-3.17.1.tar.gz && \
    tar zxvf cmake-3.17.1.tar.gz && \
    cd cmake-3.17.1/ && \
    ./bootstrap && \
    make -j12 && sudo make install -j8
RUN echo 'export PATH=$HOME/cmake-3.17.1/bin/:$PATH' >> ~/.bashrc && \
    . ~/.bashrc

RUN apt-get install -y libopenblas-dev && \
    apt-get install -y liblapack-dev

# ライブラリインストール用ディレクトリ
WORKDIR $HOME/usr/
RUN mkdir ./library

CMD bash
```

```docker:docker-compose.yml
version: '3'

services:
  cmake:
    container_name: cmake_container
    build:
      context: .
      dockerfile: Dockerfile

    tty: true
    command: /bin/bash

    volumes:
      - ./src:/usr/src
```

```CMakeLists.txt
project("testDockerCpp")

cmake_minimum_required(VERSION 2.8)

add_executable(test main.cpp)
```

```c++:main.cpp
#include <iostream>
#include <string>

int main(void){
    std::cout << "Hello World!" << std::endl;
    return 0;
}
```

## コンテナの作成
上記のファイルが準備できたら、コンテナを作成していきます。以下のコマンドでDockerfileをビルドし、コンテナを作成します。

```bash
docker compose up -d
```

コンテナが起動できたら、以下のコマンドでコンテナ内に入ります。

```bash
docker exec -it cmake_container bash
```

コンテナ内に入ったら以下のコマンドでビルド、実行をするとHello World!と出力されます。

```bash
cd /usr/src/
mkdir build
cd build
cmake .. & make -j4
./test
```

このあとこのコンテナをイメージ化するのですが、このままイメージ化しても意味がないので（コンテナ作成時に作られているので）、少しいじってみます。今回は、ソースコードを消して実行ファイルのみにしてみます。

```bash
cd /usr/src
rm main.py CMakeLists.txt
```

## コンテナをイメージ化
いよいよコンテナをイメージ化していきます。イメージ化する前にコンテナは以下のコマンドで停止しておいてください。

```bash
exit
docker stop cmake_container
```

以下のコマンドを実行することで、コンテナをイメージ化することができます。
`docker commit コンテナ名 イメージ名`

```bash
docker commit cmake_container helloworld
```
ここで、イメージ名はアルファベット小文字のみでないとエラーになります。

以下のコマンドで、今作成したイメージからコンテナを作ってみます。

```bash
docker run -itd --name helloworld_container helloworld
```

コンテナ内に入って、`./test`を実行すると`Hello World!`と表示されます。

```bash
docker exec -it helloworld_container bash
cd /usr/src/build
./test 
```

## 最後に
なんで、c++を例に使ったんだろう。Dockerfileのビルドめちゃくちゃ時間かかります。ごめんなさい。作成ずみのコンテナ使うと、さくっと試せると思います。(そもそも配布イメージ使えばよかった)
M5 stack c を買って一番最初にするのは、0時にUSBコードを挿して起動

## M5 stackC(Plus)を買って最初にすべきこと
初心者がM5 stackC(Plus)を買って最初にすべきことは、
あせる気持ちを抑えて、0時前まで待ち
0:00:00に、充電用のUSB-Cケーブルを挿す事です

## 理由
最初から入ってるサンプルプログラムにはRTCから取得した時刻を表示する時計機能があります  

内臓のRTCとサンプルプログラムは、初めて電源を投入された時にRTCを初期化して0:00:00 から計時を開始し、内臓バッテリーにより電源ボタン長押しで切った後も計時が続きます(日付はいつになっているかは存じません)  

このサンプルプログラムに時計を合わせる機能はありません

とりあえず、0:00:00に初回電源ONしておけば、ただの(腕)時計にはなります  

初めて作るプログラムがRTC時計合わせプログラム一択という運命を強要されたくない方へ（私は強要されてしまったので）


間違っていたらぜひご指摘ください＆既出かもしれません
react-router v6でreact hot loaderとの相性が悪い件

# 問題発生
react-routerを使おうとすると下記のエラーが発生した。

```
Uncaught Error: [ProxyFacade] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
```
<意訳>
ProxyFacadeはRouteコンポーネントではありません。すべてのRoutesの子コンポーネントはRouteコンポーネントである必要があります。

# 原因
[StackOverflow](https://stackoverflow.com/questions/70037167/error-proxyfacade-is-not-a-route-component-all-component-children-of-rout/70243956)の情報によるとreact-hot-loaderがすべてのエレメントをProxyFacadeでラッピングするため、react-routerがRoutesコンポーネントの子要素としてRouteコンポーネントがないと認識してしまうようだ。

# 対処方法
ソースコードの修正をリアルタイムに反映するためにreact-hot-loaderを使っていたが、react-router v6と相性が悪くて断念。
v6の方がルーティングを簡略化してかけたりして便利なんだけど、今回はv6でなくv5を使うことにした。
巷のreact-routerの情報もv5のものが多いのでv6は時期尚早かもしれない。

yarnを使ってv5をインストールする方法は下記の通り。

```
yarn add react-router@v5
yarn add react-router-dom@v5
```

# おまけ
react-routerとreact-router-domの違いは[この記事](https://qiita.com/koja1234/items/486f7396ed9c2568b235)が分かりやすかったです。

v5とv6のルーティングの書き方の違いは[このページ](https://reactrouter.com/docs/en/v6/upgrading/v5#relative-routes-and-links)が詳しかったです。
「○○100本ノック」備忘録

やったことがある、またはこれからやってみたいというPython関連での「○○100本ノック」というものについてまとめていきたいと思います。
100本ノックというのは、100個の問題について自分で考え、プログラムを書きます。
100題ありますが、もちろんすべてについて取り組む必要はないです。
プログラミングというのは見てるだけでは意外と身につかないので、実際に自分で考えプログラムを書くことで力がつくと思います。

##言語処理100本ノック
サイトから説明文の一部を引用します。
>言語処理100本ノックは，実用的でワクワクするような課題に取り組みながら，プログラミング，データ分析，研究のスキルを楽しく習得することを目指した問題集です。言語処理100本ノックの問題は，東京工業大学の岡崎直観により制作・保守されています．

https://nlp100.github.io/ja/

この言語処理100本ノックに関しては様々な方の解法がありましたので、何人か挙げさせていただきます。

- [yamaruさんの解法]
(https://qiita.com/yamaru/items/0cac24710626333bd693)

- [u++さんの解法]
(https://upura.hatenablog.com/entry/2020/04/14/024948)

##画像処理100本ノック
https://github.com/yoyoyo-yo/Gasyori100knock

画像処理のアルゴリズムを理解するための100本ノックです。

##データサイエンス100本ノック
サイトから説明文の一部を引用します。
>- データサイエンス100本ノック（構造化データ加工編）を実践するための演習問題とデータ、および環境構築のためのスクリプト一式。
- 演習問題はSQL、Python、Rで共通
- 言語によっては向かない設問もあるが、「この言語のときはこう書けば実現できる」という技術習得を目指すことを優先


https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess

##Pandas100本ノック
サイトから説明文の一部を引用します。
>この度、PythonライブラリであるPandasを効率的に学ぶためのコンテンツとして「Python初学者のためのPandas100本ノック」を作成したので公開します。本コンテンツは、Python3エンジニア 認定データ分析試験の出題内容にも沿っているため、この100本ノックを実施することで資格対策にもなります。

https://qiita.com/kunishou/items/bd5fad9a334f4f5be51c

PandasはPythonのデータ解析用ライブラリです。
Pandasを使うことができると、データの統計量を表示したり、グラフ化及びデータ分析などの作業を簡単におこなうことができるようになります。
Pythonでデータ分析を行う際には割と必須なライブラリだと思います。

##Numpy100本ノック
https://github.com/rougier/numpy-100

NumpyはPythonで数値計算を効率的に行うためのライブラリです。
ベクトルや行列などの多次元配列の処理を容易に行えます。
Pandasと同様に必要不可欠なライブラリです。

このサイトは全て英語です。
といっても、一題が短いので苦にはならないと思います。




##Python基礎力を上げる100本ノック(Youtube動画)
https://www.youtube.com/watch?v=Gh0qRBHbnVs

「いまにゅのプログラミング塾」という方のチャンネルの動画です。
2時間３０分ほどの内容となっています。動画を見ながら、一緒に作業できます。

##Python実践データ100本ノック(書籍)

[Python実践データ100本ノック(amazonに飛ぶ)](https://www.amazon.co.jp/Python%E5%AE%9F%E8%B7%B5%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF-%E4%B8%8B%E5%B1%B1-%E8%BC%9D%E6%98%8C/dp/4798058750)

内容について写経されている方がいたので参考に

https://qiita.com/yasuoyasuo/items/fec5ed4d7afc1627dc4d

#まとめ
「○○100本ノック」に関しての記事はざっとこんな感じでしょうか。
いろいろありますがコツコツ進めるもよし、時間があるから一気にやろうというのも良いと思います。
自分もまだまだ学習不十分なところが多くありますし、ここにあるようなサイトで学習を進めていきたいです。
最近では無料でこのようなコンテンツを手軽に学べるのがすごくいい時代になったと思います。このようなサイトを書いている方々には頭が上がりません。本当に感謝してます。
サブドメインがついたURLにlink_toで指定する方法

サブドメインが付いているURLをlink_toで指定する方法です。
業務の中で、サブドメインの異なるページからlink_toを用いて画面遷移する必要があったのでメモとして。

サブドメインが同じページからの遷移（通常）

```ruby
= link_to "タスク一覧", tasks_path # 「tasks_path」の指定の仕方でOK
```

サブドメインの異なるページからの遷移

```ruby
= link_to "タスク一覧", tasks_url(subdomain: 'xxx') # 「tasks_path」の指定では遷移できないので「tasks_url」と記述しなければいけない
```

 

IDを伴うURLへの遷移（インスタンス変数を渡す場合）

```ruby
= link_to "タスク詳細", task_url(@task, subdmain: 'xxx') # (インスタンス変数, subdomain: 'xxx')の形をとる
```
linuxtut.comって何？【無断転載？】

知らんうちに自分の書いた記事が転載されていた。
（元記事）https://qiita.com/tmoriki/items/63903bb4d15c32ba8a1b
（転載先）https://linuxtut.com/en/63903bb4d15c32ba8a1b/

・・・記事のIDまで一緒で草。これってそういうもんなのかな。ちょっとモヤる。
広めてくれるのは嬉しいけど、元記事URLくらいは引用しろって思うわ。

P.S.
他にもそういうことをされた先輩方はいらっしゃるようで。そういう時代ですかね。
https://note.com/kumasunorz/n/ndbb0c8c02c15
〜初心者がCrystalで競プロをしてみた〜　1回目

こんにちは。Tsubaqanと申します。
今回からちょっとマイナ−言語のプログラミングをしてみようと思います😎

〜軽く自己紹介〜

1994年生まれ。
ほとんどプログラミングの経験なし。
WordPressで記事執筆をしている程度。

そんな私が、今回Qiitaで記事を書くきっかけとなったのはずばり・・・。

<h2>マイナー言語で競技プログラミングがしたい！</h2>
という思いでした。

普段私はHTMLを触っているので、プログラミングとは程遠い世界にいます。
それでも、スキルアップのためにプログラミングしたいな、という思いに駆られ、
1月の最初にAtcoderで試験を受けたわけです。
ABC234の結果は・・・<h3>7点！</h3>
A問題しか解けませんでした。

敗因はやはり<h4>勉強不足</h4>でしょうね。

ただ2ヶ月間Crystalを触ってみて、このくらい書けるようになりました(*˘︶˘*)

```Crystal:Compare The Triplets.cr
a = read_line.split(" ").map(&.to_i)
b = read_line.split(" ").map(&.to_i)
ans = [0,0]
if a[0] > b[0]
  ans[0] += 1
elsif a[0] < b[0]
  ans[1] += 1
end
if a[1] > b[1]
  ans[0] += 1
elsif a[1] < b[1]
  ans[1] += 1
end
if a[2] > b[2]
  ans[0] += 1
elsif a[2] < b[2]
  ans[1] += 1
end
puts ans
```
これは私がHackerRankというサイトから問題を解いてみたものです。
（Crystalでは採点ができませんがおそらく合っていると思われます）

また、Topcoderというサイトではこのくらいまで。
```Crystal:A0Paper.cr
paper = read_line.gsub(/[{}]/ , "").split(",").map{|i|  i.to_i}
cnt = -1
paper.each do
 if paper[cnt] > 1
    paper[cnt] = paper[cnt] >> 1
    paper[cnt-1] += paper[cnt]
    cnt -= 1
    break if cnt.abs == paper.size
 end
end

if paper[0] >= 1
  puts "Possble"
else
  puts "Impossible"
end
```
これはおととい書きました。
これも採点手段がないので採点していません😅

Crystalは個人的に楽しい言語だと思います。
Rubyっぽい言語でも実行速度がとにかく速いです。
これからはCrystalでどんどんコードを書いて、
また載せていきますので、
興味のある方、Crystalがお好きな方はどうぞご覧くださいね＼(^o^)／

では・・・。初回はこのへんで!
次回はもう一度Atcoderに挑戦だっ！
markuplint を VSCode に導入してみた


背景
-----
「HTML5」から「HTML Living Standard」に変わったことで, 変更・追加・廃止となったタグの要素・属性をチェックできる **markuplint** というリンターを発見したので導入してみた。

概要
-----
**markuplint** とはその名の通り「マークアップすること」に関するlintツールで, HTML Living Standardに対応しています。
また, React や Vue などのフレームワークや, EJS などのテンプレートエンジンのためのプラグインも用意されていて, 各種ルールについても柔軟に設定できるようになっています。

導入手順
-----
###VSCode に markuplint プラグイン導入
```ruby:cmd
npm i -D markuplint
```
###VSCode の拡張機能をインストール
1. VSCode の Marketplaceを開く
![VSCode_拡張機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547658/fb59fea0-39ee-2017-9377-baa68209e454.png)

2. 検索窓に **markuplint** を入力しインストール
![VSCode_markuplintインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547658/fc68c0a7-b83f-afa7-4247-f7e55511880e.png)

3. VSCodeを再起動

実行方法
-----
###package.json の scripts にオプションコマンドを追加
```ruby:cmd
{
  "scripts": {
    "html:lint": "markuplint **/*.html"
  }
}
```
###スクリプトを実行
```ruby:cmd
npm run html:lint
```

:::note info
1ファイルごとの実行も可能
:::
下記のように入力することで1ファイルごと実行できます。

```ruby:cmd
npx markuplint target.html
```
###結果
![lintエラー表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547658/146a3440-a3c8-52f7-9188-d32430e31b32.png)

ログを確認するとHTML Living standard で廃止された要素にエラーが出ているので, 正常に動作してそうです。
ただ, 私だけなのかVSCode上のマークアップがされていないような。。。
コマンド実行はしっかりできているので一旦先に進みます。

:::note alert
正常に実行できなかった場合は改行コードが問題の可能性
:::
**markuplint** は CRLF に未対応のため **LF** でないとパーサーがきちんと機能しない可能性があります。
####VSCode での改行コード変更方法
![VSCode_改行コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547658/b0408861-37c0-fa4e-a0f7-8621d8f7a717.png)
VSCode 下部から改行コードを変更できます。

ルールの追加
-----
構成ファイルにルールやオプションを記載することで
markuplintが自動的にロードし実行してくれます。

###構成ファイルを作成
次のファイルを作成

```ruby:.markuplintrc.json
{
  "extends": [],
  "plugins": {},
  "parser": {},
  "parserOptions": {},
  "specs": [],
  "excludeFiles": [],
  "rules": {},
  "nodeRules": [],
  "childNodeRules": []
}
```
**.markuplintrc.json** は markuplintrc の構成ファイルです。

###2. オプション, ルール追加
####markuplintコアから提供された構成をロード
```ruby:.markuplintrc.json
{
  "extends": ["markuplint:recommended"]
}
```

####ファイル除外
必要に応じて実行ファイルを除外できます。

```ruby:.markuplintrc.json
{
  "excludeFiles": ["./node_modules/**/*.html"]
}
```

####ルール追加
いくつかのルールを追加することができます。
詳細は[こちら](https://markuplint.dev/rules)で公式がルールの記載方法をまとめてくれているので参考になります。

次の一歩
-----
プラグインについては次の記事に記載します。

参考資料
-----
https://github.com/markuplint/markuplint

https://markuplint.dev/getting-started
暗号化

自分用のメモです。

■暗号化とは？

・データの内容を他人には分からなくするための方法
ログイン時のパスワードなどは暗号化された状態でコンピュータに保存される

・暗号化の例：シーザー暗号
平文：Hello
暗号文：Uryyb（Helloから13文字ずらされている）
→「共通鍵暗号を利用、Key=13」と表現


■SSL/TLSについて

・HTTPS = HTTP + SSL/TLS
現在、SSLは使ってはいけないことになっている

・SSL = Secure Socket Layer

・TLS = Transport Layer Security

・SSL/TLSには主に4つの機能がある
①鍵交換（Kx：Key exchange）
②認証（Au：Authentication）
③暗号化（Enc：Encryption）
④メッセージ認証コード（Mac：Message Authentication Code）


■暗号化

・暗号化には公開鍵暗号方式と共通鍵暗号方式の2つが存在

・公開鍵暗号方式（RSA、ECDSA）
　RSA：巨大な数字の場合において素因数分解が困難なことを利用した暗号
　ECDSA：楕円曲線上の離散対数問題の困難性を利用した暗号（P＝NPだった場合はまずい）

・共通鍵暗号方式（DES、AES）
　DES：古いブロック番号。鍵長が56bitで短すぎるため、今は利用されない。
　AES：DESの後継として誕生、現在の標準。128、192、256ビットなど鍵長を選択できる

・共通鍵暗号方式の方が通信速度が速い


■鍵交換

・共通鍵暗号で利用するための鍵を交換すること

・RSAを利用した鍵交換はほぼ行われていない


■署名

・署名とは送信元の人の身分を証明するもの（電子署名とは別）

・RSAもECDSAも利用されている
UMLにおけるクラス図の制約って大事だよねっていう話

## 概要
特にUMLの読み方とか制約についての説明はしていません。
制約の有無により、解釈を制限できるというお話です。

## 本題

次のクラス図があったとします。
よくある再帰的な関連を持つクラスを表現したクラス図です。

![LT-制約-ページ1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518115/ce307b59-6443-c7c2-f991-9a47c7cc5d4b.png)

さて、上のクラス図からオブジェクト図を作るとしたら次のようになるでしょうか。

![LT-制約-ページ2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518115/369fe1ad-0355-53b7-1f3f-a0e48c03e2e7.png)

山田さんは、佐藤さんと田中さんの上司であることを表現したオブジェクト図ですね。
クラス図の多重度にも違反していないので、正しく表現できているように思えます。

本当にこのパターンだけでしょうか。。？
次のオブジェクト図を見てみましょう。

![LT-制約-ページ3.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518115/c46fac49-8234-f60c-0df2-76211c06fc83.png)

山田さんは佐藤さんの上司です。
佐藤さんは田中さんの上司です。
田中さんは山田さんの上司です。（？）

クラス図の多重度にも違反していないので、正しく表現てきている。。感じがしませんね。
実は最初に提示したクラス図だと、こういったケースも考えることができてしまいます。
そう、**上司と部下の関係がループ**しています。

再帰関連を使ったクラスの表現はループになりますので間違ってはいないのですが、違和感があります。
それは、**一般的に会社の組織において、上司と部下という役割は本来ループするような関係では無いため**です。
<small>（上司の部下の上司からは部下として仕事してます。というのはあまり聞きせんね。）</small>

こういった時は、次のように**制約**を定義することで、解釈に制限を設けることができます。

![LT-制約-ページ4.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518115/16e5743a-e058-d7a6-682a-acf05c08ac5d.png)

上のように階層制約が定義されたクラス図の方が、オブジェクト図も作りやすいかもしれませんね。

![LT-制約-ページ5.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518115/ee695d24-aeb2-0442-a35f-c06c592f050a.png)

以上です。