OmniAICreator/Qiita-1.07M huggingface dataset:
Android 設定 - 通知 - バッテリーセーバー が ON になっていると通知でバイブしない

設定 - 通知 - バッテリーセーバー が ON になっていると通知でバイブしない

* × 電話の着信 (留守電になる。)
* × LINE通知

(Android 5 から搭載された様子)

以下ページが詳しい
https://techblog.yahoo.co.jp/android/battery-saver/
初心者によるプログラミング学習ログ 336日目

#100日チャレンジの336日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
336日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>336日目　1.5h<br>・ポートフォリオ作成<br>・navの領域外クリックでハンバーガメニュー閉じる<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1268997596875419648?ref_src=twsrc%5Etfw">June 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
scalaのtrait, abstract class, class, objectについて理解を深める

#背景
scalaに触れていく中で、traitとclassの違いってなんや！objectってどこでどんな風に使うんや！ってなったので自分なりの理解を残しておきます。

#抽象と具体
これらの理解を深めるために抽象的なものと具体的なものに分けようと思います。
プログラミング的に抽象的なものとしては全体として知っている知識、具体的なものとしてはその具体実装を指します。

#抽象
タイトルで示した4つのうち、traitとabstract classが抽象的なものに当たります。
#具体
具体にはclassとobjectが入ります。
#違い
ほんならそれらの違いってなんやねん！となると思うのですが、説明していきます。

trait => can doの関係
abstract class => is a の関係

という説明を受けてなるほど！となりました。
つまり、"犬は吠えることができる"なのか"犬は動物だ"なのかの違いですね。
このように抽象的なものを使い分けることができます。

class => newしてあげる必要があり、いっぱい作れる
object => singletonなもの。唯一定義してあげたいもの。

のような違いがあります。

このような認識で今後は使い分けていきたい。
定期的にイベントログをチェックして同一メッセージの多発を検知する

統合監視ツールでは「エラー」以上を検知対象としているが、「警告」や「情報」であっても多発している場合は「エラー」（検知対象）にしたかったので、以下のようなバッチをタスクスケジューラに登録し10分毎に実行することにした。

```bat
@echo off

rem Level=3 は警告メッセージ
rem 直近10分(600000ミリ秒)のイベントをチェックする

set q="*[System[(Level=3) and (EventID=1) and TimeCreated[timediff(@SystemTime) <= 600000]]]"
set m="監視対象メッセージ"

wevtutil qe application /q:%q% /f:text | find %m% /c > count.txt

for /f %%a in (count.txt) do @(set /a count=%%a)

rem 閾値
if %count% gtr 10 (
	eventcreate /L application /T ERROR /ID 1 /D %m%
)
```

連続的に監視するわけではないので、厳密には閾値を超えていてもすり抜ける可能性はあるが、無いよりはマシ。
Julia MPIClusterManagers.jl 

https://github.com/JuliaParallel/MPIClusterManagers.jl

Juliaの並列周りは色々あってよくわからない。Juliaには普通にMPI通信をするMPIバインドもあるのだけどこれは別物。MPIを使って`addProcs`の際の起動を行うだけか。

## 通信モード

3つの通信モードがある。

1. マスタプロセスはMPIの外で動作する。ワーカプロセスのみMPIで実行。ワーカプロセス、マスタプロセスはTCP/IPで通信。つまりMPIの通信機構は使わない。
2. マスタを含めてすべてのプロセスがMPI内で動作。TCP/IPで通信
3. マスタを含めてすべてのプロセスがMPI内で動作。TCP/IPではなく、MPIを通信機構として使う。

スパコン系は、MPIでしか高速な通信ができないものもあるので、3が興味深い。

## モード1
モード1とモード 2，3では書き方がかなり違う。モード1の場合はわりに普通のクラスタマネージャと同様の書き方。ごく普通にJuliaを起動し、そこで`MPIClusterManager`をつかってワーカを起動する。SSHの代わりにMPIでプロセスをまとめて起動しているだけに見える。

``` Julia
using MPIClusterManagers, Distributed

manager = MPIManager(np=4)
addprocs(manager)
```

こうするとworkerが4つできてくるので、あとは普通に使える。

## モード2/3
こちらは、MPI.jlの場合と同様に`mpirun`を用いて複数のJuliaプロセスを同時に起動する形。プログラムの書き方も随分違う。MPIを起動しておいてから、ClusterManagerのイベントループを実行すると、rank0だけが帰ってきて、他のプロセスがワーカとして見えるようになる。
モード2と3はイベントループを起動する際のオプションで切り替える。

``` Julia
using MPIClusterManagers, Distributed
import MPI

MPI.Init()
rank = MPI.Comm_rank(MPI.COMM_WORLD)
size = MPI.Comm_size(MPI.COMM_WORLD)

manager = MPIClusterManagers.start_main_loop(TCP_TRANSPORT_ALL) 
#manager = MPIClusterManagers.start_main_loop(MPI_TRANSPORT_ALL) 

....


MPIClusterManagers.stop_main_loop(manager)

``` 
最後にイベントループを停止する必要がある。

分散コードとしては普通のDistributedと同様に書ける。例えば、上の`・・・・`のところに、下のように書く。

``` Julia
@everywhere import Distributed
println("rank=$rank, size=$size, workers=", workers())

@everywhere function host_and_id()
  strip(read(`hostname`, String)) * " : " * string(Distributed.myid())  
end  

futures = 
  [ @spawnat i host_and_id() for i in workers() ]

for f in futures
  println(fetch(f))
end
```

で

```
mpirun -np 3 julia mode2test.jl 
```
のようにして3プロセスで実行すると、

```
rank=0, size=3, workers=[2, 3]
host1 : 2
host2 : 3
```
のような出力が得られる。Juliaは1オリジンでプロセス番号も1からはじまるので、プロセス1がランク0に相当する。地味にうざい。残りのランク1,2がそれぞれプロセス2,3としてワーカになっている事がわかる。

## 設定の注意点
最初うまく動かなかった

~~手元のmacOS 上の1.4.2 ではモード2，3の動作がおかしい。どうもMPIとしてでなく全く独立のプロセスとして起動されてしまっているようだ。MPIがちゃんと動いて無いのかな？~~ MPI.jl の設定がちゃんとできていなかった。下のようにしてビルドし直したらどうやら動いた。まだちょっと挙動がおかしいが。

``` Julia
import Pkg
Pkg.add("MPI")
ENV["JULIA_MPI_BINARY"]="system"
Pkg.build("MPI")
```

## エラー
手元の環境では終了時にエラーが出る。手元の環境の問題か、バグか。

```
PMIX ERROR: ERROR in file gds_ds12_lock_pthread.c at line 206
```



## 所感

実装しようと思っていた機能がすでにあって、嬉しいやら悲しいやら。

とりあえず、スパコンでちゃんと性能がでるのか測ってみよう。
Docker scratchイメージからSSL/TLS通信を出来るようにする

## 概要

scratchイメージで作成したDockerコンテナを実行したところ以下のエラーが発生しました。
コンテナには、AWS上のエンドポイントにHTTPSでリクエストする処理を組み込んでいました。

```zsh
caused by: Post "https://sqs.ap-northeast-1.amazonaws.com/": x509: certificate signed by unknown authority
```

このエラーを解決するお話です。

## 原因

以下の記事で解説されています。Dockerコンテナ内からSSL通信を行っていますが、証明書が無いためエラーとなっています。

[x509: certificate signed by unknown authority の対応](https://qiita.com/reikkk/items/e81fe384ad83a8e8b845)

ただ、自分の場合scratchイメージからコンテナを作成していたのでコンテナ上で`apk`コマンドを使えず、そのままでは証明書を設定することができません。

## 対処法

DockerのMulti Stage Buildを用います。Multi Stage Buildは以下の記事が大変参考になります。
[Docker multi stage buildで変わるDockerfileの常識](https://qiita.com/minamijoyo/items/711704e85b45ff5d6405)

ソース例は以下の通りです。

```Docker
# STEP 1 
FROM golang:alpine as builder
RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
WORKDIR $GOPATH/bin/
COPY ./exe/aws-access .

# STEP 2 build a small image
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /go/bin/aws-access /go/bin/aws-access

ENTRYPOINT ["/go/bin/aws-access"]
```

 - STEP1でalpineのGoコンテナから証明書ファイルを作成
 - ローカルから`sqs-access`というexeファイルをaplineコンテナにコピー
 - STEP2でaplineコンテナからscratchコンテナに証明書ファイル、exeファイルをコピー
 - scratchコンテナでexeを実行

このDockerファイルを以下のようにbuildして、docker runすると起動します。

```zsh:コマンド例
docker build -t multi-build-aws-access .
```

ちなみに、STEP2から作成されたDockerコンテナは`4.5MB`でした。Goのコンパイル時に、不要なリンクを削除したりUPX圧縮しています。scrtachイメージ素晴らしいですね。


具体的な手順は以下記事の例を参考にさせていただきました。Add SSL ca certificatesの部分です。
[Create the smallest and secured golang docker image based on scratch](https://medium.com/@chemidy/create-the-smallest-and-secured-golang-docker-image-based-on-scratch-4752223b7324)

先人の皆様に感謝です。
【備忘録】個人的に使うGitコマンド

自分がよく使うGitコマンドをメモしておこうと思い、本記事を作成することにしました。
「git clone」などの基本的なコマンドは記載しませんが、基礎から学びたいからはこちらの記事を見てみてください！
https://qiita.com/moonbass630/items/383fc8300a83784e4c82


#個人的に使うGitコマンド

##$ git branch -a
存在するブランチを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/6f1bfeb6-a598-46e8-ef30-b340557ce151.png)

##$ git branch -vv
どのブランチがどの追跡ブランチと紐づいているのか確認できます。
「$ git branch -a」と一緒に使ったりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/44149b3e-f2c8-cc72-6c6a-bc298e292b68.png)

##$ git branch -d ブランチ名 
ブランチを削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/7c93faa2-6b22-5994-ff5e-bd850bd0fe6c.png)

