OmniAICreator/Qiita-1.07M huggingface dataset:
【Linux】dhcpサーバ構築

# DHCPサーバ構築

・パッケージのインストール

```
dnf install -y dhcp-server
```

・dhcpdの起動と自動起動設定

```
systemctl enable --now dhcpd
```

・dhcpd.confのバックアップ

```
cp -ip /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.org
```

※サンプルconfigがあるので必要な場合コピーする。

```
cp -ip /usr/share/doc/dhcp-server/dhcpd.conf.example /etc/dhcp/dhcpd.conf
```

・dhcpd.confの編集

``` /etc/dhcp/dhcpd.conf
# A slightly different configuration for an internal subnet.
subnet 192.168.10.0 netmask 255.255.255.0 {
  range 192.168.10.2 192.168.10.100;
  option domain-name-servers 192.168.10.200;
  option routers 192.168.10.254;
}

host reserve {
  hardware ethernet 00:0c:29:d6:e3:ac;
  fixed-address 192.168.10.99;
}

```

・払い出し済みのIPアドレスの確認

```
cat /var/lib/dhcpd/dhcpd.leases
```
M1 Macのローカルでjest-dynamodbを使ってテストする

JestでDynamoDBのテストする方法を調べると、Jest公式のドキュメントの [Using with DynamoDB](https://jestjs.io/docs/dynamodb) が見つかります。「めっちゃ便利！」と思って進めたのですが、M1 Macの場合はちょっと一工夫必要だったので、その問題と解決策を書こうと思います。

## 問題

ドキュメント通りに進めて、jestを実行すると以下のようなエラーが発生します。

```sh
重大: [sqlite] SQLiteQueue[]: error running job queue
com.almworks.sqlite4java.SQLiteException: [-91] cannot load library: java.lang.UnsatisfiedLinkError: Can't load library: /private/var/folders/5c/h19nr7xj51l7rgbj889mc1y00000gn/T/dynamodb-local/DynamoDBLocal_lib/libsqlite4java-osx.dylib
```

ざっくり言うと、jest-dynamodb は内部的に`sqlite4java` というライブラリを使っているらしく、これが x86_64 にしか対応してないようです。M1 Macを使っている方だと、僕のように ARM版のJavaをインストールしている方も多いと思いますが、そうすると `sqlite4java` を実行できないということっぽいです。

なので、解決法としては２通り考えられます。

- x86_64版Java をインストールして置き換える
- ARM対応の `sqlite4java` をインストールして置き換える

Java自体を置き換えるのは嫌だったので、後者を実施することにしました。

:::note warn
サードパーティ製のライブラリをインストールするという性質上、自己責任でお願いします！
何が起きても当方は責任を負いかねます🙇‍♂️
:::


## STEP 1. ARM対応板 `sqlite4java` をダウンロード


[ここにアクセス](https://search.maven.org/artifact/io.github.ganadist.sqlite4java/libsqlite4java-osx-arm64/1.0.392/dylib)して `io.github.ganadist.sqlite4java:libsqlite4java-osx-arm64` をダウンロードします。


## STEP 2. ファイルを置き換える

エラー文で出たディレクトリを開いて、ダウンロードしたファイルを移動して置き換えます。このとき、名前の変更も忘れないようにしてください。前のファイルはリネームして残しておくのがいいと思います。

```sh
$ open /private/var/folders/5c/h19nr7xj51l7rgbj889mc1y00000gn/T/dynamodb-local/DynamoDBLocal_lib/
```

![スクリーンショット 2022-08-06 12.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/ac7e6e0e-7fdb-a546-26ae-de779447ebf1.png)


## STEP 3. 一旦開く

このままだと、Macのセキュリティに引っかかって実行できません。
なので、一旦 `追加したファイルを左クリック > 開く` でアプリケーションを実行してください。

![スクリーンショット 2022-08-06 12.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/419928c0-3be6-8c1d-17d5-5ee986e5d27f.png)

すると警告っぽいのでますが、`開く` を選択してください。
これで、アプリケーションを開くことを許可できます。

![スクリーンショット 2022-08-06 12.24.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/8b69a2f9-17ca-591c-5f43-e51c30e97bf5.png)


## STEP 4. 改めてjestを実行する

```
$ jest
```

これで問題は解決しました！


## 参考

- [[Question] How can I use Jest-dynamodb in Apple Silicon? #121](https://github.com/shelfio/jest-dynamodb/issues/121)
(Windows)大文字と小文字を区別するディレクトリがパスに含まれている

<font color='blue'>妃</font>: X:\\YYY

　Windows 10に接続していた外付けHDDがFAT32だったのでNTFSへ変換した．
　エクスプローラー左paneのネットワークには自機名がぶら下がっていて，自機名をclickすると右paneに妃を表すicon: <font color='blue'>姫</font>が表示されている．
　姫をclickすると，以下のようなerror．

　　(前略)大文字と小文字を区別するディレクトリがパスに含まれているため、ファイルを開くことができません。

　以下，実行したcommandとその結果:

```
　fsutil file queryCaseSensitiveInfo 妃
  (前略)大文字と小文字を区別する属性が有効になっています。 
```
　次いで，以下のcommandを実行:
```
  fsutil file setCaseSensitiveInfo 妃 disable
```
　姫をclickすると，無事，以前と同様に妃の内容が描画された．

　妃をラズパイからmountしていたのでcifsの方から調べてしまい悪戯に時間が掛かった．

　2022-08-06現在日本語でググってもこの件に適した検索結果が返ってこなかったのでshareします．
GitHub備忘録[次心編]

# はじめに
　GitHubをデバッグの際に便利なストレージと勘違いしつつある今日この頃、Issuesが問題という意味のディスカッションの場であることを初めて知ったGitHub初心者の一歩先を行く者です。
　今回はGitHubのbranch機能を使ってみたのでそれを初心編と合わせて見ていってください。

# コマンド

```
git add 特定のディレクトリ
git commit -m "2022/08/06 second"
git branch -m something
git push -u origin something
```

　最初にGitHubにpushした時と比べると、git initの初期化とgit remote add origin ～がなく、branchをmainではなく別のものとしています。commitの際のコメントは適当です。何か気のいいメッセージを書くべきなのでしょうか？
Javaの学習　~package~

未経験からのエンジニア転職を目指していたのですが、先日無事内定をいただきました！
転職先で使用する言語がJavaということで、アウトプット学習のため少しずつ投稿していきたいと思います。（Java Silverの学習も兼ねています！）

### パッケージ（package）とは
Javaはオブジェクト指向の言語であるため、クラスをたくさん作成する可能性があります。
そのクラスを機能ごとに、分類するための仕組みがパッケージです。

#### パッケージの目的
①名前空間(ネームスペース)を提供することで、名前の衝突を回避する
②アクセス制御機能を提供する
③クラスの分類を可能にする

### パッケージの宣言方法
```java
package practice;
//package + 好きなパッケージ名;
```
また、パッケージは階層を作成できる為（ディレクトリのようなイメージ）、その場合は上の階層から「.」で繋げて記述します。
```java
package practiceA.practiceB.practiceC;
```
##### ちなみに...
・パッケージ宣言をしない場合は、無名パッケージに属するものと判断されます。そのため、パッケージに属さないクラスは存在しません。
・「package」の他に「import」も宣言することがあると思いますが、importよりもpackageを先に記述しなければコンパイルエラーが発生します。（packageよりも先に記述できるのはコメントのみである。）

### パッケージ所属のクラスを呼び出す
①同じパッケージに属するクラスを呼び出す場合は、クラス名のみで構いませんが、
別のパッケージに属するクラスを呼び出す際には「完全修飾名」（パッケージ名.クラス名）を用いて呼び出す必要があります。
```java
//java.testパッケージに属するTestクラスを呼び出したい場合
package java.practice;
 
class Practice{
    
   public static void main(String[] args){
        
       java.test.Test test = new java.test.Test();
       //Testクラスをインスタンス化（この記述の際にも完全修飾名を使用する）
        
   }
 
}
```
②上記の方法では、毎回の記述が面倒...な為、import宣言を使用する方法もあります！
```java
package java.practice;
 
import java.test.Test;
 
class Practice{
    
   public static void main(String[] args){
        
       Test test = new Test();
       //クラス名だけで別のパッケージに所属するクラスをインスタンス化できる。
        
   }
 
}
```

#### アクセス修飾子によるアクセス制御
```java
package java.test;
 
public class Test{
    //publicが付いている為、外部のパッケージに属するクラスからアクセスができる
}
```
```java
package java.test;
 
class Test{
    //publicが付いていない為、外部のパッケージに属するクラスからアクセスができない
}
```

### まとめ
なんとなく使用していたpackageに、こんなにもルールやメリットがあるとは知りませんでした！もしも間違い等お気づきの点がございましたらコメントお願いいたします！！閲覧いただき有難うございました(^^)
レンタルサーバーを借りてオンラインゲームのWikiサイトを作ってみる #1


前の記事
https://qiita.com/Unirenkon/items/7ed5bcc724205906083c

# 今回の作業

* レンタルサーバーを借りる
* 独自ドメインを取得する
* Pukiwikiをサーバーにインストール

今回は本記事（シリーズ）を書こうと思った前日にやった作業なので、SSなどを用意できなかった部分があります。

## レンタルサーバーを借りる
自前でサーバーを借りてWikiを作る場合、**Xserver**というサーバーを利用すると、**Pukiwiki**というOSSが簡単にインストールできることがわかったので、まずはXserverと契約しました。

キャンペーンをやっていて、ちょうど10日間無料をやっていたのもやるか〜と思ったきっかけです。
今のキャンペーンは2022年8月25日(木)18:00までで、さらに独自ドメイン無料、利用料金キャッシュバックもやっているとのこと※条件あり
（ただキャンペーン自体は形を変え割といつでもやっているものだろうなとも思いますw）

１０日間無料の体験はクレジットカードを登録しなくてよかったので気楽に試せると思います。

## 独自ドメインを取得
Xserverから独自ドメインを取得します。
今回は特に考えずゲーム名＋wiki＋.comという安直なドメインにしました。

## pukiwikiをサーバーにインストール

### （pukiwikiについて）
**PukiWiki**は、日本産のOSSで、PHPで実装されています。
デフォルトデザインはオンラインゲームプレイヤーなら誰もが見たことのあるようなオーソドックスなものです。
まだ詳しくは見てないのですがpukiwikiの公式サイト（それ自体もpukiwikiで構成されている）では質問箱というページがあり、過去に利用してきた人たちとコミッター（？）さんとの間での数多のやりとりが残されているので、こうしたい！と思った時にはまずはここをチェックするのがよいと思いました。
また、OSSというのもあり個人でプラグイン/スキン（テーマのようなもの）を作って配布している方もいらっしゃり、よりリッチなコンテンツにしたいのであればいずれこういうものも利用しないとなと思いました。

**Xserver×Pukiwiki**についても個人のブログなど過去に実装された方のTipsがたくさんあるので、よくわからないけどやってみる、みたいなのもある程度できると思います。

### pukiwikiのインストール方法

インストールはXsercerの簡単インストールからすぐに行えます。

インストール後、サイトを開くとうまく接続できませんでしたが、これは先ほどのドメイン取得やソフトウェアのインストールには30m~1hほど時間がかかるそうです。
しばらく待ってみると、開くことができました。
【matplotlib】ヒストグラムを密度ではなく確率で規格化する方法

# 概要
matplotlibでヒストグラムを作っていると、縦軸を密度ではなく確率で規格化したい場合があると思う。この記事では、縦軸を確率にしたヒストグラムの作り方について紹介する。
まず、例として、以下の図のような場合がある。横軸に特に意味がない量が割り当てれている場合や、各ビンに入る確率を知りたい場合などに右図のように縦軸に確率が使われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/98f842fb-713b-e304-2d65-5bd429e81cd8.png)

# 実装コード
Google Colabで作成した本記事のコードは、[こちら](https://colab.research.google.com/drive/1YLqqh9bvamooTGy7L3Vnjc2h5vs8lRTV?usp=sharing)にあります。

## 各種インポート
```Python:各種インポート
import numpy as np
import matplotlib.pyplot as plt
```
実行時の各種バージョン

| Name | Version |
|:-:|:-:|
| numpy | 1.21.6 |
| matplotlib | 3.2.2 |

## 使用データ
まずは、縦軸カウント数の本記事で使用する0~1の一様乱数のデータをヒストグラムに表示する。

```Python:縦軸カウント数
np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins)
ax.set_xlabel('data')
ax.set_ylabel('counts')
plt.show()
```
出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/e9c9bc58-40aa-f2ac-1279-da47129f66d5.png)

## 縦軸密度
縦軸を密度にしてヒストグラムに表示する。``density=True``は、ヒストグラムの面積が1になるように計算される。

```Python:縦軸密度
np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins, density=True)
ax.set_xlabel('data')
ax.set_ylabel('density')
plt.show()
```
出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/bfcdbf85-3635-73e2-2d19-ea385496c20f.png)

## 縦軸確率
各ビンに入る確率を知りたい場合がある。そこで、縦軸を確率にしてヒストグラムに表示する。

目標とする図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/53518786-ed4f-a883-995d-35e0a12f8d8b.png)


