OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Piを使ってL2TP/IPSecのVPNサーバーを作った

こんにちは。[Natsu](https://twitter.com/ntszw)です。最近はクックパッドでインターンシップをする傍ら、引っ越し準備を進めています。

さて、海外に引っ越すにあたって、実家のネットワークを中継して日本のサービスにアクセスするという規約違反をしたかったので、ラズパイ(armv7)で何とかVPNを立てました。

注意：今回は、armv8だとサポートが明記されていないDocker imageを使いました。

# 選択肢

- L2TP/IPSec
  - ほとんどのOSで標準に接続できる
  - UDPを使ってネットワーク層で通信している
  - 速度が安定する
- PPTP
  - 平分で通信するため選択肢に入れるべきでもなかった
- OpenVPN
  - セキュリティは充実しておりLinuxから繋ぎやすいが、その他のOSからの接続設定が面倒臭い
- その他、WireGuardなど
  - 検討してない

ということで、L2TP/IPSecを導入することにしました。

# 基本設定

- ソフトウェアをアップデートする
- ユーザ名、パスワードを変える
- ファイアーウォールを設定する
- 固定IPにする

省略します。

あと、Dockerを使うのでDockerも入れておきます。

# ipsec-vpn-server

IPSec VPNサーバーを立てるための便利なスクリプトをDocker化したプロジェクトがあります。READMEに書いてある通り、イメージを引っ張ってきて実行するだけでした。

https://github.com/hwdsl2/docker-ipsec-vpn-server

```sh 
$ docker pull hwdsl2/ipsec-vpn-server
$ docker run \
    --name ipsec-vpn-server \
    --restart=always \
    -v ikev2-vpn-data:/etc/ipsec.d \
    -p 500:500/udp \
    -p 4500:4500/udp \
    -d --privileged \
    hwdsl2/ipsec-vpn-server
```

# ネットワークのポート転送設定

ルーターの管理画面からポート500, 4500を解放します。

例：グローバルの500, 4500を192.168.x.x（ラズパイの固定IP）の500, 4500にマッピングします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334026/94cb7c0d-de2d-75e6-c907-1c02462cc35a.png)

# ファイアーウォールの許可設定

ラズパイではufwを使っているので、500と4500のポートを許可しました。

```sh
$ sudo ufw limit 500/udp
$ sudo ufw limit 4500/udp
```

# 接続情報の確認

```sh 
$ docker logs ipsec-vpn-server
```

ログを通して接続情報を確認できます。L2TP/IPSec接続をするには、サーバーIP、PSK(事前共有鍵)とユーザーのログイン、パスワードが必要です。

**注意！！！！！：家庭のネットワーク環境でGlobal IP Addressが固定になっていない場合（マンションなど）、Dynamic DNS (DNNS)を設定する必要があります！！！（ここでは説明省略）**

# 接続テスト

スマホでWifiをOFFにして、接続テストをしました。
【swagger/nginx】CSS/JSが読み込まれないときの対処法

[1]:https://github.com/swagger-api/swagger-editor
[2]:https://github.com/swagger-api/swagger-ui

## 経緯

1. [swagger-ui][2], [swagger-editor][1]をGitからクローンした。
2. nginxでロケーション設定して、それぞれのindex.htmlが表示される様にした。
3. しかし、なぜかCSS/JSだけ読み込まれない。（４０４エラーになる）
4. とても困った。 

## 対象ファイル（４０４エラー）

・swagger-ui
　・swagger-ui-bundle.js
　・swagger-ui.js
　・swagger-ui.css

・swagger-editor
　・swagger-editor-bundle.js
　・swagger-editor.js
　・swagger-editor.css


## 対処法

nginxのロケーションで、CSS・JSの絶対パスを指定するだけでした。
なんで、index.htmlに書いてあるパスで読み込んでくれないの・・・？

例：
`/www/swagger/`直下に[swagger-ui][2]をクローンしているとします。

初期のロケーションの設定は以下の通りです。

```terminal:nginx.conf

location /swagger-ui{
   alias /www/swagger/swagger-ui/dist;
   index index.html;
}

```

この設定の後、index.htmlは表示できたが、
`https://sample-site/swagger-ui/swagger-ui-bundle.js`のJSが読み込めず、
 `404`エラーが出ているとします。

aliasを使って、jsファイルの絶対パスを指定してあげてください。

```terminal:nginx.conf

location /swagger-ui{
   alias /www/swagger/swagger-ui/dist;
   index index.html;
}

location /swagger-ui/swagger-ui-bundle.js{
  alias /www/swagger/swagger-ui/dist/swagger-ui-bundle.js; <---- 絶対パス指定！！！！
}

``` 

他のファイルについても、同様にaliasを使って、絶対パスを指定してあげてください。
私の場合は、これで解決しました。

あんまり同じ現象で困ってる人いないと思いますが、
誰かの助けになれれば嬉しいです。
systemd で DHCP サーバー

昔やったときは上手く行かなかったですが、もう一度やってみたら`systemd-networkd`をDHCPサーバーに出来たので設定を紹介します。systemd 247で動作確認しました。

```config:/etc/systemd/network/wlan0.network
[Match]
Name=wlan0

[Network]
# 自分がDHCPサーバーなのでアドレスは自分で設定する
Address=192.168.2.1/24
# DHCPクライアントにはならない
DHCP=no
# DHCPサーバーになる
DHCPServer=yes

[DHCPServer]
EmitDNS=yes
DNS=1.1.1.1
EmitRouter=yes
```

