OmniAICreator/Qiita-1.07M huggingface dataset:
QRコードの８種類のマスクを図示する

#参考（別投稿）
１ファイルのHTML(+JavaScript)で、QRcodeを生成する
https://qiita.com/santarou6/items/db17788158dba38f3a5c
- - -


#＜本編＞QRコードの８種類のマスクを図示する

#例
本例は、一辺５７マスの、型番１０

#色凡例
マスク相当は白と黒。
（青と黄は、位置検出パターンや位置合わせパターン等でマスク化されない部分である。詳細、JIS規格 X0510 7.8マスク処理を参照。）

*規格では、横方向がj(列位置)で、縦方向がi(行位置)
*左上が原点（０，０）ゼロ始まり

#８種類について
000 → (i+j) mod 2 = 0
001 → i mod 2 = 0
010 → j mod 3 = 0
011 → (i+j) mod 3 = 0
100 → (( i div 2)+(j div 3)) mod 2 = 0
101 → (ij) mod 2 + (ij) mod 3 = 0
110 → ((ij) mod 2 +(ij) mod 3) mod 2 = 0
111 → ((ij)mod 3 + (i+j) mod 2) mod 2 = 0

#各マスク

##000 → (i+j) mod 2 = 0
![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/3ab38469-d5d1-cfe6-6ed2-c26de2ae4b78.png)


##001 → i mod 2 = 0
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/861b9491-4d5a-f01a-8b07-4c07db1f0bda.png)


##010 → j mod 3 = 0
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/15ad0b23-5f5c-7f57-e72c-2ec29e684761.png)


##011 → (i+j) mod 3 = 0
![011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/68831522-f07b-f4ee-69cb-a457f3f68662.png)


##100 → (( i div 2)+(j div 3)) mod 2 = 0
![100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/1ed67159-02f7-7553-4fbc-115592d885ca.png)


##101 → (ij) mod 2 + (ij) mod 3 = 0
![101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/0e8d4d09-3056-8c85-201a-282460ddadf0.png)


##110 → ((ij) mod 2 +(ij) mod 3) mod 2 = 0
![110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/ffe64d47-1037-666e-52a6-3e7d15a83422.png)


##111 → ((ij)mod 3 + (i+j) mod 2) mod 2 = 0
![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/4f19ee78-1f4c-a81f-fac3-f057aae7057c.png)

#ソースコード(HTML/JavaScript)

https://github.com/santarou6/QRcode_javascript/blob/main/t_c99-mask.html
https://github.com/santarou6/QRcode_javascript/blob/main/index_c99-mask.js

#QRコードにおけるマスクの指定

上記３ビットのマスク種類だが、QRコードの以下（赤マス）の位置に指定してある。（より正しくは、101とXORとった値。）マスクを外せば、QRコードは、通常の文字コードがビット化されて並んでいるだけなので、読もうと思えば人力でも読める（はず）。

![マスク位置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/ad1b5cc1-ef22-e175-83da-93211babc9dd.png)

横方向は、左から０→１→２ビット。縦方向は、下から０→１→２ビット。（同じものが２か所に記載ある。）
[TIPS]Amazon S3とは？

# Amazon S3とは

AWS(Amazon Web Services)の中のサービスの1つ、Amazon Simple Storage Serviceのことを指します。Sが3つだからS3ですね。
**名前の通りクラウド型のストレージ機能を提供するサービ**スとなります。ただ、単なるストレージとしての機能だけではなく、**バージョン管理やイベント機能もある**みたいです。

容量は無制限で、1GB使用する毎に料金が加算されていきます。つまりストレージにファイルを入れた分だけ課金されます。
記事執筆時点での料金は1GBあたり0.025ドル（東京リージョン、スタンダードストレージ）となっています。安い。

<img width="1761" alt="image.png (201.2 kB)" src="https://img.esa.io/uploads/production/attachments/10908/2020/11/20/72406/a7ccd31b-b40f-45e9-a2bb-cdd22f71e7da.png">


ウェブのどこからでもデータ格納と取得が可能のようです。データは動画や画像ファイルなど殆どのデータを預けることが可能で、ファイルそのものへのセキュリティも担保されています。各地にある物理的なデータセンターに分散して保存をしているので、障害にも強いようです。

他のAWSサービスとの連携も容易にできるので、AWS触ってる人はS3もガンガン使うのだろうと思います。

# S3の機能（さらっと確認程度）

## バージョン管理

バージョニングを有効にしておくことで、オブジェクト毎のバージョンを残すことができます。誤った操作しても元に戻すことができるsvnみたいな使い方ができそうですね。

## ライフサイクル

オブジェクト毎にライフサイクルを設定でき、「一定期間経ったら削除・低価格帯のストレージに移動」ということができるようです。Jenkinsとかで使ったら便利そう。

## ログ記録

svnみたいな感じだと思うんですが、ログを残せるみたいです。

## イベント

オブジェクトに操作が行われた場合にイベントを発火させる機能があるみたいです。ここで言うイベントは多分データ分析とかですかね。

## アクセス権限

デフォルトでは全オブジェクトのアクセス権がプライベートになっており、所有者＋管理者以外はアクセスできません。ここに認証したユーザーのみ操作を許可するなど、細かく設定することができます。

## 暗号化

オブジェクトをS3に保存すると、データを暗号化しておくことができます。 サーバーサイド、クライアントサイド、それぞれの暗号化に対応しているらしいです。

## オブジェクトへのアクセスツール

WindowsならWinSCP、MacならCyberDuckが良さそう？

# Unityでの活用方法

以下のスライドが参考になりそう
https://www.slideshare.net/UnityTechnologiesJapan002/unite-tokyo-2019aws-for-unity-developers

ゲーム内写真をアップロードしてサーバー側でサムネイル画像の作成が行われたり。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/312894b5-a8b7-14c2-22e3-da9cbcb56a6c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/52124bae-b6eb-d173-c2a3-c61a3771d73f.png)

以下の記事も。