##$ git fetch origin ブランチ名
追跡リポジトリのみ取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/3604d696-74bb-453f-da46-01acc2fdfdab.png)

##$ git log origin ブランチ名
追跡ブランチのログを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/1009e59f-f306-fd08-53c2-ec26f80d707e.png)

##$ git branch -d -r origin ブランチ名
追跡ブランチを削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/e54699db-d4a3-2969-d30b-2873462bd5d4.png)

##$ git stash と $git stash apply stash名
・これを理解しておかないといけない理由
developブランチで作業していた時に、masterブランチにcheckoutしたい時があったのですが、
「developブランチで変更中のファイルをcommitするか、stashするかしなさい」というエラーが発生しちゃいまいした。なのでstashは理解しておいた方が良いです！

「git stash」：ワーキングツリー、ステージングツリーの変更を退避できます。
退避というのは「無かった事にするけど、変更データは残しておく」ということです。
「git stash apply stash名」：git stashで退避させた変更データを復元できます。

以下のように修正されたファイルがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/6408fe32-e09a-99ff-25b8-23500ce3d4b5.png)

Gitにも修正されていることは検知されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/7575bbdc-c725-bf42-df6f-de9b8fe07560.png)

「git stash」コマンド実行すると以下のように何も無かったかのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/f3254450-f324-207b-d0a5-cd4cc875b1ff.png)

エディタからも変更データ消えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/10bac11f-64dc-f51e-c2fc-64e6b3f3c47b.png)

しかし「git list」で確認すると変更データは実は残っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/8914fc69-af19-c196-5687-d82c59189893.png)

「git stash apply stash名」で変更データを復元しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/b083a257-c398-d245-3101-b1d28b28c6d0.png)

エディタにもきちんと変更データは戻ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/f552b599-c980-0393-23de-6f9ab27a48d3.png)

また個人的にstashするときはメッセージを残した方がいいと思います。
どんなデフォルトだと変更したのか分からなくなるからです。笑

```
$ git stash save "message"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/4d0f06ef-7ae6-6e73-0685-c74cb6b1af5e.png)


#$ git stash drop stash名
stashを削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/fa1edf5c-e932-67a7-ffa8-a5ea3ced8b03.png)

#$ git stash clear
全てのstashを削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619839/c8448d2d-b769-cf25-4d1b-761a31648c04.png)
PythTBことはじめ

# PythTBの概要

Pythonでtight-binding approximationの計算が出来るアプリケーション。
[Python Tight Binding (PythTB) &#8212; PythTB 1.7.2 documentation](https://www.physics.rutgers.edu/pythtb/)

# インストール
## 一般ユーザー権限でインストール
上記の公式ドキュメントを見ると、`pip install`が出来る、大変心配りが行き届いたコード/ライブラリである。しかし、`pip install`は過去に環境破壊されたトラウマがあるので、出来るだけ使いたくはない。そこで、ドキュメントにもあるとおり、コードをダウンロードしてきて`python setup.py install`でのインストールを試みる。

### ダウンロードと展開
この記事を書いた時点でのバージョンは1.7.2。ウェブページにファイルのURLが書いてあるので

```bash
wget https:/hogehogehogehoge.hogehoge/pythtb-1.7.2.tar.gz #URLは適当なので、ウェブページから正確なものをコピペ
```
でファイルをダウンロード。

```bash
tar -zxvf pythtb-1.7.2.tar.gz
```
で展開し、`pythtb-1.7.2`のディレクトリを得る。

### インストール先のディレクトリの作成とインストール

```bash
mkdir /home/user/opt/pythtb-1.7.2
```
で、インストール先のディレクトリを作成。先ほど展開してできたpythtb-1.7.2に移動して、そこで

```bash
python setup.py install --prefix=/home/user/opt/pythtb-1.7.2
```
でインストールおしまい。インストール先の`/home/user/opt/pythtb-1.7.2`の書き込み権限は`user`が持っているので、管理者権限は必要ない。

### `PYTHONPATH`の指定
pythonで、導入したライブラリを`import`するとき、所定の場所のみが探され、そこになければエラーが返ってくる。そこで、自身で追加したものは、`import`する対象を探索する先にあらかじめ指定をしておく必要がある。それを指定するのが`PYTHONPATH`環境変数である。
以下のテキストを、`.bashrc`や`.bash_profile`に追記する。

```bash:~/.bashrc
export PYTHONPATH=/home/user/opt/pythtb-1.7.2/lib/python3.7/site-packages                 #$PAYTHONPATHがまだ定義されていない場合
export PYTHONPATH=/home/user/opt/pythtb-1.7.2/lib/python3.7/site-packages:$PYTHONPATH     #$PAYTHONPATHが定義されている場合
```
その後、(もちろん`. ~/.bashrc`として、再読み込みをするか、再度ログインしたうえで)

```python
import pythtb
```
を試して、`python`のインタラクティヴモードで入力して、エラーが返ってこなければインストールが多分正しくされている。
学んだこと②〜Mock〜

#はじめに
単体テストでMockを使用しているので、振り返りも兼ねて簡単にまとめたいと思います。

#Mockとは
簡単に説明すると、
**「テスト対象クラスから呼び出される、
　　　　　部品（他のソース）の代わりになってくれるもの」。

例えば、計算結果を出力するテスト対象クラス、
実際に計算をしてくれるサブクラスがあったとする。

このサブクラスの代わりをしてくれるのがMock。ということ。

##Mockまとめ

####1.モックオブジェクトの生成

```java
Sub sub = Mock(Sub.class);
```
Mockメソッドを使用してモックオブジェクトを生成

####2.Mockito.when().thenReturn();
```java
//aは部品の呼び出し処理
//bは呼び出された部品が返す値
Mockoito.when(sub.getAns()).thenReturn(b);
```
テスト対象ソースでSubクラスを呼び出しているが、
テストを通すにあたって、Subという部品が完成していない場合、
呼び出し部分でテストが落ちてしまい、最後まで通すことができない。
そのため上記処理を用いて、SubクラスのgetAnsメソッドが呼び出されたとき、
bという値を返すと指示しておけば、テストでその処理を通すことができる。

####3.MockObjectManager.setReturnValueAt
```java
//第1引数=クラス指定
//第2引数=メソッド名
//第3引数=呼び出し回数
//第4引数=戻り値の設定
MockObjectManager.setReturnValueAt(Sub.class, "getAns", 0, b);
MockObjectManager.setReturnValueAt(Sub.class, "getAns", 1, b);
```
2.のMockito.whenと共にこちらも使用。
注意点としては第3引数の呼び出し回数。
テスト対象ソースにて、同じ部品を複数回使用している場合は、
その回数に合わせて書く必要がある。

####4.Mockito.any
```java
//Mockito.any例
//↓int型の何がきてもbを返すよ～な設定
Mockito.when(sub.getAns(Mocito.anyInt(), Mockito.anyInt())).thenReturn(b);
```
テスト対象のMainクラスの中で、sub.getAnsを呼ぶときの引数を指定せずに、
int型であれば良しとするもの。

これは主にカバレッジをメインに見たい時に使用。
この他にもMockito.anyString()、Mockito.anyMap()、キャストして(クラス)Mockito.anyなどがある。


##その他Mockを使うテストで使用していたもの

```java

//Main=テスト対象ソース
Main main = new Main();
//Sub=他クラスの部品
Sub sub = new Sub();

//↓↓その他使用していたもの
//Mainクラスのフィールドで宣言されている変数subを指定
Field field = Main.getDeclaredField("sub");

//private変数へのアクセス制限を解除
field.setAccessible(true);