### 方法1
``weights``で重みを指定して確率のヒストグラムを表示する方法である。
この``weights``は各配列の要素の重みをどうするかの引数で、例えば``weights=np.ones(len(data)) / 1``とすると、各配列の要素の値を1として重みをつける。すなわち、縦軸カウント数と全く同じヒストグラムができる。
では、``weights=np.ones(len(data)) / len(data)``とするとどうなるでしょうか。各配列の要素数をdata数が1000個の場合、重みが``1/1000``として扱われる。つまり、各配列の要素の重みの合計が1となり縦軸確率のヒストグラムができる。

```Python:
np.random.seed(2022)
data = np.random.rand(1000)
bins = np.linspace(0, 1, 10)

fig, ax = plt.subplots()
ax.hist(data, bins, weights=np.ones(len(data)) / len(data))
ax.set_xlabel('data')
ax.set_ylabel('probability')
plt.show()
```

### 方法2
``np.histogram``で``counts``と``bin``を一旦渡して、``weights``で重みを指定して確率のヒストグラムを表示する方法である。方法を順を追って説明する。
1. ``counts``と``bins``に各ビンと各ビンに入るカウント数を渡す。
2. ``ax.hist(bins[:-1], bins)``を表示すると良く理解できるが、この``ax.hist(bins[:-1], bins)``は各ビンに1つのみ必ず入るので、全てが1のヒストグラムができる。
3. 全てが1のヒストグラムを``weights``で重みをつける。``weights=counts``とすると、各ビンが1なので``1 * counts``の、すなわち縦軸がカウント数のヒストグラムができる。
4. 確率のヒストグラムを作りたいので、各ビンを全体のdata数で割ってあげて重みをつける。つまり、``weights=counts / len(data)``とすると縦軸確率のヒストグラムができる。
```Python:
np.random.seed(2022)
data = np.random.rand(1000)
counts, bins = np.histogram(data, np.linspace(0, 1, 10))

fig, ax = plt.subplots()
ax.hist(bins[:-1], bins, weights=counts / len(data))
ax.set_xlabel('data')
ax.set_ylabel('probability')
plt.show()
```

# まとめ
ヒストグラムの縦軸を確率で表示する方法を紹介しました。誰かのお役に立てれば幸いです。

# 参考資料
https://stackoverflow.com/questions/3866520/plot-a-histogram-such-that-bar-heights-sum-to-1-probability

https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.hist.html
Docker内でsystemctlを使う with CentOS Stream 9

コンテナ内でもcronとかをsystemctlを使って起動したい！
でも普通にコンテナイメージを作るとsystemctlがエラーが出て動かない！
~~（あとなんとなくCentOS Stream 9を使ってみたい！）~~
困った！

という人用の記事です。
※今回の内容には注意点もありますので、よく読んだ上でご利用は自己責任でお願いいたします。

# 結論