[UnityからAmazon S3にファイルをアップロードし、公開状態にする](https://qiita.com/arumani/items/a0fd345dd224fb5d05db)

# 参考

- [Amazon S3（公式）](https://aws.amazon.com/jp/s3/)
- [【エンジニア向け】よく聞くAmazon S3とは｜ただのストレージじゃないの？](https://service.plan-b.co.jp/blog/creative/4981/)
- [Amazon S3とは？使用メリットや具体的な使い方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/22676)
- [Amazon S3をどう使うか-容量無制限の優れたストレージサービス](https://business.ntt-east.co.jp/content/cloudsolution/column-43.html)
KubernetesでデプロイしているPodをImage化する方法

kubectl get pod でPod名を確認します。

```
$ kubectl get pod
NAME                                         READY   STATUS    RESTARTS   AGE
oai                                         1/1     Running   0          28d
```

docker ps でNameからk8s_Pod名 というものを探し出し、それのコンテナのIDを確認します。
 
```
$ docker ps
CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS              PORTS               NAMES
6753a38ecfc9        791c227dd604                          "sleep infinity"         4 weeks ago         Up 4 weeks                              k8s_oai
```

commitをして、イメージ化します。

```
$ docker commit 6753a38ecfc9 output_name
```

docker images でイメージ化されたimageを確認します。

```
$ docker image
REPOSITORY   TAG   IMAGE ID  CREATED  SIZE
output_name  ***   ***       ***      ***
```
コマンドラインから大量のpngとjpgを圧縮する

ウェブサイトで画像を使用する時に、
サイズの重い画像を軽量化することはよくあると思います。

## TinyPNG
https://tinypng.com/

でも、このwebサービスでは以下のような問題がありました、

・web版だとアップロードした画像の行方（データを抜き取られてる可能性もなきにしもあらず）
・無料版だと、１ファイルづつアップロードするのが面倒
・大量のファイルをディレクトリを維持したまま一括で処理したい。

という思いがありました。
<hr>

一番良いのは、**ツールを買ってしまうこと**です。
ケチってもいいことはありません。
金で解決出来るものはどんどんしてしまいましょう！

ただ、エンジニアの端くれということもあり、
これからもそこそこ使いそうな処理なので、PC内で自分で自動化してしまおうということで、調べてみました。

調べたところ、以下のライブラリを使うのが良さそうです。

# ライブラリ
## pngquant (png用)
https://pngquant.org/
(tinypngの内部処理にも使われているらしい)

### インストール
````
brew install pngquant
````

### 使い方 (他にもオプション有り)
````
pngquant --ext .png --force -v .test.png (圧縮 / 出力ファイル名そのまま / 強制上書)
pngquant --ext .png --force -v *.png (圧縮 / 出力ファイル名そのまま / 強制上書 / カレントのjpg全部)
````

## jpegoptim (jpg用)
https://github.com/tjko/jpegoptim

### インストール
````
brew install jpegoptim
````

### 使い方 (他にもオプション有り)
````
jpegoptim test.jpg (圧縮)
jpegoptim test.jpg test2.jpg (圧縮 / 複数)
jpegoptim --strip-all test.jpg (圧縮/メタ全部消す)
jpegoptim --strip-all --max=90 test.jpg (圧縮 /90% / メタ全部消す)
jpegoptim --strip-all --max=90 *.jpg (圧縮 /90% / メタ全部消す / カレントのjpg全部)
````

# 使いやすいようにカスタマイズ

ここまでの情報はネット上にたくさん出てくるのですが、

**再帰ディレクトリ的に処理をする**

という方法がなかなかうまくいきませんでした。

例えば、


````
pngquant --ext .png --force -v img/*/*.png
````
img/aaa.png → NG
img/hoge/bbb.png → OK

この書き方だと、部分的に無視されてしまいます。
<hr>

````
pngquant --ext .png --force -v img/*.png img/*/*.png img/*/*/*.png
````
img/aaa.png → OK
img/hoge/bbb.png → OK
img/hoge/huga/ccc.png → OK

この書き方だと、一見良さそうですが、もっと階層がある場合にカバーできません。
そして、特定のパターンの階層にファイルが無いとエラーになってしまいました。
<hr>

色々調べた結果が、こちら。

https://stackoverflow.com/questions/9647920/recursively-batch-process-files-with-pngquant

````
find . -name '*.png' -exec pngquant --ext .png --force -v {} \;
````

**xargs**の方が速いらしい
https://qiita.com/legitwhiz/items/e609537fb6226081f5b5

````
find . -name '*.png' | xargs pngquant --ext .png --force -v
````

# npm scriptsに使いやすいようにまとめておく

これで、pngとjpgがディレクトリそのままで圧縮される。
大量のファイルだと止まるかもしれない（未検証）。

```
  "scripts": {
    "optim": "npm run optim:png && npm run optim:jpg",
    "optim:png": "find . -name '*.png' | xargs pngquant --ext .png --force -v",
    "optim:jpg": "find . -name '*.jpg' | xargs jpegoptim --strip-all --max=90",
  },
```
インフラSE2年目｜ITパスポート独学で合格した勉強法。


#はじめに
こんにちは。しばらく投稿をしていませんでしたが久しぶりに投稿をします。
内容はとっても薄いですが、よかったら見てください。

インフラSEとしてもうすぐ3年目になりますが、やっとITパスポート試験をこの間
受験しました！！

今回は、受験までにした勉強法について書きたいと思います。

#勉強期間について
受験申込をしてから受験日までは約1か月ありました。
1か月間の勉強で合格することができました！

仕事で使っている用語は知っていたので、勉強しやすかった等ありますが
理解が遅い私でも1か月で合格することができた資格なので1週間で合格できる方も
結構いると思います。汗

#参考書
まず、参考書についてです。

私は「<font color="DeepSkyBlue">キタミ式イラストIT塾ITパスポート</font>」を使用しました。
イラストが分かりやすくて初心者の方にもおすすめです。
おすすめしている方が多くて、ご存じの方がほとんどだと思いますが。。

この、参考書をまず通勤時間や時間が少しある時に読みました。
まずは、全部一通り読んでから次に紹介する過去問題を解き始めました。

だらだら読んで1週間もあれば読み終わると思います。

#過去問題

次に、参考書でITパスポートのイメージがつかめたら過去問題をひたすら解きます。
私は「<font color="DeepSkyBlue">過去問道場</font>」という無料でITパスポートの過去問題を解きまくることができる
サイトをつかってとにかく過去問題を解きました。

分からなかったり、見直したい問題にチェックを入れておくことができたり
問題の正解率が見れたりして、機能も無料なのにたくさんあってとても助かりました！

とにかく、この過去問道場を自身がつくまでたくさん解いて
模擬試験で90％台をとれれば合格はできると思います。


#試験当日

いよいよ試験当日！！
前日は、早めに寝ることをおすすめします。笑
私は、たしか13:00からでした。近くのカフェで最後に模擬問題を2～3回やって
軽食をとり試験に臨みました。

やっぱり悩む問題も多々ありましたが、焦らずに解いていくことで
時間内には見直しを含めて終わりました。

最後に、終了ボタンをクリックすると点数がでます。
早く点数を知れてうれしいですが、押した瞬間にでてくるのでなかなか勇気がいります。

#おわりに

今回は、本当にざっくりになってしまいましたが
1か月間なるべく隙間時間に少しでも過去問を解いたりすることで
合格できる試験なのでハードルはそんなに高くないと思います。
ぜひ、これから受験しようと思っている方に少しでも参考になったら嬉しいです。

ITパスポートに合格ができたので、次は来年の4月に基本情報技術者試験を受けたいと
思っています。
もし、合格したらまた投稿したいと思います。。。

最後まで読んでくれてありがとうございました。
コロナで、大変なことが多いですが頑張りましょう。
PostgresqlのTimezoneの設定ミスで1ヶ月もずれちゃった話

Timestamp型の集計日`sum_dt`に、「毎月1日 ００：００：００」の日時を入れて、取得時に`YYYY/MM`に変換して使用している処理があるのですが。

```
SELECT to_char(sum_dt,'YYYY/MM')::TEXT
FROM monthly_data
```

RDSのスナップショットを復元して別の環境を立ち上げたところ、なぜか取れるデータが1ヶ月ずれることに。

DBeaverで見る分にはデータ問題なさそうなのに・・・。

と思ったら、パラメータグループを指定するのを忘れていて、TimezoneがデフォルトのUTCになっていました。

`2020/11/01 00:00:00 +0900` (JST)は
`2020/10/31 15:00:00 +0000` (UTC)と同値なので、冒頭のクエリだと1ヶ月の違いになってしまっていました。

DBeaverで見る時はいい感じにJSTに変換してくれていたようです。

日時で出していれば、9時間ずれに気がついて、Timezoneの問題とすぐ気がついたと思うのですが、1ヶ月ずれていると思い込んでいて発見まで1時間かかりましたw。

そもそも時間が必要ないのにTimestamp型のカラムにするのよくないという話。
Auth0の設定ミスのエラーで困ったときにまず確認すること

Auth0は認証・認可に関するサービスやSDKを提供してくれるiDaaSです。

Auth0を利用するとクライアントの実装がシンプルになりとても便利ですが、Auth0側の設定に誤りがあった場合に、とりあえずAuth０が提供してくれるログをみたらなんとかなるよ〜というお話です。

Auth0についてはこちらをご参考ください。

Auth0の機能を調べてみた - Qiita
https://qiita.com/kai_kou/items/b3dd64e4f8f53325020e


## 設定ミスでエラーが発生: ケース1

以前投稿した記事の環境でAuth0の設定を変更してエラーが発生する状況を再現します。
Auth0のJavaScriptチュートリアルをシンプルな構成で試してみた - Qiita
https://qiita.com/kai_kou/items/51ce27a8f98a14263e26


上記の実装だと、ログイン後ブラウザをリロードしてもログイン状態が維持されず、再ログインが必要になります。
ブラウザのデベロッパーツールで確認してもエラーになっておらず、原因がよくわかりません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/261f7c8f-03ef-8a0a-cf0b-8e3d821b0b2b.png)

調査方法としてはAuth0が提供しているログ情報を確認するのが第一歩となります。
ログを確認すると、`Failed Silent Auth` でエラーが発生していることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/dc72aa05-7a99-c343-706b-e04d34221807.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/9c58e2d6-35aa-bdd7-cab4-16803d323f6f.png)

ログを参考にググると公式が運営するAuth0 Communityで情報がいくつも出てくるので解決のヒントが得られます。
Auth0 Community
https://community.auth0.com/

今回の対応としては、ブラウザリロード時にログイン状態が保持されるように、「Universal Login」の設定を`Classic` から`New` に変更して保存することで解消しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/284f7b75-44b5-eccb-3853-a3105db5133d.png)
これでブラウザリロードしてもログイン状態が保持されます。

参考)Auth0をSPAアプリケーションでブラウザをリロードすると認証情報が消えてしまうときの対処 - Qiita
https://qiita.com/reoring/items/6e2566d4a5af608cfbef


## 設定ミスでエラーが発生: ケース2

今度は、Applicationの設定がミスっている場合の挙動をみてみます。
本来「Allowed Web Origins」には`http://localhost:3000` が設定されているべきところを空にしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/70c6c661-dbb1-a01d-488c-3e027b7dec56.png)


この設定でブラウザをリロードすると、`https://xxxxxx.us.auth0.com/authorize` で400エラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/8f97e7d8-ac63-e855-1a71-fafab904d54b.png)

エラーとなったURLをブラウザで表示してみると下記のように、「システムの設定ミスまたはサービスの停止が発生している可能性があります。」とエラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/6efaae5c-4ec2-ed51-01e7-78cc95ac14ba.png)

こちらもAuth0のログを確認してみるとヒントが得られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/9af27413-90ae-b0b1-a215-91519d4c5638.png)

「The specified redirect_uri 'http://localhost:3000' does not have a registered origin.」とあるので、Auth0 Communityで探してみると、「あぁ〜`Allowed Web Origins` を設定する必要があるんだなぁ」と気がつくことができます。

Silent Authentication: ‘does not have a registered origin’ - Auth0 Community
https://community.auth0.com/t/silent-authentication-does-not-have-a-registered-origin/23585


## まとめ

こんなふうに、Auth0のログをうまく活用すると動かない、エラーがでるなどの原因調査に役立てることができます。


## 参考

Auth0の機能を調べてみた - Qiita
https://qiita.com/kai_kou/items/b3dd64e4f8f53325020e