//private変数に値を設定
field.set(main, sub);
```

##さいごに
Mock化について一連の流れで使用すると以下のようになる。

####例1
```java

Sub sub = Mock(Sub.class);
Field field = main.getDeclaredField("sub");
field.setAccessible(true);
field.set(main, sub);

//getAnsが引数2つの足し算のメソッドだった場合
Mockito.when(sub.getAns(1,1)).thenReturn(2);
```

####例2

```java

Sub sub = Mock(Sub.class);
Field field = main.getDeclaredField("sub");
field.setAccessible(true);
field.set(main, sub);

//getAnsの仮引数がDTO型だった場合
AnsDTO ansDto = new AnsDTO();
ansDto.setMath1(1);
ansDto.setMath2(1);

Mockito.when(sub.getAns(ansDto)).thenReturn(3);
```
学んだこと①～DJUnit～

#はじめに
私がテスト作業をするにあたって使用している**「DJUnit」**について、
簡単にまとめたいと思います。

この記事がこれからテストを初めてやるという方の**入口**として、
少しでも力になれたらと思います。

#DJUnitについて
「JUnitとは違うのか？」と最初戸惑いましたが、
どうやらほとんど同じと考えて良いみたいです。

1つJUnitと違う点を挙げるとするならば、
DJUnitを実行すると、カバレッジレポートというのが使えるということ。
↓こんなの
![カバレッジ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641913/9182a4d6-d4ef-45ee-798e-8d193266ffad.jpeg)
テストにおけるカバレッジとは何か、、、
簡単に解釈すると、
テスト対象となるソースの全体の何％を確認できたかな（網羅できたかな）ということ！

つまりDJUnitは機能的に見ると、
**カバレッジレポートを視覚的に見ることが簡単にできるJUnit**ということになります。

テスト実行後は、テスト対象ソースに、
**実際にテストが流れた場所、流れてない場所**がわかるように、
**流れていない場所には波線が付く**仕様になっています。
どの部分が網羅できていないのか、すぐわかるのでとても便利です！

実際にテストソースを作って流してみると、
思わぬところで落ちていたりすることが多いです。
そこで上記の波線をたどれば、どこで落ちてしまったのか
原因を特定する手掛かりにもなります。
（他クラスの呼び出し箇所で落ちていれば、Mockがうまくいっていないのか。など）

カバレッジレポートは簡単にエクスポートすることができるので、
エビデンスとして簡単に残すことができます。(画像では右上のアイコンから)
そちらも機会があれば、是非活用してみて下さい。

#おわりに
業務を通じて学んだことの1つとして、DJUnitについて簡単に書かせていただきました。
正直、検索すればすぐに出てくるようなことしか書いていませんが、
なるべく肉声に近い言葉でまとめてみましたので、
ネットやら本やらで調べて、たくさんの情報の中からこの知識を得るより、
入口としては分かりやすいのかなと思います。

次の記事では、**「Mock」**について簡単にまとめたいと思います。
Github + Tortoise Git + SSH接続設定

#①Puttygenによる秘密鍵作成
スタートメニューのすべてのプログラムからTortoiseGitの項目を開き、Puttygenを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/68c93c2e-12f3-2e33-2931-5a2008dca765.png)

Generateをクリックし鍵を生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/af8c1ac5-3891-3246-017f-471761af15a6.png)
作成されたkeyはgithubの登録に用いるため、全てコピーしておきます。

Save private keyから秘密鍵を保存します。
保存したkeyはクローン作成・コミット時に用います。

#②githubの鍵設定
ユーザーページのSetting項目からSSH and GPG keysを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/68117a6b-12ce-8d58-af0c-7396cc648394.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/c707ac72-2db4-7993-2767-eb1d5410f4c1.png)

New SSH keyから新規鍵の登録を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/7ccef37c-ccbf-28d2-d8b6-0c566aa069f9.png)
Keyに先ほどコピーしたkeyを入力します。

これでgithubの方の設定は完了です。

#③TortoiseGitの設定
Putty鍵のロードに①で作成した.ppkファイルを登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367854/1598ed08-d913-178a-b803-a507ae69813e.png)

以上でSSH接続設定の完了です。
`~/.stack`のシンボリックリンク先を変えたらおかしくなった


# 環境

`~/.stack`をdotfileで管理しており、それをGithubで管理しています。
gitレポジトリの管理には[ghq](https://github.com/x-motemen/ghq)を使用しています。

# 問題

ghqのアップデートによって、デフォルトのパスが`~/.ghq`から`~/ghq`に変わりました(隠しディレクトリではなくなった)。
それに応じてdotfileから出しているシンボリックリンクもパスを変更したのですが、その後stackがうまく動かなくなりました。

```sh
$ stack build
Found an invalid compiler at "/Users/me/ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/bin/ghc-8.6.5": Received ExitFailure 126 when running
Raw command: /Users/me/ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/bin/ghc-8.6.5 --info
Standard error:

