OmniAICreator/Qiita-1.07M huggingface dataset:
都道府県名をセレクトボックスで使用したい時に、Configファサードを使ってみる。

セレクトボックスを使用したい時に、optionタグを使う方法が思い浮かぶと思いますが、ビュー側のbladeに書くのが憚れるほど要素が多い時、例えば都道府県のように47個も書いてしまうと、それだけでbladeが散らかってしまいます。

そこで、こういったあらかじめ値や文字が決まっている場合は、別の場所にファイルを作って管理する方が便利です。

本記事では、Configファサードを使って呼び出す方法を紹介します。

## 都道府県のような固定値は、config内でファイルを作って管理しよう

まず、config配下にconstant.phpというファイルを作ります。

![config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487348/4e38efca-7113-2c5a-1635-d3852589fbc4.png)

次に、constant.phpでは、都道府県の情報を書き込んでいきます。

```
return [
   '1' => '北海道',
   '2' => '青森',
   '3' => '岩手',
];
```

## 呼び出すときはConfigファサードで
まず、Configファサードを使用する宣言をします。

```
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Config; //Configファサードの宣言
```

あとは、使用したいところで呼び出すだけです。

```
public function post()
    {
      //これでconstant.phpで設定した値が使用できます
      $prefecture = Config::get('constant');

      return $prefecture;
    }
```

ちなみに、返り値は下記の通り、配列です。

```
array:3 [▼
  1 => "北海道"
  2 => "青森"
  3 => "岩手"
]
```
.Net Core 3.1 Entity Framework Core Database First　する方法

## まえがき
.NetCore 3.1でMySQLでEntityFrameworkでDBファーストしようと思ったら
公式っぽいMySql.Data.EntityFrameworkCoreが3.1に対応していないせいで苦労した

## 開発環境
動作環境はcent7で.NetCore3.1なのだが使用ツールの関係で2.1も必要になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145884/14ece62b-ef58-fde6-1757-5ca17d0651af.png)

## 解法(ポイント)
* Pomelo.EntityFrameworkCoreを使うこと
* DBを読んでモデルを生成するMicrosoft.EntityFrameworkCore.Tools.DotNet　Version="2.0.3" が.NetCore 2.x を要求してくる(2.1で動いたから良しとした)

> 後日談 2020/12
> .Net5のみで動くようになってた
> インストール方法は https://docs.microsoft.com/ja-jp/ef/core/cli/dotnet
> コマンドで dotnet ef を dotnet-ef にすればOK

必要ライブラリは dotnet add package ～～～～　というコマンドで入れるのが正攻法だが
面倒なのでcsprojを以下のようにすして dotnet restore すればよい

```
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.19" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Design" Version="1.1.2" />
  </ItemGroup>

</Project>
```

ライブラリの復元が完了したら以下のコマンドを実行すればDBモデルを生成してくれる
※接続情報は自分の環境に合わせること！

```
dotnet ef dbcontext scaffold "Server=localhost; Port=3306; Database=schema; Uid=root; Pwd=password;" Pomelo.EntityFrameworkCore.MySql -o Models --context Context
```

