OmniAICreator/Qiita-1.07M huggingface dataset:
[2021Apr] .NET SDK for Linux の消費ディスクスペース

# はじめに

どうしても手元で VB.NET をコンパイルする必要があり、未体験だった .NET for Linux を試してみることにしました。

が、どのくらいディスクスペースを必要とするのか不明です。不安です。某 Android の開発環境は、公式情報と違って 10GiB とか 20GiB とかって勢いでディスクを消費しました。なんそれ。やめれ。

ということで調べてみました。


# 結論

すげぇ小さいです。感動的。

5.0.202-1 で 500MiB 未満。わお。

.NET Framework は 1 の頃から触ってますが、体感としては .NET 史上最小。これで VB.NET をビルド出来るんだからごいす。
（.NET Core は触ったことありません。あと Mono の事は思い出せません。あしからず。）


# 実測

### debian buster

apt install で表示される予定容量は下記です。

```
# apt install dotnet-sdk-5.0
（中略）
After this operation, 423 MB of additional disk space will be used.
（後略）
```


### debian:10.9-slim

Docker で debian:10.9-slim 上に .NET SDK を入れてみた結果のイメージサイズは下記です。

```
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
dotnet5                     latest              90b5ee0e1879        7 seconds ago       521MB
debian                      10.9-slim           48e774d3c4f5        2 weeks ago         69.3MB
```


# 余談