/Users/me/ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/bin/ghc-8.6.5: line 9: /Users/me/.ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/lib/ghc-8.6.5/bin/ghc: No such file or directory
/Users/me/ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/bin/ghc-8.6.5: line 9: exec: /Users/me/.ghq/github.com/Cj-bc/dotfiles/dotfiles/stack/programs/x86_64-osx/ghc-8.6.5/lib/ghc-8.6.5/bin/ghc: cannot execute: No such file or directory
```

# 解決策

パスは変えたはずなのですが、依然どこかで`~/.ghq`以下を参照しているようです。

## 1. ghcを再ビルドさせる

```
$ rm -rf ~/.stack/programs/x86_64-osx/*
```


## 2. snapshotsを削除する

パッケージのファイルが足りないと言われるので、`~/.stack/snapshots/`を削除します。

> There are files missing in the 'lens-4.17.1' package,
> try running 'ghc-pkg check'.

この時、`ghc-pkg check`をしても何も出力されません。`stack exec ghc-pkg check`を実行してください。

`ack -l '.ghq' | xargs -L1 gsed -i "s/\.ghq/ghq/g"`等で置換をこころみましたが、別の問題が発生したので素直にsnapshot消しました。
RubyでnCk mod p

# はじめに
AtCoderの過去問([ABC145 - D](https://atcoder.jp/contests/abc145/tasks/abc145_d))を解いていたらnCk mod p を求める必要があって苦戦した。
そこで [よくやる二項係数 (nCk mod. p)、逆元 (a^-1 mod. p) の求め方](https://drken1215.hatenablog.com/entry/2018/06/08/210000) をRubyで書き換えた、簡単に使えるModCombinationクラスをここに残そうと思う。

# コード

```rb
class ModCombination
    def initialize(max)
        @MOD = 10 ** 9 + 7
        @fact = [1, 1]
        @factinv = [1, 1]
        @inv = [0, 1]
        2.upto(max) do |i|
            @fact << @fact[i-1] * i % @MOD
            @inv << @MOD - @inv[@MOD % i] * (@MOD / i) % @MOD
            @factinv << @factinv[i-1] * @inv[i] % @MOD
        end
    end
    def com(n, k)
        return 0 if n < k
        return 0 if n < 0 || k < 0
        return @fact[n] * (@factinv[k] * @factinv[n-k] % @MOD) % @MOD
    end
end
```

# 使い方

- `MOD`が $ 10^9 + 7 $ 以外だったら `@MOD` の値を書き換える
- `com(n, k)` で `nCk % MOD ` が求まる

```rb
max = 10 ** 6
comb = ModCombination.new(max)
puts comb.com(n, k) # nCk mod 10 ** 9 + 7
```

# おわりに

上のコードが何をやっているかは調べれば出てくると思うので割愛する。
この記事が誰かのACに繋がればと思う。
セル結合を含むExcelを一括でデータクレンジング

次の図ようにセル結合が存在するExcelがあるときの対処方法を記載します。セル結合が施されている箇所が少ない場合は個別にセル結合を解消していけば良いですが、数千と存在する場合はどのように対処すれば良いでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/b19b280e-85a4-cbb9-9104-957ec52762fd.png)

まずは「Ctrl + F」で検索ダイアログを呼び出します。
(Excelを英語に設定しているため、ご注意下さい。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/74151571-db06-1ac7-2cd7-d8892b7726d7.png)

検索ボックスに値が入力されていないことを確認のうえ、「Alignment」タブの「Merge Cells」にチェックを入れ、「OK」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/79758b28-6289-4025-5faa-e01e436d2145.png)

「全て検索」を選択します。図のように書式セットに検索対象の書式セットが入力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/a90a1448-a787-e7bf-101c-e6bc2c6f8301.png)

「Ctrl + A」を押すとセルが結合されたセルが選択状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/f1e41f8f-06b6-6624-845a-a0dc0da309fe.png)

この状態でセル結合を解除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/699a87e9-cac0-9681-4cb1-a5a5ba468bed.png)

これでセル結合を解除することができました。しかし、セル結合をしていた部分が上に詰められて空白のセルができてしまっております。
以降でこの状態を解決する方法を記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/86807430-8099-3d9e-5c1c-b9367fb2d6f4.png)

ここで「Ctrl + A」で対象範囲を全て選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/ae67805c-d981-e994-148e-eb8ccd924e0f.png)

次に「Ctrl + G」でジャンプ機能のダイアログを呼び出し、「Alt + S」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/95b6b86e-263b-3936-d684-f455301e9db3.png)

「K」を押下し、空白を選択したうえで「OK」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/0c6f43c7-f0b4-4481-8901-b6b354565840.png)

もともとセル結合されていた部分の空白セルが選択されたら、「=A1」のように1つ上のセルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/a0147a6e-e84d-3027-c4ea-2383085b154d.png)

「Ctrl + Enter」を押して関数を確定させると、空白を埋めることができます。
そして間髪入れずに、「Ctrl + Alt + V」>「V」で値貼り付けを実行します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/23e94ba3-0058-6df6-3ca7-b1b72d7e1224.png)

これでデータとして綺麗な形に修正することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274248/4cd20cf0-be84-d030-2597-0471f4ab069d.png)
Ruby と Python で解く AtCoder ABC153 E 動的計画法

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[AtCoder Beginner Contest E - Crested Ibis vs Monster](https://atcoder.jp/contests/abc153/tasks/abc153_e)*
<font color="green">Difficulty: 1009</font>

今回のテーマ、動的計画法

いわゆる典型的な動的計画法の問題です。
トキがモンスターに勝つまでに消耗する魔力の合計の最小値を求めます。
但し、モンスターの体力を`0以下`にするということで、`0`ジャストでなくてもいい点に少しだけ注意します。

# Ruby
```ruby.rb
h, n = gets.split.map(&:to_i)
a = Array.new(n){gets.split.map(&:to_i)}
dp = Array.new(h + 1, Float::INFINITY)
dp[0] = 0
h.next.times do |i|
  a.each do |x, y|
    if i + x < h && dp[i + x] > dp[i] + y
      dp[i + x] = dp[i] + y
    elsif i + x >= h && dp[h] > dp[i] + y
      dp[h] = dp[i] + y
    end
  end
end
puts dp[h]
```
```ruby.rb
    if i + x < h && dp[i + x] > dp[i] + y
      dp[i + x] = dp[i] + y
    elsif i + x >= h && dp[h] > dp[i] + y
      dp[h] = dp[i] + y
    end
```
`elsif i + x >= h`のところで、モンスターの体力が`0以下`になったときの処理として`dp[h]`に固定しています。
# Python
```pypy.py
from sys import stdin, maxsize

def main():
    input = stdin.readline

    h, n = map(int, input().split())
    a = [list(map(int, input().split())) for _ in range(n)]
    dp = [maxsize] * (h + 1)
    dp[0] = 0
    for i in range(h + 1):
        for x, y in a:
            if i + x < h and dp[i + x] > dp[i] + y:
                dp[i + x] = dp[i] + y
            elif i + x >= h and dp[h] > dp[i] + y:
                dp[h] = dp[i] + y
    print(dp[h])
main()
```
***PyPy*** の方でないと`TLE`になります。

||Ruby|Python|PyPy|
|:--:|:--:|:--:|:--:|
|コード長 (Byte)|336|476|476|
|実行時間 (ms)|1630|TLE|399|
|メモリ (KB)|2044|3616|41452|
# まとめ
+ ABC 153 E を解いた
+ Ruby に詳しくなった
+ Python に詳しくなった
いろいろな言語に移植されたPuppeteerっぽいライブラリまとめ

Chrome DevToolsプロトコルを使い、PuppeteerっぽいAPIが使えるライブラリまとめ。
（ただし、CypressのようにCDPは使ってるけどPuppeteer APIっぽくないやつは除外）

ほぼ自分用メモ。

## :tada: Production ready

| lang | name | repo | memo |
|:--|:--|:--|:--|
| JavaScript| Puppeteer | [puppeteer/puppeteer](https://github.com/puppeteer/puppeteer) | 本家 |
| TypeScript | Playwright | [microsoft/playwright](https://github.com/microsoft/playwright) |  |
| Python | playwright-python | [playwright-python](https://github.com/microsoft/playwright-python) |

* playwrightの勢いがすごい。
    * puppeteerとはいつまで共存するんだろう
* 自動操作/スクレイピング目的だけでなく、Jestと連携してE2Eテスト書ける
    * Playwrightはjestではなく[microsoft/folio](https://github.com/microsoft/folio)というテストランナーを使ったplaywright-testが主流になりそう。


## :+1: 便利ツール

| lang | name | repo | memo |
|:--|:--|:--|:--|
| C# | playwright-sharp | [microsoft/playwright-sharp](https://github.com/microsoft/playwright-sharp) | Windowsなら最強の選択肢? |
| Dart | puppeteer-dart | [xvrh/puppeteer-dart](https://github.com/xvrh/puppeteer-dart) | dart2nativeでシングルバイナリが作れる |

* C#やDartは静的型付け言語なので、エディタによる補完が非常にかしこい。
    * puppeteer, playwright にはぜひDart採用してほしい... (無理w
* async/awaitの使い勝手が、JSと似ている
* puppeteer-sharpの開発者がplaywright-sharpを作ったのがマイクロソフトに拾われたようだ。
* puppeteer-dartは、個人開発
    * 2年以上開発は続いているが、xvrhさんが万一倒れたりしたら開発止まりそう

## :pencil: よさそう

| lang | name | repo | memo |
|:--|:--|:--|:--|
| Python | pyppeteer | [pyppeteer/pyppeteer](https://github.com/pyppeteer/pyppeteer) | |
| Java | playwright-java | [microsoft/playwright-java](https://github.com/microsoft/playwright-java) | |


* [Puppeteer (Chrome の自動操作ライブラリ) を Python に移植してpyppeteerという名前で公開しました](https://miyakogi.github.io/blog/20170902/pyppeteer.html#.XtplVWQzZlo)
    * playwright-pythonは実は半分以上JavaScriptで書かれたサーバープロセス（playwrightドライバ）が動いているが、pyppeteerはPure Python。


## :thinking: PoC?

| lang | name | repo | memo |
|:--|:--|:--|:--|
| Kotlin | kpuppeteer | [DealPoint/kpuppeteer](https://github.com/DealPoint/kpuppeteer) | |
| Java | jvppeteer | [fanyong920/jvppeteer](https://github.com/fanyong920/jvppeteer) | |
| PHP | puphpeteer | [nesk/puphpeteer](https://github.com/nesk/puphpeteer) | メンテナ募集中みたい |
| Ruby | puppeteer-ruby | [YusukeIwaki/puppeteer-ruby](https://github.com/YusukeIwaki/puppeteer-ruby) | [勝手に作った](https://yusukeiwaki.hatenablog.com/entry/2020/06/05/puppeteer-ruby-0.0.8) |
| Ruby | playwright-ruby-client | [YusukeIwaki/playwright-ruby-client](https://github.com/YusukeIwaki/playwright-ruby-client) | 勝手に作った |

* asycn/awaitがない言語では、本家(JS)からのポーティングもしんどいのかな


---

PoCレベルであれば、他にもありそう。
プロダクション運用で使えそうなのは、やはりpuppeteer, playwrightくらいか。
【Rails】Herokuの本番環境で記事や画像の投稿ができない時の対処法

記事や画像を投稿するアプリを作って、開発環境では問題なく動くが、なぜか本番環境で投稿すると"We're sorry, but something went wrong."とエラーになってしまった時の対処法です。


##まずログを確認する
```Rails:ターミナル
heroku logs -t
```

すると、以下のようなログを発見。
"ActiveModel::UnknownAttributeError (unknown attribute 'カラム名' for モデル名.):"

一度デプロイをした後新たにテーブルに追加したカラムが読み込まれていないのが原因らしい。

##本番環境でもdb:migrateをする

```Rails:ターミナル
heroku run rake db:migrate
```

しかしこれでも解消されないので、コンソールで本番環境のテーブルを確認する

##コンソールで本番環境のテーブルを確認
まずコンソールを起動

```Rails:ターミナル
$ heroku run rails console
```

コンソール上で「ActiveRecord::Base.connection_config」と入力

```Rails:コンソール
pry(main)> ActiveRecord::Base.connection_config
```

すると、
"=> {:adapter=>"postgresql",
 :encoding=>"unicode",
 :pool=>5,
 :username=>"xxxxxx",
 :password=>"xxxxxx",
 ~}"
のように本番環境でのDBとの接続情報が表示されるので、その次に以下のコードでテーブル情報を確認

```Rails:コンソール
pry(main)>ActiveRecord::Base.connection.tables
```

すると"=> ["テーブル1", "テーブル2"...]"のようにテーブル一覧が出てくる。
ここで、最初に確認したログでエラーメッセージが出ていたモデルのテーブルの中身を確認する。

```Rails:コンソール
pry(main)>モデル名.inspect
```
そうすると
"=> "Post(id: integer, name: string, content: text, created_at: datetime, updated_at: datetime...)"

とカラムと型の一覧が出てくる訳ですが、ここでもやはり後から追加したカラムが読み込まれていない。

##Herokuを再起動する
```Rails:ターミナル
$ heroku restart
```
これで解決。
カラムを追加し、db:migrate後にサーバーを再起動していなかったことが原因でした。
flywayのコールバックをJavaで書く

## はじめに

Gradleとflywayを使ってデータベースマイグレーションをしているアプリで
コールバックをJavaで書いた時に試行錯誤しました。

結論からいうと、flywayのタスク実行前にCallbackクラスをコンパイルすれば良いです。

今回検証したコードは以下のリポジトリを参照してください。
https://github.com/mahaker/flyway-callback-java

## 環境

Java: OpenJDK 11
Gradle: 5.2.1
flyway: 6.4.2
Postgres: 12

## コールバックをJavaで書く

`org.flywaydb.core.api.callback.Callback`インターフェースを実装したクラスを作って
flyway.callbacksプロパティに完全修飾名を設定します。
https://flywaydb.org/documentation/api/hooks#java-based-callbacks

また、flywayのタスクより先にclassesタスクを実行するようにします。<b>※これ大事</b>
（正確にはcompileJavaタスクかな？）

```FillTestData.java
package db.migration;

import java.sql.PreparedStatement;

import org.flywaydb.core.api.callback.Callback;
import org.flywaydb.core.api.callback.Context;
import org.flywaydb.core.api.callback.Event;

public class FillTestData implements Callback {

    @Override
    public boolean supports(Event event, Context context) {
        return Event.AFTER_MIGRATE.equals(event);
    }

    @Override
    public boolean canHandleInTransaction(Event event, Context context) {
        return false;
    }

    @Override
    public void handle(Event event, Context context) {
        try (
            final PreparedStatement statement = context
                .getConnection()
                .prepareStatement("INSERT INTO PERSON(ID, NAME, AGE) VALUES (1, 'userA', 20), (2, 'userB', 22)")
        ) {
            statement.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
```

```build.gradle
// 必要なものだけ抜粋
plugins {
    id "org.flywaydb.flyway" version "6.4.2"
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 11

flyway {
    url = 'jdbc:postgresql://localhost:15432/exampledb'
    user = 'postgres'
    password = 'example'
    locations = [ 'filesystem:./src/main/resources/db/migration/' ]
    callbacks = [ 'db.migration.FillTestData' ]
}

// !!大事！！
flywayClean.dependsOn(classes)
flywayMigrate.dependsOn(classes)
```

## まとめ

マイグレーションを実行するとinsert文が実行されていることが確認できます。

この方法はflywayの中の人に教えていただいたものです。
https://github.com/flyway/flyway/issues/2829
PHP　ベーシック認証方法

忘備録として

#ファイル構成

```
mainte
 ┣index.php
 ┣.htaccess
 ┗.htpasswd
```
ファイル名の前に『.』をつけると隠しファイルになる


#①index.phpの絶対パスを取得
```php:index.php
<?php
echo __FILE__;
// C:\~\~\php_test\mainte\index.php


//パスワード(暗号化)
echo(password_hash('password123',PASSWORD_BCRYPT));
?>

```
#②パスワード生成（暗号化）
```php:index.php
echo(password_hash('パスワードを入力',PASSWORD_BCRYPT));
```

#③.htaccessを編集
※ファイル名を『index.php』→『.htpasswd』に書き換え

```
AuthType Basic
AuthName "IDとパスワードを入力してください"
AuthUserFile C:\~\~\~\mainte\.htpasswd　←※ファイル名を.htpasswdに書き換え
require valid-user
//最後は必ず改行する
```
#④.htpasswdを編集

```
ユーザーID:②で生成したパスワードを入力
//最後は必ず改行する

例）
admin:$2y$10$eFDA/.alOneirmbv6CBu35L0rZDIX3hcgiwLBWIJXIpdkvv6GoApm

```


index.phpを開くとログイン認証が表示されるので
IDにadmin
パスワードに暗号化前のパスワードを入力
タスク管理の最初の一歩～どこにでもあるExcelで～

#### はじめに
タスク管理
何やら難しそうだけど、難しいこと考えなければただ
「やることを漏れがないようにすること」
それだけなのです。（きっと）
そこにリスクとかなんやかんやが加わって難しくなる。

まず最初にシンプルなことから始めましょうというのが
今回のコンセプトです。

#### 今回のお話
自分用のWBS的なサムシングを作ってみましょう。
あくまで自分用なので必要な機能だけ積んで、
継続して使えることを念頭に置きました。
実際私は３年ほどどの現場でも作って使っています。

Excelで作る理由はどの現場でも使えるからです。
またやっぱりExcelってすごいわとっつきやすい、って感じです。


#### どんな感じ？
こんな感じで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/06f0b0a0-4683-4a0f-08e8-59bbdf7a6d6f.png)

タスクなんて日単位でいいんですよ、
こまかく管理しても大変になるだけ。
まずはこんな感じで初めていければいいと思います。

※時間単位やガントチャート付きも作ったことがありますが、
自分用で使う分にはそこまでいらないかなというのが感想です。

#### 作ってみましょう
慣れれば10分もあれば作れるレベルです。
気軽にいってみましょう。

①今日の日付を表示
NOW関数を入れておけば、Excelを開いたときに自動計算で今日の日付を入れてくれます。
表示形式を設定して、見やすくしておくといいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/36cef9ff-67cc-3ff7-b4b3-ade1d4a629f6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/77c1d98a-dad8-a8c0-9cc2-fd2a2783313d.png)

②メインの表を作成
罫線引くだけです。
項目は「タスク名」「開始＆終了日」「完了目標」「期日」
あと何かと便利なんで「備考」とこのくらいあれば最低限いいでしょう。
私は作業順序の目安に「優先度」を追加してたりしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/95f9b6e7-e356-d90e-81be-000d2b445e3c.png)

③条件付き書式を設定
さて、冒頭の画像では色がついて期日が過ぎたりを教えてくれてましたが、
もちろんあれを逐一手作業でつけていたらそれだけで大変です。
条件付き書式を使って”自動で”色を表示しましょう。

表部分を選択した状態で条件付き書式を開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/917895ae-3905-9ebc-450f-ca0d22d12c7f.png)
新しいルールを作ります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/3560ba38-bf25-3f3c-aeb2-aeb23beca37d.png)
上の段で一番下の「数式を～」を選びます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/e63ec82a-8bd2-5893-1f9b-10d2e282b04b.png)
数式欄に色を付ける条件を入れてあげます。

条件は次の３つ
　１．タスク名が空欄でないこと
　２．終了日が空欄であること
　３．今日の日付が期日（終了目標）を過ぎていること

それぞれの書き方はggeksと、言いたいところですが、
特別に教えてしまうと
　１．`NOT(ISBLANK($C5))`
　２．`ISBLANK($G5)`
　３．`$D$2>$I5`　（`$D$2>$H5`）
(それぞれ②の画像の位置関係の場合)
＄のつけるつけないの意味は考えてみてください、
そしてその３つをANDでつなげてあげれば条件はOK。

最後に書式を好き勝手、自分がわかるように設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/31bce80c-e57f-00d1-8af4-9d7f7d3300f5.png)

完成です（ドン！）。

#### おわりに
６月に入り新人の方々も現場に羽ばたいていく時期になりました。
その方たちの助けになれれば幸いです。
また先輩諸氏につきましては、何事も少しづつです
急かさず育ててください。

以上です。
HD44780互換コントローラ搭載LCDのコントラストをPWMで調整できるようにしてみた

# 初めに
この記事の趣旨はLCDのコントラストをPWMで調整することにより部品点数を減らした上で
プログラム上から変更できることで後々の調整をしやすくするのを目標にしています。

コントラストをPWMで調整したい人ってあんまりいないのか日本語の情報なかったんですよね……
(私が見つけきれなかっただけかもしれませんが)

## サンプルコード
バックライトLEDも制御するためのコードが混ざっていますが、自己責任でご自由にお使いください。
※ATmega328pを使用したArduinoでTimer1を使用しています。他の環境では未検証です。

```c
#include <LiquidCrystal.h>

#define backlightPin 9
#define contrastPin 10

// LCD Pin (4bit mode)
#define rs 6
#define enable 7
#define d4 2
#define d5 3
#define d6 4
#define d7 5

// 関数プロトタイプ
void setBacklight (unsigned char);
void setContrast(unsigned char);

LiquidCrystal lcd(rs, enable, d4, d5, d6, d7);

void setup() {
  // put your setup code here, to run once:
  // LCD Data 4～7
  pinMode(d4, OUTPUT);
  pinMode(d5, OUTPUT);
  pinMode(d6, OUTPUT);
  pinMode(d7, OUTPUT);
  // LCD RS,E
  pinMode(rs, OUTPUT);
  pinMode(enable, OUTPUT);
  // LCD Contrast PWM
  pinMode(contrastPin, OUTPUT);
  // LCD BackLight PWM
  pinMode(backlightPin, OUTPUT);

  // Timer1 設定
  // 全初期化
  TCCR1A = B00000000;
  TCCR1B = B00000000;
  TCNT1 = B00000000;

  // クロック16MHzでプリスケーラ1の場合40KHz
  ICR1 = 399;

  OCR1A = 399;  // PWM 9 (100%)
  OCR1B = 399;  // PWM 10 (100%)

  /*
  PWM 9はコンペアマッチで立下がり
  PWM 10はコンペアマッチで立ち上がり
  PWMモードは高速PWM(TOPはICR1を使用)
  プリスケーラは分周比1に設定
  */
  TCCR1A |= B10110010;
  TCCR1B |= B00011001;

  // LCD SetUp cols 16 rows 2
  lcd.begin(16, 2);
  lcd.noAutoscroll();
  lcd.print("hello, world");

}