サンプルコード:[github](https://github.com/WaToI/dotnetCoreEfMySQL)
【ReactNative】【Expo】画面遷移のタイミングで音を鳴らす方法

アプリを作っている途中で、画面遷移の時に音がなるとより本格的になるなーと思ったものの、調べてもすぐ出てこなかったのでメモしておきます。


### 音がなる前のコード

```javascript
...

<TouchableOpacity 
  onPress={() => navigate('Home')}>
  <Text>ホーム</Text>
</TouchableOpacity>
```

**onPress**のタイミングで音を鳴らす関数を発火したいのですが、すでに画面遷移のための関数が割り当てられていています。
よって、画面遷移と音を鳴らす役割を担う関数を外で定義しないといけません。

### 音がなるコード

```javascript
...

import { Audio } from 'expo-av';

...

async function goto(destination){
  navigate(destination)
  try {
    const soundObject = new Audio.Sound();
    await soundObject.loadAsync(require('./assets/sounds/decision.mp3'));
    await soundObject.playAsync();
  } 
  catch (error) {
    console.log('error...')
  }
}

....

<TouchableOpacity 
  onPress={() => goto('Home')}>
  <Text>ホーム</Text>
</TouchableOpacity>
```

### 補足

ReactNativeで音を鳴らすのは[expo-av](https://docs.expo.io/versions/v37.0.0/sdk/audio/)が一番簡単だと思います。
音源は[効果音ラボ](https://soundeffect-lab.info/sound/button/)から拾ってきました。

作成したgoto関数を繰り返し使うために、navigateで設定する値を引数で渡しましたが、[【React】イベントハンドラで引数を使いたい【備忘録】](https://qiita.com/tsuuuuu_san/items/73747c8b6e6e28f6bd23)の方法１にある記述のように、ベストな方法ではないようです。
とりあえず動いたのでここまでにします。

ファイルを編集する度にポロン♪と鳴るのでモチベーションも上がりますね。
30万円給付の条件は厳しすぎるのか？

新型コロナウイルス感染拡大に伴う
緊急経済対策の柱に位置付けられる
「現金30万円」の給付金。

これ貰えるのか貰えないのか
気になってしまったので実装してみました。

解説動画はこちら

[![表示されなかったらすみません](https://img.youtube.com/vi/zBPQ8HfxIEE/0.jpg)](https://youtu.be/zBPQ8HfxIEE)

聞いた話だと「給付条件」は段階があるようです。

1.世帯主の2～6月の月収が減り
以下の月収金額以下である場合は給付金は貰える 

単身世帯…月収10万円 
2人世帯…月収15万円 
3人世帯…月収20万円 
4人世帯…月収25万円 

2.世帯主の2～6月の月収が1/2以下に減り
以下の月収金額以下である場合は給付金は貰える 

単身世帯…月収20万円 
2人世帯…月収30万円 
3人世帯…月収40万円 
4人世帯…月収50万円

段階があるのでちょいとややこしいですね。

今回はPythonのipywidgetsで実装してみました。
実装ポイントはif分位かと思うので
そんなに難しくないハズ?!?!

条件の目安にしていただく程度のものです
実際に貰えるかどうか等はご自身でご確認くださいませ。

```
from ipywidgets import IntSlider , interact

n1 = IntSlider(value=20, min=0, max=100, step=1,description='前年の月給')
n2 = IntSlider(value=20, min=0, max=100, step=1,description='今年の月給')
n3 = IntSlider(value=1  , min=1, max=4,      step=1,description='世帯人数')

def show_plot(n1, n2,n3):
    print('前年の月給 : {0}万円 , 今年の月給 : {1}万円 , 世帯人数 : {2}人'.format(n1,n2,n3))
    if any([(n3==1 and n2<=10),(n3==2 and n2<=15),(n3==3 and n2<=20),(n3==4 and n2<=25)]):
        print('給付金がもらえる(1)')
    elif (n2<=n1/2) and any([(n3==1 and n2<=20),(n3==2 and n2<=30),(n3==3 and n2<=40),(n3==4 and n2<=50)]):
        print('給付金がもらえる(2)')
    else:
        print('給付金は貰えない')

interact(show_plot, n1=n1,n2=n2,n3=n3)
```

実行していただくと、こんな感じになります。
スライダーを動かしていけば結果が出ます。

<img width="800" alt="スクリーンショット 2020-04-12 16.05.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379626/78c8084a-df06-c886-1560-19bb8946b193.png">



結論から行くと
自分は貰えないんで、テンションだだ下がりです。

とはいえ、この条件であれば
家族が多ければ貰える人も結構いると思うので
条件に当てはまる方は
申し込みした方が良いですね。

申し込みする役所が
クラスターになる可能性も有るので
気を付けないといけないですが。

今回はこれまでです
それでは。
【Laravel7】The stream or file "storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied

## 環境

- PHP 7.4.4
- Laravel 7.5.1

## エラー

![スクリーンショット 2020-04-12 16.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/906d2056-5703-1ac1-5022-cdca509a5524.png)

```
The stream or file "/work/backend/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied
in /work/backend/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php (line 110)
in /work/backend/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php -> write (line 42)
in /work/backend/vendor/monolog/monolog/src/Monolog/Logger.php -> handle (line 323)
in /work/backend/vendor/monolog/monolog/src/Monolog/Logger.php -> addRecord (line 541)
in /work/backend/vendor/laravel/framework/src/Illuminate/Log/Logger.php -> error (line 174)
in /work/backend/vendor/laravel/framework/src/Illuminate/Log/Logger.php -> writeLog (line 87)
in /work/backend/vendor/laravel/framework/src/Illuminate/Log/LogManager.php -> error (line 547)
in /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php -> error (line 122)
```

## 原因

`storage` ディレクトリに書き込み権限がないため。

## 対策

```shell-session
$ chmod -R 775 storage bootstrap/cache
```

`storage` と `bootstrap/cache` の2つのディレクトリは書き込み権限を付与してあげる。

## 関連記事

- [There is no existing directory at "storage/logs" and its not buildable: Permission denied エラーが出たときの対処法](https://qiita.com/ucan-lab/items/1ff680bb897fa11be85d)
今後の目標

# 今後クリアしていきたい課題
1. いずれかのプログラミング言語、RDBMS、Linuxサーバ環境を用いたソフトウェアの開発・運用経験
 GitHub、CIツール、自動テストの活用経験

2. TCP/IP、HTTPなどのネットワークプロトコルについての基礎知識

3. システムの全体構成を把握し、技術的問題（例：パフォーマンス低下）の原因を発見、解決するための能力

4. システムのパフォーマンスや信頼性を向上させるのに必要なアプリケーション、ミドルウェアへの機能追加、バグ修正を行うためのプログラミング能力

5. ソースコードの保守性を維持するためのリファクタリング習慣

6. 要件定義から運用管理まで一連の工程に携わり、プロセス上のボトルネックに対して主体的に改善した経験

7. 公式ドキュメントの調査や、海外のエンジニアとGitHubやStack Overflowでやりとりできる英語力

8. チーム開発におけるコミュニケーション能力
Gitで管理したくない拡張子の設置方法とGit へのアップロード容量制限について

Gitへアップする際にハマったことと、その対処法を記載します。

まず３００MBの動画ファイルをプッシュするとエラーが表示されます。
実はGitは容量制限が存在して１００MBまでしかアップできません。
![スクリーンショット 2020-04-12 16.11.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578250/4189495d-59eb-b8e5-5b13-5644b389be62.png)
※最終行を確認ください

最終的に下記の手順で解決できました。
１、「rm -rf .git」初期化
２、VSC上で「.gitignore」を開いて下記のように「*.拡張子」を追記してコミットすればOK。
　# movie
　*.mov
３、その後コミット、プッシュ

以上です。ご参考になれば幸いです。
プロジェクトを終わらせる - プロジェクト完了報告書の書き方とテンプレート

プロジェクト、終わらせることできていますか？
事実を客観的に報告する、プロジェクト完了報告書について。

何かを始めることに比べて「やめる」ことの報告には勇気がいる。できたことだけではなくできていないことも正直に表現する必要がある。勇気のいることだがその勇気を少しでも中和するために社内向けプロジェクトのプロジェクト完了報告書を社内で書きました。

...というときに調べた、 **プロジェクト完了報告書** についてまとめる。参考: [完了報告書の作り方](https://xtech.nikkei.com/it/article/COLUMN/20081014/316815/)


## テンプレート

```md
# プロジェクト完了報告書テンプレート (markdown版)

sample

---

## アジェンダ: 問題「朝寝坊」の総括
- 概要
- 稼働状況
- 実績
- 評価
- 今後の課題

---

## 1. 概要

提案の背景となる現状認識 「朝寝坊という問題を解決する」

---
### 提案の主題
絶対に朝寝坊を許さないタイマーアプリケーション「徹夜くん」

---
### 提案への解決策

一晩の徹夜を支援することで朝寝坊を起こさない目的を達成し、現状の事実として説明したような負のサイクルを断つ。寝ることを許さないアプリケーションを作成する。

---
### 達成度
- 経緯: 1日2日の稼働は達成できたがそれを超えると困難が生じた。
- 発生した変更事項: 機能を制限し3日を超えて使用された場合にアラートが出て睡眠を促す機能を追加することとした。

--- 

## 2. 稼働状況

### 総括的な評価
- トラブルの有無やバグの残存状況: それでも寝てしまうという顧客要望に対し追加策が必要。
- 問い合わせ状況: 長期間の徹夜においては一部稼働を止めている

--- 

## 3. 実績

- コスト
- スケジュール
- 達成した機能

--- 

## 4. 評価

- 評価点
- 反省点

--- 

## 5. 今後の課題

- 問題点
- 改善要望
- 次フェーズ
- （コンタクト先の例）https://e99h2121.github.io/ 
```


## 記載事項

### 1. 概要

#### 例)
- 企画やRFPを基に取りまとめた「システム開発の目的」の確認
- この報告書を作成している時点での上記目的の達成度
- キックオフから稼働までの経緯
- プロジェクトの途中で発生した変更事項

### 2. 稼働状況

#### 例)
- 稼働状況の総括的な評価
- トラブルの有無やバグの残存状況
- ユーザーからのヘルプデスクへの問い合わせ状況
- 一部稼働を止めている機能がある場合，その状況

### 3. 実績

- コスト
- スケジュール
- 達成した機能

#### 例)
- コストに関して増減があった場合，その金額と理由
- スケジュールの遅延や変更があった場合，その内容と理由。予定と実績の対比が一目で分かるような簡単なスケジュール表などを用いるとよい
- システムの機能に関しては追加した機能，逆に取りやめた機能，先送りした機能の概要と変更した理由。一覧表などの形式に取りまとめるとよい

### 4. 評価

- 評価点
- 反省点

#### 例)
- プロジェクト体制（ユーザー企業側の体制およびベンダー側の体制）がきちんと確立されていたか
- 要員のスキルやリソースに過不足はなかったか
- プロジェクト・チーム内のコミュニケーションは良好だったか
- 作業スケジュールの設定は適切だったか
- 契約内容は適切だったか。契約の解釈に違いは生じなかったか
- プロジェクトの推進に大きな影響を与えた環境変化や外部要因として何があったか
- システム・インフラ上の大きな変化（製品サービスの廃止やバージョン変更など）はなかったか

### 5. 今後の課題

- 問題点
- 改善要望
- 次フェーズ

#### 例)
- 現在対処中の問題点
- ユーザーからの改善要望
- 運用保守上の課題
- 次フェーズの取り組み予定など


## 基本的なドキュメントの書き方
最後に基本的なツール群です。
[質の高い技術文書を書く方法](https://blog.riywo.com/2021/01/how-to-write-high-quality-technical-doc/)
[Google社のテクニカルライティングの基礎教育資料がとても良かったので紹介したい](https://qiita.com/yasuoyasuo/items/c43783316a4d141a140f)
[ドキュメント作成スキル向上を目指す人向けおすすめ記事まとめ](https://qiita.com/yasuoyasuo/items/1eb7298f91a44dce7abc)
[エンジニア歴20数年の私が、設計書を書く際に心がけていること](https://qiita.com/y-some/items/90651c1e27f7798f87c6)
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)

## スライド化
[爆速でスライドを作る！Markdownからスライドを作れる「Marp」](https://qiita.com/msp0310/items/0e54f69457f81bc64754)
お洒落は最低限これでよし。

### Sample
こんな感じになりました
[![thumbnail](https://files.speakerdeck.com/presentations/5838853a46b64bbfba8e369219fbf941/slide_0.jpg?18057763&quot)](https://speakerdeck.com/e99h2121/puroziekutowan-liao-bao-gao-shu-tenpureto-markdownban)


## まとめ

以下、対になる資料。

https://qiita.com/e99h2121/items/7016aecc131299d481e6

https://qiita.com/e99h2121/items/d690ea1fb7e9f9eb9ad4

対し少なくとも「出来たこと」ばかりではない、「出来なかったこと」についても出来なかった理由が分かる資料は、報告する価値がある。そしてそれをシンプルに評価して次につなげてくれる組織はいい組織だと思う。以下も参考。

なかなか類するフォーマットが見つからないが海外では Project Completion Report 等とされているようなのでリンク。
[ProjectManagement.com - Project Completion Report](https://www.projectmanagement.com/deliverables/400/Project-Completion-Report)

以上お役に立てればさいわいです。
Win10+WSL(Ubuntu)+Visual Studio CodeでAngular環境の構築

# 構築環境
- Windows 10 Professional(1903)

# WSL&ディストリビューションのインストール
## WSLのインストール
コントロールパネル > プログラム > **Windows機能の有効化または無効化**か、検索ボックスから**Windows機能の有効化または無効化**を入力して、**Windows Subsystem for Linux**にチェックボックスを入れ、OKをクリックします。
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/d3b4f618-b1e0-cf7b-aca4-b52f956844fe.png)
再起動を求められるので、再起動します。
![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/6e426cfa-085b-a065-b1d0-6fec3bd9571d.png)

## ディストリビューションのインストール
Microsoft Storeから、Ubuntuをインストールします。
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/23d677d4-8776-26b0-72f4-6f3e8611b913.png)

# Ubuntuの初期設定
## ユーザー名&パスワードの設定
スタートメニューから、インストールしたUbuntuを起動します。
ユーザー名とパスワードを入力します。
![スクリーンショット (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/271580a5-0c46-57dd-5380-c124ec145a0f.png)

## アップデート&アップグレード
```
sudo apt-get update
```

```
sudo apt-get -y upgrade
```

# Node.jsのインストール
```
sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -
sudo apt-get install -y nodejs
```

# npmの権限変更
<a href="https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally" target="_blank">このサイト</a>のコマンドを入力します。

```
 mkdir ~/.npm-global
 npm config set prefix '~/.npm-global'
 export PATH=~/.npm-global/bin:$PATH
 source ~/.profile
```

# Angularのインストール
```
sudo npm install -g @angular/cli
```

Angularがインストールできたか確認します。

```
ng --version
```
![スクリーンショット (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/3103fd43-f09f-98d1-96fd-4e6dc6a53966.png)

# 初期アプリケーションの作成
```
ng new my-app
cd my-app
ng serve
```

Windows上のブラウザで`localhost:4200`or`127.0.0.1:4200`を入力すると、Angularの初期アプリケーションが表示されます。
![スクリーンショット (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/0786df0f-5033-af0d-d584-2b88d56d5a9b.png)

# Visual Studio CodeでAngularファイルを編集
Visual Studio Codeで直接、WSLのディレクトリである`\\wsl$`を開くことで、Ubuntuのフォルダにアクセスできます。
![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/0e6cccf7-27e1-6c6b-f02f-37f3ad8c7089.png)

また、Visual Studio Codeの拡張機能である**<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack" target="_blank">Remote Development</a>**を使用して、WSLにアクセスすることも可能です。

## Remote Developmentのインストール
Visual Studio CodeのExtension Marketplaceから、インストールするか、上記のリンクから、インストールをクリックし、Visual Studio Codeを開くからインストールできます。また、インストール時にその他必要な拡張が自動的にインストールされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/de6751be-9bca-f097-d724-ec9f827a8d54.png)

インストール後、WSLのディストリビューションのターミナルでVisual Studio Codeを開きます。

```
code .
```

自動的にWSLに接続された状態のVisual Studio Codeが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483911/afd6c5a9-2212-24a2-2de1-8aa49709beb0.png)
サーバ選定の基準について調べてみた

#概要
サーバーの用途ごとの選定基準について、調べました。

#用途ごとの特徴と選定ポイント
##「ファイルサーバー」
###◎特徴
・HDDの読み書きに負荷が集中する
・サーバー全体の性能はHDDのI/O速度に依存するため、CPU性能について重視する必要はあまりない
・大容量なバックアップ装置を接続するため、高速な外部接続インターフェースが必要

###◎重視する点
・HDDの容量
・HDDのI/O速度
・キャッシュに使われるメモリの容量
・ネットワーク速度
　→ギガビットEthernetのポートを複数搭載する等

##「プリントサーバー」
###◎特徴
・印刷データをスプールする領域の提供がメインのため、HDDの読み書きに負荷が集中するが、それほどの容量は必要ない

###◎重視する点
・HDDのI/O速度
・メモリ容量

##「Webサーバー」
###◎特徴
・静的コンテンツメイン
　→動作のほとんどがHDDの読み出しなので、ファイルサーバーと同様に考えるが、ファイルサーバほどの容量は必要なし
・動的コンテンツメイン
　→DBを同居させるならDBサーバー、させないならAPサーバーと同様に考える

###◎重視する点
・HDDのI/O速度
・メモリ容量
・ネットワーク

##「メールサーバー」
###◎特徴
・HDDのI/Oに負荷が集中する
・多数の宛先に一斉送信する際など、負荷が高くなることがよくあるので、ファイルサーバーより高いI/O性能が求められる
・ユーザー数に応じたHDD容量を準備する
・HDDのI\O待ちの時にメールを取りこぼさないように、メモリ性能も求められる
・クリティカルなサーバーのため、サービスを停止して外部のテープ装置にバックアップは難しい。
　→HDDの冗長化が必要

###◎重視する点
・HDDのI/O速度
・HDDの容量
・メモリ容量

##「アプリケーションサーバー」
※別のDBサーバーから動的にコンテンツを取り出してくるサーバと仮定
###◎特徴
・HDDはログくらいなので、さほど必要ない
・アプリケーションの負荷に応じたCPUとメモリ容量があればいい

###◎重視する点
・CPU性能
・メモリ容量

##「データベースサーバー」
###◎特徴
・RDBMSでは、CPUとメモリを最大限に使用するため、これらを高性能なものにし、かつバランスを意識する
　→どれか一つだけ高性能でも他でボトルネックにならないよう
・定期的なバックアップが必要なため、ディスク装置接続ポートがあるものを選ぶ

###◎重視する点
・CPU性能
・メモリ容量
・HDDのI/O性能
・HDD容量


#まとめ
・ファイルサーバー…HDDが重要
・プリントサーバー…低機能で十分

#参考サイト
以下のページを参考にさせていただきました！
https://ascii.jp/elem/000/000/577/577239/
シミュレータの画面収録メモ

# 画面を収録する

「shift + command + 5」で収録する
https://support.apple.com/ja-jp/HT208721

# Trimする
QuickTimePlayerで開いて、メニューバーの編集 > トリム...(Command + T)

# 必要なら、FFmpegでgifにする

こちらの記事を参考に
https://qiita.com/wMETAw/items/fdb754022aec1da88e6e
ROS2でxacro -> urdf -> robot_state_publisherの流れをやる方法

ROS2でxacroを展開してurdfを生成、robot_state_publisherでtfを出力する流れに関するドキュメントを探したのですが、なかなか参考になる情報が出てこなかったので備忘録を残しておきます。

# xacro,urdf,robot_state_publisherとは？
まずURDFは、ROSにおけるロボットの幾何構造を記述するフォーマットです。
URDFの使い方、記述法はこちら等にまとまっています。
[ROS講座13 URDFを記述する1](https://qiita.com/srs/items/35bbaadd6c4be1e39bb9)
[ロボットをURDFで記述する](http://ishi.main.jp/ros/ros_create_urdf.html)
[移動型ロボットのURDF作成](https://gbiggs.github.io/rosjp_urdf_tutorial_text/mobile_robot_urdf.html)

xacroはURDFのために作成されたXMLのマクロです。
左右対称に配置されているセンサの間隔をいじったりするのにURDFだと何箇所も値を書き換えないと行けないけど、xacroを使うと記述量を減らすことができます。
便利ですね。
使い方はこちらのようになっています。
[ROS講座73 xacroを使う1](https://qiita.com/srs/items/43528d00ee789171367f)
[ROS講座73 xacroを使う2](https://qiita.com/srs/items/9ac7f2f6e47732bb7535)

robot_state_publisherはURDFフォーマットの文字列をロードして、joint_statesトピックをサブスクライブすることでロボットの座標をtfの形式で出力するパッケージです。
ROS1ではこのやり方は確立されており、xacroパッケージを使ってrobot_descriptionというrosparamにURDFの文字列を設定、robot_state_publisherはそのrosparamを読んでtfを出力とうい流れになっていました。
ROS2でこれと同じことできるよねと思って色々試したらハマった上にrobot_state_publisherの中にあるlaunchを真似してもうまく行かなかったので色々試してみてこれならできたよって方法があったので備忘録を残したいと思います。

ロードが成功したlaunchは[こちら](https://github.com/OUXT-Polaris/wamv_description/blob/master/launch/wamv_description.launch.py)になります。
どうやっているかというと以下のようになります。

```Python
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
import launch
import launch_ros.actions
import xacro
from launch_ros.substitutions import FindPackageShare

share_dir_path = os.path.join(get_package_share_directory('wamv_description'))
xacro_path = os.path.join(share_dir_path, 'urdf', 'wamv_base.urdf.xacro')
urdf_path = os.path.join(share_dir_path, 'urdf', 'wamv.urdf')

def generate_launch_description():
    # xacroをロード
    doc = xacro.process_file(xacro_path)
    # xacroを展開してURDFを生成
    robot_desc = doc.toprettyxml(indent='  ')
    # urdf_pathに対してurdfを書き出し
    f = open(urdf_path, 'w')
    f.write(robot_desc)
    f.close()
    rsp = launch_ros.actions.Node(package='robot_state_publisher',
                                  node_executable='robot_state_publisher',
                                  output='both',
                                  # argumentsでURDFを出力したパスを指定
                                  arguments=[urdf_path])

    return launch.LaunchDescription([rsp])
```

robot_state_publisherの中にある[launch](https://github.com/ros/robot_state_publisher/blob/ros2/launch/rsp-launch-xacro-api.py)から変更したのはxacroをparamterで引き渡すのではなくファイルに一度書き出してからロードしているところです。
ROS2のlaunchをPythonで記述した場合に実行バイナリ・スクリプトにargumentを引き渡したい場合はarguments=[]で、rosparamを引き渡したい場合はparameters=[]で渡すというような感じで切り替えます。
今回はargumentでurdfのパスを渡せばうまく行くことがros2 runコマンドでrobot_state_publisherを動かした際にわかっていたのでこの方法で記述を試みたところうまく行きました。

最後に注意なのですが、ROS2からrobot_descriptionはparamではなくtopicとなっています。
上記のlaunchを実行してrviz2を立ち上げ、DescriptionSourceをTopic,DescriptionTopicに/robot_descriptionを指定すると以下のような画面が出てきます。

![Screenshot from 2020-04-12 15-38-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160346/346b05e9-d30b-dce3-8635-5e97778bf9d1.png)
エラー：Non-static method Illuminate\Http\Request::input() should not be called staticallyの解決法

## Illuminate\Http\Requestクラスと、Requestファサードを同時に使う

コントローラを作成して、Request $requestのようにRequestクラスを利用して、ビュー側から送った値を取り出せます。

``` 
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index(Request $request)
    {
        //Requestクラスを利用
        $result = $request->post;

        return view('home', compact('result'));
    }
}
```

しかし、ここでRequestファサードも同時に使いたいときはどうすればよいでしょうか。
単純に下のようにしてみます。

```
public function index(Request $request)
    {
        $result = $request->post;
        
　　　　　//Requestファサードを利用
        $name = Request::input('name');

        return view('home', compact('result', 'name'));
    }
```

しかし、これを実行すると、エラーが出てしまいます。

```
 Non-static method Illuminate\Http\Request::input() should not be called statically
```

これは、

```
use Illuminate\Http\Request;
```

で、Requestクラスを呼んでいるのに、Request::input()という、Staticで使っちゃダメですよってことを言っているわけです。

そこで、下のコードを加えてやると、無事にRequestファサードとして使えるようになるんですが、

```
use Request;
```

次は、

```
Cannot use Request as Request because the name is already in use
```

というエラーが出てしまいます。
これは、Requestという名前がすでに使われているので、同じ名前は使用できませんという意味です。

## 解決方法

というわけで、解決方法ですが、Requestファサードの名前をPostRequestに変更して、


```
use Illuminate\Http\Request;
use Request as PostRequest;
```


```
public function index(Request $request)
    {
        $result = $request->post;
        
　　　　　//Requestファサードは、PostRequestに変更
        $name = PostRequest::input('name');

        return view('home', compact('result', 'name'));
    }
```
とすれば、うまく動きます。
暇だしクソ絵文字でも作ろうぜ！

## 何をやったの

Unicode 絵文字のいろんなパーツをごちゃ混ぜにして、クソ絵文字を錬成できるツールを作りました。

暇つぶしや、チャットでの小ボケにドウゾ。こんな時代だしリモートを楽しもうぜ。

https://zk-phi.github.io/MEGAMOJI?mode=fukumoji
(4/13 更新: MEGAMOJI に統合しました)

<img width="1295" alt="スクリーンショット 2020-04-12 15.30.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/a7d65d52-845f-1491-a228-46c7f744db9a.png">

![emoji.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/ad5d8ab4-4519-33aa-3579-70e39133e5d9.gif)![emoji.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/ad5d8ab4-4519-33aa-3579-70e39133e5d9.gif)![emoji.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/ad5d8ab4-4519-33aa-3579-70e39133e5d9.gif)![emoji.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/ad5d8ab4-4519-33aa-3579-70e39133e5d9.gif)![emoji.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/ad5d8ab4-4519-33aa-3579-70e39133e5d9.gif)

### きっかけ

Emoji Mashup Bot https://twitter.com/emojimashupbot がときどき放つ会心の一撃が好きすぎたので、自分で作ってみたいなと思いました。

それっぽいツールは既存でもいくつかあるのですが、オープンソースのものがなかったり、権利が怪しかったり (iOS の絵文字がベースになってそうなパーツがある etc) したので、権利的にも UI 的にもシンプルなものを自前実装してみました。

## 実装

実装上の知見などを簡単に紹介します。

### 使いやすい絵文字素材

権利がクリアかつ扱いやすい絵文字画像が必要なのですが、 Twitter 社の OSS Twemoji がとても便利でした。

https://twemoji.twitter.com/

画像は CC-BY 、コードは MIT でライセンスされていて、自分の理解が正しければ、権利表示さえすれば自由に改変して使用することができます。

<img width="308" alt="スクリーンショット 2020-04-12 15.46.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54240/c006daae-d51b-c324-7beb-56e107d32003.png">

形式も SVG になっていて、イラレなどで簡単にパーツを抜き出せるのでかなり使いやすいです。

### 保存できる画像を生成する

たんに福笑いを表示するだけなら、 `img` を `position: absolute` して重ねるなどすればよいのですが、絵文字として使ってもらうためには、ちゃんと右クリックで保存できるようにしてあげたいところです。

自分のツールでは、すべての画像を１枚の `canvas` 要素に合成することで１枚の保存できる画像を生成しています。

```javascript
// パーツ画像の url リスト -> 合成された画像の url
function (items) {
  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext('2d');

  canvas.width = EMOJI_SIZE;
  canvas.height = EMOJI_SIZE;

  var img = document.createElement("img");
  for (var item of items) {
    img.src = item;
    ctx.drawImage(img, 0, 0, EMOJI_SIZE, EMOJI_SIZE);
  }

  return canvas.toDataURL();
}
```

上のコードで、各パーツの画像はすでに一度ロードされている想定になっているところだけ注意が必要です。まだロードされていない画像ファイルを使う場合は、以下のようにロードを待つ必要があり、めでたくコールバック地獄となります。

```javascript
img.onload = function () {
  ctx.drawImage(img, 0, 0, EMOJI_SIZE, EMOJI_SIZE);
};
img.src = item;
```

## まとめ

みんなもクソコラ絵文字で遊ぼう！面白い絵文字を錬成したら教えてくれよな
単純な横並びのレイアウトはgridがおすすめ

flexだと横並びにしたコンテンツ間のマージン設定がしづらい。

gridだと下記のような書き方で簡単に設定できる。
`.クラス名{
display: grid;
  align-items: center;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}`

gapプロパティを設定することでアイテム同士の横方向と縦方向の間隔をまとめて指定できる点がflexとの違いの一つ。

以上です。 お読みいただきありがとうございます。
npmのインストール

## npmの２種類のインストール

* ローカルインストール
    カレントディレクトリの node_modules 以下にパッケージをインストール。開発プロジェクト固有で依存するパッケージをインストールしたい時に使う。

* グローバルインストール
   システム共通の場所にパッケージをインストール。ビルドツールなど、システム全体で利用するツール・コマンド類をインストールしたい時に使う。

## ローカルインストール
* --save
    package.jsonのdependencies に追記される。他の人が npm install した時に、dependencies に指定したパッケージが全てインストールされる。

* --save-dev
    package.jsonのdevDependencies に追記される。npm install パッケージ名 --dev 

* --save-optional
    package.json の optionalDependencies に追記される。

## 違い
package.jsonがモジュールとして外部に公開し、他の人がnpm installした時に影響。
【Laravel7】Class view does not exist

## 環境

- PHP 7.4.4
- Laravel 7.5.1

## エラー

```
NOTICE: PHP message: PHP Fatal error:  Uncaught ReflectionException: Class view does not exist in /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php:805
Stack trace:
#0 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(805): ReflectionClass->__construct('view')
#1 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(687): Illuminate\Container\Container->build('view')
#2 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(794): Illuminate\Container\Container->resolve('view', Array, true)
#3 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(633): Illuminate\Foundation\Application->resolve('view', Array)
#4 /work/backend/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(779): Illuminate\Container\Container->make('view', Array)
#5 /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(1247): Illuminate\Foundation\Application->make('view')
#6 /work/backend/vendor/laravel/framewo in /work/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 807
```

エラーメッセージが不親切で、 `view` がどうの言ってますがまったく関係ありません。
実際のエラーをデバッグする際はLaravelの例外ハンドラにデバッグコードを追記して処理を追うと良いです。

```php:app/Exceptions/Handler.php
    public function render($request, Throwable $e)
    {
        dd($e);
        return parent::render($request, $e);
    }
```

https://qiita.com/kd9951/items/af8c3925a29a485a78c6

## 原因

- `git clone` した後に `.env` の作成を忘れていた。
- .env の所有者が root ユーザーになっていてHttpアクセス経由から参照できなかった。

## 対策

```
$ cp .env.example .env
$ php artisan key:generate
```
Java String の等価演算子(==)と初期化の関係について。初心者向け

Java 初心者にとってStringに対して等価演算子(==)の意味が”同じ値かどうか”をみるのではなく、
”参照先が同じかどうか”を見ることだというのは一つの学びのポイントであると思う。

```Java:Test1.java
public static void main(String[] args) {
	String str1 = "100";//　⓵
	String str2 = new String("100");　// ⓶
		 System.out.println(str1 == str2); //Falseになる。
	 }
 }
```

このときfalseになるのは理解した。でもStringて⓵でも⓶でも初期化できるわけで。
どういうときに参照先が同じになるのか。例えば、以下。

```Java:Test2.java
public static void main(String[] args) {
	String str1 = "100";
	String str2 = "100";
		 System.out.println(str1 == str2); //Trueになる。
	 }
 }
```

上の例だとTrueになるのだ。あれ、異なる二つの参照型変数を作ってるからfalseになってしまうのではと思っていた。
等価演算子が”参照先が同じか”を見ているてことなので、このときstr1とstr2は同じ参照先を見ているらしい。

これってどういうことなのかと思っていた。
いろいろぐぐると以下が出てきた。
[参考先：String#intern()を使った場合の、パフォーマンスへの影響を学ぶ](https://www.sakatakoichi.com/entry/stringintern)

要は、Stringにおいて、Intern()メソッドてのがあって、そいつを使うと、同じ文字列のStringオブジェクトがあった場合、
参照先をそろえるみたい。そうするとメモリの無駄使いを減らせる。確かに同じ値なのに、オブジェクトをいちいち作ってるのは効率が悪い。

これが、Test2.javaにおいて起きているのではないか。
つまり、初期化するときには自動的にIntern()メソッドが適用されている。そうすると、メモリ無駄使いもなくなるし。
以下の場合はどうなるんだろう。

```Java:Test3.java
 public static void main(String[] args) {
	String str1 = new String("100");
	String str2 = new String("100");
		 System.out.println(str1 == str2);
	 }
 }
```

この場合はfalseになるみたい。
てことはnew ~~で初期化するときはIntern()メソッドが適用されずに、newといってるくらいなので、新しくオブジェクトを作っているのだろう。

まとめると、
・str1 = "100", str2 = "100" の場合、参照先が同じになる。
・new String("100")で初期化する場合、新しくオブジェクトを生成するため、参照先は異なる。

ちなみに参照型でこの事象が発生するのか、Stringが特殊なのかを調べるために以下も実行した。

```Java:Test4.java
 public static void main(String[] args) {
	Integer int1 = 100;
	Integer int2 = 100;
		 System.out.println(str1 == str2);
	 }
 }
```
Trueでした。
てことは参照型の場合において、newを書かない限り、基本的に同じ参照点を見ているといえるのかな。
Go言語のディレクトリ構成を考えてみる 

#はじめに
最近Go言語の勉強を始め、文法についてそこそこ理解したので、APIサーバーでも立ててみようと思い、ToDoリスト開発を始めたが、Railsしか触ったことがなく、ディレクトリ構成が壊滅的にわからなかったので泣きべそを書きながらもまとめてみる。

#基本的なディレクトリ構成
    ・
    ├ cmd              //main.goはここに置く
    ├ db
    │  └ init          //データベースの初期データを記述
    ├ pkg
    │  ├ db            //データベースへの接続
    │  └ dcontext      //データベースの操作
    ├ http
    │  ├ middleware    //main.goを走らせる前に行いたいことはここに記述
    │  └ response      //主にエラー処理を記述
    └ server
       ├ handler       //railsでいうcontroller的なもの
       ├ model         //構造体定義したりhandlerで使うメソッド定義したりする
       └ server.go

Goの基本的なディレクトリ構成は上記のようになるらしい。

#まとめ
Goはrailsのようにこれと言ったディレクトリ構成がないので、柔軟性が高いが、初心者にとってはそれが辛い。
同じような初心者の方の参考になれば幸いです。
自作のhtmlコードをwebサーバとして公開する方法に関する備忘録

# 目的
自作のhtmlコードをwebサーバとして公開する方法に関する備忘録です

# 準備
以下を参考に、無料枠で使えるHTMLサーバー機能を用意します。

> [xfree](https://www.xfree.ne.jp/server/)

以下を参考に、何かしらの機能をhtml/javascriptで実装してローカルで確認します。

> [更新ボタンを押したら、「A と、見せかけてB」の文字列がランダムに更新されるようなWebサーバをjavascriptを使って作成してみる](https://qiita.com/seigot/items/38057f174ef6fb8704d1)

# コード

まず、公開webサーバにアクセスしてindex.htmlの内容が表示されることを確認します。今回はxfreeのHTML機能を利用します。
<img width="540" alt="test1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/b9db659f-840f-492a-a813-adba75b0a80b.png">

その後、index.htmlと同じフォルダへ、
実装したファイルを追加/上書きします。
追加/上書きは、今回はxfreeのファイルマネージャを利用しました。

フォルダ構成

```
(全て同じフォルダ)
./
   index.html
   to-misekakete.html
   sample.js
```

```html:index.html
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Sample</title>
</head>
<body>
<h1>sample</h1>
  <p>
    <a href="to-misekakete.html">と、見せかけて</a>
  </p>
</body>
</html>
```

```html:to-misekakete.html
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Sample</title>
</head>
<body>
<h1>sample</h1>
  <p>
    <a href="to-misekakete.html">と、見せかけて</a>
  </p>
</body>
</html>
(base) seigonoMacBook-puro-1320:http seigo$ cat to-misekakete.html 
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Sample</title>
  <script src="sample.js"></script>
</head>
<body>
  <input type="button" value="更新" onclick="sample();">
  <div id="area1">と、見せかけて </div>
</body>
</html>
```

```Js:sample.js
var data = ['りんご',
            'みかん',
            'いちご',
            'パイナップル',
            'ドラゴンフルーツ'];

/**
 * 配列の値からランダムで1つ選択して返す
 * @param arr arrayData (required) 選択する配列の内容
 * @return str
 */
function choose_at_random(arrayData) {
    var arrayIndex = Math.floor(Math.random() * arrayData.length);
    return arrayData[arrayIndex];
}

function sample(){
    var getData = choose_at_random(data);
    var getData2 = choose_at_random(data);
    var str = getData + "、と、見せかけて、" + getData2;

    console.log(str);

    document.getElementById("area1").innerText = str;
}
```

# テスト
公開webサーバ(今回はxfreeを利用)にブラウザからアクセスして、
ローカルで用意した機能がhtml/javascriptで動けばOKです。
![jy7t6-8hgu8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/3970a230-7765-1f1b-5176-206a7373cd55.gif)

# 参考
[xserver](https://www.xserver.ne.jp)
[xfree](https://www.xfree.ne.jp/server/)
[更新ボタンを押したら、「A と、見せかけてB」の文字列がランダムに更新されるようなWebサーバをjavascriptを使って作成してみる](https://qiita.com/seigot/items/38057f174ef6fb8704d1)
[【初心者コーダー向け】現役Webエンジニアが教えるサーバー契約＋FTPでサイト公開までの全行程まとめ](https://showtaki.com/30days-trial-3/)
[無料でできるPHPのWEBサイト公開（テスト用）](https://qiita.com/am10/items/a3b6a5239905da3ec18f)
[【2020年版】無料レンタルサーバーおすすめランキング](https://おすすめレンタルサーバー徹底比較ガイド.com/post-1137)
[https://おすすめレンタルサーバー徹底比較ガイド.com/post-1137](https://おすすめレンタルサーバー徹底比較ガイド.com/post-1137)
[【2020年ホームページの作り方総まとめ】ホームページ自作方法を解説](https://webst8.com/blog/homepage-open-process/)
[Webサーバーを用意する方法](http://jsstudy.hatenablog.com/entry/preparation-of-web-server#Heroku)
[WebサービスをXserverで公開する方法](https://qiita.com/kgkgon/items/c2a72f1bc22d0993cda5)
[localhost をスマホ実機で確認する方法](https://qiita.com/nanarya/items/8d01dfb4de434e7b8acc)
[mp4-to-gif](https://www.aconvert.com/jp/video/mp4-to-gif/)
MySQL5.7に入門してみる~その1~

# あらすじ
MySQLの事をほぼ理解していないサーバサイドエンジニアが、とある本を読んでMySQLのアーキテクチャから学んでいこうと思います。

どなたかの参考になればと思っています。また有識者からの突っ込み等もいただければと思っています。(お手柔らかにお願いします。。。)

# 前提条件
- MySQL -> 5.7

# MySQLのアーキテクチャ
MySQLサーバはOS上では一つのプロセスとして動作し、クライアントからのSQLの処理やディスク上のデータの読み書きを内部の複数のスレッドが担当する**「シングルプロセスマルチスレッド型」**です。内部の実装は下記のような構造になっています。

- 接続の管理やSQLの構文解析
  - ユーザ認証、権限管理
  - 接続
  - SQL文構文解析&実行計画最適化
- データやトランザクションの管理

データやトランザクションの管理には用途に応じてどのストレージエンジンを利用するかが選択可能です。なので、`運用管理やパフォーマンスチューニングのためにも、各ストレージエンジンが持つ機能や特徴の理解が重要`です。

### ユーザ認証 & 権限管理
ACLを用いてアクセス認証や権限管理を行っています。

### 接続
**新規の接続が行われると処理を担当するスレッドが生成**され、ユーザ認証後にSQL文が発行され実行します。**接続が切断されると処理スレッドは破棄**されます。
ただし**スレッドキャッシュ機能**を利用している場合は、スレッドは破棄されずプールに格納され、次の接続時に再利用されることでスレッド生成や破棄の処理を削減できます

### SQL構文解析 & 実行計画最適化
実行されたSQLを処理するために、パーサーによって構文解析を行い内部のAPIに変換され、オプティマイザによって最も効率的なデータへのアクセス経路を導き出す最適化を行います。

### キャッシュ
**処理のボトルネックになりがちなのが、ディスクやストレージ**です。そのためアクセス削減のためにキャッシュ(またはバッファ)の仕組みを持っています。`MySQLではストレージエンジン固有のキャッシュやサーバ全体で利用するキャッシュなど複数の仕組み`が用意されています

### ストレージエンジン
ストレージエンジンには下記の役割があります

- データフォーマットの定義
- データ永続化
- インデックス管理
- トランザクション管理
- ロックと排他制御
- 各ストレージエンジン固有の機能(下記はInnoDBの場合)
  - 全文検索
  - 自動クラッシュリカバリ

`InnoDBは多くのアプリケーションで必要となるACID特性をもったトランザクションを、MySQL5.7で唯一サポートしているストレージエンジンです。特別な理由がない限り標準のInnoDBを利用しておけば十分なケースがほとんど`です。**(以前は、参照性能が高いなどの理由でMyISAMストレージエンジンがデフォルト)**

# まとめ
皆さんいかがでしたでしょうか？MySQLのアーキテクチャについて少しでも理解を深めることができたでしょうか？
やっぱりストレージエンジン周りの理解がキモになってきそうな予感をしています。なのでお次はもう少し詳細に幾つかのストレージエンジンについて学んでいこうと思います。

ではまたの機会に。。。

# 参考
- [やさしく学べるMySQL運用・管理入門 5.7対応](https://www.amazon.co.jp/dp/4295000191)
ターミナルで任意のソフトでファイルを開く。openコマンド

# 動機
自分もどこで仕入れた知識か忘れましたが、某アドサーバーを作っているエンジニアさんも知らなかったので、書いても損はないと思い書き残します。

# openコマンド
shellからファイルを開く際に使うコマンドです。環境でデフォルト設定されているアプリケーションで開かれます。

私はデフォルト設定は、Finder.appでファイルを右クリックして`情報を見る`から変更しています。

```
Help: Open opens files from a shell.
      By default, opens each file using the default application for that file.
      If the file is in the form of a URL, the file will be opened as a URL.
Options:
      -a                Opens with the specified application.
```
`-a`オプションで任意のアプリケーションから開くことができると書いてあります。

# 使用例
shellから任意のアプリケーションで開きたいときに使います。

VisualStudioCodeなどは、設定でshellから`code`と入れることで開くようにエイリアスを変更できますが、そういうソフトだけではありません。そういうときに使います。

```
open . -a Emacs
```
#Rails で has_many の inverse of オプションを付けないとどうなるかの動作メモ (  rubocop Rails/InverseOf )

- 関連をたどって同じオブジェクトに返ってきた時も、別のオブジェクト扱いになっている
- Rails6 で確認
- 片方を update しても、もう片方は別のオブジェクトなので、データが古いままだったりする

以下は例
model の状態はてきとうに想像してください

```rb

book = User.books.first
# => #<Book:0x0000565441ce2b38

book.object_id
# => 65560

# てきとうに関連をたどって自分自身に戻ってくる
same_book = book.users.first.book
=# > #<Book:0x0000565440ddd048

# オブジェクトidが違う
same_book.object_id
# => 65580

# 別のインスタンスなので、たとえば片方を update しても、もう片方は古いまま
# reloadしないとデータ状態が反映されえない

# オリジナルのインスタンスの名前を更新する
book.update!(name: "わさび本")

# インスタンスの状態は新しくなる
book.name
# => "わさびの本"

# もう片方は古いまま
same_book.name
# => "からしの本"

# reload しないと DBの状態は反映されない
same_book.reload.name
# => "わさびの本"
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3066








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ActiveRecord::RecordNotFound in BooksController#edit

##ActiveRecord::RecordNotFound in BooksController#edit

Ruby on Rails超初心者です。

Ruby on Railsでログイン機能付きの本の感想を登録できるアプリケーションを作成しています。

ログインしているユーザー以外のユーザー（他人のユーザー）が投稿した本の内容に編集と削除ができないようにアクセス制限をかける実装をしていましたが、その途中でこのようなエラーが出ました。

エラー内容を見ていくと、以下の記述がありました。

Couldn't find User with 'id'=15

どうやら、userモデルのidに15はないよーというエラーみたいです。
このidは、本来はBookモデルのidであるはずだな～と思いながらコントローラーの該当のソースコードを見てみると、、

``` app/controllers/books_controller.rb
before_action :correct_user,   only: [:edit, :update, :destroy]

#(省略)

private
def correct_user
    @book = Book.find(params[:id])
    @user = User.find(params[:id])
    redirect_to(books_path) unless current_user?(@user)
end

def current_user?(user)
   user == current_user	
end

def book_params
   params.require(:book).permit(:title, :body, :user_id)
end
```

こんな記述をしていました笑
Bookモデルのコントローラーで、定義もしていないuserのparamsをとってこようとするのはおかしいですね笑

そこで、以下のように修正しました。

``` app/controllers/books_controller.rb
before_action :correct_user,   only: [:edit, :update, :destroy]

#(省略)

private
	def correct_user 
      @book = Book.find(params[:id])
      redirect_to(books_path) unless current_user?(@book.user)
  	end

	def current_user?(user)
	  user == current_user
	end


	def book_params
		params.require(:book).permit(:title, :body, :user_id)
	end
```

(ログイン機能にはdeviseを使っています。)

これで大丈夫です。

correct_userでは、ユーザーが自分だったときには何もしませんが、他人であったときはredirect_toで投稿の一覧にリダイレクトされるようにしています。
ユーザーが自分か他人かの判定は、currect_user?で行っています。

実際に確認してみましょう。

(自分の投稿した本の詳細画面)
![スクリーンショット (226).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554142/461321dc-e9e8-11c6-e1fd-d8c47ead2c32.png)

(他人の投稿した本の詳細画面)
![スクリーンショット (227).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554142/e421f3f7-9bd0-813f-8f1f-af988c765c1f.png)


大丈夫そうですね！
めちゃくちゃ単純なエラーですが、ちょっとずつ実装できるのは楽しいです笑

読んでくださってありがとうございました。
Node Version Manager

## Node.jsのバージョン管理ツール
* node.jsはバージョン依存度が高いため、バージョン管理ツールが必須です。
* 主要なものに「nodebrew」「nvm」などがあります。

---
## どちらがおすすめ？
nvmのほうが人気です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269452/4f1543c6-a467-a129-0b71-31f06264d4d0.png)

---
## Cloud9でのNode.jsとnvm
既にプリインストールされています。

```bash
whitecat:~/environment $ node -v                                                                                                                                         
v10.19.0
whitecat:~/environment $ nvm --version
0.31.7
whitecat:~/environment $ 
```

---
## nvmのバージョンアップ

```bash
whitecat:~/environment $ cd ~/.nvm/
whitecat:~/.nvm ((v0.31.7)) $ git pull origin master
From https://github.com/creationix/nvm

whitecat:~/.nvm ((73438e3...)) $ source ~/.nvm/nvm.sh
whitecat:~/.nvm ((73438e3...)) $ nvm --version
0.35.3
```

---
## nvmの設定状況

```bash
whitecat:~/environment $ nvm ls
->     v10.19.0
         system
default -> 10 (-> v10.19.0)
node -> stable (-> v10.19.0) (default)
stable -> 10.19 (-> v10.19.0) (default)
```
---
## Node.jsの最新化

```bash
whitecat:~/environment $ nvm install stable --latest-npm
Downloading and installing node v13.12.0...
Now using node v13.12.0 (npm v6.14.4)
whitecat:~/environment $ nvm alias default stable
default -> stable (-> v13.12.0)
whitecat:~/environment $ nvm ls
       v10.19.0
->     v13.12.0
         system
default -> stable (-> v13.12.0)
node -> stable (-> v13.12.0) (default)
stable -> 13.12 (-> v13.12.0) (default)
```
firebaseのcloud storageの画像をfirestoreのデータ削除をトリガーに削除したい

# 結論

下記のコードで案外簡単にできた。
ある特定のfirestoreのデータを削除するとそれに紐づく画像ファイルも消してほしかったので書いてみた。
firestoreとstorageがネストしている構造でも問題なく動作した。
firebase本当に素晴らしい！

※ 下記コードは一応TypeScriptで書かれています

```ts
import * as functions from 'firebase-functions';
import * as admin from "firebase-admin";
const firebase = admin.initializeApp();
// リージョン指定はお好みで
const tokyoRegion = "asia-northeast1";

// グループ削除をトリガーに紐づく画像ファイルを削除
export const deleteImageOnGroup = functions
         .region(tokyoRegion)
         .firestore.document("groups/{groupsDocId}")
         .onDelete((snap, context) => {
           const { groupsDocId } = context.params;
           const bucket = firebase.storage().bucket();

           return bucket.deleteFiles({
             prefix: `grpups/${groupsDocId}`
           });
         });

// アイテム削除をトリガーに紐づく画像ファイルを削除
export const deleteImageOnItem = functions
         .region(tokyoRegion)
         .firestore.document(
           "groups/{groupsDocId}/items/{itemsDocId}"
         )
         .onDelete((snap, context) => {
           const { groupsDocId, itemsDocId } = context.params;
           const bucket = firebase.storage().bucket();

           return bucket.deleteFiles({
             prefix: `groups/${groupsDocId}/items/${itemsDocId}`
           });
         });

```


##ポイント

- firestoreのonDeleteをトリガーにして発火させる
- cloud storageの構成にfirestoreのドキュメントIDを使うことで判定できるようにする
- onDeleteの引数からドキュメントIDを取得できるようにする


## firestoreの命名
groups/{groupsDocId}/グループの各フィールド
groups/{groupsDocId}/items/{itemsDocId}/アイテムの各フィールド


## cloud storageの命名
groups/{groupsDocId}/画像ファイル
groups/{groupsDocId}/items/{itemsDocId}/画像ファイル

### 参考
stackoverflow
[Firebase function (written in NodeJS) to delete file from Cloud Storage when an object is removed from Realtime Database
](https://stackoverflow.com/questions/45356384/firebase-function-written-in-nodejs-to-delete-file-from-cloud-storage-when-an)

medium
[Automatically delete your Firebase Storage Files from Firestore with Cloud Functions for Firebase](https://medium.com/google-developer-experts/automatically-delete-your-firebase-storage-files-from-firestore-with-cloud-functions-for-firebase-36542c39ba0d)
ちょっと危険な@Published

Swiftでメモリ安全性が壊れる状況を発見したので、共有

基本的にはSwiftは素晴らしい言語で未初期化の変数というものは存在しません。(明示的に`unsafe`を使う場合を除く)
`class`は`init`で全てのプロパティを初期化する必要があり、変数の確保には初期値が必要です。

Swift5.2で導入された`@propertyWrapper`によってこの安全性が壊れる場合を見つけたので紹介させていただきます。

### 具体例
具体的には以下のような状態です。

```swift
class Person {
    let id = UUID().uuidString
}

class Alice: Person {
    @Published var name: String? = nil {
        didSet { print(self.id) }
    }
    override init() {
        self.name = "Alice"
        super.init()
    }
}

let alice = Alice()
```

本来上記のコードは「何も出力されない」が正解です。
Swiftの仕様では初期化時の代入では`didSet`は呼ばれないことになっているからです。
しかし、`@propertyWrapper`があり、かつ初期値（この場合は`nil`）のあるプロパティに関しては、`super`が未初期化にもかかわらず、`didSet`が呼ばれてしまいます。

このため、上記コードでは`print(self.id)`のところで落ちてしまいます。

### 対策

デフォルト値のあるプロパティはsuper.init()の後に初期化して問題ないはずなので、そのようにする。

### 感想

早く治ってほしいです。

こういうのってどこに`issue`出せばいいのでしょうか？
有識者の方いらっしゃいましたら、お教え願えるとありがたいです。
【初投稿】docker run と createの違いについてちょっとだけ調べてみました！

どうもshirakabaといいます。

今回はQiita初投稿になります!

今回書く内容は、自分に対するメモみたいなものなので、ほとんど参考にはなりませんが...
生暖かい目でみていただけると幸いです（笑）

で、今回調べたことは、dockerのコマンドである```docker run ``` と```docker create```の違いってなんだろう...？ということです！

元々、Dockerfileを一から書いて環境構築したり、```docker-compose.yml```を使ったりはしていたのですが、どうにも、　Dockerfileを書くのがめんどくさい...って感じちゃったので、```docker pull```したものを使っていければいいのでは？って思って勉強していてついでに、コマンドとかもあんまりわかってなかったし、もう一度ちゃんとやり直してしっかり理解しよう！って思ったのがきっかけです！

あまりグダグダ書いても仕方ないので、早速まとめておきます！

## runとcreateの違い！
で、この二つの違いなのですが、

- runは？
    - コンテナの作成から起動までの一連の流れを全て行うそうです。
    - イメージを指定しているので、それがない場合はpullもしてくれるらしいです。
    - オプションで```-d```を指定したりしなければそのままコンテナの中に入るそうです(アタッチ？）が```-d```をつけることでコンテナに入らずに、ホストに戻ってくるらしいです！（デタッチですかね？）

- createは？
    - コンテナの作成だけ！だそうですね

なので、基本的には、runコマンドだけで多分いいとは思うのですが、そこらへんの使い分けなどは全然調べていません。（申し訳ないです...(´ﾟωﾟ｀) ）

個人的には、一つ一つ確認しながらの時かなぁと感じています（それしか思い浮かばない...）

とまぁこんな感じで、こっちではこれを使っているに、こっちの本ではこれなの？っていうわからないのにとりあえず真似してコマンドを入力していたところを調べてみました。

Dockerのコマンドが少しずつわかってくるとやりやすいなぁって個人的には感じているので、これからもオプションやらなんやらをちゃんと調べていきたいなぁと思ってます。

今回はこの辺りにしたいと思います！
記事を読んでいただきありがとうございました！
それでは〜

（Dockerちゃんと友達になれるといいなぁ...）

## 勉強に活用させていただいた記事
とほほのWWW入門
http://www.tohoho-web.com/docker/docker_run.html

Dockerで環境構築するための最低限のコマンドを一通り実践する
https://qiita.com/minato-naka/items/e1f91e1df2c4fe7411dc
母のITリテラシーを向上させたい

リア充70歳母に#stayhomeさせるために彼女のITリテラシーを向上させたいと思ったが結局大衆向けアプリの偉大さに心を砕かされている話（ポエム）です。

## 母紹介

70歳母は東京近郊に一人暮らししている。これまでどうしても子どもの面倒を見てもらいたいときは小一時間かけて東京の私の家まで来てもらっていた。平日はなにがしか友達と会うやら英語のお稽古やら大学の講座やら岩盤浴やらと勤しんでおり旅行・移動が大好きそれを厭わないむしろ歓迎するリア充老年であった。

コロナが来るまでは。

## 2020年4月からの母

母はとてつもなく暇を持て余している。想像に難くない。本来なら連日長電話でもしてやりたいが私も一応仕事はある上、変に人が老年扱いし気遣われるのも面倒くさがる人なのでさり気なさが求められる。こちらが移動することもできない。各携帯キャリアショップも営業自粛だろう。言わずもがな#stayhomeであり家に出来るだけ居たくなるモチベーションを彼女に与える必要があるのだ。

## いくらか考えた

### 米を送ってもらう

もともと実家で利用中の生協が定期的に米を配達してくるらしい。当然定期サブスクしているからだろうが一人暮らしの身で月に何合も米を消費するわけもなく、だが本人曰く、定期的に誰かに独り身を生存確認してもらう手段として有効とのこと。それは私も合理的だと思ったので米Keepalive、特に口出しすることなくたまに余った米を私の家に転送してもらうということを行っていた。

だからこの渦中も私の家に米を変わらず転送するというタスクを彼女に投げたままにしておくことは構わない。だが、それもいい年のおばあちゃんである母を少しでも外出させたくない身からすると別にいい手段ではない。

### LINEの頻度を上げる

リア充なだけあって基本的なスマホのツールは知っている母。なので単純に1日1回はテキトウなメッセージングをしてみる。うちの近所でどこの店が開いてるだの閉まっただの。娘が縄跳び始めただの息子が何歩歩いただの。

### 子どもの動画を送る

同じく撮りためた娘・息子画像、動画をちょいちょいと一言添えて送りつける。しかしこれらは私の工数がほぼそのまま奪われる。連絡を取ることはいとわないが連絡を取らずともただただ元気でいてほしい。もっと何かないものか。

## インターネットが使えることの面白さ

ここまで考えて最もボトルネックとなっているのは彼女のITリテラシー、というかスマホスキルであることが間違いない、と私は思っていた。もっと自力でスマホの中の楽しみを見つけていただきたい。彼女のスキルを向上させる必要を感じていた。思いついたのがこれだ。

### Youtubeの動画を送る

時代は宅録宅配信一億総Youtuberだ。ありとあらゆるジャンルの著名人が自宅から動画であれやこれやオモシロ動画をこぞってUpしている。だけではなく博物館・美術館・水族館やら動物園に至るまで自宅で見られないものはないのではという勢いだ。

#### 送った動画

- [高嶋ちさ子の威風堂々](https://www.youtube.com/watch?v=31hOQtGZYKE)
- [ディズニーランド ファンタズミック](https://www.youtube.com/watch?v=qkWBeyJD7GA)
- [嵐 LIVE TOUR](https://www.youtube.com/watch?v=J0F0e8jd5xk)

… まだまだあるはずなんだが。よくわからないスタンプでリアクションが返ってくる。見られた？と聞くとみられてはいるようだ。

ここまでやってみて結局楽しんでもらえているのかわからずLINE通話を始めてしまった。曰く「嵐のLive映像は楽しかった。寄席動画があればもっと送って（スタンプ付き）」とのこと。

##「送って」

...送ってじゃなくて検索して見つけてもらいたいなあと思うんだがLINEが「URLを送ったらサムネイルを表示」してくれる、母にも、誰にも変わらぬ優しさ。そしてご本人に今更努力というようなことを強いられたくもないと言われればそれはそれ。せめてこれで楽しんでもらえてるからやはりLINEはすごい。ああこうなる前からスマホの使い方真面目に教えてあげておけばよかったと思いつつ、これでもどうにかしてくれている大衆向けアプリの偉大さ (あるいはいわゆるエンタープライズなアプリの傲慢さ) をまだまだ感じているこの頃です。
ATOMが突然使えなくなった件

#背景
　私『Visual Studio』歴は彼是10年になりますが、Pythonの開発環境は何が良いのか分かりません…。当初は初心者らしく『Jupyter Notebook』を使ってましたが、もっと効率的なものを求めて無料エディタ『ATOM』に手を出してみました。でも、あれ？何かがおかしい。インストールして暫く使ってなかったのですが、その合間に何が起きた？なんか画面がおかしいのでした。

#症状
その“おかしい”画面というのが下図の通りです。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374906/30b52861-0426-eea1-ecd8-9b19b5ba7a16.png)
　まず、Google先生で調べるのが難しい…。なんと検索すれば良いものか？分かる限りのキーワードを頼りに調べてみました。画面の雰囲気的には『Developer Tools』という物に似ているのですが、決してそのツールが立ち上がっている訳では無さそう。
　そして気付いたのが、↓の文字。あぁ、これはエラーだったのか。
>Error: EPERM: operation not permitted

#対策方法
Google先生の導きで辿り着いた対策方法が以下の2点。

① ATOMの再インストール
　アンインストール & 再インストールをしてみました。はい、変わりません。全然解決してない。。

② C:/Users/(someone)/.atom フォルダの削除
　ココにATOMの設定が保存されるっぽいけど、その設定がヘンテコなことになっている様子。男は黙って消すべし！解決しました。以上。
PostgreSQLで「SET AUTOCOMMIT TO ON」をすると「ERROR:  unrecognized configuration parameter "autocommit"」になってしまう

# 問題
ドキュメント[^1]に書かれているようにAUTOCOMMITをオフにしようとしてもエラーとなってしまう。

実際に実行すると以下のようにエラーとなる。

```sql
postgres=# SET AUTOCOMMIT TO ON;
ERROR:  unrecognized configuration parameter "autocommit"
postgres=#
```

# 原因
そもそもドキュメント[^1]の見方が間違っていました・・・。
自分も勘違いしていましたが、このドキュメント[^1]はPostgresSQLサーバーの機能のドキュメントではなく、PostgreSQLが提供するECPGというC言語向けのライブラリーのドキュメントのようです。

ECPGライブラリーがなんなのかというと、
独自構文で書いた.pgcファイルを用意し、ECPGライブラリーで.cファイルに変換することでC言語で簡単にPostgreSQLにアクセスできるライブラリーのようです。その.pgcファイルの独自構文の中の1つが「SET AUTOCOMMIT」で、さきほどのドキュメント[^1]で解説されています。

あくまでECPGライブラリーが認識できる構文なので、どれだけpsql上で「SET AUTOCOMMIT」を打ってもエラーになるだけです。そんなコマンドはpsqlもPostgreSQLサーバーも知らないので。

英語しかないですが、ECPGの簡単な解説がwikipediaに載っていました。google翻訳をしてみるといい感じに日本語でも見れるので興味がある方はどうぞ。
https://en.wikipedia.org/wiki/ECPG



# 解決方法
少し調べた感じ、PostgreSQLサーバー自体にはAUTOCOMMITの切り替え機能は**ないようですね**。AUTOCOMMITの機能はPostgreSQLクライアントで実現されているようです。

おそらくこの記事を見ている人はpsqlを使ってPostgreSQLに接続していると思いますので、psqlを使っての解決方法を紹介します。

詳しくは公式ドキュメント[^2]を参照していただければと思いますが、2つ方法があります。
1つはセッション上で行う方法(psqlコマンド上で行う方法)、2つ目は.psqlrcファイルに書いておく方法です。

1つ目のセッション上で行う方法(psqlコマンド上で行う方法)だけ載せておくと以下のようにできます。

まず、現在の値を確認して、AUTOCOMMIT変数がonになっていることを確認します。その後、AUTOCOMMIT変数をoffにし、beginをせずにテーブルデータをDELETEします。その後、rollbackしてみると、データが戻っていることが確認できますね。
注意しないといけないのは、AUTOCOMMITはすべて大文字です。autocommitでは異なる変数を設定することになるので変更が有効になりません。注意しましょう。

```sql
postgres=# \echo :AUTOCOMMIT
on
postgres=# \set AUTOCOMMIT off
postgres=# \echo :AUTOCOMMIT
off
postgres=# select count(*) from machines ;
 count
-------
   150
(1 row)

postgres=# delete from machines ;
DELETE 150
postgres=# select count(*) from machines ;
 count
-------
     0
(1 row)

postgres=# rollback ;
ROLLBACK
postgres=# select count(*) from machines ;
 count
-------
   150
(1 row)

postgres=#
```

[^1]: SET AUTOCOMMITが記載されているドキュメント：https://www.postgresql.jp/document/9.6/html/ecpg-sql-set-autocommit.html


[^2]: psqlでAUTOCOMMITを変更する方法：https://www.postgresql.jp/docs/9.6/app-psql.html#app-psql-variables
Bashでポートスキャン

# 概要

ペネトレーションテストなどで侵害したLinuxホストから内部のネットワークに対してポートスキャンを実施することがあります。Nmapが無いことはほとんどですが、そのような時はBashの簡単なスクリプトでtimeoutコマンドをかましながら実行していましたが、timeoutコマンドがないことがありましたのでURL(※1)を参考にスクリプトを書いてみました。

# スクリプト

```bash:portscan.sh
#!/bin/bash
host=$1
for port in {1..65535}; do
    (bash -c "echo > /dev/tcp/$host/$port") && echo "$port port is open" & sleep 0.1 ; kill -9 $! > /dev/null 2>&1
done
echo "Done"
```

# 使い方

```
$ bash ./portscan.sh 10.11.xx.xx > portscan.txt
```

実行するとオープンしているポートがあれば**portscan.txt**ファイルに
**21 port is open
22 port is open
80 port is open**
のように記載されます。


# 参考URL
※1 [bashタイムアウトを実装する](https://qiita.com/Qrg/items/c6dead7b48bc8ff43a63)