純正の .NET SDK の Dockerfile （たとえば[コレ](https://github.com/dotnet/dotnet-docker/blob/ec4af28c9e9a643baff525b68c38c18cd02f2e36/src/sdk/5.0/buster-slim/amd64/Dockerfile)）では apt リポジトリは使ってなくて、tarball を使ってました。

なんかちょっと好感が持てました。バージョンを固定する意識（バージョン再現性を担保する意識）があるのかなーと想像したりして。

ちなみに同 Dockerfile では PowerShell もセットアップしていますが、単に dotnet new して dotnet run するだけなら PowerShell 無くても .NET SDK だけでＯＫぽいです。手元ではＯＫでした。


# おわりに

実はオンライン IDE 的なもので VB.NET の実験をしていたのですが、幾つか試すも LINQ できるものが無くて。

コードエディタがリッチなものが多かったですが、欲しいのはそこじゃなくて、Imports なんかも含め VB.NET がちゃんと動く処理系だったので、手元にセットアップすることにした次第です。

もっと時間をかけて探せば見つかったのかもしれないですが、手元に構築するのが存外に超絶簡単と判明したので、今後は手元で実験に励む所存です。
JS基礎文法~関数~

#概要
関数についての記事です。
引数、仮引数について取り上げて行きます。

#関数
関数とは様々な処理を１つの命令にまとめることができます。

```index.js
function show() {
  console.log('A');
  console.log('B');
  console.log('C');
}

show();
```
関数は、functionに名前を付けます。今回は、名前を付けます。
関数の中の処理を呼び出すためには関数名();とすることで呼び出すことができます。

```index.js
 console.log('------');
 show();
 console.log('------');
 show();
 console.log('------');
```

![スクリーンショット 2021-04-29 17.52.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/4ed37b85-bc6c-b52f-00eb-0f0f0dec4b47.png)

このように関数化することで、後で内容を変更する必要があるときにメンテナンスが楽になりますね。

```index.js
for(let i = 0; i <= 4; i++) {
 show();
}
```

ページ内であれば、呼び出すことができます。

#仮引数,実引数

```index.js
function show(msg) {//仮引数
  console.log('A');
  console.log(`--${msg}--`);
  console.log('C');
}
    
console.log('------');
show('hey');//実引数
console.log('------');
show('hello');
console.log('------');

```

また関数を呼び出す際に値を渡すことができます。これを実引数と言います。
そして元の値に仮置きする値を仮引数といいます。

![スクリーンショット 2021-04-29 18.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/796c26a4-4c8f-ab5a-e64c-f4946e109447.png)


#return

```index.js
function total (a,b,c) {
  console.log(a * b * c);
}

total(2,4,6); //48
total(5,3,8); //120

```
これを合算したいと思います。

```index.js
function total (a,b,c) {
  console.log(a * b * c);
}

const aaa = total(2,4,6); //48
const bbb = total(5,3,8); //120

const totalNum = aaa + bbb;
console.log(totalNum);
```

結果はNaNでした。
これは数値を求める計算で結果が数字にならないときに現れます。
この関数では、結果を返しているからです。その場合はreturnを使います。関数を実行して返ってくる値です。
returnを使うことで、関数を式に入れて使うことができます。

```index.js
function total (a,b,c) {
 return a * b * c;
}

const aaa = total(2,4,6); //48
const bbb = total(5,3,8); //120

     
const totalNum = aaa + bbb;
console.log(totalNum);
```
先程の計算式の結果は168でした。

```index.js
function name() {
   return
}
   
console.log(name());

```

undefinedが返ってきます。これは未定義という意味です。

またreturnの後に処理を記述しても実行されません。
ターミナルでちょっと役立つショートカット

（結構、常識かもしんないけど・・・）

`commnad + k`で、これまでのコマンドとログの履歴を一瞬で全て消去してくれる！！
「世紀の大発見じゃヨッシャー！」と数カ月間も悦に浸ってたけど、普通に上の編集メニューの所に載ってありますた...


そりゃそうだわ
Reactでポートフォリオサイトを作成

##はじめに##
アプリを作成する上での今回のテーマは次の通りです。

**1. 何かしらのデザインツールを使用してデザインを作成する。
2. Atomic Designの概念を理解し、コンポーネント指向でアプリを作成する。**


これらを意識してデザイン作成を行う事で、Atomic Designとコンポーネントに関しての理解を深める事や、将来的にデザイナーさんやその他の方達とスムーズにコミュニケーションを取る為の最低限のデザインに関する知識を身につける事が今回のメインのテーマでした。

##デザイン##
今回はデザインを作成するにあたってFigmaを使用しました。苦労した点としては、デザインツール自体の利用が初めてだったので使い方を覚えるところから始めました。基本的に使いながら覚える事は大事ですが、どこにどんな機能があるかや最低限の良く利用する便利な機能などのインプット学習は、ある程度必要だと思いました。

特に良く使用する機能として『グループ化』、『コンポーネント機能』があります。
ここで大事になってくるのがAtomic Designに基づいたデザインでの構築です。
Figmaを使ってデザインを作成しているうちに、Atoms, Molecules, Organisms, Components, Templatesといった概念が身についていきました。
>[超初心者がAtomic Designをより理解する為のアドバイス](https://qiita.com/shumanbeing/items/28dbc6b589cf9cf05ee7)

こちらがFigmaで実際に作成したアプリの一部です。
![550410CA-C306-490F-B29B-686306AD7778.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825163/7646b767-3299-3011-cb0a-015b130c940e.jpeg)

コンポーネント化した部分は**ヘッダー**と**プロジェクトのアイテム部分**です。
本来であればコンタクトフォームの送信ボタンなども使い回せるようにしたかったのですが、このアプリでは他に使い道もないのでやめておきました。

##アプリの作成##
今回はReactとTypeScriptを使ってアプリを作成しました。
以下、使用した主な技術とバージョンです。

```react
"@material-ui/core": "^4.11.3",
"@reduxjs/toolkit": "^1.5.1",
"node-sass": "4.14.1",
"react": "^17.0.2",
"react-hook-form": "^7.1.1",
"react-scripts": "4.0.3",
"typescript": "~4.1.5"
```

###style###
styleは基本的に全てmodule.scssで構成しました。
ただ、コンポーネント化したものをスタイルを変えて使いたい時はstyled-componentsを使う方が便利なのかなとも思いました。特にMaterial-UIを使用していると相性も良さそうなのでこの辺は次回への課題とします。

####データの取得####
お問い合わせフォームには、ReactHookFormを使用してデータを取得できるようにしました。
理由は楽チンだからです。


##Amplifyを使ったデプロイ##
まだ中身はスカスカアプリですが、まずは経験という意味も込めてとりあえず強引にデプロイまで持っていく事にしてみました。
AWSにはとてもたくさんの機能があるため、初心者には知らない言葉や機能が多すぎてとてもハードルが大きく感じます。ですが、Amplifyを使ったデプロイをする事だけであれば、ゴールがとても明確かつすぐに達成可能なので挫折しないで済みます。
設定の段階でAmplifyとgithubを連携してあるので、デプロイした後でも開発環境でちょっとした変更を加えた場合は、メインのブランチにマージすれば自動で反映される仕組みになっているのでちょっとした感動すら覚えました。
つい数日前までAWSで何ができるのかさえ全く分からなかった自分が、ちょびっとだけAWSを使ってできる機能を知る事ができたのでチャレンジしてみて良かったです。
>参考ページ
[Amplify CLI をインストールしてユーザーを設定する手順](https://dev.classmethod.jp/articles/aws-cli-install/)
[AmplifyでReactアプリのデプロイ、CI/CDをする公式チュートリアルをやってみた](https://dev.classmethod.jp/articles/amplify-react-cicd-tutorial/)


##まとめ##

デザインを仕上げるだけで二週間以上かかってしまい、なかなか進まずに苦しい時期がありました。
しかし、実際にコードを書き始める前にこのプロセスを踏んだ事で、目に見える部分だけでなく全体像を把握する事ができました。さらに、丁寧に設計ができたおかげでコードを書き始めてからはとても早かったので、非常に重要な工程だという事が良く分かり勉強になりました。
ios admobで、GADInvalidInitializationExceptionが消えなくて泣きそうだった話

admobに登録してあるアプリのメンテナンスしようとして、

https://developers.google.com/admob/ios/ios14

を参考に作業してみようかなと思って
`pod update`
の後、buildしてみると、
`Terminating app due to uncaught exception 'GADInvalidInitializationException', reason: 'The Google Mobile Ads SDK was initialized without AppMeasurement. Google AdMob publishers, follow instructions here: https://googlemobileadssdk.page.link/admob-ios-update-plist to include the AppMeasurement framework and set the -ObjC linker flag`
という例外でアプリがクラッシュしまくる。

言われた通りに`Info.plist`を編集してるだけなのだが。。。
ググりまくったら、以下の解決法を発見。
これで良いのかわからないけど、とりあえず動くようになった。

#解決法
Info.plistに
```<key>GADIsAdManagerApp</key>
    <true/>```
を追加。

#参考リンク
https://stackoverflow.com/questions/66411662/the-google-mobile-ads-sdk-was-initialized-without-appmeasurement

https://qiita.com/ko2ic/items/407f2e2841b355ebd126
APIについて

これからAPIについて触れていく機会も増えそうなので基本的なことをまとめました。
#そもそもAPIとは？
- `Application Programming Interface`の略で、他社が提供するサービス内の情報や機能を外部で扱えるようにする仕組み。

- 身近な例だと、外部サイト上でのGoogleやFacebookアカウントを使ったログイン機能。

- APIを使う方には他社の機能を使うことができ、使われる方には自社のサービスを使ってもらうことになる。

#WebAPIとは
- API提供者とAPI利用者とのやりとりを`HTTP／HTTPSベースで(つまりWebベースで)`実現するAPIのこと。

- 異なるプログラミング言語で開発されたアプリケーション間を連携させることが可能。

- ほとんどのAPIはWebAPIを指している。

#REST APIとは
- WebAPIの一つで、「RESTの原則」に従って実装されているAPI。

- 「RESTの原則」とは`「アドレス可能性」``「ステートレス性」``「接続性」``「統一インターフェース」`から成り立っている。

- `アドレス可能性(Addressability)`
 提供する情報がURIを通して表現できること。全ての情報はURIで表現される一意なアドレスを持っていること。

- `ステートレス性(Stateless)`
  HTTPをベースにしたステートレスなクライアント/サーバプロトコルであること。セッション等の状態管理はせず、やり取りされる情報はそれ自体で完結して解釈できること。

- `接続性(Connectability)`
 情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができること。

- `統一インターフェース(Uniform Interface)`
 情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)を利用すること。
PHP if文の条件式にnullが来るとfalseとして振る舞われるのを知らなかった

# 目的

- 先輩方のソースを見ていて意外と知らなかったif文の条件式にnullを入れたときの振る舞いについて簡単にまとめる

# 情報

- 下記サービスを利用して動作確認をした。
    - [https://paiza.io/ja](https://paiza.io/ja)

# 紹介

1. 下記のような簡単なPHPのソースが合ったとする。

    ```php
    <?php

    $str = 'aaa';

    if ($str) {
        echo '変数はnullではありません';
    } else {
        echo '変数はnullです';
    }
    ```

1. 上記を実行すると「変数はnullではありません」と出力される。
1. $strにnullを格納してみる。

    ```php
    <?php

    $str = null;

    if ($str) {
        echo '変数はnullではありません';
    } else {
        echo '変数はnullです';
    }
    ```

1. 上記を実行すると「変数はnullです」と出力される。
テンプレートリテラル

# テンプレートリテラル
これまで文字列や変数、定数の連結には「`+`」を用いていましたが、それ以外の方法として「`テンプレートリテラル`」という連結方法があります。
記述としては「\``〇〇${定数or変数}〇〇`\`」のように記述することで、文字列の中に定数や変数を含めることができます。
このとき、文字列全体は「 ' (シングルクォーテーション)」ではなく「 ` (バッククォーテーション)」を用いる必要があります。

```js:例
const name = 'Abe'
// 「+」を用いた場合
console.log('私の名前は' + name + 'です');
//テンプレートリテラルを用いた場合
console.log(`私の名前は${name}です`);
```
```text:出力結果
私の名前はAbeです
私の名前はAbeです
```
上記のように、テンプレートリテラルを用いても、「+」を用いた時と同様の出力結果を出すことができました。
【勉強】Next.jsで簡単な掲示板作成

#はじめに
私はモダンな技術の実務経験が無いため、Javascriptを勉強しています。
この記事では以前、Next.jsを勉強した際に作成した簡易掲示板について記載しました。

#なぜ掲示板か
教材に掲示板を選んだ理由は、初めての個人開発ということもあり、
CURD全ての機能が備わっている物が良かったからです。
個人的に勉強はしたいが何を題材にすればよいかわからない方におすすめです。

#なぜNext.js?
数あるJavascriptのフレームワークの内、Next.jsを選んだ理由についてです。
どうしてもNode.jsを使いたかったので、それと相性がいいこととが第一条件で、
一番の決め手は知人に進められたからです。

個人開発なので使う技術は普段触れない物で良いと思うのですが、
今思えば無知な状態からNext.jsではなくReactを一通り学んだ後にNext.jsに触ればよかったです……。

#実際に作った画面
[![Image from Gyazo](https://i.gyazo.com/608906ac710868f5621d5914ae3d56d6.png)](https://gyazo.com/608906ac710868f5621d5914ae3d56d6)

#機能
- 投稿表示
- 新規投稿
- 投稿削除

#環境
|名前|役割|
|---|---|
|scss|デザイン全般|
|Next.js(React.js)|フロントエンド|
|Node.js|サーバーサイド|
|MySQL|データベース|

#GitHub
https://github.com/okioka/NextBBS
※ローカルですが実際にPCで動かすこともできます。

#感想
- 大変だったこと

コンポーネント指向を理解することが難しかったです。
JavaServletでしかWebの開発をしたことがなかったことから、
今まではHTML、CSS、JavaScriptで分けて考えることが自分の中の常識としてありましたが、
コンポーネント指向では一つにして考えるので慣れるまで時間がかかりました。  

モチベーションを保つ事が大変でした。
今回は小規模で終わりが見えていたのでモチベーションの維持ができましたが、
個人開発で大規模な開発をする時に、まずはどうやってモチベーションを
維持するか考えないといけないです。
やはり自分が好きなもの、本当に欲しいと思っている物を作ることが
モチベーション保つ秘訣だと思いました。

- 学びがあったこと

今自分が触れている技術と比べて新しいので資料が少なかったです。
公式ドキュメントなどを見て調べる習慣がつきました。 

調べてもわからないことは聞くべきだと思います。
仕事ではわからないことを聞くことは当たり前ですが、
個人的な勉強で聞くことをしていませんでした。
わからないことは知り合いに聞いたり技術書を読むとで解決することができました。
自分の考えだけで解決しようとするのではなく、
自分では思いつかないような考え方に日頃から触れるようにしましょう。

#おわりに
最後まで読んでいただきありがとうございました！
VSCodeで制御文字を表示させてみた

# はじめに
以前Rubyでコードを書いてたら、何だったかは忘れたけど何らかのエラーが発生して実行できなかった。お手本となるサンプルコードを見てみてもどこが間違ってるのか確認できなかったが、コピペした訳じゃないので何かあると思いメンターさんに質問。結論！どうやら**不可視の文字が挿入されていることによるバグ**だったようだ。今考えれば、これはただの**制御文字**だったんじゃないだろうか...
本記事では、その制御文字をVSCodeのエディタ上に表示させて、バグを再現してみる。



# 前提条件
- macOS Catalina ( 10.15.7 )
- [Visual Studio Code.app](https://code.visualstudio.com/) ( 1.55.2 )
- [Google 日本語入力.app](https://www.google.co.jp/ime/) ( 2.25.4000.1+24.7.9[^1] )

[^1]: 「ばーじょん」と打てば、教えてくれる。

※あくまでこのブログ執筆時のバージョン
また、VSCodeの設定から

```settings.json
"editor.renderControlCharacters": true
```
と、有効にしておく必要がある。



# 本題
まずは、拡張子を`.js`として、空のファイルにテキトーな名前を付けて保存する(拡張子を`.rb`等にしても制御文字は表示できるが、何故かパネルの問題タブにエラーとして出力されない)。
操作はカンタン♪。一度、何でも良いから全角で文字を打ち、`return`キーで確定させて`delete`キーで一旦削除。その後もう一度、何でも良いから全角で文字を打ち、２回`delete`キーを押せばデキアガリ♪

![control-character](https://i.gyazo.com/8ae031f020f7e7b3684c5fa82090f072.mp4 “制御文字を表示”)

確かに全角で文字を打ってた時に似たような操作をした覚えがあるのだが、当時は上記の制御文字をエディタ上に表示させる設定をしていなかったから、確証はできない。ただこうやって視覚化しておくと、コーディング中に削除することができるので、Webサイトに添付するときの文字化けやプログラム実行時のエラーの予防につながる。



# 参考記事
- [エラー「 Invalid char `\x08' in expression」の倒し方 - tattaka_s’s blog](https://tattaka-s.hatenablog.com/entry/2019/07/06/153703)



# 関連投稿記事
- [VSCode関連で独自にちょっとだけカスタマイズした環境設定を晒す(part. 3/3) - Qiita](https://qiita.com/tsutsumin_pro/items/79ef5eaac6a38d4af085)
Ubuntu18.04でデフォルト4GBの論理ボリュームのサイズを変更する

自作PCで遊んでいたら、1か月もたたないうちに**ディスクの容量がいっぱいです**と怒られるようになった。
256GBのSSDでPCを作ったのでディスク容量がいっぱいになるわけがなく、調べた結果、本記事に記載する解決策にたどり着いた。


#環境
OS：Ubuntu Server 18.04
PCのディスク：容量 256GB のSSD

#症状
たくさんありますが、代表的なものをあげます。

###１．ダウンロードしたり、新しいファイルを書き込ませてくれない

ダウンロードなどしようとすると「ディスク容量がいっぱい」と言われる。

`df -h`の結果、次のように`/dev/mapper/ubuntu--vg-ubuntu--lv`が4GBしかなく、それが既にいっぱいになっている模様。

```
Filesystem                         Size  Used Avail Use% Mounted on
udev                               3.8G     0  3.8G   0% /dev
tmpfs                              785M  2.7M  782M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv  3.9G  3.6G   92M  98% /
tmpfs                              3.9G     0  3.9G   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
tmpfs                              3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/loop0                          98M   98M     0 100% /snap/core/10444
/dev/loop1                         100M  100M     0 100% /snap/core/10958
/dev/sda2                          976M  147M  763M  17% /boot
tmpfs                              785M     0  785M   0% /run/user/1000
```


###２．タブ補完をさせてくれない

`cannot create temp file for here-document: No space left on device`っていわれる。

タブ補完ができないのはなかなかうざい。



#解決方法

物理ボリュームと論理ボリュームというものがあり、**論理ボリューム**に空き容量がないことが今回の主原因。
→　**論理ボリュームを拡張する**

## 手順

ボリュームグループの既存の空き領域をすべて使用するために、論理ボリュームのサイズを変更する。

```
$ lvm
lvm> lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
lvm> exit
```

続いて、論理ボリュームを使用可能にする。

```
$ resize2fs /dev/ubuntu-vg/ubuntu-lv
```


これで完了。

## 手順後の結果
`df -h`の結果、

```
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv  229G  3.6G  215G   2% /
```

のように、ボリュームをフルに活用できる状態になりました。

##試したが駄目だったこと

`/var/tmp/`のフォルダをrmしたりしたが、変わらず。原因を踏まえると当たり前なんですけどね。


#原因の解説
現象を簡潔に説明すると、「**論理ボリューム**に空き容量がない」
もっと直感的にいうと、「`/`に空き容量がない」

`/`以下にあるフォルダの自由がなくなるため、タブ補完などもできなくなった。

bashはタブ補完をしようとしたとき`/tmp`に一時的にファイルを作成するので
`/tmp`は`/`の領域に含まれ、ここに空き容量がないため、タブ補完時にエラーメッセージが表示されたと考えれる。
`/`で空き容量が不足しているということは`/etc`や`/var`にもファイルを書き込めないとい。


##参考

[Ubuntu Server 18.04 LVMの不適切なデフォルトのパーティション分割によるスペース不足](https://qastack.jp/ubuntu/1106795/ubuntu-server-18-04-lvm-out-of-space-with-improper-default-partitioning)

[LVMとは](https://qastack.jp/ubuntu/3596/what-is-lvm-and-what-is-it-used-for)

[LVMで 論理ボリュームの作成、拡張、縮小、複製](https://qiita.com/TsutomuNakamura/items/93c6333c8dd32aeb197a#%E8%A3%9C%E8%B6%B3%E8%AB%96%E7%90%86%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%82%92%E6%8B%A1%E5%BC%B5%E3%81%99%E3%82%8B)
WSLでio_uringを使う 2021/04

# はじめに

WSLでデフォルトで使われるカーネルは`io_uring`が無効になっています。
すこし調べると[本家](https://github.com/microsoft/WSL2-Linux-Kernel)からフォークした[こちら](https://github.com/nathanchance/WSL2-Linux-Kernel)のリポジトリでbzImageが配布されていて`io_uring`が使えるのですが、少しヘビーな使う方をするとうまく動きません。https://github.com/hatoo/io_uring_test のプログラムがうまく動きません。

今回は普通にhttps://github.com/microsoft/WSL2-Linux-Kernel のコンフィグをいじって自分でカーネルをビルドしたらうまく行ったのでそのやり方を共有します。

# 手順

作業はWSL上で行います

## 1. `microsoft/WSL2-Linux-Kernel`の[リリースページ](https://github.com/microsoft/WSL2-Linux-Kernel/releases)からソースコードをダウンロードする。
クローンしたコードだとうまくいきませんでした

```
$ wget https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/linux-msft-wsl-5.10.16.3.tar.gz
```
##2. 解凍する

```
$ tar -zxvf https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/linux-msft-wsl-5.10.16.3.tar.gz
$ cd linux-msft-wsl-5.10.16.3
```

## 3. コンフィグを編集して`io_uring`を有効にする

`Microsoft/config-wsl`を編集して`CONFIG_IO_URING`のところを`CONFIG_IO_URING=y`にする。

## 4. Make

```
make -j16 KCONFIG_CONFIG=Microsoft/config-wsl
```

## 5. bzImageをWindowsの適当なところに置く

例えば

```
cp arch/x86_64/boot/bzImage /mnt/c/Users/$(ユーザー名)/Linux/bzImage
```

## 6. .wslconfigを編集する

`C:\Users\$(ユーザー名)\.wslconfig`を編集して

こんな感じにする

```
[wsl2]
kernel = C:\\Users\\$(ユーザー名)\\Linux\\bzImage
```

## 7 WSLの再起動

Windowsのシェルで

```
> wsl --shutdown
```

# ulimit -l

`io_uring`を使っていると`max locked memory`の値が足りなくてエラーになることがあります。
WSLだと普通のやり方ではulimitの値が変えられないようなのでその場合はhttps://github.com/microsoft/WSL/issues/1576#issuecomment-643804974 を参考にすると良いです。
出力/変数/定数

# JavaScript
JavaScriptでは、コンソールに出力させるには、「`console.log();`」を用います。
このとき、「`;(セミコロン)`」を記述し忘れないようにする必要があります.
コメントアウトは文頭に「`//`」と記述することで、その行はコメントと見なされます。


```js:例
console.log('Good morning');   // console.logを用いて出力
```
```text:出力結果
Good morning
```
# 変数の定義
変数の定義は「`let 変数名 = 値;`」と記述するすることで定義できます。
ここでも、末尾に「`;(セミコロン)`」を忘れないようにする必要があります。

```js:例
let name = 'Abe';
console.log(name);
```
```text:出力結果
Abe
```
### 変数の更新
変数は一度代入した値を変更することができます。
「`変数名 = 新しい値`」と記述することで値を変更できます。
このとき、文頭に`let`は記述する必要はありません。

```js:例
let name = 'Abe';
console.log(name);

name = 'Inoue';
console.log(name);
```
```text:出力結果
Abe
Inoue
```

# 定数の定義
定数の定義は`let`の代わりに「`const`」と記述することで定義できます。
なので記述としては、「`const 定数名 = 値;`」と記述します。
定数と変数の違いは、変数では一度代入した値を更新することができましたが、
`定数では値を更新することができません`。

```js:例
const name = 'Abe';
name = 'Inoue';   //値を更新しようとするとエラーが発生します
console.log(name);
```
定数のメリットとしては「`後から値を更新できない`」という点が挙げられます。

これは予期せぬ更新を防ぐことができ、より安全なコードを書くことができます。
また、第三者がコードを見たときに変更しないものだとすぐ判断できる為、可読性を上げることができます。
オブジェクト指向について学習（アウトプット）

オブジェクト指向について学べる記事を紹介して頂いたので、自身のアプトプット用にまとめました。

https://qiita.com/tutinoco/items/6952b01e5fc38914ec4e

こちらの記事を参考に勉強したいと思います！

# オブジェクト指向の3大要素

###1. 継承

クラス同士の関係性を`「AはBである」`と表現することができる。
例）トラックは車である。

継承は親クラスの要素を受け継ぐという意味と解説されることが多いが、継承の本質は***「交換可能なパーツを作成するために共通点を「規格」としてまとめることができるインターフェース」***である。
例）車の部品（エンジン、ハンドル、タイヤ等）はどの車でも使うので、***共通部品***としておく。

```java
Engine engine = new JetEngine();
Handle handle = new QuickHandle();
Brake brake = new AntilockBrake();
Wheel wheel = new StudlessWheel();

Car car = new Car(engine, handle, brake, wheel);
```


そうすることで部品は何度も１から作る手間がなくなり、かつハンドルを変えたりすることが容易になりプログラムに柔軟性が生まれる。


###2. ポリモーフィズム（多様性）
抽象クラスやインターフェースなどを利用して、メソッドの呼び出し方法を共通化し、「オーバーライド」させることによって、インスタンスごとに違う挙動をさせる。
例）犬でも猫でも動物として扱い、鳴くという処理を犬「わんわん」猫「にゃー」とさせる。

```java
    //動物の鳴くの処理はこれだけで済む
    //なんの動物か書いてないので、抽象的である。※1
    animal.bark();

    //犬クラス
    public void bark() {
        System.out.println("いぬ：ワンワンワン");
    }
```

ポリモーフィズムは***「インターフェース（抽象・規格）に対してプログラムする」***(※1)

### 3. カプセル化
情報を隠蔽することによって、不整合を起こすような操作ができないようにする仕組み。
フィールドをprivateにすると外部から操作できないので、使いたいときはgetterとsetterにしていたやつですね。

***カプセル化とは抽象化のことであり、無駄を省き、外から見ても複雑でない状態を作ること。***
実現させるためにはクラスの役割は1つにし、正しい名前を付ける必要がある。

よくわからなかったのでこちらの記事を参考にしました。

https://nobuo-create.net/java-beginner-24/

カプセル化はどうすればよい感じに実現できるのか？
getter,setter使いまくってたら意味ないよね？

例えば満腹度が上下するプログラムの時、満腹度が直接いじれてしまうとまずいですよね。
急に満腹になったりお腹が空いたりしてしまいます。
外部から隠蔽するためにカプセル化（private）しておきます。

満腹度を直接いじるのではなく、走ったり食べたりするメソッドにより満腹度が上下するようにします。
これならいきなり満腹度をいじることはできなくなります。

```java
public class Human{
        private static int count_Human = 0;
	private String name;
        private int birthday;
        private int manpukudo;

        //　getter,setter省略

        public int getManpukudo(){
                return this.manpukudo;
        }

        public void eat(){
                this.manpukudo += 60;
        }

        public void walk(){
                this.manpukudo -= 10;
        }

        public void run(){
                this.manpukudo -= 20;
        }
}
```

# オブジェクト指向の目的
オブジェクト指向の目的は***「変更に対して柔軟に対応する」***ためです。
プログラムには変更がされない箇所と、頻繁に変更されるであろう箇所が出てきます。
オブジェクト指向は***頻繁に変更される箇所をクラスに抽出するプログラミングスタイル***です。

例）ハンバーガーファストフード店で新商品が発売される前提でシステム開発をすると、新しいポテトが発売しても柔軟に対応できます。
しかし、PCも販売するかも！と設計するのは過剰実装です。

頻繁に変更されるであろう「食品の新商品」は加味して設計する必要がありますが、自動車製品の販売をすることは変更の可能性が低いです。

変更の可能性が低い箇所を土台に、高い箇所に気を配って設計する必要があります。


# 感想
オブジェクト指向は、頻繁に変更される事項を共通点としてをまとめておいて、使いやすい、分かりやすいを実現させようということでしょうか。
まだ理解はできていないですが、実務でなるほどと思えると嬉しいです。
DockerでOracle19cを構築しようとした際に発生したエラー

## 事象
こちらの記事を参考に、Mac端末でOracle19cのDocker環境を構築しようとしていたのですが、

- [CentOS7上のDockerにOracle19cを構築してみた]
(https://qiita.com/tori15specr/items/50149eb8d49eddba2718)

`docker run`コマンドを叩いたところ以下のエラーが発生しました。

```bash
/opt/oracle/product/19c/dbhome_1/bin/dbca: line 135: /u01/app/oracle/product/19.0.0/dbhome_1/bin/platform_common: No such file or directory
```

## 原因
githubに同じエラーが出ている方がいました。
https://github.com/oracle/docker-images/issues/1257

どうやらdocker Imageのbuild時に**不完全なImage**が作られていたようでした。
dockerのメモリとディスク領域が不足していたことが原因のようですので、今回はDockerの環境設定でメモリを４GB、ディスク領域の空き容量を１００GB程度に設定して改めてbuildし直します。
![スクリーンショット 2021-04-29 18.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434874/18cf91a4-1a59-9eb7-3f6e-904d6ff63261.png)

設定後、出来上がってしまっている不完全なImageを削除し、再度buildを行います。

```bash
$ ./buildDockerImage.sh -v 19.3.0 -e -i
```

うん、最初のbuildの時よりも**めっちゃ時間がかかる**。

Imageが出来上がった後、`docker run`をすれば構築完了ですが、この時もすでに出来上がっているコンテナを事前に削除しておきましょう!

## 補足
エラー解決の際、こちらの記事も参考になりました!

- [[Oracle Database] 公式Docker Imageを利用してOracle Database 19c環境を構築してみた](https://itedge.stars.ne.jp/docker_image_oracle_database_19c/)
- [[Oracle Database] 公式Docker Imageを利用してOracle Database 19c環境を構築してみた（解決したエラー編）](https://itedge.stars.ne.jp/docker_image_oracle_database_19c_error/)
VBA IEで自動ログイン

```
Sub facebook_login()
‘ ツール->参照設定
‘ Microsoft Internet Controls
‘ Microsoft HTML Object Libraly
Dim IE As New SHDocVw.InternetExplorer
With IE
.Visible = True
.Navigate "facebook.com"
Do While .ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
End With
‘ここは「検証」からclassを確認
‘クラス名前が一意であることを確認
IE.Document.all("email").Value = "実際のEメールアドレス"
IE.Document.all("pass").Value = "実際のパスワード"
IE.Document.forms("login_form").submit
End Sub
EC2オートスケーリングの為のステートレスサーバー化についての備忘録

### オートスケーリングについて
AWS EC2インスタンスの運用時には単体EC2インスタンスの場合でも、
将来的な拡張性に備えてAutoScalingグループ内での運用が望ましいようです。

**参考**

https://cloudonaut.io/5-aws-mistakes-you-should-avoid/
>すべてのEC2インスタンスは、Auto Scaling グループ内で実行されるべきです。たとえEC2インスタンスが1つだったとしても同じです。Auto Scaling グループは、EC2インスタンスをモニタリングし、仮想マシンの論理グループとして機能するもので、しかも無償なのです。





### メリット
1. 可用性の向上
2. 負荷分散
3. 運用コストの最適化

### ステートレスサーバー化
オートスケーリングはAMI（Amazon Machine Image）を利用して
インスタンスをスケーリングする為、
サーバー内に変更点があった場合、
スケーリング時にAMIの時点のサーバーの状態へと先祖返りしてしまいます。

これを回避する為には、
サーバーのステートレス化（サーバーが状態を持たないようにする）を実現する為の
アーキテクチャ設計の工夫が色々と必要になってきます。

**参考**

https://dev.classmethod.jp/articles/autoscaling_considerations-for-system-configuration/

>不安定になったEC2はいつでも捨てられる（Terminateできる）よう内部にデータは保持しないことが重要となります。データを保持していると不安定になった際にインスタンスがTerminateされて、なくなってしまいます。ここでいうデータには次のものが考えられます。

>・アプリケーションで生成された永続的に保管すべきデータ
・アップロードされた画像ファイルなど
・HTTPなどのセッションデータ
・ApacheやTomcatなどのログファイル
・/var/log/messages などOSのログファイル


#### 静的アセット
CloudFront(CDN)、S3を用いてサーバー外へ配置

#### セッション、キャッシュデータ
ElastiCache(Redis)を利用したインメモリの外部化

#### サーバー内ログファイル
CloudTrailを利用したログファイルの監視

#### マウント先のボリューム
ElasticFileSystem(NFS)を利用したボリュームのネットワーク共有


ステートレスなオートスケーリング利用のアーキテクチャ設計一案（個人的見解に基づく）
![AutoScaling.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178806/a448ad93-07ab-3d6a-68c9-a90a12a72ea4.png)

もちろんここであげたものはあくまで一例にすぎず
ケースに応じたインフラ設計が必要になってくることかと思います。

参考
---
https://cloudonaut.io/5-aws-mistakes-you-should-avoid/

https://www.fenet.jp/aws/column/aws-beginner/323/

https://dev.classmethod.jp/articles/autoscaling_considerations-for-system-configuration/
関数を作って遊んでみた！【備忘録】

こんにちは！
今日は、タイトルの通り、JavaScriptを使って、「関数」を作って遊んでみました！

関数とは、ある処理を記述した部品です。
部品を組み合わせることで、1つのアプリケーションやWebサービスは動きます。

例えば、車。
車は、外見だけでは、動きません。エンジンや、ブレーキなどの部品が正常に動かなければ、乗り物の車としては動いてくれません。
(車に詳しい方からしたら、若干、表現がおかしいかもしれないです、すみません...)

私自身、まだまだプログラミング初心者で、JavaScriptの基礎をまだまだ固めきれていないので、テキスト片手に勉強をしています。今日の内容は、関数についてだったのですが、読んで、サンプルコードやってみて、意味はわかるんだけど、正直、「え、わかっちゃって大丈夫？？自分でちゃんと作れるんかなー？？」と思い、関数をいくつか自分で作ってみて、遊んでみました！

ちなみに、テキストを読んでから、テキストを閉じて、遊んだので、これから紹介する関数は、全て、テキストのサンプルコードとは異なります。(似ているものはあります。)

# 1. 〇〇は美味い！と返す関数
引数として渡した値を〇〇の中に入れて、返します。

```JavaScript
function sample1(drink) {
    return `${drink}は美味い！`;
}

let sampleResponse1 = sample1('芋焼酎');
console.log(sampleResponse1);
// 芋焼酎は美味い！ と返ってきます。
```
# 2. 年齢によって返す値が変わる関数
引数に渡された値を、if文で条件分岐させて、返ってくる値を変えます。
年齢を指定した条件で比較して、当てはまる年齢範囲の文章を返します。

``` JavaScript
function sample2(age) {
    if (age >= 18) {
        return `${age}歳は、18歳以上ですので、入場料は、1,500円です。`
    } else if (age >= 9) {
        return `${age}歳は、9歳以上17歳以下ですので、入場料は、1,000円です。`
    } else {
        return `${age}歳は、無料招待の対象です。`
    }
}

let sampleResponse2 = sample2(5);
let sampleResponse2_2 = sample2(25);
let sampleResponse2_3 = sample2(16);
console.log(sampleResponse2);
// 5歳は、無料招待の対象です。
console.log(sampleResponse2_2);
// 25歳は、18歳以上ですので、入場料は、1,500円です。
console.log(sampleResponse2_3);
// 16歳は、9歳以上17歳以下ですので、入場料は、1,000円です。
```

# 3. 引数にオブジェクトを渡してみた！！
今度は、引数にオブジェクトを渡してみました。
ちなみに、オブジェクトとは、名前と値を1セットにしたプロパティを持つデータ型のことです。
オブジェクトにも、プロパティの値に関数が入った場合、そのプロパティはメソッドと呼ぶ、など細かく種類が分かれていますが、今回は、通常の名前と値の1セット(プロパティ)で進めて行きます。

以下では、引数に渡したオブジェクトの中のプロパティから、名前(item)と値(price)を取り出して、それらを利用した文章を返してきます。

```JavaScript
function sample3(itemObj) {
    return `${itemObj.item}は、${itemObj.price}円です。`
}

let aboutItem = {item: 'MacBook Pro', price: '240,000'}

let sampleResponse3 = sample3(aboutItem);

// ユーザー定義関数sample3の引数には、オブジェクトであるaboutItemを渡している。
console.log(sampleResponse3);
// MacBook Proは、240,000円です。
```

# 4. 複数のオブジェクトを引数に渡してみた！！
1つ上の3では、オブジェクトを1つ渡しました。
今回は、いくつか渡してみましょう！
引数にいくつかのオブジェクトを渡し、それぞれのオブジェクトの中のプロパティから名前と値を取り出して、それらを利用した文章が返ってくるようにしてみましょう。

この時、1つ1つオブジェクトを変数宣言して渡すのは面倒なので、引数として渡すオブジェクトを全て配列の要素にしてしまい、その配列をスプレッド構文でささっと渡してしまいましょう！

※スプレッド構文については、<a href="https://qiita.com/azunas/items/6735c1cf08e8f650bda7">こちら</a>で解説しているので、ご覧ください！

```JavaScript
function sample4(item1, item2, item3) {
    return `${item1.item}は、${item1.price}円、${item2.item}は、${item2.price}円、${item3.item}は、${item3.price}円です。`
}

let items = [
    {item: 'トマト', price: 98},
    {item: 'キャベツ', price: 158},
    {item: '大根', price: 190}
]

let sampleResponse4 = sample4(...items);
console.log(sampleResponse4);
// トマトは、98円、キャベツは、158円、大根は、190円です。
```

# おわりに
関数やオブジェクトへの理解が浅かったのですが、今回、遊んでみたおかげで少し、理解を深めることができました。
また、何を返そうか考えるのが楽しかったので、難しそうに見える関数への印象が変わり、仲良くなれそうな気がしました。
ぜひ、皆さんも、「理解が浅いな」と感じる文法で遊んでみてはいかがでしょうか？？

もし、間違っている点や補足などございましたら、コメント頂けますと、助かります！！

お読み頂き、ありがとうございました！

# 参考文献
以下のテキストで勉強しました。
柳井政和著 『JavaScript[完全]入門』(2021)
Intellijの罠、MybatisのInvalid bound statement (not found)

Mapper XMLとMapperクラスのパスが同じなのに
なぜか`Invalid bound statement (not found)`と表示される。。。

それはディレクトリの名前、階層がおかしい可能性があります。
例　これが
・`src/main/java/com/example/demo`
・`src/main/resources/com/example/demo`
こうなっているかも
・`src/main/resources/com.example.demo`

ん？どういうこと？と思うかたは下記へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619433/482e8a1d-e04d-d78f-3439-ecff149dadcb.png)

Intellijのほうでまとめてくれるのでわかりにくくなる。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619433/fc9fffd1-0c4c-2ada-cdff-d2730dfa4122.png)
実際は上記のようにしっかり階層をわけてあげて下さい

左の歯車マークからCompact Middle Pakagesのチェックを外すことで分割できるので
試してみてください～
FFmpeg: 動画ファイルを生成しながら継続的にストリーミング配信する

事前に全てのファイルを準備できていなくても、動的に生成される動画ファイルを連続的に配信する方法。

![概要](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2021/04/29/246be97a-e93e-4ba5-9aa0-8fd3a2e5bca4.png)

参考) [FFmpeg - Concatenate](https://trac.ffmpeg.org/wiki/Concatenate)

## 概要

concat demuxer を使い動画ファイルの一覧を記述したテキストファイルを指定することで、複数のファイルを結合することができる。
ファイルリストには動画ファイルのほか、別のテキストファイルを指定することもできる。テキストファイルは FFmpeg 実行時ではなく評価時に読み込まれるため、順次生成していけば良い。

![ファイルリスト](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2021/04/29/0192f0f6-b4b1-425d-8936-c2e3841ecf45.png)

## 手順例

 1. 以下のようなテキストファイル(例: 1.txt)を用意する。

        ffconcat version 1.0
        file '1.mp4'
        file '2.txt'

 2. ffmpeg でストリーミング開始する。

    例)

        ffmpeg -re -f concat -safe 0 -stream_loop -0 -i ./1.txt -c:v copy -f flv (ストリーミング先URL)

 3. 再生が完了するまでに次の動画ファイルとテキストファイルを用意する。

    例) 2.txt

        ffconcat version 1.0
        file '2.mp4'
        file '3.txt'
Laravel+vueでなんか作る(Laravel基礎⑥ ～Gate編～)

当記事はUdemyの講座、[Vue 3 and Laravel: A Practical Guide with Docker](https://www.udemy.com/course/vue-laravel-admin/)を進めるにあたり、理解を深めるために記された備忘録です。

今回はGateを用いてコントローラの各メソッドに対するアクセス権限を限定します……が、Gateに関しては元講座におけるインストラクターの方の説明が相当巻いていたため、何なら**黒魔術としてGateを運用しよう！**ぐらいのスタンスで当記事は執筆される運びとなりました。
まあ私的な備忘録なんてそんなものと言えばそうなのですが……。

#リレーションについて
前提として、元講座は以下のようなリレーションを行っている。

- ユーザー(User)はそれぞれ、「管理者(admin)」「編集者(editor)」「閲覧者(viewer)」のいずれかの役割(Role)を持つ。これはRoleとUsersのOne to Manyリレーションシップで表現されている。
- 「管理者」「編集者」「閲覧者」の役割(Role)はそれぞれに「権限」(Permission）を持つ。これはRolesとPermissionsのMany to Manyリレーションシップで表現されている。
- 「権限」は「view_users」「edit_users」「view_roles」「edit_roles」「view_products」「edit_products」「view_orders」「edit_orders」の8つである。一読すればわかる通り、これらはUsers、Roles、Products、Ordersに関する閲覧(index、show)と編集(create、update、destroy)の権限をそれぞれ表している。

#モデルについて
上記のリレーションはややこしいが要点としては簡単で、**Userが持つRoleが持つPermissionsに、当該モデルに関する権限が書いてある**と考えればいい。
ここに一介の閲覧者(viewer)であるJohn Smith氏がいたとしよう。彼の持つ権限の一覧は以下のようにすれば列挙できる。

```php
return $johnSmith->role->permissions->pluck("name");
```

```JSON:戻り値は以下の通り
[
    "view_users",
    "view_roles",
    "view_products",
    "view_orders"
]
```
ここでUserモデルに少し手を加える。
あるユーザーが特定のpermissionを有しているかを確かめる``hasAccess()``メソッドを追加するのだ。

```php:User
    public function hasAccess($access){
        return $this->role->permissions->
               pluck("name")->contains($access);
    }
```

```php
$johnSmith->hasAccess("edit_roles");
//上記はfalsyとなる

$johnSmith->hasAccess("view_roles");
//上記はtruthyとなる
```

#コントローラについて
Gateを用いて各種メソッドへのアクセスを制限するには、以下の一文をそれぞれ追加するだけでいい。

```php:RoleController
    public function destroy($id){
        \Gate::authorize("edit","roles");
//ここを追加する
        Role::destroy($id);
        return response(null,Response::HTTP_NO_CONTENT);
    }
```
アクセスを与えるPermission（この場合は``edit_roles``)のアンダーバーより前の部分を第一引数に、それより後を第二引数に指定する。

#AppServiceProvider

続いて``App\Providers\AppServiceProvider``の``boot()``関数内で、Gateの挙動を指定する。
ここのコードはかなり黒魔術っぽいが、機能は何となく理解できる。
以下インラインに示す。

```php:AppServerProvider
\Gate::define("view",
//Gate::authorize()の第一引数ごとに挙動を指定できる
        function(User $user,$model){
//この関数の第一引数は各Gateにアクセスしたユーザであり、
//第二引数はGate::authorize()の第二引数である。
            return $user->hasAccess("view_{$model}") ||
                   $user->hasAccess("edit_{$model}");
        });
//上記でモデルに追加したhasAccessメソッドの出番である。
//trueが返ればGateを通過できる。falseだと通過できない。

//以下、Gate::authorizeの第一引数がeditだった際のの挙動も指定する
\Gate::define("edit",
        function(User $user,$model){
            return $user->hasAccess("edit_{$model}");
        });
```

これでGateを用いて各メソッドへのアクセスを権限ごとに制限することができた。
WINツール



#win32ファイルをwinファイルに変換するツール
.bash_profile
に以下のパスを通す

`export PATH=/usr/local/win32tools/w32tow1.src:$PATH`


#winファイルをsacファイルに変換するツール
ツール直下で
`$ make`

macosの場合以下のエラーが出ることがある

s4read_data.c:3:13: fatal error: 'malloc.h' file not found
``#include    <malloc.h>``
            ^
1 error generated.
make[1]: *** [s4read_data.o] Error 1
You need change #include <malloc.h> to #include <stdlib.h> at line 3 of win2sac.src/s4read_data.c.

無事コンパイルできたら
.bash_profile
に以下のパスを通す
`export PATH=/usr/local/win32tools/win2sac.src:$PATH`



#winファイルをsacに変換するツール#使えなくなりました
.bash_profile
に以下のパスを通す
`export PATH=/usr/local/bin:$PATH`

`/usr/local/biｎ`にあるwintosacとshmdumpが必要
VBA IEブラウザからHPを開く

```
Sub BrowseSite() 
‘ ツール->参照設定
‘ Microsoft Internet Controls
‘ Microsoft HTML Object Libraly
Dim IE As SHDocVw.InternetExplorer
Set IE = New SHDocVw.InternetExplorer
IE. Visible = True
IE. Navigate "kokodane.com"
‘Do While IE. ReadyState <> READYSTATE_COMPLETE
‘Loop
‘Debug.Print IE. Location Name, IE.LocationURL
‘MsgBox "開きました。"
‘IE.Quit
End Sub
Laravel 419|PAGE EXPIRED 解決方法

こちらの記事では今回発生したエラー'419|PAGE EXPIRED'の解決方法と原因についてご紹介します。

今回発生した該当コードは下記の通りです。
検索ワードを入力し、画面遷移したブラウザで検索結果を表示させようとした際にエラーが発生しました。

```
<form method="post" action="/list/search">
  <input type="text" name="search">
  <button>
  検索
  </button>
</form>
```

#419|PAGE EXPIRED 発生原因と解決方法
発生原因はformタグに@csrfを記述しなかったからです。
@csrfは、CSRF対策のために用意されたBladeディレクティブで、`Laravelでは、CSRF対策がなされていないフォームの送信は例外が発生して受け付けられないようになっています！`

ですので、formタグに`@csrf`を追加すれば今回のエラーは解決します。

```
<form method="post" action="/list/search">
@csrf // CSRF対策
  <input type="text" name="search">
  <button>
  検索
  </button>
</form>
```

#CSRF（Cross Site Request Forgery）とは
CSRFとは`クロスサイトリクエストフォージェリ`と呼ばれる`Webアプリケーションの脆弱性を利用したサイバー攻撃`の一種になります。

###攻撃手法
1.攻撃者が攻撃用Webページや不正なスクリプトなどを準備し、脆弱性のあるサイトのフォームなどから不正送信。
2.攻撃対象サーバ上のWebアプリが不正なリクエストを処理し、ユーザーが意図していない処理が行われる。

###影響・被害
攻撃者自身が直接攻撃対象サーバへアクセスせずに、攻撃対象のWebアプリケーションに任意の処理を行わせることができます。

###主な攻撃
・いたずら的書き込み
・不正サイトへの誘導
・犯罪予告といった掲示板やアンケートフォームへの不正な書き込み
・フォームへの大量なコンテンツの送り付けによる`DoS攻撃`

攻撃Webページに誘導された一般ユーザに直接的な被害はありませんが、攻撃対象サーバへの不正なリクエストを送信した攻撃者として認識されてしまうことがあります。

#`DoS攻撃`
情報セキュリティにおける`可用性（利用者が必要なときに安全にアクセスできる状態）`を侵害する攻撃手法の一種。

Webサービスを稼働しているサーバやネットワークなどのリソース（資源）に、意図的に過剰な負荷をかけたり脆弱性をついたりする事でサービスを妨害します。

#`@csrf`ディレクティブ
上記のようなサイバー攻撃を防止するために用意されたのが`@csrf`です。
`@csrf`は、`「トークン」と呼ばれるランダムな文字列を非表示フィールドとしてフォームに追加し、トークンの値が正しいフォームのみを受け付けるようにします。`
こうすることで、`用意されたフォームからの送信なのかどうかを見分けることができ、正しいフォーム以外からの不正な送信を阻止することが可能になります！`

参考サイト
・参考にしたQiita記事
https://qiita.com/taka_no_okapi/items/fb4bbe59c18eeaf5a043

・Laravel公式ドキュメント
https://readouble.com/laravel/8.x/ja/csrf.html

・クロスサイトリクエストフォージェリについて
https://www.trendmicro.com/ja_jp/security-intelligence/research-reports/threat-solution/csrf.html
React + Firebaseを用いたアプリ開発。

# 食事管理アプリ

1日の合計カロリーを計算できるアプリを作りました。

URL：https://react-firebase-7e85f.web.app/



# 開発経緯

### アプリのコンセプト

* 簡単に使用する事ができ、ダイエットのサポート。

最近のフィットネスブームでボディメイクに興味を持つ人が増えてきました。私もその1人です。運動を行い食生活を改善することによりMAX体重125kgから85kgまで体重を落とすことに成功しました。<br>
体重を落とすために1番必要なのは食生活の改善です。1日にどのくらいのカロリーをとり、その内脂質、タンパク質、炭水化物の量はどのくらいか計算しなければいけません。多くの人がこの食生活の部分を適当に行ってしまい、挫折してしまいます。　<br>
そこで多くの人が面倒で避けてしまう食生活の改善を簡単に行えるサイトを作りたいと考え本アプリを作成いたしました。

### アプリの概要

前回作成した[Fai Fai Diet](https://fai-fai-di.web.app/)の改良版として本アプリを作成いたしました。

改善点としては
* 履歴を残せるようにする。
* 食材を登録できるようにする。
* ユーザー別に認証する。

以上、３点を本アプリでは改善いたしました。



# 使用イメージ

### 認証機能の追加
emailとpasswordでアカウントを作成したりログインしたりできる機能を実装いたしました。

![demo1](https://user-images.githubusercontent.com/78431096/116250160-6e314880-a7a8-11eb-9a68-c8a9194605ae.gif)

### 食材の登録
自分の好きな食材の写真、栄養を保存できるようにしました。

![demo2](https://user-images.githubusercontent.com/78431096/116251611-cb79c980-a7a9-11eb-9711-6274f11919a3.gif)

### 食材の編集、削除
登録した食材の編集、削除も可能です。

![demo4](https://user-images.githubusercontent.com/78431096/116255200-fdd8f600-a7ac-11eb-9d84-6a61b2c4a7e4.gif)

### カロリー計算、登録
食べた量に対して栄養を計算し直す事ができます。

![demo5](https://user-images.githubusercontent.com/78431096/116261607-c53c1b00-a7b2-11eb-909d-bc4bded213e3.gif)

### 総合摂取カロリーの計算
１日食べたものを登録することによってその日の総合カロリーを計算します。
![demo8](https://user-images.githubusercontent.com/78431096/116262321-64611280-a7b3-11eb-8703-ecfa66e01e2c.gif)

### 履歴を残せる
1日の総合摂取カロリーを履歴として残せるようにしました。

![demo7](https://user-images.githubusercontent.com/78431096/116260059-54483380-a7b1-11eb-8321-a0b38905ee52.gif)

# 機能一覧

* ユーザー登録機能
* ログイン機能
* 食材の栄養素の登録
* 食材の栄養素の編集
* 食材の栄養をの削除
* 摂取した食材の量に応じて栄養素の自動計算
* 合計カロリーの自動計算
* 履歴表示機能


# 使用言語

### フロントエンド

HTML/CSS/JavaScript/React/Redux

### データベース

firebase

### その他ツール

Visual Studio Code

### デプロイ環境

firebase

# 改善した点

### ユーザー別に認証する
各ユーザーの情報が登録してあるコレクションのサブコレクションとしてそのユーザーが摂取した食材を保存するコレクション、そのユーザーの今までの履歴を保存するコレクションを登録することによってユーザーごとにデータを管理する事ができました。

### 食材を登録できるようにする
ログインしたユーザーすべての人が共有できるようにしました。食材でだけではなく料理も登録できるようにしてあり自分が考えて作ったダイエット飯を共有できるようにするためです。この意図は、1人でやると日々食べるものが同じになってしまいます。そこで減量飯をシェアする事ができたら飽きる事なくダイエットを継続出来るのではないかと考えたからです。

### 履歴を残せるようにする
登録ボタンを押した時点での総合摂取カロリーと日付を保存し表示で記すようにしてあります。

# 苦労した点

### データベースの削除
ドキュメントをまとめて削除するところがつまづきました。
最初はコレクションに直接deleteメソッドをしようしエラーが出てしまいました。

```
db.colection('').delete()
///エラー
```

このエラーはbatchメソッドを使用し解消いたしました。  <br>
→[こちらのQiitaの記事](https://qiita.com/kengo95/items/91dee723d52121442d2d)でアウトプットいたしました。

# 学んだこと

* firebase へのデータの追加、取得、削除　一連のメソッドを学べました。
* JavaScriptの非同期処理の考え方を学べました。

この経験を生かし最終的にはWEBエンジニアとして実務を全うできることを目指します。

最後まで読んでいただきありがとうございました。
明細1行に複数のレコードを取得している場合のページ切り替えを考える

はじめまして。主にエンハンスで活動しております。
今回はフレームワークにMyBaisを用いたWebページの話です。

既存の画面にも明細1行に複数行のレコード情報を取得しているページはあったのですが、せっかくのMyBatisですから、一度に複数のレコードを取得したいと思い、200行くらいのレコードをMyBatisの機能で1オブジェクトに変換しました。200行が1オブジェクトになるんですよ。1オブジェクトの中にListがあって、それが10サイズのリストになっていて、さらにListを含んでいる。そういうオブジェクトがMyBatisのresultMapでできちゃうんですから驚きです。
画面にも、200オブジェクトではなく1オブジェクトとして送られてくるので、1行分です。嬉しいですね。
ここで、明細エリアの説明をしたいと思います。明細エリアにはページ切り替えがついていて、1ページの表示件数は10件です。DB上では200行取得できていましても、行数としては1行分にあたりますので、ページ切り替えは発生しません。**ところが**、崩れました。ページ切り替えの部品が。

ページ切り替えのオブジェクトはPageDtoというものを使っていまして、中身はこんな感じです。

```Java:PageDto.java

/** 件数 */
private Integer count;
/** 表示している明細の開始行数 */
private Integer indexFrom;
/** 表示している明細の終了行数 */
private Integer indexTo;
/** 表示している明細欄の次ページ */
private Integer indexNext;
/** 表示している明細欄の前ページ */
private Integer indexPrev;
/** 表示している明細欄の最終ページ */
private Integer indexMax;
```

今回は、1行が複数レコードで構成されるので、それが原因だろうと考え、このPageDtoにステップ数を追加しようと思いました。ただし、その改修方法ですと、既存のPageDtoにも影響が出るため、試験範囲を広げなければなりません。
そこで、このPageDtoに値を設定する共通サービスを修正することにしました。それでは、その共通サービスを見てみましょう。

```Java:PageService.java

public PageDto createPageDto(int pageCnt, int current, int count) {
    PageDto page = new PageDto;
    page.setCount(count);
    int max = Mah.ceil(count / pageCnt);
    page.setIndexMax(max);
    page.setIndexNext(current + 1 > max ? max : current + 1);
    page.setIndexPrev(current - 1 > 1 ? current - 1 : 1);
    page.setIndexTo(current * pageCnt > max ? max : current * pageCnt);
    return page;
}
```

実際はこんな風に三項演算子なんかは使われていないですけど、記事を読むにはシンプルでわかりやすいと思いましたので使用しました。既存のPageDtoについて理解するのに、ここまでで2時間以上、費やしてしまった気がします。最初から、JSPの方でどのように見ればすぐわかったのに、Javaの設定方法やJUnitのケースを見たり、遠回りしてしまいました。

ということで、今回の改修案です。

```Java:PageService.java

public PageDto createPageDto(int pageCnt, int current, int cnt, int stepCnt) {
    PageDto page = new PageDto;
    int count = cnt / stepCnt;
    page.setCount(count);
    int max = Mah.ceil(count / pageCnt);
    page.setIndexMax(max);
    page.setIndexNext(current + 1 > max ? max : current + 1);
    page.setIndexPrev(current - 1 > 1 ? current - 1 : 1);
    page.setIndexTo(current * pageCnt > max ? max : current * pageCnt);
    return page;
}
```

引数が異なるので、既存のメソッドにも修正が入らないし、安心ですね。JUnitがあるので、既存のメソッドから↓下のように呼び出しても良いのですが、今回のお客様との距離感を考えるとやらないですね。


```Java:PageService.java

/** 既存のメソッドから新規メソッドを呼び出す */
public PageDto createPageDto(int pageCnt, int current, int count) {
    return createPageDto(pageCnt, current, count, 1);
}
```

以上です。最後まで、ご覧いただきありがとうございました。
分割関連の数え上げはとりあえず指数型母関数にすると exp にまとまりがちですのご紹介です。

たとえば、次のものの指数型母関数がわかります。（他にも思い出したらあとから加筆していくかんじで行きます。みなさまもご提案ぜひです！）

* ベル数 $B _ n$（要素数 $n$ の集合 $[n]$ の分割の個数）

## こちらの公式を使うと良いです。

$R$ を可換環、$x$ を不定元、$f: \mathbb N _ + \rightarrow R$ を関数として、

$$
\sum _ { n \ge 0 } \left ( \sum _ { \mathcal A \vdash [ n ] } \prod _ { A \in \mathcal A } f ( \vert A \vert ) \right ) \frac { x ^ n } { n ! }
= \exp \left ( \sum _ { j \ge 1 } f ( j ) \frac { x ^ j } { j ! } \right )
$$

が成り立ちます。

## 証明

集合 $[n]$ の分割 $\mathcal A$ に対して、その要素数を降順に並べてできる自然数 $n$ の分割 $\lambda$ を対応させます。$\lambda _ i = j$ となる $i$ の個数を $m _ j$ と置くことにすると、この対応は、置換群 $\mathfrak S _ n$ の $[n]$ への作用の $\mathcal A$ における固定化部分群を考えると、$n ! / { \prod _ { j \ge 1 } j ! ^ { m _ j } m _ j ! }$ 対 $1$ 写像であることがわかります。

さらに、有限な長さ $l$ を持つ正整数列 $a \in \mathbb N _ + ^ l$ に対して、それを降順ソートしてできる自然数 $n$ の分割 $\lambda$ を対応させます。この対応は、置換群 $\mathfrak S _ l$ の $\mathbb N _ + ^ l$ への作用の $a$ における固定化部分群を考えると、$l ! / { \prod _ { j \ge 1 } m _ j ! }$ 対 $1$ 写像であることがわかります。

これにより $\mathcal A$ 添字な和を $a$ 添字な和にまとめ直すと、これは $n ! / { l ! \prod _ { j \ge 1 } j ! ^ { m _ j } }$ 対 $1$ 対応になります。すなわち、

$$
( \mathrm { LHS } )
= \sum _ { l \ge 0 } \frac 1 { l ! } \sum _ { a \in \mathbb N _ + ^ l } \prod _ { j \ge 1 } \frac { f ( j ) x ^ j } { j ! } 
$$

となります。これを因数分解して $\exp$ でまとめると、右辺に等しくなります。


## ベル数

公式に $f ( j ) = 1 \ ( j \ge 1 )$ を代入すると良いです。すると、ベル数の指数型母関数はつぎのようになります。

$$
\sum _ { n \ge 0 } B _ n \frac { x ^ n } { n ! }
= \exp \left ( \sum _ { j \ge 1 } \frac { x ^ j } { j ! }  \right )
= e ^ { e ^ x - 1 }
$$

[Wikipedia - ベル数](https://ja.wikipedia.org/wiki/%E3%83%99%E3%83%AB%E6%95%B0) をご覧いただくと、この結果も書いてあります。
JS基礎文法~繰り返し処理~

#概要
プログラムでは、大量のデータを扱います。大量のデータを扱う場合は配列に格納してfor文などの繰り返し処理を行います。
繰り返し処理で使われる繰り返し処理についての記事です。

#for文

指定回数の処理を行うのに使用する繰り返し処理です。
配列との組み合わせで、要素の先頭から末尾までの処理をする目的で使用されます。配列での使用については別の記事でかきます。
今回の記事ではfor文での処理の流れについて触れます。

```index.js
 for(let i = 0;i <= 10; i++) {
   console.log('hello');  //hello ×10
 }
```
iは変数を表します。
let i = 0　▶　初期化式　最初の一回のみ実行されます。
i <= 10 ▶条件式　この条件がtrueの間処理が繰り返されます。　falseになるとfor文を抜けます。
i++ ▶　変化式　判定用の変数を更新します。

```index.js
for(let i = 0;i <= 10; i++) {
  console.log(`${i}回hello`);
}
```
このようにテンプレート文字列を使うと何回目helloなのかわかりやすく表示することができます。iは変数カウントを表します。

#break

breakを使用することで、処理中に特定の条件でtrueであったときにループを抜けることができます。
今回は8のときにfor文を抜けるようにプログラムしました。

```index.js
for(let i = 0;i <= 10; i++) {
    console.log(`${i}回hello`);　//hello８回まで表示
    if (i === 8 ) {　//iが８のときに抜ける
      break;
    }
}
```

#continue

continueを使うことで繰り返し処理を中断して、変化式に移動します。
ブラウザ上では、３回目のみループを抜けます。

```index.js
 for(let i = 0;i <= 10; i++) {
   if (i === 3 ) {
     continue;
   }
  console.log(`${i}回hello`);
}
```

#while文

while文は()内の条件式がtrueである間ループします。
なお、hpを減らし忘れると条件式が永遠にtrueになり無限ループになります。
今回は−２０ずつhpが減少するように設計しました。
また、hpが20のときに注意喚起のメッセージをif文で追加しました。

```index.js
let hp = 100;

while (hp > 0) {
 console.log(`${hp} です`);
 hp -= 20;
   if(hp === 20) {
     console.log(`${hp}がピンチです`);
    }
}
```

#do while文

do while文は条件式が末尾にあります。
これにより、最低一回は処理内容が実施されます。

```index.js
let hp = -30;

do  {
  console.log(`${hp}です`);
  hp -= 20;
} while(hp > 0)
    
```
軽量 Linux ディストリ

## antiX Linux

* https://antixlinux.com/
    * http://ftp.riken.jp/Linux/mxlinux-iso/ANTIX/Final/antiX-19/?C=M;O=A

![VirtualBox_xubuntu_29_04_2021_18_10_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/17f5342f-c929-11e9-66e9-3a79b6ef0b57.png)

軽いが、以下画面で２分は待たされる。

![VirtualBox_xubuntu_29_04_2021_20_46_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/c94221f8-8f62-a9a1-c050-dc1d0ec1315b.png)

antiX-19.3_x64-base.iso
icewm + ROX filer

![VirtualBox_xubuntu_29_04_2021_18_35_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/8ab35e1f-638d-6e0c-1df7-9101dce88792.png)

snapshot機能

![VirtualBox_xubuntu_29_04_2021_20_27_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/046355dc-0132-a508-6945-96760fa03223.png)


```sh:日本語入力
apt install -y \
  fcitx fcitx-mozc \
  zenity \
  im-config \
  fcitx-config-gtk
```

```sh
im-config

fcitx-config-gtk3
```



## MX Linux

* [公式](https://mxlinux.org/download-links/#Mirrors)
* [日本語化版 - ライブCDの部屋](http://simosnet.com/livecd/antix/)
    * MX-19.4.1_x64 "ahs" : 最新のハードウェアサポート (VirtualBoxでは起動途中で止まった。)
    * user / pass = demo / root

```sh:日本語入力
apt install -y \
  --install-recommends \
  fcitx fcitx-mozc
```


```sh
im-config

fcitx-config-gtk3
```

![VirtualBox_xubuntu_29_04_2021_18_30_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/04262eee-96a2-08ce-b94f-b261ecc6a853.png)

## NNLinux

* [NNLinux](https://lzuoteng99.wixsite.com/index)
    * Debian10, Xfce4 ベース。mozcなど入っている

![b10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/a2c75434-c02a-7f9b-173b-4883bc5c746e.png)

インストールには 10GB の空きが必要。

![VirtualBox_xubuntu_29_04_2021_18_03_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/2ad1b531-c7a2-cdfb-7e63-6363695fe920.png)


## PuppyLinux64 9.5 (Ubuntu20.04ベース)

* 公式 (英語版)
    * [fossapup64-9.5.iso](http://distro.ibiblio.org/puppylinux/puppy-fossa/)
    * [日本語化パッケージ](http://sakurapup.browserloadofcoolness.com/viewtopic.php?f=26&t=3490)

### 日本語フォーラム

* [日本語フォーラム](http://sakurapup.browserloadofcoolness.com/viewforum.php?f=24)

### 日本語化済みiso

* [fossa64-simple-r1.iso](http://sakurapup.browserloadofcoolness.com/viewforum.php?f=24)

![VirtualBox_xubuntu_29_04_2021_17_35_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/61bb09bd-b159-87b3-dcb3-a4bccc81802e.png)
[Rails]ウィザード形式のフォームの実装

#はじめに
先日あるサイトにて新規会員登録の項目が大量あると登録する気が失せるなと感じました。そのことをきっかけに、ユーザへの興味を削がないように登録フォームを進めさせる方法はないかなあと考えていたらウィザード形式なるものに出会いましたのでアウトプットします。

#ウィザード形式とは
ウィザード形式とは、対話の如く順番に操作画面が進んでいく方式のことです。身の回りでいえば、新幹線の切符購入画面とかそうですよね（出発駅選択→到着駅選択→時間選択→座席指定みたいな）。ユーザからすると、1ページで項目を一気に登録しないといけないフォームよりも、ウィザード形式の方が、今何をしているのかシンプルにわかりやすくてみやすいと言う特徴があります。

#実装（ユーザ登録編）

ユーザ登録の後、住所情報を登録するウィザード形式を作ることとします。

```registrations_controller.rb
def new
   @user = User.new
 end

 def create
   @user = User.new(sign_up_params)
    unless @user.valid?
      render :new and return
    end
   session["devise.regist_data"] = {user: @user.attributes}
   session["devise.regist_data"][:user]["password"] = params[:user][:password]
   @address = @user.build_address　#1対1の場合は、buildメソッド_関連づけられたモデル名
   render :new_address
 end
```
このコントローラで行うことは次の3つです。

ユーザ情報入力画面から受け取った情報の
①バリデーションチェックを行い、
②sessionに登録情報を持たせて、
③次の住所情報登録で使用するインスタンスを生成しておく。

三行目でreturnしている理由は、バリデーションチェックが通らない場合は、その後の処理もいったん止めたいからです。もし、この記述を怠ると、その後出てくるrenderが実行されて「、DoubleRenderErrorというエラーが発生します。

```ruby
unless @user.valid?
      render :new and return
    end
```


次に、sessionを使用することで登録した情報を保持します。

```ruby
session["devise.regist_data"] = {user: @user.attributes}
session["devise.regist_data"][:user]["password"] = params[:user][:password]
```

###attributesメソッド
ここでattributesメソッドについて軽く触れておきます。
attributesメソッドはインスタンスメソッドから取得できる値をオブジェクト型からハッシュ型に変換してくれます。
実際に見てみるとよくわかります。

```terminal
# 例：Userインスタンスがもつオブジェクト型の値
#=><user:12345678921>

# 例：Userインスタンスがもつハッシュ型の値
#=> {name=>"yamada", :sex=>"man"}
```

これを踏まえ、今回の記述を再度見てみると、sessionにはハッシュ型で渡していることがわかります。

#実装（住所登録編）

住所登録では以下のようなアクションを追加します。

```registrations_controller.rb
#省略
def create_address
   @user = User.new(session["devise.regist_data"]["user"])
   @address = Address.new(address_params)
    unless @address.valid?
      render :new_address and return
    end
   @user.build_address(@address.attributes)#住所情報付け足し
   @user.save
   session["devise.regist_data"]["user"].clear
   sign_in(:user, @user)
 end

 private

 def address_params
   params.require(:address).permit(:postal_code, :address)
 end
```

おそらくuserモデルとさほど変わりはありませんが、、、
sessionはclearメソッドを使用して明示的に削除するようにしましょう。

そして、最後にsign_inでサインインします。

# 終わりに

ただ開発するのではなく、どうしたらユーザ（お客様）にとって、快適で便利になるのか、実装した結果どうなるのかを意識して開発に取り組んでいきます！
ラズパイ初心者がRaspberrypiZeroWHを使ってLINEで動くスマートロックを作ってみた(サーバー構築編2) 

# 前回のあらすじと今回の概要
前回は、docker-composeを用いてflaskとnginxをuwsgi繋げ、httpsでアクセスするところまで行った
今回はLINEのAPIを使ってオウム返しbotを作るところまでやろう

## ディレクトリ構成
┣ ~
　　┣ app
　　　　┣ Dockerfile
　　　　┣ main.py
　　　　┣ requirements.txt
　　　　┣ uwsgi.ini
　　┣ docker-compose.yml
　　┣ nginx
　　　　┣ Dockerfile
　　　　┣ nginx.conf
　　　　┣ ssl
　　　　　　┣ fullchain.pem
　　　　　　┣ privkey.pem

# LINEdevelopers登録・各種設定
## Linebot作成、Messageing-APIを有効化
https://developers.line.biz/ja/
ここからログイン

公式ドキュメント参照
https://developers.line.biz/ja/docs/messaging-api/getting-started/

## アクセストークンとチャネルシークレット発行
LINE Developersコンソールで、作成したチャネルを選択。
［チャネル基本設定］タブで、チャネルシークレット発行
［Messaging-API設定］タブで、チャネルアクセストークン(長期)を発行

# Flaskサーバーの設定
~/appディレクトリ内のファイルを編集していく
## requirement.txt
line-bot-sdkパッケージをインストールさせる

```:~/app/requirement.txt
Flask
uwsgi
line-bot-sdk     # 追加!!
```

## main.py
以下のように4つのブロックを付け足す

```python:~/app/main.py
from flask import Flask, render_template, request, abort
##1.line-bot-sdkの各モジュールをインポート################################
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
########################################################################

app = Flask(__name__)

##2.アクセストークンとチャネルシークレットを入力############################
line_bot_api = LineBotApi("YOUR_CHANNEL_ACCESS_TOKEN")    # アクセストークンを入力
handler = WebhookHandler("YOUR_CHANNEL_SECRET")           # チャネルシークレットを入力
########################################################################

@app.route("/")
def hello_world():
    return "hello world!"

@app.route("/.well-known/acme-challenge/<filename>")
def well_known(filename):
    return render_template('.well-known/acme-challenge/'+ filename)

##3.WebhookにURLを指定してWebhookからURLにイベントが送られるようにする########
@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'
########################################################################

##4.Webhookから送られてきたイベントの処理内容(この場合テキストメッセージが届くと同じメッセージを返す)
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))
########################################################################

if __name__ == "__main__":
    app.run()
```

# Webhookしてみる
Message-API基本設定タブからWebhookURLの欄にURLを入力
![webhook1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533399/1109953c-5b70-6fe6-242d-1b97db3b50a9.png)

更新→検証を押し、成功!が表示されたらOK
![webhook2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533399/2547a946-f178-9e51-d98a-8ebf11a4c0f9.png)

# 自分のLINEに作成したbotを友達登録して、実際にbotにメッセージを送ってみる

![success.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533399/d1d208d5-1286-b453-78ec-31b9d516595e.jpeg)
オウム返しされたら成功！！
これにてサーバー構築終了！
お疲れ様！！

次回はLINEbotに送るメッセージに応じてサーボモーターを操作していくよ！
少し電気回路も触るけど、メインはコーディングだからソフトウェア編にかな