unsigned char contrast = 0;
void loop() {
  // put your main code here, to run repeatedly:
  //  setContrast(100);
  setContrast(contrast++);
  if (contrast > 100)contrast = 0;
  delay(100);

}


// バックライト設定用関数
void setBacklight(unsigned char light) {
  if (light > 100)light = 100;
  int result = light * 4 - 1;
  if (result < 0) result = 0;
  OCR1A = result;
}

// コントラスト設定用関数
void setContrast(unsigned char param) {
  if (param > 100)param = 100;
  //  int result = param * 4 - 1;
  //  if (result < 0) result = 0;
  unsigned int result = 199 + (param * 2);
  OCR1B = result;
}
```

### 簡単な説明
Arduino標準のPWMの場合PWM周波数が低いので画面にチラつきなどが発生するため
各種レジスタを直接弄って設定を変えています。

まず上部でdefineを使って各種ピンを定義しています。
ここでピンの指定を変更したらPWM周り以外は簡単に変更できます。
なお、LCDとの接続はHD44780の4bitモードで読み込みをしない前提なので最小限のI/O 6本を使用しています。

その下でコントラストとバックライトの明るさをセットするための関数のプロトタイプ宣言を行っています。

LCD関連の関数はLiquidCrystalライブラリの物なので詳しくはArduinoの[日本語リファレンス](http://www.musashinodenpa.com/arduino/ref/ "Arduino 日本語リファレンス")にてご確認ください。

次はあらかじめ定義しておいたピンのモードを初期化します。
その後、Timer1の制御レジスタとカウンタを一度ゼロクリアします。
今回は40KHzでPWMを生成するのでICR1に399を設定します。
なお、計算式は
　PWM周波数 = クロック周波数 / (分周比 * (1 + カウンタのカウントアップ上限))
なので
　(16 * 10^6) / (1 * (1 + 399)) = 40000 Hz
となります。
ここから式を変形して
　(16 * 10^6) / (40 * 10^3) = 400
　(400 / 1) - 1 = 399
みたいな感じになります。
※高速PWMモードの場合はこの式ですが、位相基準PWMモードの場合分周比と一緒に
　2をかける必要があるため詳しくはデータシートをご覧ください。

OCR1AとOCR1Bは初期は100%の出力(contrastPinについてはHi-Lo逆転)のために399を代入しています。

TCCR1AやTCCR1Bの詳しい事はデータシートをご確認ください。

setContrast関数は内部で出力を50～0%に制限しています。
(いい感じに薄い表示から濃い表示になってくれます)

### 最後に
私がテストしたLCDは20KHzだとノイズの所為か分かりませんが画面表示がずれたりしていたので、
PWMの周波数を上げたら解決しました。

多少なりとも誰かの参考になれば幸いです。
ITパスポート（本に載ってない）

サーバ証明書
SSL通信を行う際に必要となる証明書です。SSL/TLS接続時にクライアント側に公開鍵をサーバから受けたしますが、その際にサーバ証明書が利用されます。

CPRM
DVD-RやSDカードなどに採用され、ディジタルコンテンツを記録メディアに一度だけ複製することを許容する著作権保護技術は、CPRMです。
コピーワンスとも呼ばれ、デジタル放送に使われています。

ゼロデイ攻撃
OSやソフトウェアの脆弱性への対応パッチが配布される前に、その脆弱性を突いた攻撃を行うことです。

ディジタルフォレンジックス
コンピュータの残っている記録を分析して、犯罪捜査の証拠を見つけることです。
「ディジタルフォレンジックス」と言われたら、「犯罪」と「法的証拠」がキーワードになると覚えておきましょう。
SEGGER Embedded Studio ( for Nordic )がライセンス切れになった


久しぶりにWindowsで起動したら
「The evaluation period for this release has now expired」と出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8db43343-e20c-0266-ce83-dbfafd1568b3.png)




# 環境
- MS-Windows Pro 64bit
- SEGGER Embedded Studio for ARM Release 4.10a  Build 2018110203.37618 Windows x64


SES (SEGGER Embedded Studio ) の Nordic の Free licenses を使用。

Segger Embeddid Studio は Nordic Semiconductor の
Cortex-M based device series (nRF51, nRF52, nRF53, nRF91) に対し Free licenses が使えるようになっている。

# 原因

起動したのは 1年以上ぶりかな？ 以前、Linux 版を 10日ぐらい中国のグレートファイアーウォール内で使っていたらライセンス切れになったことがある。ライセンスサーバーに定期的に疎通しないと使えなくなるのかな？

# 再アクティベーション


https://license.segger.com/Nordic.cgi からアクティベーションをリクエストする。メールがやってくるのでそこに記載されたアクティベーションコードをコピーする。


SESのTools-License Manager を開いてコードを登録、アクティベーションを行ったが・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/53128d5c-9236-371b-190e-505d627b1d7c.png)

おなじエラーが出ます。

SESのTools-License Manager を開くとまだアクティベーションができていない状態に戻っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ae5b2d45-f220-39e4-96e1-63e09d4266f5.png)

# Nordic の SDK を開く

実は、NordicのSDK内のサンプルプログラムを開かないとアクティベートされないらしいです。

https://devzone.nordicsemi.com/f/nordic-q-a/43274/my-segger-license-is-never-activated

先の main.c は Nordic の SDK とは関係なしに作ったプログラムだったので、SDKの

examples\peripheral\blinky\pca10056\blank\ses

を開いて実行すると、無事アクティベートできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a3870533-752d-a6d6-8303-b3ce8185d81c.png)

一旦アクティベートが通ると、SDKに関係のないプログラムも実行できるようになります。
permit()でJSONの複雑な形式を指定する手順

元のJSON

```json
 {
     "mark": 1,
     "offset": [23, 45],
     "Labels": [
         {
             "Name": "Rectangle",
             "Instances": [
                 {
                     "Box": {
                         "Width": 0.1,
                         "Height": 0.2
                     },
                     "Confidence": 99.9
                 }
             ]
         }
     ]
 }