Auth0のJavaScriptチュートリアルをシンプルな構成で試してみた - Qiita
https://qiita.com/kai_kou/items/51ce27a8f98a14263e26

Auth0 Community
https://community.auth0.com/

Silent Authentication: ‘does not have a registered origin’ - Auth0 Community
https://community.auth0.com/t/silent-authentication-does-not-have-a-registered-origin/23585
laravel/ui リダイレクト先変更方法

特に解説はありません。




app/Providers/RouteServiceProvider.phpを開き

HOMEプロパティに格納している値を変更

```php:RouteServiceProvider.php
.....
class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * The path to the "home" route for your application.
     *
     * @var string
     */
    public const HOME = 'HOME';#<=任意のリダイレクト先に変更

    /**

.....
```
例
homeからwelcame画面にしたい場合

```php:RouteServiceProvider.php
public const HOME = '/';
```
LINEの絵文字・スタンプメッセージ送信メモ

これはうまくいくけど、

```javascript

                let text_length = pushText.length;
                pushText += "$"

// チャンネルに登録されている方たちに連絡
                client.broadcast([{
                    type: "text",
                    text: pushText,
                    "emojis": [
                        {
                            "index": text_length,
                            "productId": "5ac1bfd5040ab15980c9b435",
                            "emojiId": "002"
                        }
                    ]
                }]).then(data => console.log(data))
```


こっちのスタンプはうまくいかんのなんでやろ。指定の仕方がまちがってるのか？


```javascript
                client.broadcast([{
                    type: "sticker",
                    packageId: "11537",
                    stickerId: "520027451"
                }]).then(data => console.log(data))
                .catch(e => console.log(e))
```


追記⇒ただのIDのコピペミス！！「520027451」の最後の1がいらなかった。見たところ、他のも全部8桁や。
[apache2.4]Expect :100-continueヘッダーに対応していないHTTPサーバをOrigin/バックエンドで使う時は「Proxy100Continue Off」

解決に1日要しました。涙

お役にたてば幸いです。

# 背景

- あるAPIを実装
- APIは簡易HTTPサーバ上で動作(HTTPメソッド=POSTで待受)
- Apacheをリバースプロキシとして利用
- 動作試験(curlや簡易クライアント)は良好
- 本番クライアント(.NETアプリ)からのリクエストでエラー(100%)

# エラー内容

- Apacheが返しているHTTPステータスコードは503
    - IP制限の場合は403エラーになるのでIP制限は無関係
- APIクライアントではタイムアウトエラー
- Apacheのエラーログの内容は以下

```
[proxy_http:error] [pid xxx] (104)Connection reset by peer: [client IPアドレス:ポート] \
   AH01102: error reading status line from remote server バックエンドのIPアドレス:ポート
```
 
よくわからなかったので、Apacheのdumpioモジュールを有効にして、リクエストヘッダー等を記録。
試験と本番のリクエストの違いを調査してみたところ以下がわかりました。

本番(=エラー)リクエストにはHTTPヘッダーに`Expect: 100-continue`が含まれている。(そしてbodyは空)

このHTTPヘッダを動作試験用のスクリプト(curl)に追加してみてたら同じ事象が再現しました。
これが原因のようです。

```
curl -H 'Expect: 100-continue' 以下省略
```

# 原因

`Expect: 100-continue`ヘッダーは、「これからPOSTします(コンテンツ長はこれです)けどいいですか？」というサーバへの問い合わせです。
サーバはリクエストを受け取れる場合は「いいですよ。」とHTTPステータスコード`100`を返す必要があります。

ところが、バックエンドの簡易HTTPサーバはこのヘッダーに対応していないようです。
本来は、「100を返す」「次のリクエストボディを待つ」という動作が必要なのですが、
「100を返さずに」「リクエストボディを待つ」という挙動をしてしまっているようです。

今後、IoT機器などで簡易なHTTPサーバ使われることがあり、こういった事象に出くわすこともあるかもしれませんね。

# 対策

1日要しました。

`Expect: 100-continue`でググって出てくる対策は以下でした。

- APIクライアント側で`Expect: 100-continue`を送らないようにする
- HTTPヘッダーから除去

前者はAPIクライアント側が変更不可でした。
後者はリクエストにBODYが含まれていれば有効(=curlで確認)ですが、クライアント側がRFP仕様どおりにボディは空で、100応答を待っている場合は、機能しません。

これはHTTPサーバ(とAPI一式)を変えるしかないのか…。そんな時間ないよ…。と絶望。

原点に戻って、Proxyの設定で何かいいのないかなぁとApacheのドキュメントを眺めていたら、、、
何やら期待できそうなディレクティブがありました。

[Proxy100Continue - Apache2.4(公式)](https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html#proxy100continue)

```
このディレクティブは、プロキシが Expect 100-continue をOriginサーバに転送すべきかどうかを決定します。
これにより、HTTP リクエストボディを読み込むべきかどうか、あるいは、 リクエストボディを転送する前に
プロキシが 100-CONTINUE 中間応答を生成するべきかどうかを決定することができます。
```

説明がちょっとわかりづらいのですが、この設定のデフォルトは`On`です。
現在の挙動からして、おそらく「Originに転送する」になっています。
すると`Off`にすればApacheが変わって100を返してくれて、万事OKになるのでは？

で、試してみたところ、、、ビンゴでした！！

関係者(全員リモートですが)から歓声と安堵のため息が上がりました(たぶん)。
良かった・・。
CodeBuild実行時に$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)で発生したエラーの解決方法

## 問題点
AWS CodeBuild実行時に

```
Running command $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
```
時に、```An error occurred (AccessDeniedException) when calling the GetAuthorizationToken```と言われてこけてしまった。

実行結果
![スクリーンショット 2020-11-20 14.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785079/8616997c-16f2-87ac-9733-1fc0da03032f.png)

## なぜ起こったのか？
CodeBuild実行時にECRを操作する権限がアタッチされていなかったから。

## 解決方法

### 手順_01
``CodeBuild > ビルドプロジェクト > 該当プロジェクトの詳細を表示``から``ビルドの詳細 > 環境``で``サービスロール``を確認

サービスロールのリンクから``IAM Management Console``へ行く

### 手順_02

``ポリシーのアタッチ``から``AmazonEC2ContainerRegistryPowerUser``をアタッチする

### 手順_03

ビルドを再試行して実行できることを確認する
ServiceNow - フィルタの条件指定

#概要
ServiceNowフィルタのbefore及びafterは決められた選択しか選べない。しかし場合によっては任意の日付を指定したい。例えば3日より前のレコードのみを表示したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/a341b6ad-4170-c613-3d62-4249ff71f13a.png)

#解決
before及びafterではなく、「relative」を利用する。relativeを選択した場合は次のように任意の値を入力することが可能になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/46aed511-9554-6044-a2ea-428caa6b42f1.png)

以上
[メモ] macOSでOpenCVのビルドがエラーになる件