**【注意点】**
以下の手順のdocker run時に *--privileged*オプションをつけていますが、
これは**危険性のあるオプション** です。
このオプションは[ドキュメント](https://docs.docker.com/engine/reference/commandline/run/#full-container-capabilities---privileged)では、 **「潜在的な危険のある操作はデフォルトではできないようになっているが、--privilegedオプションによってそれが可能となる」** というようなことが書かれています。
したがってこの記事の内容を利用する際は、利用ケースをよく考えて使っていただければと思います。


**【systemctlの使えるイメージの作り方、コンテナ起動の仕方】**
１. 以下のDockerfileを用意して、
```Dockerfile:Dockerfile
FROM quay.io/centos/centos:stream9

ENV container docker
RUN dnf update && \
	dnf -y install cronie && \
	dnf -y install systemd && \
	dnf clean all && \
	systemctl enable crond.service

CMD ["/usr/sbin/init"]
```

２. コンテナイメージをビルドして
```
docker build -t local/cs9-systemd:0.5 .
```

３. コンテナをバックグラウンドで起動して
```
docker run --privileged --name cs9-systemd -v /sys/fs/cgroup:/sys/fs/cgroup:ro -d local/cs9-systemd:0.5
```

４. あとはコンテナ内でbashを起動して手元のターミナルとつなげる
```
docker exec -it cs9-systemd /bin/bash
```

上記1～4の手順を実行すると、コンテナ内でsystemctlが使えます。
上記の例ではコンテナ起動時にcronのデーモンを動かす設定をしており、
`crontab -e`でジョブを設定してあげると自動実行されることが確認できると思います。
追加でなにかデーモンを起動したい場合は、通常のCentOSのようにコンテナ内で`systemctl start`を使うことでできます。 

試しにsystemctl list-unitsを使ったところ。ちゃんと動いている。
|:--|
| ![systemctl list-unitsを使ったところ。ちゃんと動いている。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049468/787cad19-b099-c518-7032-ab238c5400ea.png)|


# 解説
## そもそもなぜsystemctlが動かないのか？
それはsystemdはPIDが1のときでないとエラーを返して起動しないようになっているから。
これはsystemdやsystemctlを実行したときのエラー
`System has not been booted with systemd as init system (PID 1). Can't operate.`にもそう書いてありますね。
PIDはプロセスのIDのことであり、PID1は一番最初に起動したプロセスに割り当てられるようです。
普通にlinuxを起動した際はsystemdが一番最初に起動するプロセスになるのですが、
dockerの場合はdocker runをした際に指定されたプログラムがPID1になります。
例えば`docker run [コンテナ識別子] /bin/bash`とした際は、bashがPID1として起動します。
また、プログラムの指定を省略した際は少々動きが特殊で、
Dockerfileに書かれたCMDの内容があればその内容、
なければ`/bin/bash`がデフォルトとして指定されるようです。
ともかくこのdocker独特の挙動によってsystemdが動かないわけですね。

## 対策
今回の場合はdocker runを実行したときに/usr/sbin/initが実行されるようにする！
/usr/sbin/initの中でsystemdが起動され、systemdのPIDが1になるようです。
上記Dockerfile内の`CMD ["/usr/sbin/init"]`がそのための記述ですね。
上記の手順3`docker run`ではコンテナ起動時に動かす（PID1になる）プログラムを指定していないので、
CMDに書いた`/usr/sbin/init`が実行されます。
なお、CMDに書くべきものはディストリビューションによって異なるようです。

## その他Dockerfileの解説
`dnf install -y cronie` : cronieという名前のcronのパッケージをインストール
`dnf -y install systemd` : systemdのパッケージをインストール（実際には一緒にインストールされるsystemctlのコマンドを使います）
`dnf clean all` : パッケージインストール時にできたキャッシュ情報を削除
`systemctl enable crond.service` : systemctlの実行テストとして起動時にcronのデーモンを起動するようにお試しで設定

# まとめ
（問題点がないわけではありませんが）コンテナ内でも一応systemctlを動かすことができました。
ここまで読んでいただきありがとうございました。


# 参考
* Centos - Official Image | Docker Hub：https://hub.docker.com/_/centos/
  * 旧CentOSのDockerhub　 
  * Example systemd enabled app containerの項目を参考にした
* Official CentOS systemd docker container：https://hub.docker.com/r/centos/systemd/
  * systemdが使える旧CentOSのコンテナイメージの実物がある
* CentOS : https://quay.io/repository/centos/centos?tab=tags
  * CentOSの後継、CentOS Streamのコンテナイメージのレポジトリ
Ruby 配列を検索して置き換えまたは削除

# 方法
[1] 文字列"hoge"を"hogehoge"に置き換える
```ruby
array = ["huga","hoga","hoge"]

# arrayから"hoge"を検索して"hogehoge"で置換
array.map!{|x| x=="hoge" ? "hogehoge" : x}

p array
# 出力結果=> ["huga","hoga","hogehoge"]
```
[2] 文字列"hoge"を"hogehoge"に置き換える（非推奨）
```ruby
array = ["huga","hoga","hoge"]

# arrayから"hoge"を検索して"hogehoge"で変換
array[array.index("hoge")] = "hogehoge"

puts array
# 出力結果=> ["huga","hoga","hogehoge"]
```
こちらの方法は検索する文字列がない場合このようなエラーが出る。
![10272050481bd11c4015d899de61beda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661107/8696f311-86e3-a2d2-d8ac-ccb1882c506d.png)

[3] 数値0だけを削除する
```ruby
array = [0, 0, 4, 5, 0 ,0]

# arrayから0を削除
array.delete_if { |num|
  num == 0
}

p array
# 出力結果=> [4, 5]
```
# まとめ
paizaのスキルチェックでよく検索する配列の操作についてまとめました
ConMas Gateway スクリプトのデバッグ (1)

製造現場の紙帳票のデジタル化を担うi-Reporter。現段階ではまだベストなソリューションとは言えませんが、今後の機能アップが期待出来るとすればそのポテンシャルは大きく、紙帳票のデジタル化に留まらず、旧態依然な現場のパネルまでも、i-ReporterをのせたWindowsのタッチパネルに入れ替わるかもしれません。日本の製造業をチャンピオンに返り咲かせるDXの誘因として重要なソリューションのひとつであることに間違いはありません。。
このi-Reporterシステムに必須といってもよいのが"ConMas Gateway"です。まだ機能面での不足がある ConMas Gateway ですが、i-Reporter の jQuery.ajax とも言える ConMas Gateway を使わずして i-Reporter の存在意義は語れません。

この記事では、ConMas Gateway スクリプトの効率的なデバッグ手法について複数回に分けて解説します。

>この記事の内容は、IT系開発に不慣れなFA系システム開発者向けです。WEBシステムのサーバ・サイド開発等に長けたITエンジニアにとっては、当たり前のことが書かれています。

>この記事の内容を理解するために、i-Reporterに関する細かな知識を事前に得ている必要はありません。ただし、この知識がない方は、ある程度の想像力を働かせながら読み進める必要があります。
## システム・モデル
![Screenshot from 2022-08-06 18-02-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737842/498323f7-7cea-64c8-dfdc-2deadc83b62c.png)
- ConMas Gateway から起動されたスクリプトは、i-Reporter からPOST（あるいはGET）されたデータを、標準入力を介して ConMas Gateway から受け取ります。
- スクリプトは i-Reporter へのレスポンスを標準出力を介して ConMas Gateway へ渡し、ConMas Gateway はこれを i-Reporter にレスポンスします。

つまり、ConMas Gateway のスクリプトは、WEBシステムにおける CGIを使うスクリプトと何ら変わりがありません。

> 面白いのは、ConMas Gateway と ConMas Server の間にインタフェースが全く存在せず、両者は何のやりとりもしないことです。
> もちろん、ConMas Server のデータベースは公開されているため、ConMas Gateway が直接あるいはスクリプトを介して、このデータベースをアクセスすることは可能です。

なお、ConMas Gateway はスクリプトがなくても、自らの機能でデータベースをアクセスし結果を i-Reporter にレスポンスすることが出来ます。ただし、このデータベースのアクセスはシンプルなものに限定され、複雑な処理、あるいはデータベース・アクセス以外の処理を行うにはスクリプトが必要となります。
この記事では、このスクリプトのデバッグについて述べており、ConMas Gateway 自身が持つデータベース・アクセスについては述べていません。
## データ
i-Reporter とスクリプトの間でやりとりされるデータはJSONです。これは、データを処理する手続きをシンプルに記述できるという点で歓迎できます。
- POSTされるデータは、クラスタ（i-Reporterで処理される帳票上のデータの最小単位）の属性と（当該クラスタに入力された）データが key: value のタプルとなったJSONです。複数のタプルが配列で並びます。どのクラスタをPOSTするかは、事前に ConMas Designer 上で選択します。
- GETされるデータは任意です。ConMas Designer による設定でURLに続くデータを任意に記載することが出来ます。
- レスポンスは、帳票上のクラスタのIDと当該クラスタに表示されるデータをタプルにしたJSONです。もちろん、このタプルは配列で複数にすることができます。
>この記事では、データのフォーマットに関する細かな解説をしません。データのフォーマットに関する細かなルールや、ConMas Designer での設定については、シムトップス社から提供されるマニュアルを参照してください。これらの情報がなくても、この記事を読み進める上での支障にはなりません。
>マニュアルにアクセスするには、シムトップス社のサイトにアクセスするためのIDが必要になります。
## 標準と思われるデバッグ手法
標準と思われるデバッグの手法は、i-Reporterで（必要であれば帳票にデータを入力し）帳票上のアクション・クラスタを発動させ、当該クラスタに設定されたスクリプトを動作させながらテストと不具合の解消を進めるという（何の工夫もない）いたって普通の方法です。
小さく単純でテストが簡単なスクリプトのデバッグでは、この方法でも良いかもしれません。ただし、大きく複雑で、高度なテストとデバッグを要するスクリプトの場合には問題が生じます。
#### 問題
- この方法ではスクリプトの動作を簡単にはトレースすることができない
- この方法でのスクリプトのトレースは、デバッグのための古典的なプリント、あるいはカバレージをファイル等に出力するなどが必要となる。一方で、Python で提供される Pdb や Trace 等のコマンドラインで容易に使える強力なツールが使用できない。
## 次回
続きは次回とさせていただきます。
初心者の方々のために、ゆっくりとマッタリと進めさせていただきます。
次回は「ではどうすれば良いか」です。

[ConMas Gateway スクリプトのデバッグ (2)](https://qiita.com/COOLMAGICPRODU1/items/ff901626fed95d79ebb6)
対称式「22年 北海道大 後 理・工 1」をwolframalphaとsympy でやってみたい。

オリジナル
a+b+c,a3+b3+c3-3abc

https://kamelink.com/blog/2022/07/26/1-7-22-hokkaidoudai-kou-ri%e3%83%bbkou-1/

# wolframalphaで

(1)

https://www.wolframalpha.com/input?i=SymmetricReduction%5Ba3+%2B+b3+%2Bc3%E2%88%923abc%2C+%7Ba%2Cb%2Cc%7D%5D+&lang=ja

もしかしたら、次の入力がまちがっているかもしれません。

https://www.wolframalpha.com/input?i=a%2Bb%2Bc%3D0%2CSymmetricReduction%5Ba3+%2B+b3+%2Bc3%E2%88%923abc%2C+%7Ba%2Cb%2Cc%7D%5D+&lang=ja

(2)
省略

(3)

https://www.wolframalpha.com/input?i=a3%2Bb3%2Bc3-3*abc%3D63&lang=ja

整数解の数18
18÷(3*2*1)=3

```
{
{a == -2, b == 2, c == 3}, 
{a == -2, b == 3, c == 2}, 
{a == -1, b == 0, c == 4}, 
{a == -1, b == 4, c == 0}, 
{a == 0, b == -1, c == 4}, 
{a == 0, b == 4, c == -1}, 
{a == 2, b == -2, c == 3}, 
{a == 2, b == 3, c == -2}, 
{a == 3, b == -2, c == 2}, 
{a == 3, b == 2, c == -2}, 
{a == 4, b == -1, c == 0}, 
{a == 4, b == 0, c == -1}, 
{a == 6, b == 7, c == 8}, 
{a == 6, b == 8, c == 7}, 
{a == 7, b == 6, c == 8}, 
{a == 7, b == 8, c == 6}, 
{a == 8, b == 6, c == 7}, 
{a == 8, b == 7, c == 6}
}
```

# sympyで
```python
(勉強中)
```

# 参考
レンタルサーバーを借りてオンラインゲームのWikiサイトを作ってみる #0

# 経緯
海外でリリースされる予定のオンラインゲームの日本語Wikiがなかったので作ろうかなと思って調べてみたら、@WikiみたいなレンタルWikiを使って作る以外にも自前でサーバーをレンタルして作ることができるそう
昔からプライベートでなんかレンタルサーバー借りて独自ドメインでサイト作ってみたい〜みたいな気持ちがあったけど、ネタもやる気もなかったところでいい機会かなと思ってやってみる

# 筆者について
新卒時代に1mmくらいWebエンジニアとしてのキャリアがあるくらいの素人

# 記事を残そうと思った理由
昔の記憶を掘り起こしたり色々調べたりして今回やったことを今度なんかの機会にやりたいなと思った時に見返せる自分用メモ
素人なので情報の信用性とか用語の使い方とかの解像度が薄めです
また、個々の技術については基本は他の方の記事やブログから得た情報です

# ワークフロー
※6以降は今の時点では願望レベルです

1. レンタルサーバーを借りる
1. 独自ドメインを取得する
1. Pukiwikiをサーバーにインストール
1. フロントを簡単にいじれるように環境を整える
1. 記事を書く
1. SEO対策をする
1. 広告を貼る
1. 協力者を得てWikiを繁栄させる
Linux ハードリンクとシンボリックリンクについて（自分用メモ

Linuxにはファイルやディレクトリを管理するための様々なコマンドがあります。

touch ... 空のファイルを作成したり、ファイルのタイムスタンプ（アクセス時刻や修正時刻）を変更する
cp ... ファイルやディレクトリのコピーを行う
mv ... ファイルやディレクトリを移動する、または名前を変更する
rm ... ファイルやディレクトリを削除する
file ... ファイルの種別を表示する

各コマンドには「-ショートオプション」や「--ロングオプション」の形式でオプションを指定できます。
そのため、設問のように「-（ハイフン）」から始まるファイル名を指定すると、シェルによってオプションと認識されコマンドが正常に実行されません。


「-（ハイフン）」から始まるファイル名をオプションとみなされないようにするためには、次のいずれかの方法でコマンドを実行します。
・コマンドに「--」オプションを指定する
　「--」オプションはオプションリストを終了し、これ以降の引数をオプション以外のものとして扱います。
・ファイル名にパスを記述する
　ディレクトリやファイルの場所を示す絶対パスや相対パス（参考を参照）を記述することで、ファイル名やディレクトリ名と認識されます。



●Linuxではファイル(ディレクトリはファイルの一種)を「ファイルの実体（データ本体）」と「inode」を使用して管理しています。inodeにはファイルの属性や、「ファイルの実体」にアクセスするためのアドレスなどが格納されています。 Linuxには、同じ「ファイルの実体」に対して複数の名前でアクセスできる、リンクという仕組みが2種類。それが「ハードリンク」と「シンボリックリンク」。  
【ハードリンク】 ファイルの実体を直接参照するリンクのこと。ファイルを新規作成した場合は、ハードリンクが1つある状態です。 同じ実体を参照するハードリンクは複数作成できます。それらは同じinode番号を持つことになります。  ハードリンクの数とinode番号は「ls -il」コマンドで確認することが出来ます。  ハードリンクを作成するにはlnコマンド（書式：ln 元ファイル リンクファイル）を利用します。  ハードリンクの制限として以下の2点があります。 1. ディレクトリのハードリンクは作成できない 2. 異なるファイルシステム（パーティション）にハードリンクを作成できない  これらの制限はシンボリックリンクを使う事で解決できます。  

【シンボリックリンク】 シンボリックリンクとは、Windowsでのショートカットのようなもので、元ファイルの場所を指し示すリンクの事です。 シンボリックリンクが持っている情報は「元ファイル（ディレクトリ）がどこにあるのか」というパス情報のみです。  シンボリックリンクを作成するにはlnコマンドに「-s」オプションを付加して作成します。（書式：ln -s 元ファイル リンクファイル）
Linux パーミッションと権限について（自分用メモ




パーミッションとは、ファイルやディレクトリに対する権限。権限には「読み取り権」「書き込み権」「実行権」の3種類

・読み
ーファイル
ファイル内容を参照（cat,moreなど）

ーディレクトリ
ディレクトリの内容を参照(ls,findなど）

・書き
ーファイル
ファイルに書き込み（viなど）

ーディレクトリ
ディレクトリ内に真摯ファイルを作成。既存ファイルの名前変更や削除（touch,mv,rmなど）

・実行
ーファイル
ファイルを実行

ーディレクトリ
ディレクトリ内のファイルへのアクセス。ディレクトリへの移動（cd）


ファイルやディレクトリを新規作成した際の、デフォルトのパーミッションを設定するにはumaskコマンドを利用します。

umask [マスク値]

umaskコマンドではマスク値というものを設定して、新規に作成するファイルとディレクトリのデフォルトのパーミッションを決定します。マスク値はユーザ毎に指定できます。通常「/etc/bashrc」などに設定されており、シェルの起動時にシステムのデフォルト値に戻ります。

マスク値が0の場合に使用されるデフォルトのパーミッションは、ファイルが「666」、ディレクトリが「777」です。これらの値から、指定したマスク値を引いた値が新たなデフォルトのパーミッションとして設定されます。

666 - マスク値 = ファイルのデフォルトのパーミッション
777 - マスク値 = ディレクトリのデフォルトのパーミッション

パーミッションの表記は各桁が独立して、左から所有ユーザ、所有グループ、その他のユーザを表します。ですのでumask値を引く際も各桁ごとに引きます。
なお、ファイルのデフォルトのパーミッションは「666」で実行権が無いので、umask値に関わらず実行権は設定されません。



また、特殊なパーミッションとして、以下の3つがあります。

・SUID
実行ファイルに設定する事で、そのプログラムをどのユーザが実行しても、プログラムの所有ユーザの権限で実行されます。
設定はchmodコマンドで、通常のパーミッションの値に4000を加えた値を設定するか、所有ユーザに「s」という権限を追加します(u+s)。
これが設定された代表的なプログラムに「passwd」コマンドがあります。

・SGID
実行ファイルに設定する事で、そのプログラムをどのユーザが実行しても、プログラムの所有グループの権限で実行されます。
設定はchmodコマンドで、通常のパーミッションの値に2000を加えた値を設定するか、所有グループに「s」という権限を追加します(g+s)。

・スティッキービット
ディレクトリに設定する事で、そのディレクトリに対して書き込み権限を持つユーザでも、自分が所有する以外のファイルを削除できなくなります。
設定方法はchmodコマンドで、通常のパーミッションの値に1000を加えた値を設定するか、その他ユーザに「t」という権限を追加します(o+t)。
これが設定された代表的なディレクトリに「/tmp」ディレクトリがあります。


ファイルやディレクトリのパーミッションを変更するにはchmodコマンドを利用します。

chmodコマンドの書式は以下のとおりです。
chmod [-R] パーミッション ファイルまたはディレクトリ

「-R」オプションを使用すると、指定したディレクトリおよびその配下にあるファイルのパーミッションを変更することが出来ます。

パーミッションの指定には数値か記号のどちらかを用います。
・数値の場合
chmod -R 755 dir

・記号の場合
・対象
u 所有者
g 所有グループ
o その他のユーザ
a 全てのユーザ

・操作
+権限を追加
-　権限を削除
= 権限を指定

・権限
r 読み取り権
w書き込み権
x実行権
s SUIDまたはSGID
t スティッキービット


対象、操作、権限の順に指定します。また「,」を使用して繰り返すことも出来ます。



指定したファイルまたはディレクトリの所有ユーザや所有グループを変更するにはchownコマンドを利用します。所有ユーザを変更できるのはrootユーザのみです。
また、所有グループのみを変更可能なchgrpコマンドもあります。ユーザが所属しているグループであれば、一般ユーザでも変更できます。


・所有ユーザのみを変更する場合
chown [-R] ユーザ名 ファイルまたはディレクトリ

・所有ユーザと所有グループを同時に変更する場合
chown [-R] ユーザ名:グループ名 ファイルまたはディレクトリ

・所有グループのみを変更する場合
chown [-R] :グループ名 ファイルまたはディレクトリ
chgrp [-R] グループ名 ファイルまたはディレクトリ

「-R」オプションを使用すると、指定したディレクトリ、およびその配下にあるファイルの所有ユーザやグループを再帰的に変更できます。
なお、「:」の部分は「.」としても同じです。
Automation 360のAPIで悩む（200個制限？）

# はじめに
先日「第15回 AA de Knight(*1)」という勉強会に参加させてもらいました。この「AA de Knight」、Automation Anywhereを触っている人には、とてもお勧めです。
（なお私はSB C&Sの人ではありません。宣伝じゃないよ）

さて、その中でAA API活用の話があり、またちょうどControl RoomのBotの情報をまとめて取得したいという相談があって「file/list」のAPIを使ってみました。
そのときに情報は200個以上あるはずなのに、200個までしかとれず悩んだ、という小ネタです。

(*1) https://aaj.connpass.com/event/245785/

# 最初のフィルタ
Botの情報をできるだけ多く取りたいという事で以下のフィルタを書きました。

```
{
  "filter": {
       "operator": "substring",
       "value": "Automation Anywhere\\Bots",
       "field": "path"
      }
}  
```

でも、全部のBot情報が取れていないように見えました。
戻りのJSON見ると以下が返ってきてて、いかにも200個で制限がかかっていそうです。
```
{'page': {'offset': 0, 'total': 1027, 'totalFilter': 200},
```

# 上限をあげるフィルタ
結論から言うとA-peopleに書いてあったやり方で回避できました。
```
{
  "page": {
      "offset": 0, 
      "length":3000
      },
  "filter": {
       "operator": "substring",
       "value": "Automation Anywhere\\Bots",
       "field": "path"
      }
}  
```

戻りを見ても...
```
{'page': {'offset': 0, 'total': 1027, 'totalFilter': 1022}, 
```
あ、なんかとれてそう。
(実際にはこのあとに大量の情報が取れています)


# 簡単なまとめ
A-peopleに書いてあったのは、ユーザ情報を全部とりたいのに200人分しかとれない！？って話でした。
情報取得系のAPIで全部とれない、と悩まれた場合は"page":{length:数値}を調整してみましょう、という話です。

# おまけ
AA社のWebページで、この200個制限の話を探したのですが、見つける事ができませんでした。
（1時間くらいしか探してないから、見落としているかも...）
この制限について書いてある場所、ご存じの方、教えて頂ければ幸いです。
GitのコミットにGnuPGで署名する

Gitのコミットには、ユーザのメールアドレスが記録されています。メールアドレスを使って、誰がコミット作成者（Author）やコミット実施者（Committer）であるかを判別する仕組みになっています。

しかし、メールアドレスは各自が `git config` で設定する属性です。実のところ、設定を変更すれば他者へのなりすましが簡単にできてしまいます。

なりすましの対策として、Gitのコミットにデジタル署名をすることで、なりすましではなく本人であることを示せます。とくに、GitHubで設定しておけば、署名つきコミットに対して「Verified」バッジが表示されます。

![GitHubのVerifiedバッジ](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/git_gpg_sign_images/git_gpg_sign_verified.png)

本記事では、macOSでGitのコミットに署名し、GitHub上で「Verified」バッジが表示されるよう設定する方法を紹介します。

# 必要なツールのインストール

以下、macOSを使う前提とします。また、[Homebrew](https://brew.sh/)が導入されている前提とします。

HomebrewでGnuPGをインストールします。

```
brew install gnupg
```

[GnuPG](https://gnupg.org/)は、[RFC4880](https://www.rfc-editor.org/rfc/rfc4880.html)で定義されたOpenPGP規格を実装したソフトウェアです。データや通信を暗号化したりデジタル署名を付けたりできます。GnuPGはGPGとも呼ばれます。

もうひとつ、Homebrewでpinentry-macをインストールします。

```
brew install pinentry-mac
```

[GPGTools/pinentry](https://github.com/GPGTools/pinentry)は、パスフレーズの入力をサポートするソフトウェアです。pinentry-macはpinentryのmacOS版で、とくに、パスフレーズをキーチェーンに保存する機能が便利です。

# GPGキーの生成

署名に使う公開鍵・秘密鍵のペアを生成します。先ほどインストールしたGnuPGを使います。

GitHubのドキュメント「[新しい GPG キーを生成する - GitHub Docs](https://docs.github.com/ja/authentication/managing-commit-signature-verification/generating-a-new-gpg-key)」に手順が詳しく書いてありますので、このとおりに実行します。

鍵の種類やサイズを聞かれますが、デフォルトのままで問題ありません。自分の好みで変更してもかまいません。

GPGキーのパスフレーズも聞かれます。このパスフレーズはあとでコミットへの署名のときに使うので、忘れないようにしてください。

# GitHubアカウントの設定

生成した鍵ペアの公開鍵をGitHubアカウントに追加します。この設定により、GitHub上で署名つきコミットに対して「Verified」バッジが表示されます。

GitHubのドキュメント「[GitHub アカウントに GPG キーを追加する - GitHub Docs](https://docs.github.com/ja/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account)」に手順が詳しく書いてありますので、このとおりに実行します。

# Gitの設定

生成した鍵ペアのキーIDをGitの設定に追加します。この設定により、Gitのコミットに対して指定の秘密鍵で署名できます。

GitHubのドキュメント「[Git へ署名キーを伝える - GitHub Docs](https://docs.github.com/ja/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key)」に手順が詳しく書いてありますので、このとおりに実行します。

ただし、今回はすでにpinentry-macをインストールしています。このため、「GPGスイートを使用していない場合は〜」と記載がある、シェルで環境変数 `GPG_TTY` を設定する手順はスキップします。代わりにpinentry-macを設定する手順を実行します。

# コミットへの署名

Gitでコミットを署名つきコミットにするには、次のようにします。これですべてのコミットが署名つきになります。

```
git config --global commit.gpgsign true
```

署名つきコミットの際、GPGキーのパスフレーズを聞かれます。pinentry-macの設定ができていれば、次のようなダイアログが表示されますのでパスフレーズを入力します。なお、「Save in Keychain」を有効にしておくと、パスフレーズがキーチェーンに保存されます。

![pinentry-macのダイアログ](https://raw.githubusercontent.com/usami-k/qiita-contents/main/images/git_gpg_sign_images/git_gpg_sign_pinentry.png)

保存されたパスフレーズは、macOSのキーチェーンアクセスで「GnuPG」を検索すると確認できます。

パスフレーズは、コミットごとに聞かれるわけではありません。一度入力するとgpg-agentが覚えてくれます。そのため、署名つきコミットにしたからといって、コミットの手間がそれほど増えるわけではありません。

なお、すべてのコミットを署名つきにするのではなく特定のコミットだけ署名つきにするには、上記の設定をせずにおき、コミット時に `git commit -S` と `-S` オプションをつけます。しかし、通常はすべてのコミットを署名つきにするのが良いでしょう。


# まとめ

以上で、Gitのコミットに署名し、GitHub上で「Verified」バッジが表示されるよう設定できました。

ここではmacOSでの方法を紹介しましたが、それ以外のOSについてはGitHubのドキュメントか別の記事を参照してください。

# 参考文献

- [コミット署名の検証を管理する - GitHub Docs](https://docs.github.com/ja/authentication/managing-commit-signature-verification)
- [🔰【Win/Mac】Gitコミットに署名を付けよう！✍ - Qiita](https://qiita.com/heppokofrontend/items/13f269f536fdaf9226c4)
【Pug】distフォルダの生成場所を変更したい

# はじめに

Pugでdistフォルダの生成場所を変更したいときに詰まったので記事にしました。


### 対象読者
* Pugでdistフォルダの生成場所を変更したい
* .pugから.htmlへ変換する方法に
VScodeの拡張機能であるFormatter Heroを使用している方


# 今回のやりたいこと
| 通常 | やりたいこと |
|:-:|:-:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/d8b73ada-beb2-fa70-1f07-7f3b3758a0fe.png" width="値(%でも可)"> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/dc3a9700-3193-8fab-03a7-24e19bfcb0ac.png" width="値(%でも可)"> |
|pugフォルダの直下にdistフォルダが生成される | pugフォルダと同じ階層にdistフォルダを生成する|

# 手順
### 1. 設定ファイル設定を開く
以下のいずれかの方法で開く
1. Win：「Ctrl」+「,」
1. mac：「⌘」+「,」
1. VScode左下の歯車から、設定ファイルに移動する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/e7784b15-e84a-a973-839d-28a0b67303fc.png" width="50%">

### 2. " compile hero "と検索する

### 3. 適応場所を選択する
ユーザーか、ワークスペースか、

>このときに、ユーザーの設定にしていますとすべてのものに適応するみたいな感じになるのでワークスペースだけの設定にするなど臨機応変に対応するほうが良いかと思います。（参考文献）

### 3. フォルダ生成場所を変更する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/35f69e71-4b96-597d-16ec-9108b1a288db.png" width="100%">

～～～　以上　～～～

# 参考文献
https://pg-log.com/pug-compile/#toc4
#twitter #twitterapi (バージョン1.1)で取得したデータの文字化け対処( #Javascript )

本内容を利用した場合の一切の責任を私は負いません。

# バージョン
- node.js
node-v10.16.0-win-x64
- twitterモジュール
twitter-node-client@0.0.6
- Visual Studio Code(以降、VSC)
VSCode-win32-x64-1.38.1

レスポンスはUTF-8のようだが、何故か正常に認識しない。
(ファイルに出力してVSCで見た時に文字コードで表示される。)
対処は簡単で、JSONのパースと文字列化を再試行する。
レスポンスは文字列なので、それをパースし、また文字列化するということ。

具体的には下記。

```javascript
    let tmp;
    fs.writeFileSync("result0.json", ret.detail[0]);
    tmp = JSON.parse(ret.detail[0]);
    let tmp2;
    tmp2 = JSON.stringify(tmp);
    fs.writeFileSync("result1.json", tmp2);

    twitterUrl = Client.baseUrl + "/search/tweets.json" + tmp.search_metadata.next_results;
    ret = await syncDoRequest(twitterUrl);
    tmp = JSON.parse(ret.detail[0]);
    tmp2 = JSON.stringify(tmp);
    fs.writeFileSync("result2.json", tmp2);
```

ret.detail[0]の中にレスポンスのJSON文字列が入っている。
result0.jsonと再試行したresult2.jsonは論理的には同じはずだが、実際に後者は文字化けが解消されている。
【バッチ】コマンドの学習

Windowsコマンドを忘れないようにメモした記事です。

## ファイルパスの一覧を作る

① __DIR コマンドを使う方法__

```bat
C:\>DIR *.png /B /S
C:\...\A.png
C:\...\B.png
C:\...\A\A.png
C:\...\A\B.png
C:\...\B\A.png
C:\...\B\B.png
...
```

* オプションの意味
	+ `/B`:ファイル名のみ表示
	+ `/S`:サブディレクトリも処理する

② __FORFILES コマンドを使う方法__

```bat
C:\>FORFILES /M "*.png" /S /C "CMD /C ECHO @PATH"

"C:\...\A.png"
"C:\...\B.png"
"C:\...\A\A.png"
"C:\...\A\B.png"
"C:\...\B\A.png"
"C:\...\B\B.png"
...
```

* オプションの意味
	+ `/M`:ファイル名のパターン
	+ `/S`:サブディレクトリも処理する
	+ `/C "CMD /C コマンド"`:各ファイルを対象に実行するコマンドを指定する
		- @fname:ファイル名（拡張子なしの）
		- @ext:拡張子
		- @file:ファイル名（拡張子あり）
		- @path:ファイルパス（フルパス）
		- @relpath:相対パス

> * 出力の特徴
> 	+ 1行目が空行（※2行目から出力される）
> 	+ 二重引用符で囲まれる


## ディレクトリを移動する

① __CD コマンド を使う方法__

② __PUSHD/POPD コマンド を使う方法__

> * 知ったこと
>   + ディレクトリを移動 = CDコマンドだと思っていたが、PUSHD/POPDを使う方法もある


## 名前が2種類あるコマンド

① __DEL/ERASE コマンド__

* ファイルを削除する

② __RD/RMDIR コマンド__

* ディレクトリを削除する

③ __MD/MKDIR コマンド__

* ディレクトリを作成する

④ __CD/CHDIR コマンド__

* ディレクトリを移動する

⑤ __REN/RENAME コマンド__

* ファイル/ディレクトリの名前を変更する


## 似ているコマンド

① __CHOICE__ と __PAUSE__

② __MORE__ と __TYPE__


## ZIP形式やLZH形式よりも高圧縮率!?

① __MAKECAB コマンド__

* CAB（キャブ）形式で圧縮する
	+ CAB形式とは、マイクロソフト社独自の圧縮形式
	+ デジタル署名を付与することも出来る
	+ 解凍には __EXPAND コマンド__ を使用する


## コマンド プロンプトをカスタマイズする

① __PROMPT コマンド__

```bat
C:\>PROMPT $G
>
```

* プロンプトを`>`に変更する

② __TITLE コマンド__

```bat
C:\>TITLE hoge
```

* コンソールのタイトルを変更する

③ __COLOR コマンド__

* コンソールの色を変更する

④ __CLS コマンド__

* コンソールをクリアする


## Grepみたいなコマンドがある

① __WHERE__


## ファイルセットに複数のファイルを指定する

バッチファイル

```bat
@echo off
for %%f in (input.txt input2.txt *.png) do (echo %%f)
pause
```

出力

```bat
input.txt
input2.txt
sample.png
sample2.png
sample3.png
...
```

* バッチファイルの場合、変数名は%%にする
* 複数ファイルを指定する場合は、スペースで区切る

> * delimsとeolのデフォルト値
>   + delims:半角スペースとタブ
>   + eol:;（セミコロン）


## 参考にしたサイト

* [Windowsコマンド虎の巻](<https://windows.command-ref.com/>)
    + Windowsの主要コマンドの一覧リファレンスです。
【Laravel】データベーステストで本番用データベースを汚さない方法。

データベーステストのやり方がわからなかったので、アウトプット。


1.Mysqlに入りデータベースを作成


2.`phpunit.xml`を開いて、`APP_ENV`の値を`testing`に変更。こうすることで.envファイルに本番用の`mysql`があってもテストではこっちが使用される.
3.テスト作成コマンド
 ```
php artisan make:test [テストケースクラス名] --unit
```

`RefreshDatabaseトレイト`とは
テストごとにデータベースをリセットしてくれる便利なトレイト。
* マイグレーションを実行しなくても、勝手にテスト実行の際実行してくれる。
* テスト終了したら削除してくれる(カラムだけ削除される。テーブルは削除されない)
* `use RefreshDatabase;`をすることでつかうことができる。↓

```
<env name="Hoge_DATABASE" value="test_hoge"/>



use Illuminate\Foundation\Testing\RefreshDatabase;

class hogeControllerTest extends TestCase
{
    use RefreshDatabase;
    //データベースを自動でマイグレーションしてくれる
```
  `.env`をコピーして、`.env.testing`を作成。
* これは書かないと本番用のDBのデータが消える可能性がある。
`cp .env .env.testing　`
`APP_KEY=`
の部分を空白にしてからファイルをコピー
* `APP_ENV=local`から`APP_ENV=testing`に変更
* `DB_DATABASE=`これをつくったDBの名前に変更

* テスト用データベースに本番データベースを反映


```
php artisan migrate --env=testing
```
* キーをジェネレート
```
$php artisan key:generate --env=testing
```
あとはテスト書くだけ。

参考サイト

https://qiita.com/yyy752/items/2252b26a2b1e03943ac2

https://qiita.com/mitashun/items/8b200c0b8c7080471ff6

https://qiita.com/akkino_D-En/items/024661836b7570d78704
#twitter #twitterapi のバージョン1.1でのページネーション(次ページ、ページング)の方法( #Javascript )

本内容を利用した場合の一切の責任を私は負いません。

具体的に書かれたのを見つけられなかったので。

v1.1の場合、下記にある通り1クエリーではなく集合になっている。
https://developer.twitter.com/en/docs/twitter-api/tweets/search/migrate
具体的には、下記のようなレスポンスのJSONにあるnext_resultsというプロパティの値になる。

```
    "search_metadata": {
        "completed_in": 0.042,
        "max_id": 1555659918312710100,
        "max_id_str": "1555659918312710153",
        "next_results": "?max_id=1555512290128330752&q=%23ultimaonline&count=5&include_entities=1&result_type=recent",
        "query": "%23ultimaonline",
        "refresh_url": "?since_id=1555659918312710153&q=%23ultimaonline&result_type=recent&include_entities=1",
        "count": 5,
        "since_id": 0,
        "since_id_str": "0"
    }
```

(公式の下記の中にもプロパティがあるのがわかる。
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/api-reference/get-search-tweets)
この値をそっくり次のリクエストのクエリーに使えば次ページのレスポンスが得られる。

例えば、下記のリクエストをし、

```
https://api.twitter.com/1.1/search/tweets.json?q=%23ultimaonline&result_type=recent&count=5&include_entities=true
```

下記のレスポンスなら、

```
略
    "search_metadata": {
        "completed_in": 0.044,
        "max_id": 1555783830627225600,
        "max_id_str": "1555783830627225601",
        "next_results": "?max_id=1555551735057465343&q=%23ultimaonline&count=5&include_entities=1&result_type=recent",
        "query": "%23ultimaonline",
        "refresh_url": "?since_id=1555783830627225601&q=%23ultimaonline&result_type=recent&include_entities=1",
        "count": 5,
        "since_id": 0,
        "since_id_str": "0"
    }
}
```

次ページのリクエストは下記となる。

```
https://api.twitter.com/1.1/search/tweets.json?max_id=1555551735057465343&q=%23ultimaonline&count=5&include_entities=1&result_type=recent
```
HTMLの基礎知識（新規投稿：星評価平均）

Step1:詳細ページの平均（Controller）
自分は2つのカラムしか追加していないので、自分のカラム数に合わせてコントローラーを編集

![スクリーンショット (71).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738887/f26fff0a-6a63-f453-b20d-75f435d1c582.png)



```ruby:controller.rb
def show
       @register = Register.find(params[:id])
      /追加部分
       @regi=@register.overall
       @regi2=@register.level
       @total=@regi+@regi2
       @to=@total/2
      /ここまで
end
```


Step2:詳細ページの平均（View）

```ruby:show.html.erb
<h2>平均：
<span class="star-rating">
   <span class="star-rating-front" style="width: <%= getPercent(@to) %>%;">★★★★★</span>
   <span class="star-rating-back">★★★★★</span>
</span>
</h2>
```

Step3:一覧ページの平均（View）
一覧は詳細ページとは違いViewで変数を組みます！

```ruby:index.html.erb
<h2>平均レベル：
<span class="star-rating">
   <span class="star-rating-front" style="width: <%= getPercent((t.level+t.overall)/2)%>%;">★★★★★</span>
   <span class="star-rating-back">★★★★★</span>
</span>
</h2>
```

以上になります！！
GigaDevice社製MCUをVSCodeでビルドする

# GigaDeviceとは
ST MicroのSTM32を使ったことのある方は多いのではないでしょうか．しかしながら，昨今の半導体不足は深刻でSTM32を入手する事は絶望的と言っても良いような状況となっています．そこで選択肢となるMCUとしてGigaDeviceが挙がることがあります．
GigaDevice製のデバイス型番は"GD32F103"など，ST Microの型番を強烈に意識して採番されています．型番のとおり，GD32F103であればSTM32F103と基本的にはピン互換となるように設計されています．
（メモリマップやペリフェラルの扱いは異なるのでバイナリ互換ではありません．あくまでピン互換，フットプリント互換になります．STM32とバイナリ互換なMCUも世の中には存在します…がどこまで信用できるのかが不明です）
STM32を扱うつもりでGD32の開発を始めるとなかなか癖の強いペリフェラルやライブラリに苦戦しますが，背に腹は代えられないですね．

# 開発環境は？
GigaDeviceを含む中国や台湾系のArm MCUの開発環境は，MDK-ARM(Keil uVision)を想定したライブラリやテンプレートプロジェクトが提供されていることが多いです．GigaDeviceは一部MCUについてはGCC用のライブラリも公開していますが，断片的であったりします．
MDK-ARMのライセンスを持っていれば良いですが，それなりの価格であるため，小規模事業者や趣味的に扱おうと思うと二の足を踏んでしまうのではないでしょうか．(試用版ライセンスでも非営利かつ32kBまでのバイナリであればビルド可能です)

# VSCodeを使いたい
無償でありながらコード補完が強力なので，どうしてもな理由が無ければエディタはVSCode，コンパイラはGCCを使いたいです．
都合の良いことに拡張機能のPlatform IOを使うことで簡単に開発環境を用意することができるようになりました．チップによってはArduinoライブラリのポーティングが済んでいるものもありますが，枯れていないので基本的には Standard Peripheral Library (SPL) での開発をおすすめします．

# 導入
VSCodeの拡張機能からPlatformIOを検索してインストールします．この画面上でインストールが完了した後も準備が完了し，実際に使えるようになるまでには場合によって更に数分必要です．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/4f98f389-1ef4-1a15-48f9-fd5afefd058a.png)
ここでターミナルを眺めているとFailed to install PlatformIO IDE.と表示されることがあります．その場合はこのあたりを参考にすると良いでしょう．https://github.com/platformio/platformio-core-installer/issues/221

# PlatformIOにCommunityGD32Coresをインストールする
PlatformIOのCLIコンソールを開き，pio platform install https://github.com/CommunityGD32Cores/platform-gd32.git と入力します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/9d227947-a383-a8df-582b-ba7b6daa1dd9.png)
これによってPlatformIOにGD32用のArduinoライブラリとSPLが導入され，GCCでビルド可能になります．

# プロジェクトを作る
PlatformIO のHomeから新しいプロジェクトを作ります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/56e310ef-79e4-eb14-ec8b-6c3900393909.png)
任意のチップ/ボードを選んでライブラリを選択します．ここで使用するライブラリをArduinoかSPL(Standard Peripheral Library)から選ぶことができます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/fb43d692-8d13-e13e-9775-794f86c497fd.png)
インストールされたライブラリは，C:\Users\<user-name>\.platformio\packages\framework-spl-gd32 以下に展開されます．ここから必要なヘッダファイルをincludeするなりしてコードを書いていきます．例としてLチカをするとこんな感じですね．GigaDevice提供のサンプルに則り，割り込みルーチンはgd32e23x_it.cの方へ纏めてあります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/af219a8a-831b-3524-153d-4e22b5e9b8e4.png)

# デバッガを使う
コードが書けたらデバッガで書き込み・デバッグをします．ワークスペースに生成されているplatformio.iniを編集します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995170/3f2ab3c2-802c-21cd-7d68-298a3b875b11.png)
debug_tool というプロパティを追加し，値として open-ocd や jlink を指定することでデバッグできるようになります．
カミンスキー攻撃 とは

## 勉強前イメージ

攻撃って事はわかるけどカミンスキーはわからん

## 調査

### カミンスキー攻撃 とは

ダン・カミンスキー氏が発表した脆弱性で、DNSキャッシュポイズニング攻撃の効率を向上させる手法になります。

DNSキャッシュポイズニング とはDNSのキャッシュサーバに偽の応答をキャッシュさせることで
そのキャッシュを使ったユーザを偽のサイトに誘導する攻撃手法になります。
元々キャッシュポイズニングはキャッシュサーバから権威サーバに問い合わせを行う瞬間に行われる。
TTL値によるが数十分~数時間が多く、タイミングが少ないです。

その為、権威サーバに問い合わせを行う頻度を増やすために
わざと同ドメイン内に存在しないホスト名の問い合わせを行って権威サーバへ問い合わせるように仕向けます。
DNSキャッシュポイズニングでは難しかった連絡したDNSキャッシュポイズニングを行うことができるようになりました。

### カミンスキー攻撃の対策

- DNSSECの使用

[DNSSEC](https://qiita.com/miyuki_samitani/items/0f26423cf54d7bd20c07) とはDNSの情報に電子署名を付けることで、
DNSのデータが正しい発行元のデータであることを検証することができるようにする拡張仕様です。

- DNSキャッシュサーバのポートのランダム化(ソースポートランダマイゼーション)

カミンスキー攻撃では問い合わせのUDPポートが固定の場合は数秒で成功すると言われています。
その為、DNSのポートをランダム化できるようにすることでDNSキャッシュポイズニングやカミンスキー攻撃での偽の応答を取り入れづらくします。

## 勉強後イメージ

キャッシュポイズニングの進化系？
逆にキャッシュポイズニングってめっちゃタイミング合わせてやってた感じなのかな・・・・

## 参考

- [効率的なDNSキャッシュ・ポイズニング？カミンスキー攻撃とは](https://www.lrm.jp/security_magazine/about_kaminsky-attack/)
- [カミンスキー攻撃 【Kaminsky attack】](https://e-words.jp/w/%E3%82%AB%E3%83%9F%E3%83%B3%E3%82%B9%E3%82%AD%E3%83%BC%E6%94%BB%E6%92%83.html)
AWS認定ソリューションアーキテクトプロフェッショナルを２年半ぶりに更新したので勉強方法まとめる

AWS認定ソリューションアーキテクトプロフェッショナルを更新したので、勉強方法を備忘がてら書いていこうと思います。
学習した際のメモは別途公開しますね。

# 前提
AWSメインのクラウド基盤のエンジニア。最近Top Engineers(Service)、ALL Certificate Engineersに認定されました。
AWSはSAP on AWS以外の資格取得済み、Azure Solution Architect Expert取得済み。
Google Cloud Professional Cloud Architect取得済み。

勉強期間:１ヶ月くらい

# 問題の解き方
これはどの試験にも共通するのですが、サンプル問題や問題集などをみるとわかるのですが、問題文に書いてあるキーワードから、最も適切な選択肢を選ぶことが要求されます。
例えば、「コストを最重視する」、「可用性が重要」、「運用が楽なもの」等々
どれも実現できそうな選択肢の中から、問題で求められる選択肢を素早く選びます。キーとなる言葉をしっかり押さえることが大事です。

# 試験までに何をやるか
## 試験ガイドを読む
[試験ガイド](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-pro/AWS-Certified-Solutions-Architect-Professional_Exam-Guide.pdf)

出題される分野、配分をしっかり読みましょう。
ここに書いてあるものを中心に記憶に怪しいサービスがあれば深堀りします。
2年半ぶりなので、サービス内容のアップデートなども気にしました。

## サンプル問題を解く
[サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-pro/AWS-Certified-Solutions-Architect-Professional_Sample-Questions.pdf)

２年半前と変わった？もはや記憶にないので覚えていませんが、長文問題の記憶を呼び覚まします。
だいたいこの時点で７割くらいは解けそうだなぁという感覚。間違えた問題を中心に苦手な部分をさらに深堀りします。

## オンライトレーニングを受ける
最近日本語に対応してきている、トレーニング。
結構あっさりした内容ですが、復習にはちょうどよいですね。
サンプル問題もでるので、間違えた部分をちょっと深堀りします。

https://explore.skillbuilder.aws/learn/course/external/view/elearning/34/exam-readiness-aws-certified-solutions-architect-professional?sap=sec&sec=prep


## 問題集を解く
以下3つを２周解きました。大体６，７割は普通に解けるなぁ、１，２割は知ってたけど考え方がちょっと違うなってレベル。
間違えた問題のみ、復習と深堀を実施しました。

https://aws.koiwaclub.com/

https://www.udemy.com/course/aws-53225/

https://www.udemy.com/course/aws-certified-solutions-architect-professional-aws-practice-exams/

## 模擬試験を解く

https://aws.amazon.com/jp/certification/certified-solutions-architect-professional/#:~:text=AWS%20Certified%20Solutions%20Architect%20%2D%20Professional%20%E5%85%AC%E5%BC%8F%E7%B7%B4%E7%BF%92%E5%95%8F%E9%A1%8C%E9%9B%86

答えも解説もつくようになった練習問題です。
スラスラ解けることを確認したら残りは試験の申込みだけです。


# 試験の感想

https://qiita.com/Regryp/items/0645fb976655262e9229

2年半前に上記記事を書いた際はすごい難しかった記憶があったのですが、
実際に受けてみると意外とスルスル解ける・・・・　試験や業務で身につけた知識が結構役に立っているのかなと思いちょっと嬉しかったです。ただ、やはり７５問は多し・・・　５０問を超えた時点でちょっと疲れがでてきましたが、なんとか集中力をたもつことができました。

# 試験結果
合格
スコア８７５
うーん、９００点台とりたかったなーという感覚。まぁそこそこでしょう。

# まとめ
各種資格の維持が今後の悩みの種ですが、これがあるからこそ、知識のアップデートが進むのかもしれません。
アップデートを追う、新しいサービスに触れてみるなど、日頃の継続したインプットとアウトプットの重要さを改めて感じました。これからも精進します！
array.map(d3.csvParse) と書くとエラー発生 (d3.js)

こんにちは。
```array.map(d3.csvParse)```と書こうとしましたが、```array.map(dat=>d3.csvParse(dat))```と書く必要がありました。さもないとエラーとなりました。d3.v7 です。


```javascript
console.log(["foo,bar\n1,2", "foo,bar\n1,2"].map(dat=>d3.csvParse(dat)));
```

```
[[{foo: "1", bar: "2"}, columns: ["foo", "bar"]], [{foo: "1", bar: "2"}, columns: ["foo", "bar"]]]
```

* ただし、要素が一つの場合には、エラー発生しませんでした

```javascript
console.log(["foo,bar\n1,2"].map(d3.csvParse));
```

```
[[{foo: "1", bar: "2"}, columns: ["foo", "bar"]]]
```
AtCoder B,C問題をKotlinで解こう - ABC262

当記事ではAtCoder、ABCのB問題ならびにC問題（時々D問題も）のKotlinでの解法を超初心者向けに詳細に解説します。

https://atcoder.jp/contests/abc262/tasks

## [B - Triangle (Easier)](https://atcoder.jp/contests/abc262/tasks/abc262_b)
#### やりたいこと
頂点の数は最大で100と多くはない。A<B<Cが成立する全ての頂点の組み合わせに対して
* A,B間に辺が存在する
* B,C間に辺が存在する
* A,C間に辺が存在する

以上の3条件を満たすかどうかをチェックし、計上していこう。
#### 入力値の取得
辺の情報は、辺が結ぶ2点をインデックスとして使用するBool型の2次元配列を作って管理しよう。
```kotlin
    // 入力値の取得
    val (n, m) = readLine()!!.split(" ").map { it.toInt() }
    // 辺の情報を保持する配列
    val path = Array(n + 1) { BooleanArray(n + 1) }
    // 辺の情報の取得
    (1..m).map {
        val (u, v) = readLine()!!.split(" ").map { it.toInt() }
        path[u][v] = true
    }
```
#### サンプルコード
```kotlin:main.kt
fun main(args: Array<String>) {
    // 入力値の取得
    val (n, m) = readLine()!!.split(" ").map { it.toInt() }
    // 辺の情報を保持する配列
    val path = Array(n + 1) { BooleanArray(n + 1) }
    // 辺の情報の取得
    (1..m).map {
        val (u, v) = readLine()!!.split(" ").map { it.toInt() }
        path[u][v] = true
    }

    var ans = 0
    for (a in (1..n - 2)) {
        for (b in (a + 1..n - 1)) {
            if (!path[a][b]) {
                // 頂点(a,b)間に辺が無い場合
                continue
            }
            // a,b,c間それぞれに辺のあるものを計上する
            ans += (b + 1..n).count { c -> path[b][c] && path[a][c] }
        }
    }
    println(ans)
}
```
## [C - Min Max Pair](https://atcoder.jp/contests/abc262/tasks/abc262_c)
#### やりたいこと
条件を満たすペアは以下の２パターンとなる。
+ 共に要素の値と要素のインデックス値が一致している。
+ 要素の値と要素のインデックス値が入れ替わっている。

前者は値とインデックス値が一致している要素の数を仮にmとすれば $m*(m-1)/2$ で求められる。
後者は入力で与えられた要素を順に処理し、現在処理中の要素(a1)の値のインデックス値の要素（a2)の値がa1のインデックス値と一致しているかどうかを判定すれば良い。

#### 入力値の取得
```kotlin
    // 入力値の取得
    val n = readLine()!!.toInt()
    val a = readLine()!!.split(" ").map { it.toInt() - 1 }
```

#### 条件を満たすペアの計上
数列aを順に処理していき、後者のケースで$(a_i,a_j)$のペアが条件を満たすときiを処理している時とjを処理している時で二重に計上されないよう対策しよう。
```kotlin
    var ans = 0L
    for (i in a.indices) {
        if (i == a[i]) {
            // 要素のインデックス値と値が一致している場合
            indexAndValueMatch++
        } else if (a[i] > i) {
            // 二重に形状されることを防ぐため、要素の値がインデックス値よりも大きいものに限定して処理する。
            if (a[a[i]] == i) {
                // 要素(a1)の値をインデックス値としてもつ要素(a2)の値がa1のインデックス値と一致しているかを判定
                ans++
            }
        }
    }
    ans += indexAndValueMatch.let { it.toLong() * (it - 1) / 2 }

```

#### サンプルコード
```kotlin:main.kt
fun main(args: Array<String>) {
    // 入力値の取得
    val n = readLine()!!.toInt()
    val a = readLine()!!.split(" ").map { it.toInt() - 1 }

    // 要素のインデックスと値が一致しているものの数
    var indexAndValueMatch = 0

    var ans = 0L
    for (i in a.indices) {
        if (i == a[i]) {
            // 要素のインデックス値と値が一致している場合
            indexAndValueMatch++
        } else if (a[i] > i) {
            // 二重に形状されることを防ぐため、要素の値がインデックス値よりも大きいものに限定して処理する。
            if (a[a[i]] == i) {
                // 要素(a1)の値をインデックス値としてもつ要素(a2)の値がa1のインデックス値と一致しているかを判定
                ans++
            }
        }
    }
    ans += indexAndValueMatch.let { it.toLong() * (it - 1) / 2 }
    println(ans)
}
```
（初心者向け）サーバーとは

# サーバーとは
サーバーとはデータや情報などの**コンテンツを提供するコンピューター**のこと。
## 対義語はクライアント
提供するというサーバーに対して、「要求する存在」を**クライアント**と言う。サーバーに対してコンテンツを要求し受け取る側をまとめてクライアントと呼ぶ。
#サーバーの具体例
サーバーには様々な種類が存在する
* DNSサーバー
* ウェブサーバー
* メールサーバー
* ファイルサーバー

# サーバーにとって重要なこと
サーバーは多くの人にコンテンツを提供しているので、同時に多くの要求を受けることもある。
障害が起きれば、影響範囲が広いのも特徴。例えばウェブサーバーに障害が起きると、多くの人がウェブサイトを見れなくなってしまう。
よって、
* 同時に多くのクライアントから要求があっても稼働できること
* 24時間365日、稼働し続けられること
* データの保護やバックアップがしっかりしていること

サーバーとなるコンピュータは安定性や耐久性が高まること、セキュリティやバックアップ体制・仕組みが構築されていることは必要

# 普通のコンピューターとサーバーコンピューターの違い
どちらも**CPUやメモリ、HDDなどから構成されている点は同じ**
しかし、用途が違うためハードウェアに求められる特徴も異なる

サーバーは同時に多くの人がアクセスするので、同時に大量のアクセスを捌ける**サーバー用のCPU**が用いられることが多い。
災害や外部からの衝撃にも耐えられるように強固な箱が求められる
また部品も耐久性が高いものが好ましい。
「冗長化」というバックアップを備えた電源や、データを分散することで速やかなリカバリーを可能にする**RAID**機能も必要になる
# 物理サーバーと仮想サーバー
## 物理サーバー
* 専用サーバー（ベアメタルサーバー）
一台の物理サーバーを自社だけで使うこと
* レンタルサーバー（共有サーバー）
一台の物理サーバーを複数名でシェアをして使う
## 仮想サーバー
* VPS(Virtual Private Server)
1台のサーバーをシェアするものの、仮想技術を使って複数のOSを動かし「それぞれのための環境」を構築する
* クラウド（IaaS）
VPSが1台の物理サーバー上に複数の「それぞれのための環境」を用意しているのに対し、クラウドは複数台の物理サーバーの「それぞれのための環境」を構築しています。そのため必要な分のCPUやメモリを自由に追加できるという特徴がある
GCPのSource Repositoriesを使うためのSSHの設定

GCPのSource Repositoriesを使うためのSSHの設定の流れです
パソコン側はWSL2を例にしてます
```
ssh-keygen
```
パスワードを聞かれるので好きなものを入力。
./sshにid_rsa(秘密鍵)、id_rsa.pub(公開鍵)が生成される。
```
cat id_rsa.pub
```
でid_rsa.pub(公開鍵)の中身を表示し、中身をコピーしておく。

gcpログインする。

Source Repositoriesの画面で右上のメニューからManage SSH Keysを選択。
右上にあるRegister SSH keyボタンを押す。
入力フィールドがあるので、てきとうな名前を入力し、公開鍵をペースト。
```
git clone -b develop/master ssh://<アカウント>source.developers.google.com:2022/p/<プロジェクト名>/r/<リポジトリ名>
```
例えば上記のようにWSL2でgitコマンドを入力すると接続しますか？と聞かれるのでyes。
鍵生成時のパスワードを入力。
クリックでリンクをコピー 【HTML・CSS・JavaScript】

完成形はこちら↓

![ezgif.com-gif-maker (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602337/31cb7f25-984d-f76b-e090-5bb744103455.gif)
※アイコンはfontawesome v5を使用しています。

```html:html
<div class="text-link">
 <div class="copy-link">
    <input type="text" class="link" value="ここにURLを入れてね">
    <button type="button">
      <i class="fas fa-clone"></i>
    </button>
   </div>
</div>
```

```scss:scss
.copy-link {
  position: relative;
  padding: 10px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 10px;
  display: flex;

  input {
    padding: 10px;
    font-size: 18px;
    color: #555;
    border: none;
    outline: none;
    width: 100%;
  }

  button {
    padding: 10px;
    background: var(--main-color-dark);
    font-size: 18px;
    color: #fff;
    outline: none;
    border: none;
    border-radius: 10px;
    cursor: pointer;

    &:active {
      background: var(--main-color-light);
    }

    &::before {
      content: "Copied!";
      position: absolute;
      top: -50px;
      right: 0px;
      background: var(--main-color-dark);
      border-radius: 20px;
      padding: 9px 10px;
      font-size: 14px;
      display: none;
    }

    &::after {
      content: "";
      position: absolute;
      top: -20px;
      right: 25px;
      width: 10px;
      height: 10px;
      background: var(--main-color-dark);
      transform: rotate(45deg);
      display: none;
    }
  }

  &.active button::after,
  &.active button::before {
    display: block;
  }
}
```

```javascript:JavaScript

let copyText = document.querySelector(".copy-link");

copyText.querySelector("button").addEventListener("click", function() {
//アイコンをクリックしたら、下記を実行
 let input = copyText.querySelector("input.link");
 input.select(); //select()メソッドはinput or textareaのテキストを選択します
 document.execCommand("copy") //document.execCommand("copy")は任意の値をクリップボードにコピーするJSのコマンド
 copyText.classList.add("active"); //activeクラスを付与し、吹き出しを表示させます
 window.getSelection().removeAllRanges(); //range(範囲)を削除します

 setTimeout(function() {
  copyText.classList.remove("active");
 }, 2500)  //2.5秒後に吹き出しを非表示にします
})
 ```

selection・rangeについては下記の記事に詳しく説明されています
　▶︎ https://ja.javascript.info/selection-range