```

配列の中がスカラー値のものは、値をすべて削除し、keyの前からvalue後のカンマ```,```の前までブレース```{}```で囲む

```json
 {
     "mark": 1,
|    {"offset": []},
     "Labels": [
         {
             "Name": "Rectangle",
             "Instances": [
                 {
                     "Box": {
                         "Width": 0.1,
                         "Height": 0.2
                     },
                     "Confidence": 99.9
                 }
             ]
         }
     ]
 }
```

「連想配列」のvalueがスカラー値のものは、value部の記載を削除する(カンマ```,```は残す)

```json
 {
|    "mark",
     {"offset": []},
     "Labels": [
         {
|            "Name",
             "Instances": [
                 {
                     "Box": {
|                        "Width",
|                        "Height"
                     },
|                    "Confidence"
                 }
             ]
         }
     ]
 }
```

keyの羅列しか残っていない「連想配列」は、元のブレース```{}```をブラケット```[]```に変え、keyの前からvalue後のカンマ```,```の前までブレース```{}```で囲む

```json
 {
     "mark",
     {"offset": []},
     "Labels": [
         {
             "Name",
             "Instances": [
                 {
|                    {"Box": [
                         "Width",
                         "Height"
|                    ]},
                     "Confidence"
                 }
             ]
         }
     ]
 }
```

valueが「連想配列の配列」のものは、要素の2つ目以降を削除した後、ブレース```{}```をkeyの外側に持っていく

```json
 {
     "mark",
     {"offset": []},
|    {"Labels": [
|
             "Name",
|            {"Instances": [
|
                     {"Box": [
                         "Width",
                         "Height"
                     ]},
                     "Confidence"
|
|            ]}
|
|    ]}
 }