### 背景
普段は`brew install opencv` や、 `pip install opencv-python` して使えば良いのだが、設定変更してビルドする必要が生じたので、[公式に従って](https://docs.opencv.org/master/d0/db2/tutorial_macos_install.html)ビルドしてみたら、エラーとなったのでメモ。

* macOS Catalina 10.15.7
* Clang 12.0.0
* [OpenCV 4.2.0](https://github.com/opencv/opencv/releases/tag/4.2.0) のSourceCode

opencvフォルダのあるところで、

```bash:bash
mkdir build_opencv
cd build_opencv
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON ../opencv
make
```

### 解決策
結果として以下のように、 **BUILD_JPEG_TURBO_DISABLE** = ON を追加すれば良い。

```
cmake -DCMAKE_BUILD_TYPE = Release  -DBUILD_JPEG_TURBO_DISABLE=ON -DBUILD_EXAMPLES = ON ../opencv
```

### 原因
3rdparty/libjpeg-turbo のCMakeFile.txtに`set(JPEG_LIB_VERSION 62)`と定義されているが、`#if JPEG_LIB_VERSION >= 70`の時しか_jpeg_default_qtablesが定義されない様子。

### 参考
https://github.com/microsoft/vcpkg/issues/13766#issuecomment-706013096

### 問題のログ

```bash:bash
$ make
[  2%] Built target zlib
[  5%] Built target libjpeg-turbo
[  7%] Built target libtiff
[ 15%] Built target libwebp
[ 18%] Built target libjasper
[ 19%] Built target libpng
[ 26%] Built target IlmImf
[ 28%] Built target ippiw
[ 34%] Built target libprotobuf
[ 34%] Built target quirc
[ 34%] Built target ittnotify
[ 35%] Built target ade
[ 35%] Built target opencv_videoio_plugins
[ 42%] Built target opencv_core
[ 47%] Built target opencv_imgproc
[ 47%] Built target opencv_imgproc
[ 47%] Linking CXX shared library ../../lib/libopencv_imgcodecs.dylib
Undefined symbols for architecture x86_64:
  "_jpeg_default_qtables", referenced from:
      cv::JpegEncoder::write(cv::Mat const&, std::__1::vector<int, std::__1::allocator<int> > const&) in grfmt_jpeg.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libopencv_imgcodecs.4.2.0.dylib] Error 1
make[1]: *** [modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/all] Error 2
make: *** [all] Error 2
```
コマンドラインからmanのリファレンスをプリンターで印刷する

今世紀になってもコマンドのリファレンスを紙に印刷して読みたいという人も、存在するかも知れない。
その際に、さっさとコマンドラインで印刷したいという人も、世の中には存在するかも知れない。

というわけで、とりあえずネットでやり方だけググったのでメモ

まずは、プリンターの一覧を表示する

```
lpstat -p -d
```

`-p` でプリンタ、`-d` でデフォルトのプリンタがあれば表示される。
あとは

```
man -t コマンド名 | lpr -P プリンタ名
```

印刷できる。結構きれい。
まったくわからんやつがFlutterについて少しまとめてみた！


## ざっくり構成について、調べてみる。
* 画面が`Widget`のあつまりで作られている。ツリー構造で出来上がってます(以下)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416392/6e0db71b-cb29-0cf6-9a63-b26d8db4f465.png)

* libファイルの中に `.dart`ファイルを置きます
* ファイル増えてくると、分割してあげるといいらしい。

[わかりやすくまとめてあるページ(参考にしてみてください)](https://qiita.com/matsukatsu/items/e289e30231fffb1e4502)


## StatefulWidgetとStatelessWidgetの違いについて
### StatefulWidget
* ウィジェットの生存期間中に変更される値を維持することができる。(動的な画面が作れるってことだと思う)
* 実装するためには、 `Stateクラスのインスタンスを作成するStatefulWidgetクラス`と `Stateクラス`が必要。たぶんこんな感じだと思う....

``` .dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
@override
_Myappstate createState() => _Myappstate();

class _Myappstate extends State<MyApp> {
@override
Widget build(BuildContext context){
return MaterialApp( ..... //ここでウィジェットを作って返す(省略)
}
```

### StatelessWidget
* 扱う値がすべて不変的、プロパティを変更することができない。
* 全て値が`final`な扱いになる。(固定値?)
* 簡単な言葉でいうと、静的なウィジェット(?)
* 一番大きい枠組みの部分で変更いらないなら、`StatelessWidget`で作ってみてもいいのかなって思った！

``` .dart

class MyApp extends StatelessWidget {
  final String text;

  SampleStatelessClass({@required this.text});

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text(text),
      ),
    );
  }
}
```

## なんかむずかしいなって感じたとこ

 * `state<MyApp>`を継承して実装しないといけないとこ！(この辺まだ理解できてない)
 * `widget`種類多い
 * 調べると、英語の物が多い
 * 部品をかき集めて、１つの画面作るのが案外難しい。



## 最後に
今まで、独学でWebを勉強してきましたが、スマホアプリの開発はなんか、ネストが深くなっていきそうな予感がしました。。
よりわかりやすいコードを書く練習をしないと！と思わされますね:sweat_smile:
以上！これからも精進致します！！
python3 flaskのログを抑制する

pythonでflaskを使ってserverを実装/起動すると、以下のようなログが出ることがある。
ログ頻度が高いと、CPU負荷増に繋がることがありログ抑制したいときがある。

```
127.1.1.0 - - [15/Nov/2020 hh:mm:ss] "GET / HTTP/1.1" 200 
127.1.1.0 - - [15/Nov/2020 hh:mm:ss] "GET / HTTP/1.1" 200 
127.1.1.0 - - [15/Nov/2020 hh:mm:ss] "GET / HTTP/1.1" 200 
127.1.1.0 - - [15/Nov/2020 hh:mm:ss] "GET / HTTP/1.1" 200 
```

ログ抑制は、以下のようにログを/dev/nullに出力すればよさそう

```
import logging 
from flask import Flask

app = Flask(__name__)

# WebAPI
@app.route("/", methods=["GET"])
def root():
    return "hello world"

if __name__ == "__main__":
    # app run
    l = logging.getLogger()
    l.addHandler(logging.FileHandler("/dev/null"))
    app.run(debug=True, host="0.0.0.0", port=5000)
```

# 参考
[flaskのデフォルトのログを出力されないようにする](https://yaaamaaaguuu.hatenablog.com/entry/2017/11/04/010415)
【エンジニャーのための】業務知識完全に理解した

## はじめに
この記事は「[完全に理解したTalk Advent Calendar 2020](https://qiita.com/advent-calendar/2020/easyeasy)」24日目の投稿記事です。

>完全に理解した、それはまさに「分かった気になったくらい」の理解できたくらいのもの！ 「覚えたての知識」や「この知識なら自信出てきた！」みたいなものから「あれ、ちょっと怪しいかも？」となり始めた知識まで自分が話したい知識をなんでもゆるーく話をしてみませんか！

>みんなにOUTPUTして、是非自分の実力を高めちゃいましょう！

>運営：　　Easy Easy
>イベント：完全に理解したTalk
>https://easy2.connpass.com/


## TL;DR
業務知識とは？
・業務に必要な知識です。
要件定義や基本設計など上流工程での作業を`補佐`してくれるもの。
あくまでも`補佐`なので正直なところなくても上流工程作業はできる。
ユーザーが話している内容の理解の助けになる。
プロジェクトに入るときにユーザーからこれくらい心得ておいてよね、と言われたりもする。

**結論：業務知識があると仕事が楽になる。**

## 業務知識とは
~~業務に必要な知識です。以上、終了。~~
日々の仕事をこなしていくために必要になる知識と定義します。
筆者は業務知識とは大きく以下の4つに分かれていると考えています。

1.　法律
2.　世界/各国の基準
3.　業界の基準
4.　各社の基準

#### 1. 法律
いわずもがな、国が決めた守るべき事柄です。
これに違反すると罰金であったり、訓戒、処罰が降ります。

法によっては割と頻繁に改正が入ります。
直近では2020/10/01に酒税法が変わりました。また、2021/04/01から新しい会計法が施行されます。
会計法や税法はそこそこの頻度で変更があります。それらに関連するシステムを構築、保守するのであれば抑えておく必要があるでしょう。
法に関することは厳密性を求められるため、難解な言葉や言い回し、専門用語が用いられることがあります。
これらを理解するための知識も求められます。

#### 2. 世界/各国の基準
世界の基準であればISO（International Standardization Organization,国際標準化機構）が定める統一的規格があります。
有名なものではメートル法もISOによって定められた規格です。~~ヤードポンド法は悪~~
各国の基準とは、例えば日本であればJIS規格、ドイツであればDIN規格の工業規格があります。
モノの大きさ、寸法をこの工業規格によって統一することで、商品を販売している会社が違っても、互換性を保つことができます。
例えばネジを締めることができる、コンセントから電源を取り出すことができる、といったことが可能になります。

#### 3. 業界の標準
小売業界、製造業界、サービス業界、教育業界など業界ごとの標準です。
また、上記の業界の中からさらに細分化して適用される標準もあります。
製造業界の中でも自動車業界は祝日が営業日ですが、これも業界の標準であるといえるでしょう。
この自動車業界の祝日が営業日であり、年末年始やGW、お盆に長期休暇になることを通称トヨタカレンダーと表現したりします。

#### 4. 各社の基準
これについては、実際に各社で従事しないと理解はできないものであると考えています。
各社の基準とは、それぞれの社にある文化であったり、伝統であったりするものからきている慣習であったりするためです。

## 業務知識があると役に立つシーン
食品製造業界のユーザー（以下A）とあなた（以下B）でシステム化にあたり、以下の会話をしたとします。

B　「では、仕入れた材料はXXで検品され、YYへ納入されるということですね。」
A　「そうです。そして仕入れた材料はZ社へ有償支給品として搬送します。Z社に半製品に加工してもらいます。また、有償支給品の買戻しは粉引きを考慮してください。割引額は加工した重量に応じての割合が決まっています。」

ここで登場する業務知識を求められる用語は3点あります。

1. 有償支給品
2. 半製品
3. 粉引き

これらの言葉の意味が理解できていれば、仕入れた材料がどのような経路をたどり、どのような状態になって買い戻されるか理解できるでしょう。

## まとめ
業務知識というのはあくまでも仕事をサポートしてくれるものになります。
業務知識だけあっても当然ダメですし、しかしながら業務知識が全くないというのも効率よく仕事を行うことができません。
実際にシステムを介して取引されるモノ、コトが言葉から理解できるようになれば、システムの使われ方、あるべき姿もイメージしやすくなると思います。

**最も言いたいこと：技術と一緒に身につけていきましょう。**
コマンドラインからUbuntuアップデート時のメモ（16.04→18.04, 18.04→20.04どちらも）

※SSH越しに実行すると、SSH切断時にアップデート失敗になる可能性があります。ネットワーク状況に不安がある場合はOS imageを利用したクリーンインストールをお勧めいたします。
※本手順は参考情報であり、コマンドラインからのバージョンアップに不安がある場合はOS imageを利用したクリーンインストールをお勧めいたします。

基本的に以下コマンドを実行すればアップデートできた（結構時間がかかります）

```
sudo apt-get -y update; sudo apt-get -y upgrade;
sudo apt-get dist-upgrade;
do-release-upgrade 
```

途中、対話を求められる場合は基本的には「y」を入力

```
サポートが中止された（あるいはリポジトリに存在しない）パッケージを削除しますか？ 
186 個のパッケージが削除されます。 
パッケージの削除に数時間かかることがあります。 
続行する[yN]  詳細 [d]
```

完了後、以下からアップデート完了を確認できる

```
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
…
```

# エラー`Please install all available updates for your release before upgrading.`

```
$ do-release-upgrade 
Checking for a new Ubuntu release
Please install all available updates for your release before upgrading.
```

`apt-get -y update`及び`sudo apt-get -y upgrade`により解決

```
sudo apt-get -y update; sudo apt-get -y upgrade;
```

# エラー`You have not rebooted after updating a package which requires a reboot. Please reboot before upgrading.`

```
$ do-release-upgrade
Checking for a new Ubuntu release
You have not rebooted after updating a package which requires a reboot. Please reboot before upgrading.
```

rebootして解決

```
reboot
```

# エラー パッケージのバージョンアップできない

該当パッケージをアンインストールすると良いかもしれない

```
# （例）ros kineticをアンインストールする場合
sudo apt-get remove ros-*
```

# 参考
[Please install all available updates for your release before upgrading｜Ubuntu](https://www.jacepark.com/please-install-all-available-updates-for-your-release-before-upgrading/)
Cluster API: v0.3.11 変更内容

## はじめに

ここでは Cluster API v0.3.11 の変更内容についてまとめています。Cluster API は複数の Kubernetes クラスタのプロビジョニングやアップグレード、オペレーションをするための宣言的な API とツールを提供する SIG Cluster Lifecycle のサブプロジェクトです。

- https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.11

## ⚠️ Breaking Changes

- E2E テストは、環境変数を使用せずに `CNI_RESOURCES` を解決するようになりました ([#3846](https://github.com/kubernetes-sigs/cluster-api/pull/3846))
    - :memo: CNI のマニフェストを ConfigMap として作成する際に `CNI_RESOURCES` という環境変数を一度保存していましたが、マニフェストが長すぎるとエラーになっていました
    - :memo: `clusterctl.SetCNIEnvVar` メソッドは廃止予定になり、代わりに `createRepositoryInput.RegisterClusterResourceSetConfigMapTransformation` メソッドを使う必要があります
- DigitalOcean のインフラストラクチャプロバイダは、`do` から `digitalocean` にリネームされました ([#3816](https://github.com/kubernetes-sigs/cluster-api/pull/3816))

## ✨ New Features

- KubeadmControlPlane (KCP) は、MachineHealthCheck (MHC) を使用してセットアップしたときに不健全なマシンを修正するようになりました ([#3830](https://github.com/kubernetes-sigs/cluster-api/pull/3830))
    - :memo: これまで MHC は、MachineDeployment によって作成されたワーカマシンのみが対象となっていました。この変更で、KCP によって作成されたコントロールプレーンマシンが不健全になった場合にも MHC で削除できるようになりました。
- MHC の Status に `remediationsAllowed` フィールドが追加されました ([#3372](https://github.com/kubernetes-sigs/cluster-api/pull/3372))
    - :memo: `remediationsAllowed` フィールドは、MHC が修正できるマシン数を表します。このフィールドによって運用者は、現状のクラスタでマシンに障害が発生した場合にどの程度までのマシンが自動的に修正（削除）されるのかをぱっとみで把握できるようになりました。
- MHC は、外部の remediation テンプレートの使用をサポートしました ([#3606](https://github.com/kubernetes-sigs/cluster-api/pull/3606))
    - :memo: MHC は、これまで不健全になったマシンを drain したのち Machine オブジェクトを削除して、マシンを再作成するという方法のみを提供していました。しかし、特にベアメタルサーバなどではマシンの再作成に非常に時間がかかる場合もあり、それを避けて単に OS をリブートすることでマシンの復旧にかかる時間を短縮したいニーズがあったようです。この変更でインフラストラクチャプロバイダが提供する独自の remediation コントローラに処理を委譲できるようになりました。
    - :memo: 詳しくは [Propocal ドキュメント](https://github.com/kubernetes-sigs/cluster-api/pull/3190) を参照ください。
- Machine の Ready condition に machine health check conditions が追加されました ([#3796](https://github.com/kubernetes-sigs/cluster-api/pull/3796))

## 🐛 Bug Fixes

- KubeadmControlPlane の ssh keys の更新検証を緩和して、ssh キーをローテーションできるようになりました ([#3927](https://github.com/kubernetes-sigs/cluster-api/pull/3927))
    - :memo: KCP で `spec.KubeadmConfigSpec.Users` フィールドの更新が許可されるようになり、SSH AuthorizedKeys が更新できるようになりました
- etcd の起動開始が遅い場合に `reconcileEtcdMember` が etcd メンバを削除しないように修正されました ([#3919](https://github.com/kubernetes-sigs/cluster-api/pull/3919))
- `kubectl drain` で CPU 使用率が高くなる問題が修正されました ([#3915](https://github.com/kubernetes-sigs/cluster-api/pull/3915))
    - :memo: Machine オブジェクト削除時に実行される `kubectl drain` には、k/k のコードが流用されています。k/k の drain のコードで CPU 使用率が高くなる問題が修正されたため、それがバックポートされました。
- 必要なイメージを事前に取得することで、Makefile で docker を使用するターゲットの問題が修正されました ([#3897](https://github.com/kubernetes-sigs/cluster-api/pull/3897))
    - :memo: `docker.io/docker/dockerfile:experimental` などを事前に取得されるように変更されました。おそらく、registry-mirrors を設定していると、Buildkit を使った際に `dockerfile` イメージの取得に失敗する問題への対処だと思われます
- proposal のルートページへのリンクが `/docs/proposals/` に修正されました ([#3842](https://github.com/kubernetes-sigs/cluster-api/pull/3842))
curlを使って、docker gpgダウンロード時にエラーになることがあった際の解決メモ

curlを使って、docker gpgダウンロード時にエラーになることがあった際の解決メモです

```
$ curl -fsSL http://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
gpg: no valid OpenPGP data found.

```

以下とするとダウンロードできることがある

```
wget http://download.docker.com/linux/ubuntu/gpg
sudo apt-key add gpg
```

プロキシ環境下なら、以下のようにproxyサーバを指定すると解決するかも

```
$ curl http://download.docker.com/linux/ubuntu/gpg -x http://xxx.xxx.xxx.xxx:portno
```

# 参考
[gpg: 有効なOpenPGPデータが見つかりません](https://teratail.com/questions/18823)
[curlコマンドにてproxy設定](https://qiita.com/tkj/items/c6dad4efc0dff4fecd93)
【Ruby】バイナリーサーチを用いた配列内の要素検索

配列内に任意の値が存在するかを確認するプログラムを作成します。
任意の値が配列内に存在しない場合は、「値は配列内に存在しません」と表示し、存在する場合は、配列の何番目にあるかを表示します。

今回のプログラムではバイナリーサーチという、配列を2分割した検索方法を用います。
例えば以下のような配列がある場合、中央値である「3」から左右と比較して検索する手法です。
これにより検索したい値が「1」であった場合、「4,5」は比較を行わないため処理速度の向上につながります。

```java:ruby
array = [1, 2, 3, 4, 5]
```

## 回答例

```java:ruby
def binary_search(array, number_of_elements, target)
  left = 0                       //配列の先頭の番号
  right = number_of_elements - 1 //配列の末尾の番号
  while left <= right            //配列番号が逆転するまで繰り返し
    center = (left + right) / 2  //中央値の配列番号の決定
    if array[center] == target   //配列の中央値が検索したい値であった場合
      return center
    elsif array[center] < target //配列の中央値<検索した値であった場合
      left = center + 1          //arrayの「1,3,5,6,9」を対象外とする設定
    else
      right = center - 1         //それ以外の場合、arrayの「9,10,13,20,26,31」を対象外とする設定
    end
  end
  return -1                      //何も当てはまらなかった（配列に存在しなかった場合の返り値）
end

array=[1,3,5,6,9,10,13,20,26,31]

puts "検索したい数字を入力してください"
target = gets.to_i
number_of_elements = array.length

result = binary_search(array, number_of_elements, target)

if result == -1
  puts "#{target}は配列内に存在しません"
else
  puts "#{target}は配列の#{result}番目に存在します "
end
```

## 解説
まずはメソッド外。
1. 配列「array」の準備
2. 任意の文字「target」の準備
3. 配列の要素数「number_of_elements」の準備
これら3つの変数を実引数に設定し「binary_serach」メソッドを実行しています。

続いてメソッド内。
1. 配列の先頭及び末尾の``配列番号``を「left」「right」に代入。
2. while文にて、この「left」「right」の値が逆転するまで繰り返しを行う設定。
3. 以下の記述で中央値の配列番号を取得しています。今回の配列の要素は偶数個であるため、「(0+9) / 2 = 4.5」となります。配列番号4.5は存在しませんが、rubyにおける計算式の小数点は切り捨てられるため、今回の配列における中央値は「``array[4] = 9``」となります。

```java:ruby
「center = (left + right) / 2」
```
if文による条件分岐を行い、左右のどちらに値が存在するかを繰り返し判定します。
最終的に配列内に任意の値が存在しなかった場合は「return -1」という返り値を渡してメソッドを終了します。

最後に再びメソッド外。
1. 任意の値が存在しなかった場合は「-1」が戻ってくるので、存在しない旨のメッセージを出力。
2. 任意の値が存在した場合は正しい値が戻ってくるので、存在する箇所を出力。


バイナリーサーチ知らないと思いつかない方法だと思いますので、しっかり覚えておきたいです。
ご意見等ございましたらコメントをいただけますと幸いです。
ミドルウェア

<h1>予備知識</h1>
・OS（基本ソフトウェア）
・アプリケーション(応用ソフトウェア)
OSとアプリの例はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592457/30f5a742-1e4e-4985-f135-b48409db9135.png)
<h1>ミドルウェアとは</h1>
OS(基本ソフトウェア)とアプリケーション(応用ソフトウェア)の<font color="red">中間</font>に位置し、統一的なインターフェイスや便利なコンピューター利用機能を応用ソフトウェアから利用できる様にするためのソフトウェアです。
OSはコンピューターで使う最低限必要な機能を提供してくれています。逆にアプリケーションはOSでできないことをやってくれます。このOSとアプリケーションの間に入って、<font color="red">「特別なことをするときに使う基本機能」</font>を提供してくれます。

例えると、
漁師さんが取ってきてくれるのは魚です。これをOSさんが提供してくれている機能だとします。
ある時、アプリケーション・Aさんは焼き魚が食べたくなりました。また、アプリケーション・Bさんは煮付けが食べたくなりました。AさんBさんはそれぞれで魚を捌き始めました。ですが、捌くのにとても手間取っています。そこでCさんは考えました。「捌いてくれる場所があれば、便利なんじゃないか」と。そして、Cさんは魚を捌く魚屋さんを作りました。これにより、AさんBさんは捌く手間を省いて料理できる様になりました。この「魚を捌く」魚屋さんにあたる部分が「ミドルウェア」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592457/84dc4334-c33e-1a05-02f1-5d8697e7e129.png)

<h2>Web3層構造</h2>
Webサーバー、アプリケーションサーバー、データベースの3つのサーバーから構成されているWebアプリケーションの構成のことをいいます。かつては、Webサーバーとデータベースのみの2層構造で成り立っていましたが、それだとWebサーバーに多大な負荷がかかってしまうので、Webサーバーとアプリケーションサーバーの2つに分割され、大量の処理が可能となりました。以下ではその3つのサーバーの役割と例になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592457/d6361734-5a79-a87d-aea5-c4786d54cdd8.png)

<h3>Webサーバー</h3>
必要に応じて、Webサーバー内の保管データを保護して、アクセス制限を行ったり、Webサイトの閲覧者によるリクエストに応じて、Webサーバーに保管中のデータを表示してくれます。

|Webサーバー|説明|
|:--|:--|
|<a href="https://httpd.apache.org/">Apache</a>|フリーでありながら、高い信頼性と充実した機能を備えたWebサーバー。ただし、大量のアクセスがあった場合にレスポンスが遅くなる問題点あり。|
|<a href="https://www.nginx.co.jp/">Nginx</a>|Apacheの問題点である大量のアクセスがあった際にレスポンスが遅くなる点を解決するために作られた。|
|<a href="https://www.winserver.ne.jp/column/about_iis/">IIS</a>|Microsoft Windowsの標準Webサーバー|
<h3>アプリケーションサーバー</h3>
Webサーバーからのリクエストを受け取り、そのリクエストに応じてアプリケーションを実行するためのサーバー。webサーバーとの大きな違いとしては、単体で使えるかどうかと言うところです。動的コンテンツ(RubyやPHPなどのプログラム)のない、静的コンテンツ(HTML,画像)だけのサイトを公開するのであれば、APサーバーを使わずWebサーバー単体で実現することができます。

|アプリケーションサーバー|説明|
|:--|:--|
|<a href="https://jpn.nec.com/oss/middle_support/jboss/lineup.html?">JBoss</a>|プログラミング言語Javaより開発されたOSSの総称。40以上の様々なプロジェクトがあり、Webサイトより自由にダウンロードして使うことができる。|
|<a href="https://jpn.nec.com/oss/middle_support/jboss/lineup.html?">Tomcat</a>|OSSとして公開されているアプリケーションサーバー。JavaサーブレットやJSPを処理することが可能。単独でwebサーバーとして利用することも可能だが、Apache Web Serberのプラグインとして動作することも可能。|
<h3>データベース管理サーバー</h3>
各種必要なデータを保存してくれます。共有データとしてのデータベースを管理して、このデータベースに対するアクセス要求を管理、リクエストされた要求に応じて処理を行うソフトウェアです。

|データベース管理サーバー|説明|
|:--|:--|
|<a href="https://www.mysql.com/jp/">MySQL</a>|オープンソースとして公開されているリレーショナルデータベース管理システム。高速性と堅牢性に定評あり。世界的にも導入実績は多い。|
|<a href="https://www.postgresql.jp/">PostgreSQL</a>|オープンソースとして公開されているリレーショナルデータベース管理システム。主にLinuxとApache Web Serverを連携させて使用されることが多い。|
|<a href="http://firebird.gr.jp/">Firebird</a>|ボーランド株式会社のInterBase6.0ソースコードを流用したレリレーショナルデータベース。オープンソースとして公開されている。|
プロキシ環境下でpip3を使う方法メモ

いわゆるプロキシ環境下でpip3を使う方法メモです
以下のように、proxyサーバのIPアドレスやポートを指定すればOK

```
pip3 --proxy=http://xxx.xxx.xxx:port install ~
```

# 参考
[【備忘録】pipでプロキシを突破できなくて詰まった話](https://qiita.com/samunohito/items/40a03e1464899225e698)
[プロキシ環境で pip install する方法
](https://qiita.com/arai-wa/items/49dbff70c4f22ad51521)
コンタクトフォームに入力したときに自動でつく背景色を消す方法

先日メンターをしていたときにこんな質問がきました。

「予測変換で入力したときにだけ背景色がつきます。
これをつけないようにしたいのですが、どうすればよいでしょうか？」

やばい！わからないということで必死こいて調べて無事解決できました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">✅inputのオートコンプリートしたときの背景色<br><br>コンタクトフォーム で予測からの自動入力されたときに、色が変わりますが、これで初期化？できます。<br><br>勉強になった。<a href="https://t.co/yNqDS3v96B">https://t.co/yNqDS3v96B</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/%E3%83%87%E3%82%A4%E3%83%88%E3%83%A9?src=hash&amp;ref_src=twsrc%5Etfw">#デイトラ</a> <a href="https://t.co/hQ8pCfVBzF">pic.twitter.com/hQ8pCfVBzF</a></p>&mdash; おか | 知多半島のホームページ屋 (@oka_jumboworld) <a href="https://twitter.com/oka_jumboworld/status/1329427272575700997?ref_src=twsrc%5Etfw">November 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


とりあえず、こちらをスタイルシートに書いてあげれば解決します。
すみません、意味は全くわかりませんし分かろうとしていません。笑

```style.css
0
@keyframes onAutoFillStart { from {} to {}}

input:-webkit-autofill {
animation-name: onAutoFillStart;
transition: background-color 50000s ease-in-out 0s;
}
```

これは知らないとはまると思うので、武器として知っておくとよさそうですね。

■この記事は以下の情報を参考にして執筆しました。
https://teratail.com/questions/171007
Slackでこんなチャンネルを作ったらメンバーの関係性やモチベーションが↑↑↑した話

## 0. はじめに

仕事だけでなく、情報収集、メモ代わりといった形でSlackを利用している方は多くいるかと思います。
弊社では、社員同士のコミュニケーション増加や、技術情報の交換等を目的に、仕事とは別でSlackを活用しています。
その中でも人気のあるチャンネルの一部を紹介させて頂きます。

## 1. チャンネル紹介

### 1-1. 雑談チャンネル

**どんな内容を発言してもOKなチャンネルです:two_men_holding_hands:**（さすがに誹謗中傷はないですが）

 - 「眠い」とか「腹減った」とか「〇〇完全に理解した」とか、今の感情をそのまま書く
 - 話題/速報ニュースがあった場合に共有する（今だとコロナ関係が多いですね）
 - 飯テロ画像を貼り付ける（特に深夜）

といった使い方をしています。
一番メッセージ数が多いのがこのチャンネルかもしれません:innocent:
気軽に発言・リアクションできるため、社員同士の関係向上に繋がっているかと思います。
仕事中の息抜きとしても活用されています。

### 1- 2. ナレッジチャンネル

**技術情報等を発信するチャンネルです:writing_hand:**社内版mohikanといった感じでしょうか。

 - ネット（主にQiita/Zenn）で良い記事があった場合に共有
 - ネット（主にQiita/Zenn）で記事を書いた場合に共有
 - 仕事を通して何か学んだ場合に共有

といった使い方をしています。
身近な人に紹介してもらった記事って、なんか読みたくりますよね:relaxed:

### 1- 3. イベントチャンネル

**イベント/セミナー情報を発信するチャンネルです:stadium:**

 - 県内でのイベントがあった場合に共有
 - オンラインイベントがあった場合に共有

といった使い方をしています。
自分が興味のあるイベントを紹介してもらったら、リマインダー登録したり、カレンダー登録したりしています:alarm_clock:
イベント参加中のメンバーは、「こんな内容だよー」「面白いから誰かおいでー」といった形で、リアルタイムに状況を教えてくれることもあります。


### 1- 4. 壁打ちチャンネル

**技術的に困っている場合等に、誰かに相談するチャンネルです:badminton:**

　⇒　[**「壁打ち」の意味とは？ビジネスやネット(ツイッター)での使い方！**](https://goiryoku.com/kabeuchi/#:~:text=%E3%80%8C%E5%A3%81%E6%89%93%E3%81%A1%E3%80%8D%E3%81%AE%E6%9C%AC%E6%9D%A5%E3%81%AE,%E7%B6%9A%E3%81%91%E3%82%8B%E3%81%93%E3%81%A8%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E6%84%8F%E5%91%B3%E3%81%A7%E3%81%99%E3%80%82&text=%E3%80%8C%E5%A3%81%E6%89%93%E3%81%A1%E3%80%8D%E3%81%AF%E3%81%93%E3%81%AE%E3%82%88%E3%81%86,%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82)

 - 若手メンバーが先輩に相談する
 - 技術の選定悩んでいるときに相談する
 - 学ぼうとしている技術がチンプンカンプンなときにとりあえず相談する

といった使い方をしています。
ナレッジチャンネルに若干被るのですが、結論が出てまとまったらナレッジチャンネルに投稿というルールにしています。
1人で悩むより、ずっと効率がいいですよね！
**朝起きてSlackを見てみると、このチャンネルのメッセージ数がすごいことになっている場合があります。**やっぱり夜型の人多いですね:eyes:

## 2. おまけでこんな効果もあった！

自分だけかな？:rolling_eyes:
夜中に家で作業しているとき、誰かがオンラインになってると、**「おお、自分一人じゃねぇ！あの人も頑張ってる！」**感が生まれモチベーションがあがります。（心理学でいうところの同期行動？に近いんですかね。わかんね。）


## 3. おわりに

**こんなチャンネル作ったら面白かったよー！みたいなのあれば、共有頂けると嬉しいです。**
※実は↑これを聞くのが目的だったり:innocent:
コロナの影響で社員同士が顔を合わせる機会がぐっと減ってきているので、面白いチャンネルが増え、Slackが盛り上がってくるといいなー:innocent:
Pythonでシーザー暗号のプログラムを書く

#はじめに
CTFを始めたらシーザー暗号と言うものが出てきたので復号処理が必要になった。
手作業でも出来るけどここはプログラムでしょ！リハビリにもなるし！と言う事で早速書いてみた。
私のマシンにはPythonの開発環境しか無かったのでPythonでGo！

#シーザー暗号とは
復号するためにはどんなアルゴリズムで生成された暗号なのかを知らなければいけない。
シーザー暗号は文字を3文字ずつシフトして生成する。ほうほうシンプル！
※特に3文字じゃなくても良いそう。
参考サイト：https://ja.wikipedia.org/wiki/シーザー暗号

#暗号化と復号化のプログラム
まずは暗号化を。
平文を1文字ごとに指定のキー(数)でシフトする。
大文字小文字は別なので今回は英小文字のみで組む。
英文字は25個なのでぐるっと回るように注意。
適当な文字列「wjrslairznb」を暗号化！

```python
def crypt(plainStr, shiftInt):
    resultStr = ""
    for char in plainStr:
        if ord(char) + shiftInt > ord('z'):
            resultStr = resultStr + chr(ord(char) + shiftInt - 26)
        else:
            resultStr = resultStr + chr(ord(char) + shiftInt)
    print('crypt:' + resultStr)
```
実行結果
![スクリーンショット 2020-11-20 14.11.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863728/f7ecb613-39be-a121-159b-08199975259e.png)


復号化は単純に逆に計算しただけです…

```python
def decrypt(cryptoStr, shiftInt):
    resultStr = ""
    for char in cryptoStr:
        if ord(char) - shiftInt < ord('a'):
            resultStr = resultStr + chr(ord(char) - shiftInt + 26)
        else:
            resultStr = resultStr + chr(ord(char) - shiftInt)
    print('decrypt:' + resultStr)
```
実行結果
![スクリーンショット 2020-11-20 14.12.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863728/b06a266f-b1b4-de1e-0520-266e53ef2beb.png)
もっとサラッとシンプルに出来そう…

#余談：シーザー暗号って暗号としては簡単過ぎるけど使えるの？
使えない。脆弱ぅ！！
古代ローマに作られた暗号なので、昔は有効だったのでしょうと言う事。
暗号に歴史あり。

#おわりに
実はプログラムは久しぶりでしかもPython環境はあるのにほとんど触った事ないしでとても楽しかった。
この手のプログラムはググれば山程出てくるけどまずは自分で書いてみて、後で天才的なコードを見て答え合わせをするのが好きです。
【jQuery】datepickerを使って、カレンダーを実装！

問い合わせフォームの作成時に、カレンダーにカスタムが必要で使用したdatepickerの概要を説明します。

##【目次】
１.datepickerでできること
２.datepickerでカレンダーを作ってみる
３.付けられるオプション


###１.datepickerでできること
前提として、カレンダーから日付をワンクリックで選択できる機能を使うことができる他に、ドロップダウンリストから選択できる機能など様々なカスタムができるものである。
それ以外にもオプションで、
・英語／日本語表記にする
・指定の日付フォーマットを使用できる
・曜日や時間も表示させられる
・カレンダーを表示させる時のアニメーションを設定できる
・過去の日付は表示させない　...etc

###２.datepickerでカレンダーを作ってみる

######①まず、必要なソースを打ち込む。※そのままコピペでOK！

```
1.https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
2.
3.https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.min.css
```

```
1.<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.min.css">
2. 
3.<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
```
これで、jQueryUIが使えるようになりまいした！

######②inputタブで簡単なカレンダー表記をさせてみましょう！

```
1.<input type="text" id="datepicker">
```

```
1.$('#datepicker').datepicker();
```

これでカレンダー設置完了です！
こんな感じ↓
![記事用スクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/884878/c890e297-8eb7-ed56-0b8a-98584177df1b.png)


#【！！これで完成！！】

あとは、好きなようにカスタムしてみてください★
\setcounter{section}{0}をすると目次のハイパーリンク(しおり)がうまく飛ばない問題

# \setcounter{}{}をすると目次のハイパーリンクがうまく働かない問題
XeLaTeXで文書を組版していて、```hyperref```パッケージから生成した目次のハイパーリンクがうまく機能しないことがあった。以下の文書の目次において、**「つぎに」のセクションをクリックしても「はじめに」のページに飛ばされてしまう。**


```latex:old.tex
\documentclass{bxjsbook}

\usepackage[unicode]{hyperref}
\hypersetup{% hyperrefオプションリスト
setpagesize=false,
bookmarksnumbered=true,%
bookmarksopen=true,%
}

\renewcommand{\thesection}{\arabic{section}}

\begin{document}
\tableofcontents
\newpage

\section{はじめに}
\newpage

\setcounter{section}{0}% ここが問題の元

\section{つぎに}
\end{document}
```

**結論からいうと、```\setcounter{}{}```を用いていたのが原因だった。**

# 前提
上の文書では、

+ 文書クラスを```bxjsbook```にしたい
+ だけど、```\chapter{}```は使いたくない
+ だけど、あるページでセクション番号を1に戻したい

というクラスファイル作成者の意図を無視した要求のもとに書かれており (色々と制限があってそうせざるを得なかったのです……)、```\setcounter{section}{0}```と書いてセクション番号をリセットした。

```\setcounter{}{}```を用いるとしおりがうまく働かないことは知られているようだ (参考: https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=2528 )。

# 解決法
```\setcounter{}{}``` でなく、```\addtoreset{}{}```を用いて```section```をリセットすればこの問題は起こらないらしい。```\addtoreset{#1}{#2}```は、#2のカウンタが進むたびに#1のカウンタを0にリセットする。適当なカウンタを作成し、```section```をリセットしたいところでそのカウンタを一つ増やしてやればよいということになる。以下が変更後の文書。

```latex:new.tex
%(プリアンブル略)
\newcounter{hoge}%%%(*1)

\makeatletter
\@addtoreset{section}{hoge}%%%(*2)
\makeatother

\begin{document}
\tableofcontents
\newpage

\section{はじめに}
\newpage

\stepcounter{hoge}%%%(*3)

\section{つぎに}
\end{document}
```

(\*1)で、新しく```hoge```というカウンタを設定した。
(\*2)で、```hoge```が進むたびに```section```が0になるように設定した。
(\*3)で、```hoge```を1進めた (そしてそれに伴い```section```がリセットされた)。

これで二回タイプセットすればハイパーリンクが適切に付いた文書ができるはず。

# まとめ
章・節番号をリセットするために```\setcounter{}{}```を使うとハイパーリンクがうまくいかないことがあるので、```\addtoreset{}{}```と```\stepcounter{}```を用いてカウンタをリセットしたほうがいい。
Pandasでto_csvしたら一行ずつになった件

pandasを用いてto_csv関数を用いたら、出力が一行空きになったのでここに備忘録を記す。

# 開発環境
- windows10 64bit
- python 3.8.5
- pandas 1.1.2（だったけど、1.1.4に変更した。問題の解決には関係なかったけど）

必要な記述は以下の通り

```python

import pandas as pd

pd.to_csv("C://TEST/TEST2//data.csv",line_terminator='\n')
```

引数```line_terminator='\n'```を入れたら、丸く収まりましたとさ。
gnome-terminalコマンド実行時にwarning(Option “-e” is deprecated and might be removed in a later version of gnome-terminal.)


gnome-terminalコマンド実行時に、以下のようなwarningが出る。（例. xeyes実行）

```
$ gnome-terminal -e "xeyes"
# Option “-e” is deprecated and might be removed in a later version of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to execute after it.
```

deprecateということなので、文面の通り`-- ` を挟んで後ろにコマンド指定するとよい

```
$ gnome-terminal -- xeyes
```

以下のようにすると、`""`で囲んだ部分が１つのコマンドと思われるようなので注意

```
$ gnome-terminal -- "xeyes"
```

# 参考
[Ubuntu – Option “-e” is deprecated and might be removed in a later version of gnome-terminal](https://itectec.com/ubuntu/ubuntu-option-e-is-deprecated-and-might-be-removed-in-a-later-version-of-gnome-terminal/)
タスクランナーで作ったサイトをHerokuでデプロイする

npm-scriptsやgulpで静的サイトを作った際にHerokuをテストサーバにしたい時の手順です。

## 前提
npm-scriptsやgulpで静的サイトを作った場合、管理の都合で、静的サイトはgitigoreしていることが多いと思います。
同じリポジトリのまま、Herokuへデプロイする手順です。

## 手順
###(1) Heroku上でnodeでサーバを立ち上げるファイルを作る
``` sh
# Procfileを作る
echo 'web: node server' >> Procfile

# expressをインストール
npm i express

# server.jsを作成する
touch server.js
```

### (2) Herokuでサーバーを立ち上げるserver.jsを編集
``` server.js
var express = require('express');
var app = express();

var user = process.env.USER;
var pass = process.env.PASS;

app.set('port', process.env.PORT || 3000);

if (user && pass) {
  app.use(express.basicAuth(user, pass));
}

app.use(express.logger('dev'));
app.use(express.compress());
app.use(express.static(__dirname + '/dist'));

app.listen(app.get('port'), function() {
  console.log('Server listening on port %s', app.get('port'));
});
```
`/dist` をルートディレクリとしてサイトを作成している想定です。必要に応じて編集してください。

### (3) package.jsonへheroku環境でサイトをビルドするスクリプトを入力
```package.json
{
  "scripts": {
    "postinstall": "gulp build" 
  }
}
```
Heroku上でpackageのインストールが完了したあとにpostinstallが実行されます。
postinstallにはサイトをビルドするスクリプトを記入してください。

### (4) デプロイする
``` sh
# アプリーケーション
heroku create

# デプロイ
git push heroku master

# アプリケーションを開く
heroku open
```
`heroku create アプリ名`でアプリ名を指定することもできます。
matplotで凡例を手動で作りたい

# はじめに
matplotの凡例はほとんどの場合自動作成で事足りると思いますが、イレギュラーが発生したので手動で設定する方法をメモしておきます。

# 普通のプロット
おそらくほとんどの場合これで十分で、これができるようにデータをまとめればいいと思います。

```python
import numpy as np
from matplotlib import pyplot as plt

red_x, red_y = np.random.randn(10), np.random.randn(10)
blue_x, blue_y = np.random.randn(10), np.random.randn(10)
green_x, green_y = np.random.randn(10), np.random.randn(10)

plt.scatter(red_x, red_y, c="r", alpha=0.5, label="red")
plt.scatter(blue_x, blue_y, c="b", alpha=0.5, label="blue")
plt.scatter(green_x, green_y, c="g", alpha=0.5, label="green")

plt.legend()
plt.show()
```
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660862/ead0489d-4a0c-85bd-96c9-588d76a1943e.png)


# 手動で設定する
特殊な状況、特殊なデータを扱っていて上のコードにできない、もしくはコードが汚くなってしまうときは以下のようにして手動で設定できます。

```python
import numpy as np
from matplotlib import pyplot as plt

red_x, red_y = np.random.randn(10), np.random.randn(10)
blue_x, blue_y = np.random.randn(10), np.random.randn(10)
green_x, green_y = np.random.randn(10), np.random.randn(10)

# データの部分からlabelを取っ払う
plt.scatter(red_x, red_y, c="r", alpha=0.5)
plt.scatter(blue_x, blue_y, c="b", alpha=0.5)
plt.scatter(green_x, green_y, c="g", alpha=0.5)

# 凡例用に空のデータをlabel付でプロットする（実際はなにもプロットしてない）
plt.scatter([], [], c="r", alpha=0.5, label="red")
plt.scatter([], [], c="b", alpha=0.5, label="blue")
plt.scatter([], [], c="g", alpha=0.5, label="green")

plt.legend()
plt.show()
```

![sample_changed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660862/6f829de3-9233-a292-0030-303a01010d75.png)

# おわりに
凡例の部分だけ透明度や点の大きさを変えるなどのときにも使用できそうな感じです。
席替え用のWebアプリ作ってみたよ

こんにちは。すずともです。

席替えするとき

1. 番号書いてあるくじ作って
1. みんなに引いてもらって
1. 自分の引いた席に移動してもらって
1. 自分の番号と名前をLINEグループに投げて
1. 代表がExcelで座席表を作り
1. 印刷して教卓に貼る

っていう感じで、多くの工程がありますね。（クラスによっても違うと思うけど…）

僕のクラスは自治性が強いので全部学生でやってますが、クラスによっては先生がしてくれるところもありますし。

まぁ、何でもいいとして、結構めんどくさいなぁと。
これ、Webアプリ作れば楽になるんじゃね？と思って、Webアプリ作ってみました。

# 成果物
とりあえず最初に成果物置いておきます。
Github pagesにて公開しました。
よかったら使ってくださいな。

[https://kamekyame.github.io/seat_change/](https://kamekyame.github.io/seat_change/)

[Github Souece](https://github.com/kamekyame/seat_change)

# 使い方
使い方はいたってシンプル。

1. 生徒・座席情報の入ったJSONファイルをアップロード
2. 席替えボタンを押す！
3. 印刷！（またはファイルダウンロード）

試しに使ってみたい人は、
[Github](https://github.com/kamekyame/seat_change)の方に、[sample.json](https://github.com/kamekyame/seat_change/blob/master/sample.json)というファイルがあるので、それを自分のPCにダウンロードして、ファイルアップロードにぶち込んでください！

こんな感じになると思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/06138a50-f9a1-be93-5d66-83d3fd2c406c.png)

席替えボタンを押すとこんな感じにシャッフルされます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/7a90e64c-4e4a-2c36-4a71-852e19283dae.png)


# いろいろな機能
席替え自体は、上記の手順でできるわけですが、僕のクラスはこんな単純な席替えではありません笑

というのも、

- 6列6行の座席配置ですが、人数が35人なので1マス空席
- 席替え前に目の悪い人や前行きたい人が前方の席を占領

っていう条件・風習がありまして、席替え前に席を固定する必要があります。そういうクラス向けに

- 席の交換機能
- 席の固定機能

も実装してあります。

## 1.席の交換機能
名前部分をクリックすると、このように、名前一覧が出てきます。
ここで好きな名前を指定すると、席の交換ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/cfae37c8-d222-b5df-83bc-25b05ee78894.png)

## 2.席の固定機能
席の名前以外の部分（黄色いところ）をクリックすると座席の固定が出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/97a7d0e1-fc8e-fe08-bade-e355283edb95.png)

生徒１を固定するとこのようにグレーになります。
この状態でいくら席替えしても生徒1の場所は変わりません。

# 印刷
席替えをしたら、先生のために印刷をしないと...

ということで、印刷用のCSSを用いて、印刷したときにもきれいになるようにしました。
方法は簡単で、「Ctrl + P」で印刷するだけ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/ecdda162-2814-a9d8-4729-fdb8ad646f48.png)

このように、ヘッダー・フッターが消えた状態で印刷ができます。

# 先生用⇔生徒用の切り替え

実は、今見てる座席表は、生徒側から見た視点。
先生側から見ると、教卓が手前に来る形になります。

そこで、右上の「先生用⇔生徒用」ボタン。
このボタンを押すと座席内の文字が180度回転します。

この状態で印刷すると、あっという間に教卓に貼る先生用の座席表の完成です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/74aaa821-2423-4797-da13-5db22030967a.png)

# ファイル形式
アップロード・ダウンロードに使われるJSONファイルの中身については、GithubのREADMEに書いてあるので、Githubを見てください！

# 最後に
友達との軽い話から作ってみた「席替えWebアプリ」
Vue.jsを使って書いてみたのですが、スマートにかけてよかったです！
また、印刷用のCSSの存在も知れたので、個人的にはスキルアップにつながったかなぁと。

よかったら席替えの時に使ってください！（Qiitaの記事読んでる人に学生がどのくらいいるかは置いといて...）

Githubに公開してるので、issue、PR、フォークなどご自由にどうぞ！(一応MITライセンスです)