上記は無線LANの設定ですが、以下の仮定を置いています：
* 無線LANを他のアクセスポイントに繋ぐか、自分がアクセスポイントになる設定は例えば[iwd](https://qiita.com/kakinaguru_zo/items/31ce8fee5180bf349a3d)などで行われている。`systemd-networkd` 自体は無線を扱えないので、iwd, wpasupplicant, hostapdなどに無線の設定をやらせる必要があります。
* インターネットに繋ぐためのデフォルトルートはどこか他のインターフェース（例えば`eth0`）で行われている
gitのコミットからプッシュまでのコマンドの流れ

## 概要
gitのコミットからGitHubへのプッシュまでの流れを簡単にまとめます。

## git branch
まずは、コミットする前に現在のブランチを確認します。

```zsh
% git branch
  feature
* master
```

## git checkout *ブランチ名*
現在のブランチがコミットしたいブランチでない場合、ブランチを変更します。

```zsh
% git checkout feature
Switched to branch 'feature'

% git branch
* feature
  master
```

## git diff
ステージングにある変更ファイルの差分を確認します。

```zsh
% git diff
diff --git a/routes/web.php b/routes/web.php
index bc07a90..4e62548 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -25,6 +25,11 @@ Route::get('/', function () {
     ]);
 })->name('home');
 
+Route::post('/quiz/{quiz}/answer/confirm', [QuizController::class, 'answerConfirm'])->where('quiz', '[0-9]*')->name('quiz.answer.conf');
+
Route::post('/quiz/{quiz}/answer/result', [QuizController::class, 'answerResult'])->where('quiz', '[0-9]*')->name('quiz.answer.result');

Route::get('/ranking/correct', [HomeController::class, 'rankingCorrect'])->name('ranking.correct');
```

※左に 「+」 がある行が追加したコードになります。またコードを削除した場合は、「-」となります。

## git add .
変更をステージングエリアに追加する。

```zsh
% git add .
```

※出力はありません。

## git status
ステージングエリアに変更したファイルが有ることを確認します。

```zsh
% git status
On branch feature
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   routes/web.php

```

※　「Changes to be committed:」内にあるファイルはコミットできるファイルになります。

## git commit -m ‘*コメント内容*’
コミットコメントを記載してコミットします。

```zsh
% git commit -m 'ルートの追加'
[feature cdf2899] ルートの追加
 1 file changed, 2 insertions(+)
```

## git log
コミットログを表示してコミットできていることを確認します。

```zsh
% git log
commit cdf28999264f4a120a909f3c80fb9c8510db665a (HEAD -> feature)
Author: hirokimituya <hiromitu819@yahoo.co.jp>
Date:   Wed Aug 4 19:42:39 2021 +0900

    ルートの追加

```

※コミットログの表示をやめるには、`q`を入力します。

## git push origin *ブランチ名*
GitHubにコミット内容をプッシュします。

```zsh
% git push origin feature
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 373 bytes | 373.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To github.com:hirokimituya/jetstream-doc.git
   2b5159d..cdf2899  feature -> feature
```

## まとめ
普段はGitHub Desktopを使用してgitコマンドを使用していませんが、たまにはgitコマンドを使ってGitHub Desktopが使えないもしものときに備えることも必要かもしれません。
以上になります。ご観覧ありがとうございました。
Houdini 18.5 Redshiftのインストール macOS

いつの間にか、Redshift for macOSでてました。OctaneXがクラッシュ地獄だったので期待してます。

https://qiita.com/hiro_assh/items/01ba80957d7b2a8bae9b

上記の通り、packagesにjsonを追加。jsonの名前は任意。ここでは、redshift.jsonを追加している。

![Screen Shot 2021-08-04 at 19.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346396/aa264047-6447-c106-48ef-03caece9ba1e.png)

jsonの中身。

```json
{
	"env": [
        {
	     "REDSHIFT": "/Applications/redshift/redshift4houdini/18.5.499"
        }
	],
	"path": [
             "$REDSHIFT"
        ]
}
```



Houdini起動後、ShelvesにRedshiftを追加で、タブメニューにRedshift出てきます。
![Screen Shot 2021-08-04 at 19.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346396/a77453f8-2951-1a24-7ff5-3b3a76315e13.png)

パッケージの追加は、
Octaneも同じことをすればOK。

以上。
Laravel8でチャットアプリを作るための準備

larave8でチャットアプリを作るために環境構築から準備するために使った記事をまとめるメモ

## 環境構築
### Homestead
環境はHomesteadを使ってVirtualBox上に構築する。
当初はDockerを使ってみたかったが、自分のPCではかなり重かったのとコンテナ間での通信などで詰まってしまい諦めた。

https://qiita.com/oreo3@github/items/1705b133e00019800ff6

DBとの接続で詰まったときに見た記事

https://qiita.com/shach334/items/3d9224278dedbc86bef8

### Vueの導入
vueを使ってみたかったので利用。

https://qiita.com/kide/items/13742fd6438a42f4deb4

## laravel8のルーティングの設定方法
laravel6までしか触ったことが無かったので調べた。

https://qiita.com/M_Ishikawa/items/8527c3193072226f0686

## チャット機能
Websocket通信を利用するのにLaravel Echo Serverを利用する。また、PUB/SUBを利用するためにRedisを利用する。
Eventの設定などやvueの書き方も以下の記事を参考にした。

https://qiita.com/nishinoshake/items/1be777f1d5f4f36ebe09

https://qiita.com/NkawaK/items/5ba2cb1c2ef6fb03042d

Pusherの代わりとして動かせるlaravel-websocketsを利用しようとしていたが、laravel8だとパッケージのバージョンの依存関係がうまく解決できなかったのでlaravel Echo Serverを利用することにした。

https://blog.capilano-fw.com/?p=2831

## 例外処理
axiosのエラーハンドリングの参考にした。

https://humo-life.net/memo/doku.php?id=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E8%A8%80%E8%AA%9E:php:laravel:axios
SQLで同じテーブルで異なる条件で抽出した値が共通する対象を抽出する方法

```sql:intersect.sql
SELECT COLUMN1,COLUMN2 FROM TABLE_A 
WHERE COLUMN3 = '条件１' AND CLOUMN4 = '条件２'
INTERSECT --ALL　--ALLをつけると重複行も抽出する
SELECT COLUMN1,COLUMN2 FROM TABLE_A
WHERE COLUMN3 = '条件４' AND COLUMN4 = '条件５'
--以下条件分繰り返し
--INTERSECT
--SELECT COLUMN1,COLUMN2 FROM TABLE_A 
--WHERE COLUMN3 = '条件６' AND COLUMN4 = '条件７'
```

積集合のINTERSECTを同テーブル同士で使用すると複数の条件で選択した値が共通する対象を抽出できます。
もちろん、別テーブル同士でも同じことができます。

抽出結果

|COLUMN1|COLUMN2|
|:--:|:--|
|COMUMN1|COLUMN2|
|...|...|
C# 個人的によく使う変数等の備忘録

<h1>すぐ忘れちゃうのでメモ</h1>

<h3>一覧</h3>

・デスクトップのパス

```C#:C#
string dsk = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
```

・フォルダの存在の確認と作成

```C#:C#
string path = @"C:\test1";
if (Directory.Exists(path))
{
       Console.WriteLine("存在します");
}
else
{
       Directory.CreateDirectory(path);
}
```

・ファイルの存在の確認と作成

```C#:C#
string path = @"C:\test\NewFile.txt";
if (File.Exists(path))
{
    Console.WriteLine("存在します");
}
else
{
    FileStream fileStream = File.Create(path);
}
```

<h2>メモ</h2>
随時書き足していってメモ代わり
こうすると使いやすくなるよ！っていう書き方などあれば教えてくださいm(__)m
また、同時に間違いなども指摘してもらえると嬉しいです(。-`ω-)
プリザンター 1.2 (.NET Core統合版) でシングルサインオン

# はじめに
プリザンター 1.2 (.NET Core統合版) をWindows Server + PostgreSQLで試しています。（[Windowsにプリザンター.NET Core (PostgreSQL対応) 版をインストールする](https://qiita.com/YoshikiSawada/items/8b7715dcacdb7ec6bbb9)）
シングルサインオンできるようになったので、設定手順を残します。

# 事前準備1
Windows Serverにプリザンター .NET Core版をインストールします。
（DBはSQL Serverでも構わないと思います）

# 事前準備2
「[プリザンターにシングルサインオンできるように設定する](https://pleasanter.org/manual/active-directory-sso)」の手順1, 2を実施します。
1. Windows認証のインストール
2. Windows認証の有効化

# web.config編集
Pleasanter_1.2.0.0\pleasanter\Implem.Pleasanter\web.configに```<authentication>...</authentication>```を追加します。

```xml:web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <security>
      <authentication>
        <anonymousAuthentication enabled="false" />
        <windowsAuthentication enabled="true" />
      </authentication>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2147483647" />
      </requestFiltering>
    </security>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\Implem.Pleasanter.NetCore.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
  </system.webServer>
</configuration>
<!--ProjectGuid: C0C351EC-DAC6-4888-BD8B-C3E4B6CBAB6B-->
```

これだけだと、エラー0x80070021（セクションがロックされている）が発生してしまうので、C:\Windows\System32\inetsrv\config\applicationHost.configを編集します。
以下のように2つのセクションのoverrideModeDefaultをDenyからAllowに変更します。

```xml:application.config
<section name="anonymousAuthentication" overrideModeDefault="Allow" />
<section name="windowsAuthentication" overrideModeDefault="Allow" />
```

以上で設定完了です。
IISを再起動すると、シングルサインオンできるようになっています。

# 参考
* [Windowsにプリザンター.NET Core(PostgreSQL対応)版をインストールする](https://qiita.com/YoshikiSawada/items/8b7715dcacdb7ec6bbb9)
* [ASP.NET Core で Windows 認証を構成する](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/windowsauth?view=aspnetcore-5.0&tabs=visual-studio)
* [IISでエラーコード0x80070021が発生した場合の対処法](https://ips.nekotype.com/4200/)
Google Compute Engineの無料プランの条件変更（2021年8月）について焦った話



来月には価値がなくなるであろう時事ネタです。

個人の趣味で、無料プラン枠内でGoogleComputeEngineを使ってます。
7月末に、こんなメールが届きました。

> [Action Required] To continue receiving your Free Tier discount, upgrade your F1-Micro VM to an E2-Micro VM by September 1, 2021

メール本文曰く、
> 【要対応】
無料枠を使い続けたいならF1-MicroからE2-Microに変えてね。
期間は8/1～8/31。

とのこと。

全体に仮想環境がスペックアップされたようで、従来のF1-Micro（2CPU、0.5Gメモリ）の新規契約が廃止され、無料対応インスタンスはE2-Micro（2CPU、1Gメモリ）になる模様。ありがたい。
ただし自動では置き換えられず、自身で変更手続きをしないと有料でF1-Microを使い続けることになるようです。

メールを見て、8/2に早速変更を済ませたまでは良かったんですが、今日何気なくWebコンソールを見ていると

> 2021/08/01～2021/08/04（合計費用）
￥22

**課金が始まっている…！？**

めちゃくちゃ焦ったんですが知り合いに公開しているサービスなので急に止めるわけにも行かず、悩んだ挙げ句英語限定のサポートチャットに連絡。

## オチ

Googleの請求システムのバグみたいです。

> Please know that you're not doing it wrong and our engineers are already working towards the resolution of this issue. You can also check the status of the issue via the Google Outage Dashboard : https://status.cloud.google.com/incidents/LGFBxyLwbh92E47fAzJ5

今鋭意修正中で、無料対象（USリージョン、E2Micro）で課金されているように見えるのは誤請求との事。
一安心でした。
SSHを自動化するexpectコマンド

今回はSSHでのログインを自動化するコマンドの記事です．

##まずは必要なパッケージをインストール

aptitude search で探します．
見つかったら，インストールしましょう．

```
$ aptitude search ^expect
p   expect             - 対話型アプリケーションの自動化  

パッケージ名がわかりました．

$ sudo apt-get install expect -y

もしくは

$ sudo aptitude install expect -y
```


##使い方

シェルファイルの先頭には，シバンを記載しなければいけません．
そのパスをまずは探します．

```
$ which expect
/usr/bin/expect ←これが重要
```

シバンに記載するパスがわかったところで，肝心のシェルファイルの中身です．

```ssh_ex.sh
#!/usr/bin/expect
set timeout 5
spawn ssh user@123.45.67.89
expect "s password:"
send "passwd\n"
interact
```

spwan:ターミナルに打ち込む内容を記述
→要するにコマンドです．

expect:expect以下の““で囲まれた中の表示がある場合に、以下のsendを入力する。
→パスワードを聞かれますよね？その末尾を切り取ったものです．

send:改行の\nを忘れずに
→改行が無いと，打ち込んだだけです．手打ちの場合も[Enter]押しますよね？

interact:このコマンドがなければ、ログインしても、中に入ることができない
↓↓↓↓↓↓↓↓↓↓↓

```
interactはspawnで作成されたジョブの標準入出力を、キーボードと画面にする。
すなわち通常の通信になる。
```

[参考サイト](https://blog.wnotes.net/posts/expect-other-programs/)

これで，sshは自動化できましたね．
次回はparallel-sshについて解説していきます．
auth.jsonはどこ

# auth.json
鍵を発行しましたが、
auth.jsonは問題ないのか
確認をしたかったので、その時の作業のメモです。


# auth.jsonはどこ
```
$ find ./ -name auth.json
./.config/composer/auth.json
```
探してみます。


```
$ cd .config/composer/
/.config/composer$ ls -la
total 24
-rw------- 1 vagrant vagrant  189 Aug  4 01:31 auth.json
```
ここにありました。

# 中身確認
```
/.config/composer$ cat auth.json
{
    "http-basic": {
        "repo.magento.com": {
            "username": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        }
    }
}
```
中身も見れました。
認定アドミニストレーター合格への道

Salesforceと出会って3か月で、認定アドミニストレーター試験に合格できました:ok_woman_tone1:

#私のスペック
・今年4月まで「Salesforce」という言葉も知らなかった
・文系学部出身（社会人2年目）
・勉強は苦手、、、

#勉強方法
##1. Trailhead
Salesforceには、Trailheadという学習環境が用意されています。
Trailhead内で『認定アドミニ』と検索すると、様々なトレイルが出てくるので、それを手始めにやりました。
　↓ トレイルの一部を記載しておきます:raised_hands_tone2:
 「【Salesforce公式】認定アドミニストレーター資格 対策」
 「アドミニストレーター認定試験に向けた学習」
 「認定アドミンを目指そう！」

##2. ポイントスタディ

ポイントスタディには、有償のものと、無償のものがあり、有償の方は試験範囲のすべてを網羅しているようです。
私は、6月にあった無償のポイントスタディを受講しました。
無償のものでも、セキュリティなど混乱しやすい部分をカバーしてくれるので、勉強が苦手な私には無償で十分でした（無償のものだけでも5時間あります、、）:joy:

##3. 過去問 / 想定問題
私の場合、時間がなかったので、Trailheadとポイントスタディと並行して、過去問に取り組みました。
また、会社の朝会で先輩に問題を「今日の1問」を出してもらっていました:joy:

↓ お世話になったブログです:sunny:
「Salesforceの一番星」さん
　　試験対策問題がめちゃくちゃ沢山のっています。
　　実際の試験で出てきた問題も結構あり、ありがたやでした:shamrock:
https://keneloper.com/salesforce-certified-administrator-exam-questions1/
Unknown actionで怒られてハマった

<h1>はじめに</h1>
Ruby on railsの学習を始めて、数日たち順調だと思っていた矢先に半日、下記のエラーでハマったため備忘録として残します。

<h1>エラー</h1>
```
Unknown action
The action 'show' could not be found for MessagesController
```

link_toでDELETEメソッドを呼ぼうとしたら発生。
コントローラーにshowアクションが無いと怒られてます。
パス、メソッドもあっているのに上記が発生してるので何かおかしいと思い諸々、調べてみました。

<h1>確認したこと</h1>
- 開発者モードやコード上に異常がないか
    - コード自体の内容や開発者モードで確認しただけなので割愛します。

- コントローラーのprivate内にアクションを記載していないか
    - Rubyではprivateと記述すると以下全文privateになるためdestroyアクションが属してないか。

- jquery_ujsが書いてあるか
- ```erb:app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs  <-この行を足します
```
    - 上記のように追加しないとエラーになる場合があり、またjqueryを先に読み込ませないとエラーになります。

<h1>解決</h1>
コントローラーのlink_toメソッドをbutton_toメソッドに変更しました。
原因としてはlink_toがRubyのCSRF対策により外部アクセスとみなされアクセスが出来なかったようです。
下記の表に大まかな違いを記載しておきます。


|  |link_to  |button_to  |
|---|---|---|
|HTMLタグ  |a  |form  |
|httpリクエスト  |get  |post  |

簡単ですがこれで以上になります。

<h1>参考ページ</h1>
https://note.com/sugarsugarsweet/n/n3229169bca4f

https://qiita.com/yoshinyan/items/194d3c4dcc0f246b1ad1

https://qiita.com/y-temp4/items/2d50feb3ff0d65acdf67
Burn のことってあまりかかれていないよね？

ということで、ニッチな製品のさらにニッチな部分の記事なんかを書いてみる。

## そもそも Burn ってなに？

Burn は、WiXToolset に含まれるいろいろなプログラムの一つで、ブートストラッパーと呼ばれる種類のプログラムになります。

ブートストラッパーなので、作成時には出てきません。そのため、名前は聞いたことあるけどよくわからないなぁ…なんて人もいるかもしれませんね。

WiX では Bootstrapper Project でビルドした際の exe そのもの部分が、Burn になります。すでに出来上がっている exe に、BootstrapperApplication で設定した UI サポートモジュールと、にビルドイメージを埋め込んで作られます(pdb とソースを落とせばステップ実行も可能、ただし F5 実行には対応していない)。

今回はそんな、Burn というあまり陽の当たる機会のないプログラムについてのお話。

## プログラムから Burn を実行する場合に意識しておくべきたった一つのこと。

Burn はブートストラッパーですが、プログラムとしてはごく一般的な Windows 用 GUI プログラムであり、exe としてビルドされます。

当然、Windows から見れば、ワードやエクセルと同じ普通のプログラムとして動きます。

ただ、インストーラという特性上、セキュリティリスクへの対応から DLL Injection へのセキュリティ対策が施されています。

Burn の場合、DLL Injection 対応で、自身を専用のフォルダにコピーしてから動かす形になっているのですが、この時のプログラムの構造が「**シングルスレッド**の **Windows GUI アプリ**だが **UI スレッドを持たない**」という構造になっており、Burn自身が、コピーした実際のインストーラ本体が終了するまで「[WaitForSingleObject](https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject?WT.mc_id=DT-MVP-32182)」で無限待機するという構造になっています。
その結果どうなるか？というと、Burn なブートストラッパーを起動したプログラム側で、UIが動き出すまで待つつもりで [WaitForInputIdle](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-waitforinputidle?WT.mc_id=DT-MVP-32182) で無限待機すると、UIが待機状態(メッセージループが稼働する)ことがないため、アプリ終了まで帰ってこないという状態になってしまい、待機する側が意図しない待機状態になってしまうという特性があります。

実際のところテストせずにリリースするなんてことはないと思うので、事前に発覚すると思いますが、この状態を把握していないと呼び出し元アプリは、メッセージ処理を受け付けない状態でスリープ状態で待機してしまうことになるため、いざ外部制御しようとしても反応しない(実際デッドロック状態)という状況になってしまいます。

## 実際のところ Burn のプロセスってどうなってるの？

そんな待機方法をしてるんだ？となると気になるのが一体いくつのプロセスが動くの？という素朴な疑問だと思います。

Burn では、まず最初の起動プロセス(１つ目)が、自身を専用フォルダにコピーして、そこでUIプロセスとして起動してねとパラメータを渡して起動(２つ目)し、自身は待機状態なります。
２つ目のUIプロセスは、実際に画面表示したり(非表示設定の場合は当然何も画面表示しません)しつつ、実際のインストールコマンドを実行します。
インストールコマンドが実行されると、インストーラ実行プロセス(３つ目)を必要に応じて昇格を伴いつつ実行します。
３つ目の実行プロセスは、Chainにあるリストに沿って、インストーラを粛々と実行していくという処理になっています(この先の実行プロセスは、Burn とは別のものが動いていく)。
ちなみに、昇格するかどうかは、ExePackage の場合は、PerMachine のフラグを参照、MsiPackage の場合は ForcePerMachine フラグか、msiそのものの設定を見て自動判定します。

この流れを把握しておくだけでも、いざ問題が出たというときの調査などはだいぶ変わると思います。Burnの内部をデバッグする必要がぁ～なんてのはほとんどないと思いますが、ある程度把握できてれば、カスタムBAを作るんだ！なんてなった時に助けになるかな？と思います。
「rf-killのため操作は不可能です」っていう表示が出る場合の対処法

数日，自前のPCがおかしい．
wpa_supplicantを立ち上げようとすると，何故かインターフェースがUPしない．
エラーメッセージは以下の通り．

```
rf-killのため操作は不可能です
```

お前何者だよ．いきなり登場するなよ．
せめて自己紹介くらいしろよ．

エラーが発生したのは，内蔵無線LANをUPしようとした場合に登場．
無線LANのアンテナ(IO-DATAとNETGEAR)は問題なく認識するし，立ち上がる．
内蔵無線LANのインターフェースがおかしい感じ〜〜〜

##まずはrf-killが何者なのか調べる

参考サイトを見てもらえばわかるが，RF-KILLはLinuxカーネルのサブシステムであるよう．
なぜか起動時にブロックされている模様．
そのために　<font color="Red">$ unblock all </font>と打ち込んで開放するというのが解消方法らしい．
状態を確認するのは以下のコマンドを使用．

```
$ rfkill list
0: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
1: hci0: Bluetooth
Soft blocked: no
Hard blocked: no
```

[rf-killについての参考サイト](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/power_management_guide/rfkill)

##解決コマンド

今回対象の無線LANインターフェースはwlp4s0です．

```
$ sudo rf-kill unblock all
$ sudo ifconfig wlp4s0
```
このコマンドで問題なく立ち上がる．
起動後に毎回打ち込むのが面倒なので，自動的にunblockするようにする．

```
$ sudo touch /etc/rc.local #これはrc.localがない人が作成するコマンド．
$ sudo vi /etc/rc.local

rc.local内部に以下の一文を記載
rf-kill unblock all 
```

viは:wqで保存して終了します．
##ブロックされていたらどうなるのか？

ブロックされたら，どうなるのか？
それはスマホの機内モードと同様な扱いになります．
すなわち，電波を出さなくなります．
<font color="Blue">飛行機に乗るときはrf-killしましょう．</font>

なぜ，いきなり登場したかの原因は探り中です．
自前のPCは大学入学時に買ってもらったPCであり，かれこれ5年強使っています．
OS入れ替えたときは特に変な挙動は見せていなかったが，内蔵のHDDがもしかしたら寿命なのかもしれませんね．
起動ファイル関係が破損している可能性も大いにあります．
また何か判明したら追記していきます．
Python インストールメモ

#はじめに
- PythonをWindows10にインストールしてみました。
- Pythonの実行環境として Anaconda があります。シンプルな環境で学びたいのでPythonの公式サイトで配布されているPythonを利用しました。
- コマンドプロンプトでpythonを実行すると「Microsoft Storeが開いてしまう問題」が発生しましたが、エイリアス設定をすることで解決しました。

#環境
- OS：Windows10 64bit
- インストール日：2021/08/04
- python-3.9.6

#自分が行った手順
##①インストーラをダウンロード
- Python公式ページの[ダウンロードリンク](https://www.python.org/downloads/)が、探しにくかったので[こちら](https://pythonlinks.python.jp/ja/index.html)からWindows用インストーラをダウンロード

##②ダウンロードしたパッケージを実行
- python-3.9.6-amd64.exe（当時の最新版）

##③コマンドプロンプトでpythonを実行
- なぜかMicrosoft Storeが開いてしまう？？？ 
![2021_0804_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843142/40244d38-42b1-f88b-ea64-3f99c91b603c.jpeg)

##④エイリアスの設定
- 設定→アプリ→アプリと機能→アプリ実行エイリアスで赤枠の部分をOFFに変更
![2021_0804_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843142/dbbba6f8-21fd-b200-b8a6-1efff527e97a.jpeg)

##⑤コマンドプロンプトでpythonを実行
- 直ったみたい・・・
![2021_0804_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843142/b9a7d6b6-4408-dc59-911b-ace366f0b67c.jpeg)

#参考ページ
[python.exe を実行すると Microsoft Store が開くのはなぜですか?](https://docs.microsoft.com/ja-jp/windows/python/faqs)
>python.exe を実行すると Microsoft Store が開くのはなぜですか?
新しいユーザーが Python の適切なインストールを見つけられるよう、Microsoft Store で公開されているコミュニティのパッケージの最新バージョンに直結したショートカットを Windows に追加しました。 このパッケージは、管理者のアクセス許可がなくても簡単にインストールでき、既定の python および python3 コマンドを実際のものに置き換えます。
コマンドライン引数を指定してショートカットの実行可能ファイルを実行すると、Python がインストールされていないことを示すエラー コードが返されます。 これは、意図していない場合にバッチ ファイルおよびスクリプトによって Store アプリが開かれるのを防ぐためです。

※Microsoftの「Windows での Python の使用についてよく寄せられる質問」からの引用

#最後に
- [Microsoftのこのページ](https://devblogs.microsoft.com/python/python-in-the-windows-10-may-2019-update/)によると「Windows 10 May 2019 Update」での変更のようです。
- MicroSoftさん、こそっと余計なことせんといてほしい💦
Javaで文字列が数値かどうかを判定する

なんでこんな初歩的なことを書くかというと、7月18日(日)に行われたJava™プログラミング能力認定試験 1級（サーティファイ）で出題されたのです。

ド忘れしちゃって苦し紛れに書いたのがこれ。

```java:
boolean isNum = true; // 数値だよ
try {
    Integer.parseInt(str);
} catch (NumberFormatException e) {
    isNum = false; // 数値じゃないよ
}
```

満点だったので合ってはいたようです。
ただ、これだと[全角数字もチェックOKになってしまう点](https://qiita.com/cress_cc/items/a72c25b39f5baaaac4d6)は要注意です。
知識や技能というよりは「妥協する力」を問われる試験だった。

実務では正規表現を使うのが正解なんだろうなあ。。
python ：MeCab でyoutube の投稿タイトルでよく使われる名詞を探す

# ・MeCabを使って自然言語処理に入門する
自然言語処理の入門として、MeCabを使用してみる。
youtube の投稿動画のタイトルでよく使用されている名詞を抽出する作業を行なってみる。
###・参考
・youtube統計データ（kaggle)
 　https://www.kaggle.com/datasnaek/youtube-new
・MeCab公式サイト
　https://taku910.github.io/mecab/
# ・import
```python:import
import MeCab
import pandas as pd
from collections import Counter
```
・MeCab：自然言語処理のため
・pandas:youtube統計データのcsvデータの読み込みと投稿タイトルの抽出
・collections：名詞の個数を数える
# ・csvデータの読み込みとタイトルデータの抽出
```python:pandas
#csv データの読み込み
df1 = pd.read_csv("「実際に読み込むデータ」.csv")

#読み込みたいカラムの文字列をwordsに格納
#重複したタイトルは読み込まない
words = []
for i in df1.loc[:,"実際のカラム名"]:
    if i not in words:
        words.append(i)
```
# ・MeCabの出力フォーマットを決める
```python:MeCab
mecab = MeCab.Tagger("-Osimple")
```
一番解析結果がシンプルな"-Osimple"を使用。
他には”-Oyomi”、"-Ochasen"など。

```python:MeCab
#mecab.parse(i)でwords内の投稿タイトルを順々に処理し、単語に区切っていく
result = []
for i in words:
    tango = mecab.parse(i).split("\n")

#区切った単語が名詞であればresultに格納していく
#j.split("\t")で単語自体とその単語の分類に分けている
    for j in tango:
        if "名詞" in j:
            meishi = j.split("\t")[0]
            result.append(meishi)
```

##### ・例　mecab.parse(i)では下記のようになっている

```python:MeCab
#words の中身
【叡王戦第１局】豊島将之叡王 vs 藤井聡太二冠

#mecab.parse(i)実行結果
【　　　　　　　　　　　　　記号-括弧開
叡　　　　　　　　　　　名詞-固有名詞-人名-名
王　　　　　　　　　　　名詞-一般
戦　　　　　　　　　　　名詞-接尾-一般
第　　　　　　　　　　　接頭詞-数接続
１　　　　　　　　　　　　名詞-数
局　　　　　　　　　　名詞-接尾-助数詞
】　　　　　　　　　　　　記号-括弧閉
豊島　　　　　　　名詞-固有名詞-人名-姓
将之　　　　　　　名詞-固有名詞-人名-名
叡　　　　　　　　　　名詞-固有名詞-人名-名
王　　　　　　　　　　名詞-接尾-一般
藤井　　　　　　名詞-固有名詞-人名-姓
聡　　　　　　　　　名詞-固有名詞-人名-名
太　　　　　　　　　名詞-固有名詞-地域-一般
二　　　　　　　　　名詞-数
冠　　　　　　　　　名詞-接尾-助数詞
EOS
```

最後に、collections のCounter で格納された名詞の数を数える。
most_common()で格納された数が大きい順に並べる。
数が多いので今回は上からTOP１０を表示。

```python:collections
Cnt = Counter(meishi)
top10 = Cnt.most_common()[:10]
for i in top10:
    print(i[0])

#print(i[0]):TOP10の単語
日
人
大
アニメ
さん
年
お
話
の
回
```
結果は本当か？と思ってしまいますが、MeCabの使い方としてはOK！
以上、入門でした。
p5.playをやる記事#05_アニメーションを適用する

[前回の記事](https://qiita.com/sdkfz181tiger/items/4207d679375ddae11b20) | [次回の記事](https://qiita.com/sdkfz181tiger/items/44e50719ff5cdaf036d7)

p5.playの使い方を解説しております。
[第1回の記事](https://qiita.com/sdkfz181tiger/items/c424b0777f7d7fe2203a)はこちらにありますのでご参照ください。

## アニメーションを適用する

今度はアニメーションに挑戦です。
前回の記事では単純に画像を適用していましたが、今回は"スプライトシート"を使います。

## スプライトシートとは?

スプライトシートとは、"複数の絵が並べてある画像"の事です。

![t_run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/39492800-5398-f1e8-946f-3b6cf2ea4501.png)

5つのキャラクターが並べて描かれてありますが、これは1枚の画像です。
この画像の1部を順番に表示する事でアニメーションを実現します。
"パラパラアニメ"を想像するとわかりやすいかと思います。

上記の画像を、スケッチにアップロードしておきましょう。
([前回の記事](https://qiita.com/sdkfz181tiger/items/4207d679375ddae11b20)を参考にしてみてくださいね)

## スプライトシートの作り方

スプライトシートの作り方ですが、オススメのオンラインエディタがあります。(お気に入りです!!)

[Piskel](https://www.piskelapp.com/)

こちらも動画を用意しておりますので参考にしてみてくださいね。

<iframe width="560" height="315" src="https://www.youtube.com/embed/K8dtEazwhuY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## スプライトシートとアニメーションのロード

では、さっそく使ってみましょう。
アニメーションを実現するには、2つの関数を利用する事になります。

１つ目はloadSpriteSheet関数です。
引数には、スプライトシートとして読み込む対象のファイル名、横幅、高さ、コマ数を指定します。
今回のスプライトシートの場合は1コマの大きさが144x144になり、5コマになりますね。

![t_run_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/c7ecfe14-c6b4-4413-93a6-095752771f0d.png)

```JavaScript
let ss = loadSpriteSheet(ファイル名, 1コマの横幅, 1コマの高さ, コマ数);
```

そして2つめは、loadAnimation関数です。
この関数の引数には、先ほど作ったスプライトシートオブジェクトを指定するだけです。

```JavaScript
let an = loadAnimation(スプライトシートオブジェクト);
```

## アニメーションの適用

最後はスプライトに対してaddAnimation関数を実行するだけです。
タグ名には、任意のアニメーション名を指定します。("run"とか"jump"とか自由に決めましょう!!)

```JavaScript
スプライト.addAnimation(タグ名, アニメーションオブジェクト);
```

全体のコードは下記の様になります。

```JavaScript
let an;// 1, アニメーションを格納する変数

function preload(){
   let ss = loadSpriteSheet("t_run.png", 144, 144, 5);// 2, 画像をロードする
   an = loadAnimation(ss);// 3, アニメーションをロードする
}

function setup(){
   createCanvas(windowWidth, windowHeight);
   frameRate(32);
   noSmooth();
   let spr = createSprite(width/2, height/2);
   spr.addAnimation("run", an);// 4, アニメーションを適用する
}

function draw(){
   background(0);
   drawSprites();
}
```

上手くいけば、下記の様にタヌキが歩き出します。(素敵!!)

![nacmk-h2f1z.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9823/e71dbe1d-5b0f-d847-5c3d-0d3f2ebf1e5f.gif)

次回も引き続き、スプライトについてのお話になります。

[前回の記事](https://qiita.com/sdkfz181tiger/items/4207d679375ddae11b20) | [次回の記事](https://qiita.com/sdkfz181tiger/items/44e50719ff5cdaf036d7)

## おまけ動画(こちらもよろしくお願いします)

<iframe width="560" height="315" src="https://www.youtube.com/embed/bHtS5tgRmFY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
htmlspecialchars関数とは PHP

#■htmlspecialchars()とは
PHP上でコードをテキストとして表示させる時に使うメソッド
エスケープを行うとも言う。
エスケープしないとXSSが行えてシステムに問題が起こる。

``` php
htmlspecialchars(第一引数,第二引数,第三引数);
```

▼第一引数
エスケープしたい文字を入れる。
変数でも良い。

▼第二引数
変換のパターンを入れる。


|変換パターン|説明|
|:--|:--|
|ENT_QUOTES|ダブルクオテーション、シングルクオテーションどちらも変換|
|ENT_COMPAT|ダブルクオテーションのみ変換|
|ENT_NOQUOTES|ダブルもシングルも変換しない|
|ENT_COMPAT|デフォルト|

▼第三引数
文字コードの指定
UTF-8など


###■htmlspecialchars()を使わない場合
コードがテキストとして表示されずコードの能力が発揮されている。
*危ない

``` php
<?php 
 $a = "<p>こんにちわ</p>";
 echo $a;
?>

//結果 こんにちわ
```

###■htmlspecialchars()を使う場合
コードがテキストとして表示されていてコードの能力が効いていない。
*安全

``` php
<?php 
 $a = "<p>こんにちわ</p>";
 echo htmlspecialchars($a,ENT_QUOTES,'UTF-8');
?>

//結果 <p>こんにちわ</p>
```

htmlspecialchars()を使わないとエンジニア側ではなくだれでもコードを書いていじる事ができてしまう。
安全性に問題がおきる。
【AWS】運用管理サービス

# 運用管理サービス

## Amazon CloudWatch
AWS上で稼働する様々なシステムやAWSのリソースの情報を**収集／監視／可視化するサービス**

### ◉CloudWatchの動作イメージ

[![Image from Gyazo](https://i.gyazo.com/a62edb3c087dd082c8d8687b0680bff4.png)](https://gyazo.com/a62edb3c087dd082c8d8687b0680bff4)

### ◉EC2のメトリクス
CloudWatchで**取得／監視する項目のこと**

#### ◎標準メトリクス
AWSから提供されている**標準の監視項目**

| メトリクス | 説明 |
|:-:|:-:|
| CPUUtilization  | CPU使用率  |
| DiskReadOps  | インスタンスストアボリュームからの読み取り回数  |
| DiskReadBytes  | インスタンスストアボリュームから読み取られたバイト数  |
| NetworkIn  | 全てのネットワークインターフェイスから受信されたバイト数  |

#### ◎カスタムメトリクス
- メモリ使用率
- ディスク使用率
- スワップ使用率
など

### ◉CloudWatchの監視間隔と保存期間

| プラン | 課金 | 監視間隔 | 収集データの保存期間 |
|:-:|:-:|:-:|:-:|
| 基本モニタリング  | 無料  | ５分間隔  | 最大15ヶ月  |
| 詳細モニタリング  | 追加料金が必要  | 1分間隔  | 最大15ヶ月  |

### ◉CloudWatchアラームによるアラームとアクション設定
メトリクスが**ある一定の値になった（閾値を超えた）**場合に、アラームとアクションを起動する

#### ◎CloudWatchの状態

| 状態 | 説明 |
|:-:|:-:|
| OK  | 定義された閾値を下回っている正常な状態  |
| ALARM  | 定義された閾値を上回っている異常な状態  |
| INSUFFICIENT-DATA  | CloudWatchに送信されるデータが不足しているため、正常か異常か判断できない状態  |


### ◉CloudWatch Eventによるイベント駆動型監視とアクション設定
**イベント**をトリガーにアクションを実行する
#### ◎監視対象
- EC2インスタンスの状態変化（pending／running／terminatedなど）
- スケジュール（分／時／日間隔）
- Auto Scaling（起動成功／起動失敗など）

#### ◎監視後のイベント
- Lambda関数
- SNS（Simple Notification Service）トピック
- Kinesisストリーム
- SQS（Simple Queue Service）キュー

## その他の運用管理サービス
### ◉CloudWatch Logs
Cloud TrailやVPCフローログなど様々な**AWSのログを統合的に収集するサービス**

### ◉Cloud Trail
- AWSアカウントで利用された**操作（APIコール）**をログとして記録するサービス
- 不審なアクセスや操作がないか／意図しない設定変更がされていないか監視できる

### ◉VPCフローログ
VPC内のネットワークインターフェイス間で行き来する通信の内容をキャプチャする機能

### ◉AWS Config
AWSのサービスで管理されているリソースの構成変更を追跡するサービス

- EC2インスタンスの作成や削除などの構成変更
- S3バケットに対する構成変更
など

### ◉AWS Systems Manager
AWS内の様々なリソースの運用情報を統合的に可視化／制御するサービス
#### ◎機能
- パラメーター機能
- オートメーション機能
- 実行コマンド機能

### ◉AWS Trusted Advisor
AWSの**ベストプラクティス**に基づいて、ユーザーのAWS利用状況をチェックし、改善すべき事項を推奨するサービス

- コスト最適化
- セキュリティ
- 耐障害性
- パフォーマンス
- サービスの制限

### ◉AWS Backup
AWS内におけるデータの**バックアップを一元化／自動化するサービス**

- EBSボリューム／EC2インスタンス／RDSデータベースなどのバックアップの定期実行
- バックアップ状態の監視

#### 参考
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html#ec2-cloudwatch-metrics

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html

https://aws.amazon.com/jp/cloudtrail/

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html

https://aws.amazon.com/jp/config/

https://aws.amazon.com/jp/systems-manager/

https://aws.amazon.com/jp/premiumsupport/technology/trusted-advisor/best-practice-checklist/

https://aws.amazon.com/jp/backup/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc
WSL2で時刻がずれる問題が解決していた！

WSL2ではPCをスリープ状態にすると時刻がずれてしまう問題があり、そのせいで`apt`や`git`コマンドでエラーが発生することがありました。

この問題がカーネルバージョン5.10.16.3で解決していたようです。
WSL2カーネルの更新方法をまとめておきます。（といってもWindows Updateを適用するだけですが）

# カーネル更新方法

1. 現在のカーネルバージョンを確認

    ```bash
    $ uname -r
    4.19.104-microsoft-standard
    ```

    WSL2ではMicrosoftによってチューニングされたカーネルが使用されています。

1. WSL2カーネル更新

    WSL2のカーネルはWindows Updateから提供されています。
    私の環境では更新プログラムのチェックを行うと「Windows Subsystem for Linux Update - 5.10.16」という名前で更新プログラムが降ってきました。

    :::note warn
    WSL2カーネルの更新プログラムを受け取るには詳細オプションの「Windows の更新時に他の Microsoft 製品の更新プログラムを受け取る」をオンにしておく必要があるようです。
    :::

1. 更新後のカーネルバージョンを確認

    WSL2を一度停止してから確認します。

    ```bash
    > wsl --shutdown
    > wsl
    $ uname -r
    5.10.16.3-microsoft-standard-WSL2
    ```
    正しくアップデートされていることが確認できました。

これでずれなくなるはず。。。

# 参考

https://github.com/microsoft/WSL/issues/5324

https://docs.microsoft.com/en-us/windows/wsl/kernel-release-notes#510163
Herokuデプロイ時の『Process exited with status 143』の対処法

#概要
railsで作成したアプリをHerokuにpush。後日、変更を加え再度Herokuにpushしたらエラー発生。ターミナルでログを確認すると下記の表示が。

```:ターミナル
$ heroku logs
...
...
2021-08-04T03:41:21.918364+00:00 heroku[web.1]: Process exited with status 143
```


#原因
###### Herokuのサーバが立ち上がっていないためexitになってしまう。。。（当たり前）


#改善方法
Herokuを（再）起動させる。

```:ターミナル
#再起動のコマンド
$heroku restart

# Herokuを停止して起動
$ heroku ps:scale web=0　　 # =>停止
$ heroku ps:scale web=１　　　　# =>起動
```
#Heroku　dynoについて
- リンク→https://jp.heroku.com/dynos
- 設定うんぬん→https://devcenter.heroku.com/ja/articles/dynos
mat-tooltip で複数行対応するためにしたこと


上手いことすんなりいかなかった記憶なので
備忘録として後世の自分に残しておく  
参考サイト：https://www.angularjswiki.com/material/tooltip/  
👆に詳細がかいてあるのでぜひ。


## 環境

Angular v10

## 備忘録

custom-tooltipを追加し改行させるように設定する。

```scss
.custom-tooltip {
  white-space: pre-line;
}
```

matTooltipClass="custom-tooltip"でバインドする。
「`&#13;`」で改行してくれるようになる。

```html
<mat-icon
  matTooltip="AAA&#13;・BBB&#13;・CCC"
  matTooltipClass="custom-tooltip"
>info
</mat-icon>
```

custom-tooltipにfont-sizeでフォントのサイズも変更できたのでcss周りをいじれるようになった。
Laravel の Blade 構文のコンパイルと javascript の処理

#初めに
この記事は執筆時点での最新版である laravel8.x と LTS である laravel6.x を前提に記述しています。

今回は laravel の blade 構文と javascript の処理の順序について整理したいと思います。

# Blade のコンパイル
laravel の blade テンプレートと言えば、`@if`などの表記の記法と`{{ $variable }}`といった表示の記法が主と思います。

実際には、コントローラ等のレスポンスで

```
view('(resources/views 以下のパス)');
```

と記載して返しているかと思います。

この際に帰される実際のページのファイルはHTMLとPHPで構成されたコンパイル済みのファイルです。

標準的な laravel であれば、コンパイル済みのファイルは`storage/framework/views`内に格納されています。
（コンパイル済みのファイルのファイル名は元のファイルとは違うので、判別する際は実際にファイルの中身を見て判断する必要があります）

# コンパイル済みのファイルと javascript
上記の通り、blade の構文で書いたファイルはサーバーサイドでコンパイルされたうえで内容が解釈され、アクセスしてきたユーザーに返されます。

基本的に画面ファイル内に存在する javascript は、ブラウザが表示を行う際に処理されるため、結果として、
・blade 構文の`@if`や`@foreach`などで script の内容をダイナミックに制御できる
・view に渡した変数を`{{ $var }}`を用いて script 内に配置できる
といったメリットが得られます。

このメリットは、javascript 側のプラグインなどで大いに活用でき、views に渡した変数の内容に応じて、javascript 側のプラグインのオプションを制御するなどといったことが行えます。

# blade + vue.js
blade 上で vue.js を書く場合も上記と同様のメリットがありますが、表記の衝突などで問題が発生します。
最も頻発する例では、変数の表示が`{{ }}`で衝突するという問題です。
この問題では、blade 側のコンパイル時に処理される部分は`{{ }}`を、blade のコンパイル時には処理されずに vue.js で処理されてほしい部分については`@{{ }}`を用いる必要があります。
[AWS]同一アカウントでスイッチロールしたメモ


Service Catalogのチュートリアルを行うにあたり
普段使っているアカウントで検証用のロールに切り替えたときのメモです:pencil:

Service Catalogのチュートリアルはこちら：

https://docs.aws.amazon.com/servicecatalog/latest/adminguide/getstarted.html

## スイッチロール 手順
1. IAMロールの作成
1. ロールの切り替え

#### 1. IAMロールの作成

1. IAMコンソールを開く
1. ロール>ロールを作成
1. 信頼されたエンティティ：別のAWSアカウント を選択
1. アカウントID欄に自分のIDを入力
1. AWSServiceCatalogEndUserFullAccessをアタッチ&STS.AssumeRoleのアクセス許可を追加

#### 2. ロールの切り替え
1. 作成したロールの詳細画面を開く
1. 「コンソールでロールを切り替えることができるユーザーに、このリンクを知らせます。」のURLをコピー
1. 2のURLをブラウザに貼り付けてアクセス
1. 画面の指示に従ってロール切り替え

元に戻したいときは

1. コンソール画面上部の「ロール名@アカウントID▼」をクリック
1. 「〇〇(ユーザー名)に戻る」

で戻せます。

## 参考
スイッチロールの方法についてはこちらの記事を参考にしました。

https://dev.classmethod.jp/articles/iam-switch-role-in-same-account/

Service Catalogのチュートリアルでスイッチロールを使う点についてはこちらの記事を参考にしました。

https://zenn.dev/mn87/articles/81479d5323766c
Carbon - コードを綺麗な画像に変換

#Carbon

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1845219/6c9a6247-d587-c0b3-19ae-e05d141ce336.png)

https://carbon.now.sh/

ブラウザ上でコードを入力
画像として保存することができるツール

背景色や余白、カラーなどの設定を変更することができる

参考サイト
[URL]https://www.moongift.jp/2017/10/carbon-%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E7%B6%BA%E9%BA%97%E3%81%AA%E7%94%BB%E5%83%8F%E3%81%AB%E5%A4%89%E6%8F%9B/
ICOスクリプトソフトウェア–成長するビジネスのための成功したICO立ち上げ戦略


ICOスクリプトソフトウェアは、投資から十分な利益を上げることを計画している投資家に明確な最上位の手を提供します！
どのように？
さて、私たちはここのブログでこれらすべてについて議論し、それがあなたにいくつかの本当に役立つ情報を提供することを願っています。また、ICOなどの基本的な用語についても説明します。

ICOとは何ですか？
皆さんご存知かもしれませんが、ICOはイニシャルコインオファリングを表しています。 ICOは、あなたがあなたのビジネスのためにいくらかの大きな現金を集めるために気をつけている場合に実行することができる最高のテクニックです。 ICOは、特定の価値を保持する基本的な物質です。

あなたは本当の意味であなた自身でトークンを作成することができます、そして購入者は彼らが彼らの子猫に持っているトークンと同等のあなたの管理を実際に要求したいと思うでしょう。

ICOスクリプトのオープンソースプログラミングは、独自のトークンをディスパッチしたい場合の理想的な段階です。あなたのビジネスに最適なICO開発管理を選択してください。

ただし、ICOスクリプトの進歩を始める前に、以下で参照されている特定の事柄を完全に理解する必要があります。

市場でICOスクリプトソフトウェアを立ち上げるための提案
1.ICOプロジェクトの価値
あなたが発行したいトークンは、あなたの組織が作成していて、それを市場に出すことを意図しているアイテムと同様に評価されるべきです。同様に、あなたは一般の人々があなたのトークンの代金を支払う準備ができている金額を合理的に理解しているべきです。さらに、重要なアップグレードを行うことができるように、トライアルを取得し、群衆からいくつかの重要な批判を集めることが賢明です。同様に、ICO開発、暗号通貨開発などで特定されたさまざまな集まりについて記録を作成することも重要です。

2.法的手続き
ICOコンテンツをディスパッチしたい国のガイドラインとガイドラインのすべてを満たす必要があります。適切に計画し、さらに暗号化マネーフィールドについて常に最新の状態を保つようにします。

3.ICOトークンと配布計画を作成します
ICOコンテンツをディスパッチしたい国のガイドラインとガイドラインのすべてを満たす必要があります。適切に計画し、さらに暗号化マネーフィールドについて常に最新の状態を保つようにします。

4.ホワイトレポートを生成する
ホワイトペーパーは、前提条件、詳細、市場調査、使命、ビジョン、ビジネスの進歩、ベンチャー全体の改善策などから、すべての微妙な点を明確に決定するアーカイブです。
ホワイトペーパーを作成するときは注意してください。

5.ウェブサイトを開発する
ウェブサイトは、必要な詳細を一般に公開するのに最適なプラットフォームです。これには、目的、チーム、ICOスクリプトソフトウェアの目標などの情報が含まれる場合があります。

6.ソーシャルメディアプラットフォームを賢く使用する
Instagramのようにウェブベースのメディアステージを活用することで、期待される顧客の獲得を巧みに支援します。これらのWebベースのメディアの目的地でローカルエリアページまたはディスカッションを作成して、限られた容量の中で最大の群衆に連絡して時間を集中できるようにします。そのような議論はあなたのトークンを支持するのを助け、その結果、実りあるICO派遣につながります。

7.業界からの必要なバックアップ
膨大な数のICOスクリプトオープンソースが定期的に派遣されているため、ビジネスからの十分な支援は非常に重要です。また、離れて立つために、ビジネスの支援は非常に必要であるため、そのエネルギーを生み出すのに役立ちます。実りある派遣に必要です。
同様に、本当の意味でICOスクリプトをディスパッチする前に、与えられた焦点の下にあるものを検討してください。

なぜICOローンチソフトウェアをローンチするのに適切な時期なのですか？

規制されたグローバル市場
国の大多数は、デジタル通貨と関連する行政に関して特定の厳しいガイドラインとガイドラインを持っています。さらに、日本、米国、フランスなどの特定の国はすべて、それをリベラルにしたか、そのような暗号ベースの通貨基準に向けて支援を始めました！

機関投資家の資金の流入
機関投資家の現金のより確実な収束は、象徴的な取引領域の有効性をサポートし、その結果、Icoへのより多くの収集誓約を促します。

非常に効率的で信頼性の高い管理プラットフォーム
今日私たちが持っているICOステージのほとんどは、それらの象徴的な取引手段を扱う際に慣習的なプログラミングに依存しています。
ICOには独自のルールと測定値があり、古くて不可欠な機器では監視できません。
シンボリックディール業界を明示的に管理する新しい調査装置の概要は後で発生します。


独自のICOスクリプトソフトウェアを構築することを計画していますか？
ICOビジネスは絶えず進化しており、財政支援者は現在、ICOスクリプトソフトウェアの利用に傾倒しています。

https://echyip.com/product/ico-script-software/
Pythonで特定ファイル探索

#Pythonで特定ファイル探索

##はじめに
皆さん、職場で知りたいことがあるときに、知りたい内容がまとまった資料があればいいのにと思ったことないだろうか。今回は、自分のPCやサーバーで特定の文字を名前に含むファイルや特定の拡張子を持つファイルを探索する方法を紹介する。
※ページ下部のコメントでより良い書き方を教えていただいたので、そちらを参照ください。

##os.walk
Python module **"os"**の.walkというclassを使う。osはさまざまなOS操作をpython上で行うmoduleであり、ファイル操作、Job管理、環境変数の操作などができる。.walkは特定のpathの下層のフォルダとファイル名をすべて取得してくれるclassである。

https://docs.python.org/3/library/os.html?highlight=os%20walk

##探査プログラム
以下にサンプルプログラムを示す。引数にファイル名の部分一致か拡張子一致を選ぶmode、探索対象のフォルダのpath、探索したいキーワードか拡張子を与えている。探索結果はcsvファイルで吐き出している。

※エンコーディングをコメントしてましたが、Pythonコーディング規約にそぐわないとご指摘いただいたので削除しました。
~~# -*- coding: utf8 -*-~~
Pythonコーディング規約 : [pep8](https://pep8-ja.readthedocs.io/ja/latest/)

```Python
#!/usr/bin/env python

import sys
import os
import numpy as np

if len(sys.argv) != 4: 
   print("INPUT ERROR in python")
   print("python find.py mode folder word")
   print(" mode               - select mode  ") 
   print("                      -1 = include in file name") 
   print("                      -2 = match to file extension")
   print(" folder             - root directory for search  ")   
   print(" word               - keyword for finding file")
   print("")
   print(" output ")
   print(" csv     - path name list")
   print("")
   print(" e.g : python find.py -1 C:\ apple")
   exit()

mode = sys.argv[1]
path = sys.argv[2]
word = sys.argv[3]

datray = np.array([])
datray  = np.append(datray , "Path Name")

for root, dirs, files in os.walk(path):
    for file in files:
        path = os.path.join(root, file)
        if mode == "-1":
            if word in file:
                print(os.path.join(root, file))
                datray  = np.append(datray , os.path.join(root, file))
        if mode == "-2":
            lword = -1*len(word)
            ext = file[lword:]
            if ext == word:
                print(os.path.join(root, file))
                datray  = np.append(datray , os.path.join(root, file))

DAT =  np.column_stack(datray)
outname = './find_'  + str(word) + '.csv'
np.savetxt(outname, DAT , delimiter=",\n", fmt="%s")
```

##まとめ
今回は、Pythonを使って簡単な特定ワードを含むファイルまたは特定拡張子を持つファイルの探索プログラムを紹介した。暇つぶしに社内サーバーのファイルを漁ってみるのもいいだろう。
PowerAutomateDesktopを用いてexcelの表まとめの自動化までのメモ

を書いていきます。

#目的
あるフォルダにあるexcel軍をそのフォルダの_matome.xlsxにまとめる

#手段
PowerAutomateDesktopが使えそうだったので使ってみるっ

#現状詰まっている点
一つのexcelを貼り付ける所まで出来たのですが
複数をループしてやるやり方が分からないのです……

現状こんなレベルなのですが
なんとか使えるレベルまで持って行きたいと思っておりますので
応援（？）よろしくお願いいたします。

#参考文献リスト
[Power Automate Desktop を使ってみよう – SAFETY RABBIT](https://www.safetyrabbit.net/techinfo/power-automate-desktop-%E3%82%92-%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/)

[Power Automate サポート - Power Automate Desktop と Power Automate に関するサポートサイト 無料のチュートリアルなど多数公開しております](https://support.asahi-robo.jp/)

[【Windows 10版でどこまでできるか】Power Automate Desktop のライセンスやできることや気になることまとめ【随時更新】 - Qiita](https://qiita.com/maekawawawa/items/b9c7b866f5ee31d2acd3)

[【レビュー】タダで使えるWindows用業務自動化ツールを活用! Microsoft「Power Automate Desktop」の使い方 - PC Watch](https://pc.watch.impress.co.jp/docs/topic/review/1317232.html)

[Power Automate Desktop の使い方（チュートリアル）- ロボ研](https://support.asahi-robo.jp/tutorial/power-automate-desktop)

[ループ処理 - Power Automate サポート](https://support.asahi-robo.jp/tutorial/power-automate-desktop/beginner/loop)

とか見てみるぞー
ちなみに上のは

[【Windows 10版でどこまでできるか】Power Automate Desktop のライセンスやできることや気になることまとめ【随時更新】 - Qiita](https://qiita.com/maekawawawa/items/b9c7b866f5ee31d2acd3)
からのリンクの抜粋だったと思う(^_^;)
Vue.js基礎知識に関する記事一覧

公式ドキュメントに沿って自分用教科書として記事を随時更新しているので一覧まとめです

[Vue.jsの環境構築をしてhellowordを出力する【初心者向け】](https://qiita.com/kty000/items/244b0db02bff7164188b)
[vue.jsの使い方の基礎＃１](https://qiita.com/kty000/items/98aa7e83ec496daf3137)
[Vueのコンポーネントを学ぶ](https://qiita.com/kty000/items/2236e96b1bf56fc79ddd)
[vue.jsの使い方の基礎＃２【computed/methods/watch】](https://qiita.com/kty000/items/c2169079fedbafa51f20)
[vue.jsの使い方の基礎＃３【v-if / v-else / v-else-if / v-show】](https://qiita.com/kty000/items/177cd505c00f3bb5af5b)
[vue.jsの使い方の基礎＃４【v-forの使い方色々】](https://qiita.com/kty000/items/118b8fb591efbc1afe5c)
[vue.jsの使い方の基礎＃５【v-onの使い方】](https://qiita.com/kty000/items/58d0bddb924e2cb476e3)
[vue.jsの使い方の基礎＃６【フォーム入力バインディング】](https://qiita.com/kty000/items/ddd3cf761a4adf8edac1)
同じ .htpasswd ファイルを使っているのに複数回Basic認証のダイアログが開いてしまう

# 問題

Apache のサーバーでウェブサービスを動かしていて、領域 `/private1/` と `/private2/` 以下を共通の .htpasswd ファイルを使った Basic 認証必須の設定としている。
想定している動作としては、ブラウザで `/private1/` を開いて１度パスワードを入力したのであれば、`/private2/` 以下にアクセスしたときに、再度パスワード入力を要求されたくない。
しかし、今回はそうではなく、`/private1/` 以下へのアクセスの後に `/private2/` 以下にアクセスしたとき、再度のパスワードの要求が行われてしまった。 もちろん、その逆も同様である。

# 原因

今回、Basic認証の設定は `/private1/.htaccess` と `/private2/.htaccess` でそれぞれBasic認証の設定を個別に行っていた。 しかし、作成者がそれぞれ別だったため、AuthUserFile では同じ `.htpasswd` ファイルを使っていたが、**異なる AuthName を使う設定となっていた。**

> AuthName ディレクティブでは、認証に使う Realm (訳注: 領域) を設定します。Realm は大きく分けて二つの機能を提供します。 一つ目は、クライアントがパスワードダイアログボックスの 一部としてユーザにこの情報をよく提示する、というものです。 二つ目には、クライアントが与えられた認証領域に対してどのパスワードを 送信すれば良いのかを決定するために使われる、という機能です。

> 例えば、"Restricted Files" 領域中で 一度認証されれば、同一サーバ上で "Restricted Files" Realm としてマークされたどんな領域でも、クライアントは 自動的に同じパスワードを使おうと試みます。 このおかげで、複数の制限領域に同じ realm を共有させて、 ユーザがパスワードを何度も要求される事態を 防ぐことができます
> https://httpd.apache.org/docs/2.4/ja/howto/auth.html

とあるため、クライアントブラウザ側の入力を１度で済ませたい場合、同じ名前の AuthName を設定する必要がある。

なお、Chrome 以外のブラウザではダイアログにこれを表示してくれるが、Chrome では AuthName 部分が表示されないため少し注意のこと。
Grove IoT スターターキット for SORACOM でブザーをならす

Grove IoT スターターキット for SORACOM でブザーをならす方法です。
Arduino で2次元配列を使うサンプルにもなっています。
ブザーの Grove は D38 に接続します。

```text:grove-buzzer/grove-buzzer.ino
// ---------------------------------------------------------------
/*
	arduino_buzzer.ino

					Aug/04/2021
*/
// ---------------------------------------------------------------
#include <WioLTEforArduino.h>

#define BUZZER_PIN      (WIOLTE_D38)
#define BUZZER_ON_TIME  (100)
#define BUZZER_OFF_TIME (500)

WioLTE Wio;

int led[5][3] = {{0,0,1},{0,1,0},{1,0,0},{1,1,0},{0,0,0}};

// ---------------------------------------------------------------
void setup()
{
	pinMode(BUZZER_PIN, OUTPUT);
	delay(500);
	Wio.Init();
}

// ---------------------------------------------------------------
void loop()
{
	for (int it=0; it<5; it++)
		{
		digitalWrite(BUZZER_PIN, HIGH);
		Wio.LedSetRGB(led[it][0],led[it][1],led[it][2]);
		delay(BUZZER_ON_TIME);

		digitalWrite(BUZZER_PIN, LOW);


		int time_delay = BUZZER_OFF_TIME * (it + 1);
		delay(time_delay);
		}
}

// ---------------------------------------------------------------
```

実行時の様子
![IMG_20210804_165341.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/766c55f6-d63a-bbf3-a7f3-5644b2f7ced6.jpeg)
PIC32でMPLAB Code Configurator (MCC) を使うためのtips

PIC32MXデバイスでMPLAB Code Configurator (MCC) を使おうとしたら、こんなことになった。

```
15:52:09.870 WARNING: The project\\\'s device is not supported by the currently loaded libraries. All library versions are available for download on the MCC website. www.microchip.com/mcc
15:52:09.894    INFO: Stop MCC
```

マイクロチップのサポートに連絡するとライブラリが対応してないんじゃないかと聞かれたが、使用しているPIC32MX110F016Bは最新ライブラリに対応しているらしい。

どうやら、PIC32MXのライブラリそのものが開発停止されており、最新のMPLAB Xに実は対応していない、ということだったようだ。

#公式サポートの答え
以下やりとり。（Q：筆者　A：サポート職員さん）

Q: このライブラリ自体が古いので、最新版のmplab-coreでは動かないようだ。coreは切り替えられるのか？

A: 基本的に**MPLAB X IDE、MPLAB Code Configurator (MCC)、MCC core、mccライブラリのバージョンは基本的に１対１対応。**古いライブラリは新しいcoreと互換性がないし、古いMCCも新しいIDEでは走らない。近いバージョン（半年くらい）のものなら走ることがあるが、これはたまたまと認識したほうがいい。
最新バージョンのIDEを使うなら、Harmonyを使うしか無いのかなと思う。

Q: Harmonyはランニングコスト的にあまり使いたくは…

A: つまりMCCv3を走らせることが目標になるね

Q: MCC内でデフォルトのcoreを切り替えたり、MPLAB内でMCCを切り替えたりはできる？

A: **できない。**IDEとMCCは一対一対応。複数バージョンのMCC（v3とv4）の共存はできない。（たぶんデフォルトcoreの切り替えも不可能）

Q: 複数バージョンのIDEを共存させることはできる？

A: **できる。**Net Beansがそれをサポートしているから。

#つまり
**古いライブラリを使いたいなら、IDEごと複数バージョン用意せよ**

ということでした。自分はかなりここでハマったので、これを備忘録としておきます。

（的確な回答をくださったサポートの担当者様、ありがとうございました）
Google Play Console経由でaabファイルをインストール

# はじめに
Google Play Console経由でインストールする方法について、以下の2パターン解説。
* 方法1: 内部アプリ共有
* 方法2: 内部テスト

# 方法1: 内部アプリ共有
1. Google Play Consoleのアプリ画面からメニューを開き、`設定`→`内部アプリ共有`→メーリングリストをチェック→`変更を保存`をクリック
![内部アプリ共有.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/13375317-7b2f-2a3a-8441-2558cabef6dd.png)

2. `App Bundle エクスプローラ`を選択し、`新しいバージョンをアップロード`ボタンからaabをアップロード。
![AppBundleエクスプローラ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/d353adfa-b7c0-0d97-fcab-f3bc479f1d24.png)

3. アップロードしたバージョンを選択し、ダウンロードタブの`共有可能なリンクをコピー`からスマホでダウンロード

※`アーティファクトを共有するには、事前にトラックに公開する必要があります。`と出てきた場合、方法2でトラック公開後に再度上記操作を行ってください。

# 方法2: 内部テスト

1. Google Play Consoleのアプリ画面からメニューを開き、`内部テスト`→`新しいリリースを作成`を選択し、リリース作成。
![screenshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/d4c1ca39-c3b7-64ee-665d-901d287c4643.png)

2. 作成し終わったら、```テスター数```タブの下部にある```リンクをコピー```から、テスターへ招待

3. Androidスマートフォンで、Google Playストアアプリからアプリをインストール

# 補足
bundletoolを使う方法は[こちら](https://qiita.com/ikemura23/items/9b6064cb123edc1e233f)に掲載されている。

https://qiita.com/ikemura23/items/9b6064cb123edc1e233f
Raspberry Pi 4B にQt5をインストールする

# はじめに

RaspberryPi-4B 4GB版を手に入れたので、Qt5を入れて開発環境を整えてみました。
いままではLinuxやMac上のQtでクロスコンパイルしてラズパイSDに転送という方法でしたが、ラズパイ4はパワーがあって実機でビルド＆ランすることができるので開発サイクルが楽になります。
![IMG_2216.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839672/8725df9c-fb45-f6ad-1a86-db1b67818be2.jpeg)
# 環境
ラズパイ本体はこれ。

https://www.amazon.co.jp/dp/B08L39CNFF/

![スクリーンショット 2021-08-04 15.52.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839672/3e3b557b-accd-1a71-8b41-54c6b77449dd.png)
32GBのSDカードを載せてUbuntu21.04で動作させています。
ラズパイへのUbuntuインストールは、このあたりの記事が親切です。
基本的にRaspberry Pi Imager任せです。

https://uepon.hatenadiary.com/entry/2020/05/05/211011

ディスプレイはタッチパネル付きを使っています。

https://www.amazon.co.jp/dp/B08KW5XMQY/

実際には画面が細かすぎるので、VNCで画面を飛ばしてMac画面上で操作しています。
![スクリーンショット 2021-08-04 16.31.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839672/a11e3a04-d0bd-a1f6-678e-76adb154c94b.png)

    Settingアプリ→Sharing→Screen Sharingをオンにする。


# Qtのインストール
### Qt本家のインストーラー
最初に本家Qtのオンラインインストールを試みたのですが、Linuxのインストーラはx86にしか対応しておらず、armのラズパイにはインストールできません。ここに気が付くのに時間が掛かりました（笑）
![スクリーンショット 2021-08-04 16.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839672/ba2d0688-aed2-b614-703d-4bebdcbf9f47.png)

https://qt.io/offline-installers

### Qtソースからのビルド
それではラズパイ用にarmビルドが必要だと思い、このサイトや

https://qiita.com/task_jp/items/428744efe67320cd4d6a

このサイトを参考にコマンドを打ちまくりましたが、うまくいかず。

https://www.tal.org/tutorials/building-qt-512-raspberry-pi

### apt-get
結局、ラズパイからでも以下のコマンドで簡単にインストールできました。

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install qt5-default
    sudo apt-get install qtcreator
    sudo apt-get install qtdeclarative5-dev
# Qt Creator画面
![スクリーンショット 2021-08-04 15.44.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839672/322c9437-f27c-d4ad-f5e9-f541a1a1cad7.png)
まだHelloWorld程度の動作確認ですが、ビルドもランも軽快に動いてくれてます。
Installing ffi 1.15.0 with native extensions Gem::Ext::BuildError

急にffiがインストールできなくなるエラー

```
Fetching ffi 1.15.0
Installing ffi 1.15.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory: PATH_TO/vendor/bundle/ruby/2.7.0/gems/ffi-1.15.0/ext/ffi_c
/Users/USER/.rbenv/versions/2.7.1/bin/ruby -I /Users/USER/.rbenv/versions/2.7.1/lib/ruby/2.7.0 -r ./siteconf20210804-11406-5ju1ry.rb extconf.rb
checking for ffi_prep_closure_loc() in -lffi... no
checking for ffi_prep_closure_loc() in -llibffi... no
checking for ffi_prep_closure_loc() in -llibffi-8... no
checking for whether -Wl,--exclude-libs,ALL is accepted as LDFLAGS... no
creating extconf.h
creating Makefile

current directory: PATH_TO/vendor/bundle/ruby/2.7.0/gems/ffi-1.15.0/ext/ffi_c
make "DESTDIR=" clean

current directory: PATH_TO/vendor/bundle/ruby/2.7.0/gems/ffi-1.15.0/ext/ffi_c
make "DESTDIR="
/bin/sh: -c: line 0: unexpected EOF while looking for matching `"'
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [PATH_TO] Error 2

make failed, exit code 2

Gem files will remain installed in PATH_TO/vendor/bundle/ruby/2.7.0/gems/ffi-1.15.0 for inspection.
Results logged to PATH_TO
/vendor/bundle/ruby/2.7.0/extensions/x86_64-darwin-20/2.7.0/ffi-1.15.0/gem_make.out

An error occurred while installing ffi (1.15.0), and Bundler cannot continue.
Make sure that `gem install ffi -v '1.15.0' --source 'https://rubygems.org/'` succeeds before bundling.
```

個別インストール `gem install ffi -v '1.15.0' --source 'https://rubygems.org/'` ではインストールできても `bundle install` ではインストールできない

解決法

```
% xcode-select --install
% bundle install --path vendor/bundle
```