```


最も外側の```{}```を削除し、```permit()```の引数にする

```json
| params.permit(
     "mark",
     {"offset": []},
     {"Labels": [
             "Name",
             {"Instances": [
                     "Box": {
                         "Width",
                         "Height"
                     },
                     "Confidence"
             ]}
     ]}
| )
```

完成
webアプリ開発までの道のりは遠い

#具体的な目標を立てた
最初の目標として掲げたアプリ開発について，まずは具体的どういうものを作るのかを決めた．
私的にはやっぱりお金が稼げる枠組みを自分で作れるようになりたい．
そこで，自分で取引サイト(ECサイトというらしい)を構築することにした．

#ECサイト開発に必要な手順
手順については，

１．ゼロからはじめる Django で ECサイト構築（その１：ECパッケージの選定）
https://akiyoko.hatenablog.jp/entry/2016/05/24/000826
２．【初心者向け】通販サイトの作り方・ネットショップの始め方
https://www.yamatofinancial.jp/learning/start-up/how-to-make-ecsite.html

を参考にしていこうかな，と漠然と考えながら初めて見た．

#知識不足過ぎて分からない．
1つ目のサイトのその1までは仕組みについてや利用するライブラリ等の説明なのでついて行けた．
この人の説明は丁寧でわかりやすい．
しかし，その2からは何をするコードなのかはわかるが，何のためにしているコードなのかが分からない．
完全に自分の知識不足だ．プログラミングの基礎はあっても，システムやらサーバーやらの知識が皆無なのが問題っぽい．

#これからやること
流石にシステムやサーバー面の基礎をつけないと話にならなそうなので，まずはその辺を勉強していきたいと思う．
とりあえず本買ったからまずは読んで，基礎知識つけて，そしたら，

１，サーバー立てる！
２，Djangoつかってコード書く！
３，お金の手続き方法用意する！

この3つを一つ一つ理解していくぞ！
ThunderbirdをOutlookに変換する最良の方法

"メールボックスフォルダーをThunderbirdからOutlook 2019に移行したいのですが、高速でインスタントなソリューションはありますか？"

これは、ThunderbirdのメールをOutlookに転送するためのユーザー間の大きな検索クエリですが、完全な情報を提供できる人はいないと思います。だから私はこの変換プロセスであなたを助けるためにここにいます。

#ユーザーはなぜThunderbirdをOutlookに変換するのですか？

Mozilla Thunderbirdは個人での使用に適していますが、ビジネスおよびエンタープライズレベルについて話す場合、Outlookが最高の電子メールクライアントです。 Outlookでユーザーが信頼する理由は他にもいくつかあります。

- カレンダー機能はThunderbirdでは使用できないため、ユーザーが個別にダウンロードする必要があります。
- ユーザーは、Mozilla TBで変換スタイルのメッセージビュー機能を個別にダウンロードする必要があります。
- Outlookは高度なデータセキュリティといくつかの追加機能を提供します。
- MS Outlookには、Exchange Serverに接続するオプションがありますが、Thunderbirdにはそのような機能はありません。
- Microsoft Outlookは96言語をサポートし、Thunderbirdは53言語をサポートしています。

##プロフェッショナルな方法 ThunderbirdからOutlookへ移行

**[Xtraxtor](https://xtraxtor.com/)** は、単一および複数のTBデータファイルをOutlook PSTファイル形式にすばやく移動できます。この最高のアプリケーションは、ユーザーがThunderbirdファイルを自動的に検索する「自動ロード」という頻繁なオプションで設計されています。このサンダーバードからOutlookへの移行ソフトウェアは、苦労せずにサンダーバードのメールボックスデータをOutlook PSTファイルにすばやく移行します。
ダウンロード: https://xtraxtor.com/dl/setup-4n6-xtraxtor.exe

##の手順ThunderbirdからOutlook 2019 移行;##

ステップ1.PCにXtraxtorをインストールして実行します。

ステップ2. Open >> Thunderbird >> Configured Accountに移動します。

![thunderbird-converter-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/28473e7b-ecc2-9cbe-8e8d-6b2669a35079.png)


ステップ3. ソフトウェアがThunderbirdのメールボックスをロードします.

ステップ4. [エクスポート]をクリックし、保存オプションとして[PST]を選択します。

![thunderbird-converter-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/d5d72d3b-2bd1-4683-9235-98aa63c83d8f.png)


ステップ5. 保存ボタンをクリックして、変換プロセスを開始します。

![thunderbird-converter-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/e2c3530e-d07d-fe67-2017-db50aa25c3ed.png)


ステップ6. MS Outlook 2019にPSTをインポートします。

完成しました！これは、ThunderbirdをOutlookに移動する方法です。
インスタンスにIDを与える

## UE4でのインスタンシング
### SV_instanceidが取れなかった
これまでUE4ではSV_instanceidがVRの用途でしか使われておらず、マテリアル上からは取得できませんでした。
したがって、インスタンス毎の違いを出すには、PerInstanceRandomノードを使ったり、インスタンスの初期位置をインデックスに見立てるなどの回りくどい処理をする必要がありました。
### CustomDataの登場
最近InstancedStaticMeshにインスタンス毎のカスタムデータが設定できるようになり、ここにIDを突っ込む事で、これまでややこしかった処理が簡単に書けるようになりました。
###　なにが楽になったのか
RenderTargetとInstancedStaticMeshをつかってUAV的な事をやる場合に、読み込むデータの位置や、書き込み先の割り出しが容易になりました。
特にエンジン改造やC++のコードが必要ではないので、CSなどのプラグイン作成をするほどではない部分や、ナイアガラだと実装しづらい部分の隙間を埋めることが出来ます。

## 実装例　リアルタイムヒストグラム実装
ここでは実際の実装例として、以下の動画にあるリアルタイムヒストグラムを解説します。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">こないだのは色がわかりにくかったから修正。最終的なヒストグラムの描画はポストマテリアル。<br>あとでQiita書くか <a href="https://t.co/IrtiEqjhUB">pic.twitter.com/IrtiEqjhUB</a></p>&mdash; おく/奥川 剛 (@t_oku) <a href="https://twitter.com/t_oku/status/1268900599623331840?ref_src=twsrc%5Etfw">June 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
簡単なものなので、大まかに流れだけ説明します。

### 準備するもの
①InstancedStaticMeshをもったBPアクター
②①のInstancedStaticMeshにアサインするためのマテリアル
③SceneCapture2D
④256*1でFP16のRenderTarget
⑤結果を描画するためのポストマテリアル
### インスタンスにIDを振る
①のBPアクターにInstancedStaticMeshを追加します。
メッシュは1m*1mの正方形(/Engine/BasicShapes/Planeで構いません)をアサインし、マテリアルは②をアサインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/bee31796-103d-1f35-12ec-6de3ebd3183a.png)
追加InstancedStaticMeshComponentに、CustomDataを一つ追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/d1074926-8773-5848-295c-2c42443aa624.png)

BPアクターのConstrutionScriptにて、サンプリング数分(今回は100*100の1万個）のインスタンスを作成し、同時にCustomDataを書き込んでいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/e850d5fc-e974-ffb3-0f1f-82afa6fc574c.png)
### インスタンス用マテリアルの実装
まず、②のマテリアルはUnLitで”加算”設定にし、出力のエミッシブには1を設定します。書き込み先であるRenderTargetの値をインクリメントさせて行くためです。
次に、割り当てられたID(0~9999)から、シーンの画像中で自身がサンプリングすべき位置(UV)を算出し、フェッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/9d12806d-a2a1-06fc-627a-10b640b4783e.png)
そして、その輝度(0~1.0)を256*100倍してWPOに渡します。これで書き込み先をどこにするか決定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/c2b3b6f7-dcc9-abac-bd14-98eb9a85f3e7.png)
### RenderTargetへの書き込み
①のアクターを(-12800,0,0)に配置します。 
③のSceneCapture2DのモードをUse ShowOnlyListに設定し、ShowOnlyActorsに①のアクターだけを追加します。
③のSceneCapture2Dの設定を正射影にし、OrthoWidthを25600に設定します。
ターゲットには④の1Dターゲットを指定します。
ここまでで、以下のような描画結果になります。左端(0，0)が一番暗い所、右端(255,0)が一番明るい所に対応しており、シーン中使われてる輝度が多い所ほど値が大きくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/15b00b46-7b45-1560-252c-9932502ee1b1.png)
### 結果の表示
出来上がった1Dテクスチャをポストマテリアルでフェッチして、グラフ表示すれば、CPUへの書き戻しなしで、ヒストグラムを描画する事ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/5d27588a-6853-2cd5-2417-242c723acf1d.png)
### まとめ
実戦投入するにはいくつか整理日する必要がありますが、実装自体は半日かからずサクッとお手軽にできました。
次は、DOFなどで使われてるような、任意の形状にボケるスキャッターベースのブラーなどを時間あれば同様の手法で実装してみたいと思います。
Touch Bar 搭載の Mac でディスプレイのみスリープ

Touch Bar 未搭載の Mac であれば、`shift` + `ctrl` + `power` or `eject`ボタンでディスプレイのみスリープできたが、Touch Bar 搭載の Mac には`power`、`eject`ボタンともに無いのでこの同様のショートカットを利用でいない。ただ、下記コマンドでディスプレイのみスリープできる。

```bash
pmset displaysleepnow
```
iOS Safariのoverflow:scroll内の要素でtransitionendが発生すると、バウンススクロールがキャンセルされる

iOSのOverflow:hiddenを持った要素内スクロールで問題が発生。
iOS safariでは、スクロールが末端でバウンスするエフェクト（ぼよよーんって感じの表現）がかかる。つまり一時的にスクロール可能最大量以上のスクロールがされた状態がユーザーに見える。
ところで、要素内でtransitionendイベントが発生すると、このバウンスが一時的にキャンセルされるのか、スクロール可能量以上のスクロール状態ではなくなる。

結果として、連続的にtransitionendが発生するような演出を入れていた場合（スクロール要素内の要素が次々とスライドインするような演出）、
バウンススクロールが連続的に強制的にスクロール可能最大量にリセットされ、震えているように見える。

効果的な対処法はちょっと思いつかない。
スライドインする要素が全部出現終わるまでは、javaScriptで強制的にバウンススクロール時のスクロールイベントをキャンセルするなどした。ただこれも十全ではない。
return(返り値)を複数返す方法

#返り値を複数返す方法とは！？

こんにちは、徳永です

returnの概念がやっと理解できたかな？と思った矢先にこんな問題が

>関数内で値を２つ定義し、その二つの値を返り値に入れて
>出力してください！

ふむふむ・・・

返り値を２つね、楽勝！！

```php:

function test()
{
    $num_1 = 100;

    $num_2 = 200;

    return $num_1, $num_2;
}

echo test();//エラー

```

あれ、構文エラー？？？

複数返り値にもたすことはできないのかな？

ならばこれで・・・

```php:

function test()
{

$array = [
    $num_1 = 100,
    $num_2 = 200
];
    return $array;
}

echo test()[0];  //100
echo test()[1];  //200


```

なるほど

返り値を二つ以上返したい場合は配列に入れて返せばいいのですね！

では試しに・・・

```php:

function test()
{
    $i = 0;

while ($i < 100) {
    $array[$i] = $i;
    $i++;
}
    return $array;
}

var_dump(test());

//array(100) {
//  [0]=>
//  int(0)
//  [1]=>
//  int(1)
//  [2]=>
//  int(2)
//  [3]=>
//  int(3)...........
```
何個でも返り値を持たせることができそうですね

以上、return(返り値)を複数返す方法でした

Twitterやってます、よかったらフォローお願いします！
https://twitter.com/tokuppee15
標準入力で1行目に整数N、以降にN個の整数が続く際の最大値、最小値、要素数を求める

※paizaスキルチェック時に出てきたことメモ

標準入力で1行目に整数N、以降にN個の整数が続く、(N+1)個の整数が以下の形で与えられる。

**1行目のNを除いた整数の最大値を求める**


```
N
a_1
...
a_N
```

**上記の内から(a_1 ... a_n)の最大値を求める。**

↓入力値の例

```
3(N)
7(a_1)
9(a_2)
4(a_N)
```

↓求めたい出力値の例

```
9(a_2 = 最大値)
```

以下2パターンある。


**(1)要素0がN個あるリストを作成**

```
N = int(input())

#要素0がN個あるリストを作成
A = [0] * N

#リストに入力される要素を0と入れ換える
for i in range(N):
    a = int(input())
    A[i] = a

print(max(A))
```



**(2)空のリストを作成**

```
N = int(input())

#空のリストを作成
A = []

#リストに入力される要素を新しく入れる
for i in range (N):
    A.append(int(input()))

print(max(A))
```



※最小値、要素数を求める場合は以下を使う
最大値:max()
最小値:min()
最大値:len()
Real World HTTP 知識のメモ

# この本を読むにあたった経緯
Laravelなどのフレームワークを触り、フロントエンドの部分やバックエンドの部分について知識を深めていたが、WEBに関する知識が足りないと痛感させられていた。その時に、知人から、「この本を読むと大切な部分について理解できるよ。」と勧めていただき、本書を手に取った。

#この記事の目的
この本を通じて、学んだこと、またはこの記事を読むことで何が大切だったか思い出すための議事録が欲しいと感じたからである。
また、書いた記事を通して、いろいろな人からコメントをいただき、理解を深めたいと思ったことも挙げられる。

#議事録
## 1章 HTTP（Hyper Text Transfer Protocol）：基本となる 4 つの要素
HTTPとは、WEB上でサーバとクライアントが様々な情報（HTMLで書かれた文書など）をやりとりする時に使われる通信手段（プロトコル）のこと。
ちなみにHTTPとHTTPSとあるが、HTTPは暗号化されてないもの、HTTPSは暗号化されたものという認識で大丈夫だと思う。（たぶん）

HTTP は以下の 4 つの要素に分解できる。
- メソッドとパス
- ヘッダー
- ボディ
- ステータスコード

#### メソッドとは
指定されたアドレスにあるリソースに対する操作をサーバに指示するもの。
オブジェクト指向のプログラミングのメソッドと同じ。

（現在使用されているメソッドの例）
GET：サーバに対して、ヘッダとコンテンツを要求
HEAD：サーバに対して、ヘッダのみを要求
POST：新しいドキュメントを投稿
PUT：既に存在する URL のドキュメントを更新
DELETE：指定された URL　のドキュメントを削除

####パスとは
パスとは、様々な情報やファイルがどこにあるかを辿れるようにする道筋。
一般的によく見る URL を参照して考えてみる。
https://www.oreilly.co.jp/index.shtml
これは スキーマ://ホスト名/パスとなっていて、
スキーマ：https
ホスト名：wwww.oreilly.co.jp
パス：index.shtml
となる。

####URL あたりの知識について
URL（Uniform Resource Locators）：インターネット上に存在する様々な情報の場所を指し示す手段を提供するもの。
URN（Uniform Resource Name）：リソースに対する名前の付け方のルール
URI(Uniform Resource Identifier)：上記 2 つの定義。URL ともう混同しないよね！！


####ステータスコード
「404 Not Found」の404 が（一番よく見る？）例として挙げられる。この数字を見るだけで、サーバがどのように反応したかが一目でわかる。
- 100番代
処理中の情報の伝達。
- 200番代
成功時のレスポンス
- 300番代
サーバからクライアントへの命令。エラーではなく、正常処理の範疇。リダイレクトやキャッシュの利用を指示。
- 400番代
クライアントから送られてきたリクエストにおかしい点がある場合に渡される。
- 500番代
サーバ内部でエラーが発生した場合にクライアントに送付される。

##2章 ブラウザの基本機能の裏側
####クッキー
WEBサイトの情報をブラウザ側に保存する仕組みのこと。サービス側からクライアント（ブラウザ）に「これを保存しておいて」とクッキーの保存を指示する。
クライアントはサーバから受け取ったクッキーをローカルのストレージに保存し、同じ URL にアクセスがあるときはそのクッキーを読みだしてサーバのリクエストヘッダに加える。

####認証とセッション
BASIC 認証、Digest 認証とあるがどちらも最近使われていない。
最近は、フォームを使用したログインとクッキーを使用したセッション管理の組み合わせである。
クライアントは、フォームでIDとパスワードを送信する。サーバ側では、ユーザIDとパスワードで認証し、問題がなければセッショントークを発行。サーバはセッショントークンをリレーショナルDBやキーバリュー型のDBに保存しておく。トークンはクッキーとしてクライアントに戻される。2度目の以降のアクセスは、クッキーを再送することで、ログイン済みのクライアントであることがわかるという仕組み。

####プロキシ
HTTPなどの通信を中継する仕組み。中継するだけでなく、様々な付加機能が実装されることもある。会社や大学などの組織のメンバーの誰かがアクセスしたコンテンツは、他のユーザもアクセスする可能性が高いということで、キャッシュ機能を持ったプロキシを組織のネットワークの出入り口におくことで、コンテンツをおくWEBサーバの負担を減らし、かつ各ユーザが高速にページを閲覧できるようにするといった効果がある。


####キャッシュ
既にダウンロードで、内容に変化がなければダウンロードを抑制し、それによってパフォーマンスを上げるメカニズムが「キャッシュ」である。GETとHEADメソッド以外は基本的にキャッシュされない。

#最後に
こんな感じで議事録っぽくまとめていこうと思っています！