OmniAICreator/Qiita-1.07M huggingface dataset:
初心者　flutter×ブロックチェーンに挑戦する　1

# 電子投票アプリをつくる

##  まずは完コピから

　[Flutter大学](https://flutteruniv.com)と[UNCHAIN](https://app.shiftbase.xyz)に所属していながら、ぜんぜん別のことをやっているというのも、だんだん気持ち悪くなってきたので、そろそろ二つを統合しようと思う。で、たまたまネットで見つけた電子投票アプリをつくってみることにした。まずは完コピで一回。次は少し頭を使っていく予定。

　完コピのネタ元はこちら。

https://blog.logrocket.com/building-dapp-flutter-solidity/

- 今話題の仮想通貨まわりに挑戦しよう
- スマートコントラクトってなに？
- MetaMaskを導入しよう　

　イーサリアムのウォレットです。Rinkeby Test Networkを選択します。　間違えると本物のイーサを使うはめになるかも？　おもちゃのイーサを充当しておきましょう。これはUNCHINで毎日使ってるのでOK。

- [Remix IDE](https://remix.ethereum.org)に登録しよう。

　環境構築いらずで使えるオンラインのプラットフォームです。初めて使うけど、なんとかなりそう。記事には画像がしっかり入っているので理解しやすいです。solidityで書いていきます。今回はシンプルな関数が四つだけなので、かんたん。初めての人でも問題ない。もちろん、貼り付けてもOKでしょう。

- solidityのバージョン　0.6.6になってますが、最新は0.8.4です。
- solidityでcompileボタンを押して、イーサリアムでdeployボタンを押す。

　たった一枚、ファイル書いて、ボタン二回押すだけ？　いつもの、インストールしたり、あっち書いたり、こっち書いたりはなんなんでしょう。らくっちゃ楽ですけど、見えない部分が増えてるわけで、勉強向きではないかな。初期設定いらずで初心者でも楽ですよ、と考えるか、ちゃんとわかるようになってから楽しましょうね、と考えるか。差が出ますかね。

- [INFURA](https://infura.io/resendverify)にプロジェクトを登録しましょう

 UNCHAINでは[alchemy](https://www.alchemy.com/)使っている部分でしょうか。正直、まだその役割をよく理解していないけど、毎回通るところ、ですね。

- flutter projectをつくりましょう。

　やっと登場です。え、どこでつくるの、同じRimix?　と思いましたが、関係なさそうです。いつもどおりAndroidstudioでつくりました。

- pubspec.yamlに二つ追記してpubgetします。
- web3dart: ^2.3.3 と書いてありますが、最新は^2.3.5です。
- http: ^0.13.4 これは変わらずでした。

　ここから突然、飛び石説明になります。つまりこれ、flutterはわかってますよね前提の記事ですね。AとBと二つのボタンが表示された画面がぽんと出ていて、シンプルでしょ、自分で書いてね、ですよ。笑　でも記事の最後にGitHubのアドレスがありますから、こちらを完コピできます。main.dartとhomepage.dart２枚だけです。確かにシンプルですね。


- UIができたら、諸々、加えていきます。
- final String myAddress = "0x......

 これ、たぶん、自分のウォレットのアドレスです。たぶん、で申し訳ありませんが。

- final String blockchainUrl = "https://rinkeby.infura.io/....

 ここは、さっき登録したINFURAで表示された自分のprojectのアドレスです。

- Remixに戻って、もう一回deployして、ABI を取得。
- assetsフォルダをつくって、中にcontract.jsonというファイルをつくって、ABIをべたっと貼ります。

これ、githubのを貼ってはいけません。自分のdeployですから、唯一無二です。deployし直したら張り直しですって、UNCHAINで毎回言われる。

- homepageに戻ってCredentials key = EthPrivateKey.fromHex("....

 これ、たぶん、ウォレットの秘密鍵です。たぶん、で申し訳ありませんが。

　なんで、たぶん、が２カ所あるかというと、実は検証ができてないんです。記事完コピで、変えたのは要するに、「自分の」ウォレットや、「自分の」project、「自分の」deployに関わるところです。で、これでちゃんとsimulatorで走るんですが、問題が一つあります。

- 私のsimulatorはMetaMaskに繋がっていない。私のMetaMaskはGoogleChromeの拡張機能ですから。

　なので、投票者として、一回だけ投票する、という身分確認を兼ねたウォレットに接続できてないんじゃないかと思うんです。投票ボタンは押せますが、ずっとペンディングで投票結果が表示されません。

　UNCHAINの課題だと、MetaMask繋がってないと、繋がってませんよと警告が出て、繋ぐボタンを押す、みたいな設計なんですけどね。

　ということで、いろいろ新しい経験をして、赤々しいエラーはなく、simulatorも走るけど、肝心の投票結果が出ません、というちょっと残念な結末で本日は終了です。

　次回はこれを、UNCHAINで使い慣れたフォーマットのスマートコントラクトに変更しつつ、フロントはflutter、simulatorで走ってね、をやっていきたいと思います。

## 次はもう少し頭を使って苦しみます。![スクリーンショット 2022-04-01 12.30.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1646810/29c40ed3-2170-5ce1-ba0c-b49af4a34c2f.png)

次の記事

https://qiita.com/dongri727/items/af2fced633c9669c5aac
Pysparkにおけるキャッシュの利用

## はじめに
こんにちは。株式会社ジール所属の@oreo_tです。

最近、PySparkでキャッシュを利用したパフォーマンス改善をしたのでTipsとしてまとめます。
キャッシュ利用の背景としては、顧客情報に対して複数の加工をするときに必要になりました。
例えば、契約者には契約情報、負傷者には治療情報など、顧客テーブルのデータに対して役割ごとに違うテーブルの情報を結合しています。
そこで、結合のたびに都度顧客テーブルを呼び出すと時間がかかるという状況を改善するために、キャッシュを使用しました。

## Pysparkのキャッシュとは？
PysparkのDataframeをメモリ上(またはディスク上)で保持することにより、一つの処理の中で複数回Dataframeを呼び出すときにパフォーマンスを向上することができる機能です。
Pysparkにおけるキャッシュは関数が用意されていて、「persist」と「cache」の2種類があります。

##  Pysparkのキャッシュの種類
### persist
引数にStorageLevelを入れるとどこにキャッシュするか指定できます。
以下、StorageLevelのオプション例です。
|引数の値|仕様|
|:-:|:-:|
DISK_ONLY|ディスクのみに格納|
|MEMORY_ONLY|メモリのみに格納|
|MEMORY_AND_DISK|メモリからあふれた分はディスクに格納|
|MEMORY_AND_DISK_DESER|メモリからあふれた分はディスクに格納、さらにデータをシリアライズする|


persistを引数無しで呼び出すと、デフォルトのMEMORY_AND_DISK_DESERが選択されます。


#### persistの使用例①
ここでの使用例としては、「ドラッグストアの全店舗の売上データが１テーブルにまとまっておりデータ量が膨大になっているため、店舗ごとに分けたい」という状況でキャッシュを使用しようとしています。
以下すべての使用例で同じ目的のためにキャッシュを使用しています。
売上テーブルから上野店のデータと渋谷店のデータを分けて取得したい場合、
以下のようにキャッシュしてから上野店のdataframeと渋谷店のdataframeを作成することで、
パフォーマンスが向上します。
```persist_1.py
dataframe = spark.("SELECT * FROM sales_table")
dataframe.persist()
dataframe_ueno = dataframe.filter(col("shop_name")=='上野')
dataframe_shibuya = dataframe.filter(col("shop_name")=='渋谷')
```

#### persistの使用例②
persistの中に引数を入れることで、キャッシュの仕様を変更できます。
以下、メモリ上のみにキャッシュするように設定した場合です。
```persist_2.py
dataframe = spark.("SELECT * FROM sales_table")
dataframe.persist(StorageLevel="MEMORY_ONLY")
dataframe_ueno = dataframe.filter(col("shop_name")=='上野')
dataframe_shibuya = dataframe.filter(col("shop_name")=='渋谷')
```


### cache
引数はなく、前述した「persistの引数MEMORY_AND_DISKの場合」と同じ仕様(メモリからあふれた分はディスクに格納)でキャッシュをします。
cacheとpersistのどちらを使えばよいか迷った場合、こちらを使えばよいかと思います。

#### cacheの使用例
売上テーブルから上野店のデータと渋谷店のデータを分けて取得したい場合、
以下のようにキャッシュしてから上野店のdataframeと渋谷店のdataframeを作成することで、
パフォーマンスが向上します。
```cache.py
dataframe = spark.("SELECT * FROM sales_table")
dataframe.cache()
dataframe_ueno = dataframe.filter(col("shop_name")=='上野')
dataframe_shibuya = dataframe.filter(col("shop_name")=='渋谷')
```

## キャッシュの利用状況の監視について
キャッシュの容量の設定や、実際に使われているメモリやディスクの使用量の監視方法については、説明範囲が広いため今回は割愛させていただき、また別の記事で説明したいと思います。

## 終わりに
今回紹介したキャッシュはパフォーマンス改善に役立つ便利な手法ですが、扱うデータ量やマシンスペックによっては必ずしも効果を発揮するわけではない、という点には注意が必要です。
例えば取得したデータが大きすぎる場合、メモリ不足でキャッシュできない、ということもあります。
また、キャッシュできたとしても、キャッシュしたデータを使いまわさないような処理構造であれば意味がなくなってしまいます。
ですが、パフォーマンスチューニングの手法の中では比較的簡単で効果が出やすいと思うので、
利用できそうな場面ではぜひご活用ください。
rails paramsとは

# 結論

ユーザーからの情報を受け取るメソッド
```
 params[カラム名]
```

＊parameter：　設定値

# 具体例

ユーザーがある投稿を削除しようと選択した時、以下の手順で処理を行う。

```index.html.erb
<%= link_to '削除', "/users/#{user.id}", method: :delete %> 
# viewに表示されている`削除ボタン`,url
の指定、HTTPメソッドの指定（delet,patch,get
いずれか）
```
ユーザーが要求したURLが左、それを右へ渡す。

つまり`HTTPメソッドdelete URL`という`要求`が来たから、その要求を処理するために`users_controllerのdestroyアクション`に`要求`を渡す
```routes.rb
Rails.application.routes.draw do
  delete "/user/:id", to: "user#destroy"
end
# 要求をコントローラーの`destroy`アクションへ渡す
```
```users_controller.rb
class UsersController < ApplicationController

def destroy
 user = User.find(params[:id])
 user.destroy
end
     # ここで要求を受け取る！findメソッドは受け取ったPK（主キー）からレコードを取り出すメソッド、そのためにparamsメソッドが必要
　　　　　　　　　　#userに取り出したレコードを格納し（find）、削除する（destroy）
```
これが具体的なparamsメソッドの使い方と行われている処理です。

以上です。
head･tailコマンドの組み合わせで開始行と終了行を指定する方法

用途として､長いファイルサイズのログファイルを分析するときなどに｡

## やり方

`head`コマンドと`tail`コマンドを組み合わせる｡

```shell
# まず開始･終了行数を調べておく (大量ヒットする場合はheadを付けておくと良い)
grep -n '${検索ワード}' ${ファイル名} | head

# 指定範囲でファイルを取得する
head ${ファイル名} -n ${終了行数} | tail -n ${終了行数 - 開始行数 + 1}
```

## 実行例

ログファイルに見立てたファイルを作成しておく｡

```logfile.log
1行目
2行目
3行目
4行目
5行目
6行目
7行目
8行目
9行目
10行目
```

例えば **3～7行目を取得する** 場合､

```bash
# 開始･終了行数を検索しておく (今回の例だと検索するまでもないが･･･)
$ grep -n '3行目' logfile.log | head
3:3行目
$ grep -n '7行目' logfile.log | head
7:7行目

# 指定範囲でファイルを取得
# headで 終了行数7 | tailで 終了行数7 - 開始行数4 + 1 → 5
$ head logfile.log -n 7 | tail -n 5
3行目
4行目
5行目
6行目
7行目
```

見事3～7行目が取得できた🍻

### 図解

```bash
        head -n 7  # 上から7行                
1      | 1       |                            
2      | 2       |      tail -n 5  # 下から5行
3      | 3       |     | 5       |            
4   →  | 4       |  →  | 4       |            
5      | 5       |     | 3       |            
6      | 6       |     | 2       |            
7      | 7       |     | 1       |            
8                                             
9                                             
10                                            
```
STM32G031とI2Cを使い0x40(8ビット表記0x80)に「hello...」と出力する。(Arduino)(ライブラリー化)



目的
I2Cのテスト
I2C->USART9600bps->USBのテスト
STM32-I2C-USART

STM32G031 I2Cシリアル変換　


![o_con300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/09dacb60-511b-a72b-64fd-12ce12dabc1d.jpeg)





STM32G031とVSCode+STM32CubeでI2Cスレーブの受信文字をシリアル出力(受信)(STM32-I2C-USART)(CH340N)



https://qiita.com/caa45040/items/5032e6905c9425f41495






メインプログラム


```c++



//I2C_OUT_0X80_MAIN_031_1

#include <Arduino.h>
#include <Wire.h>

#include "I2C_OUT_0X80_031_1.h"

//初期化
void setup()
{

  //i2cの初期化
  pc.beginNS(9600);

} //setup


//メインループ
void loop()
{

  //データの表示
  pc.printNS("HELLO WORLD\r\n");

  //4桁の値の表示
  pc.printNS(1234);
  //リターン
  pc.printNS("\r\n");

  //1秒の待ち
  delay(1000);

} //loop




```

I2C_OUT_0X80_031_1.hのプログラム


```c++


#ifndef TEST_H
#define TEST_H

//I2C_OUT_0X80_031_1


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

char ch_hex_a_b[16];
char *ch_hex_a(int x)
{

    ch_hex_a_b[4] = 0;

    if       ( x >= 9000 ) {x = x - 9000; ch_hex_a_b[0] = '9';
    } else if( x >= 8000 ) {x = x - 8000; ch_hex_a_b[0] = '8';
    } else if( x >= 7000 ) {x = x - 7000; ch_hex_a_b[0] = '7';
    } else if( x >= 6000 ) {x = x - 6000; ch_hex_a_b[0] = '6';
    } else if( x >= 5000 ) {x = x - 5000; ch_hex_a_b[0] = '5';
    } else if( x >= 4000 ) {x = x - 4000; ch_hex_a_b[0] = '4';
    } else if( x >= 3000 ) {x = x - 3000; ch_hex_a_b[0] = '3';
    } else if( x >= 2000 ) {x = x - 2000; ch_hex_a_b[0] = '2';
    } else if( x >= 1000 ) {x = x - 1000; ch_hex_a_b[0] = '1';
    } else                 {              ch_hex_a_b[0] = '0';
    }//if

    ch_hex_a_b[3] = '0' + (  x - (DIV10(x) * 10)  );  // 3  <- 120 - 123
    x = DIV10(x);                                     // 12 <= 123 / 10
    ch_hex_a_b[2] = '0' + (  x - (DIV10(x) * 10)  );  // 2  <- 12 - 10
    ch_hex_a_b[1] = '0' +  DIV10(x);                  // 1  <- 12 / 10

    return(ch_hex_a_b);

} //ch_hex_a


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
  int  printNS(int num);     //メソッドの宣言 オーバーロード
};


#define ADDR1  0x40

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //i2cの初期化
  Wire.begin(sdaPin, sclPin); //STM32G031J6M6
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  //I2Cに送信
  Wire.beginTransmission(ADDR1);
  Wire.write( ch );
  Wire.endTransmission();

  delay(1);//連続送信防止の為に1ms待つ

  //戻り値
  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//文字列の表示 オーバーロード 4桁
//メソッドの定義
int _pc::printNS(int num)
{
  if(num < 0) { putcNS('-'); num = 0 - num;   }
    
  char *str1 = ch_hex_a(num);
  
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif





```
samtoolsやbcftoolsはリモートファイルでも開ける

タイトルの通り。
samtoolsやbcftoolsはリモートのファイルでも開ける。

```sh
samtools flagstat https://raw.githubusercontent.com/kojix2/ruby-htslib/develop/test/fixtures/moo.sam
bcftools view -H https://raw.githubusercontent.com/kojix2/ruby-htslib/develop/test/fixtures/test.vcf
```

以上。

…短すぎるので、背景を少しだけ書く。
htslibのソースコードを読んでいると、インデックスを読み込むときにリモートファイルをローカルにコピーするみたいな表現が出てくるのが気になった。htslibのGithubのリポジトリを検索していたら次のissueがあってリモートのファイルが開けることがわかりました。

https://github.com/samtools/htslib/issues/69

この記事は以上です。
Microsoft SQL Server Management Studio のセットアップオプション

# はじめに
Microsoft SQL Server Management Studio（以下SSMS）を無人インストールしたいと思ったが、オプションについて情報を見つけられなかった。
ダウンロードして `/help` を叩けば良いだけだが、それすらめんどくさかったので結果を貼っておく。

ダウンロードはこちらから。

https://docs.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms


# helpの結果

バージョンは 18.11.1 です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472216/3126cb5c-e365-465f-5acb-88f45baf3653.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472216/96eeb7e2-99bc-0e40-720a-c0d686f5b4c6.png)


# 無人インストール

```
> SSMS-Setup-JPN.exe /install /quiet /norestart
```

# そのほか

使えるならchocolatey使った方が楽です。
でも、日本語版にできませんでした。。。
SQL個人的チートシート

SQL頻繁に使わないので、忘れがち。
この1ページにまとめておく。

# SELECT 検索
```基本.sql
SELECT * FROM テーブル WHERE カラム = '値';
```

# UPDATE 更新
```基本.sql
UPDATE テーブル SET カラム = '値' WHERE カラム = '値';
```

コンマで複数指定可能
SET カラム = '値' ,カラム = '値' 

## INNER JOIN
```join.sql
SELECT A.*, B.カラム FROM テーブルA AS A
JOIN テーブルB AS B ON A.カラム = B.カラム
```

## UPDATE JOIN
パターン①②とも同結果

```①.sql
UPDATE テーブルA
JOIN テーブルB ON テーブルA.カラム = テーブルB.カラム
SET テーブルA.カラム = テーブルB.カラム;
```

```②.sql
UPDATE テーブルA,テーブルB
SET テーブルA.カラム = テーブルB.カラム
WHERE テーブルA.カラム = テーブルB.カラム;
```
参考：[sqlのテーブル結合(left join)時の注意点](https://qiita.com/oh_yeah_sayryo/items/7de9c471f94a3406aa7d)

# INSERT 挿入
```基本.sql
INSERT INTO テーブル　（カラムA, カラムB） VALUES ('値A', '値B');
```
全カラム指定する場合、カラム宣言を省略可能。上記なら次の部分：`（カラムA, カラムB）`
　
```他テーブル参照①.sql
INSERT INTO テーブルA　SELECT * FROM テーブルB WHERE Bのカラム = '値';
```
テーブルAの1つ目のカラムにテーブルBの１つ目のカラム、２つ目、３つ目と順番に挿入される。
　

```他テーブル参照②.sql
INSERT INTO テーブルA　(カラムA, カラムB) SELECT カラム1, '0' FROM テーブルB;
```
カラム宣言を省略しなければ、一部のカラムのみ参照する記述が可能。
上記ではカラムAにはカラム1、カラムBには'0'が挿入される。

# DELETE レコード削除
```基本.sql
DELETE FROM テーブル WHERE カラム = '値';
```

:::note warn
SELECT文の「SELECT *」を「DELETE」に置き換えただけなので、
削除前にSELECTでレコード確認し、そのままDELETEに変更する運用が安心
:::

DELETE文は（レコードの）物理削除を行う。
delete_flagを立てて値を変更するのが論理削除。

コミットしていなければロールバック可能。


# DROP テーブル削除
```
DROP TABLE テーブル;
```

完全削除なのでロールバック不可。


# TRUNCATE 全レコード削除
```
TRUNCATE TABLE テーブル;
```

テーブル削除し、再作成しているため処理高速。
なので、条件指定なしのDELETE文より高速で全件削除可能。
ロールバック不可。

# DB2関連
```sql:
--データベースへの接続
db2 connect to {データベース名} user {username} using {password}

--データベース接続解除
db2 connect reset

--スキーマ設定（設定すれば当セッション内では、コマンド実行時スキーマを省略できる）
----db2はデフォルトでログインユーザ名を暗黙的にスキーマに設定する。
db2 set schema {スキーマ名}

--SQL実行
db2 "select * from （スキーマ名.）{テーブル名}"

--エクスポート（”of ファイルタイプ”　csvで抽出するならdelを設定）
----先頭のダブルクォートはselectの前でも良い
db2 "export to （/パス/）{ファイル名} of del select * from （スキーマ名.）{テーブル名}"

--インポート（”of ファイルタイプ”　csvで挿入するならdelを設定）
db2 "import from （/パス/）{ファイル名} of del insert into （スキーマ名.）{テーブル名}"

--当日日付の条件指定例(a_dateのファーマットがyyyymmddの時)
~~ where a_date = to_char(current_timestamp,'yyyymmdd')
```

## 備考
DB2コマンドオプション：https://www.ibm.com/docs/ja/db2/9.7?topic=clp-options
Laravel IDE Helper Generator

```terminal
composer require --dev barryvdh/laravel-ide-helper
```
でインストール。<br><br>
設定をしない人も多い。その場合はこの段は省略。
```terminal
php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider" --tag=config
```
すると/config/ide-helper.phpができるのでこれを修正。
```config/ide-helper.php
...
'write_model_magic_where' => false,// trueから修正
...
'write_model_relation_count_properties' => false,// 同上
...
```
<br><br>
```terminal
php artisan clear-compiled
php artisan ide-helper:generate
php artisan ide-helper:models
php artisan ide-helper:meta
```
下から2行目ではnoと入力、最終行はPhpStormのみ。
使い方は

```composer.json
"scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan ide-helper:generate",
            "@php artisan ide-helper:meta",
            "@php artisan package:discover --ansi"
        ],
},
````
これで
```terminal
composer dump-autoload
```
を実行すればそのたびにdocs（こう書いてある）が再生成される。
最後に.gitignoreに
```.gitignore
... 
_ide_helper.php
_ide_helper_models.php
.phpstorm.meta.php
```
を追加。
【PTA-DX】PTAの共有GmailをLINEに転送した話

＜2022/4/22追記＞
getMonthの仕様によってメール受信日時が前日になるバグに対応

＜2022/04/03追記＞
　　下書きを拾ってしまうバグに対応
　　送信済メールも通知されるよう仕様を変更
　　別端末でのログイン時の「セキュリティ通知」メールを除外するよう仕様を変更

子どもが小学生になり、PTAの業務に携わることになりました。
どんなアナログ業務が待っているんだろうとワクワクしていましたが、
昨年までの担当の方がデジタル化を進めてくれていて、
**GoogleドライブとGmail**を使った運用をされているようでした。

前年度の担当者からの引き継ぎを3月に始めたものの、
一ヶ月で不便に思うことが出てきました。
前年度の方が「好きにやっていいよ」とおっしゃってくれたので、
この機会にPTA業務のDXを進めてみようと、
第一弾として**Gmailで受信したメールのLINE転送**から始めてみることにしました。


## トポロジー
![pta-dx01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282645/7751a843-0c29-2159-8303-4b5710859315.png)


## PTA業務の概要
- 小学校の放課後のイベントを企画・運営する
- 参加している業務のグループは５名程度
- イベント企画のために、市役所や学校の担当者と連絡が必要
- 連絡はGmailでメールを行う
- 書類はGoogleドライブ上で管理
- ひとつのGmailアカウントをグループに所属する全員で共有する
- 主要デバイスはスマホ。書記担当（私）はPCも利用
- グループ内の連絡は専用のLINEグループのトークを利用

## 発生した問題
市役所の方からGmailにメールが届きました。
メンバーの一人が、届いた瞬間にGmailからこのメールを開き、既読になりました。
すると他の人のスマホでは通知が消えてしまい、メール受信に気づけませんでした。
なお、このメールは最初にメールを開いた人ではなく、それ以外の人がやりとりしていたものでした。
つまり、**本来メール受信を気付くべき人が気づけなかった**ということです。

## 問題の原因
根本原因は **Googleアカウントを共有していること** です。
正しい解決策は、アカウントの共有をやめて、メンバー各自のGmailアカウントに
Googleドライブのファイル／フォルダの共有をかけることが最善です。
そのうえで、連絡は各自のメールアドレスを使って行うべきです。
ただし、PTAとは特殊な組織で、**ママ友パパ友というプライベートな関係**で成り立ちます。
**個人のGoogleアカウントはお互い明かしたくない秘密を抱えたもの**であり、
正しい解決策をとることは難しそうだと判断しました。

※補足：秘密は色々考えられるけど、主にオタク趣味的な部分が可能性高い

## 解決方法
Gmailで受信したメールをLINEのトークグループに転送することにしました。
PTAのメンバー間ではLINEでのやりとりがメインで、LINE通知はもっとも気にする通知のひとつです。

### 使ったサービス
以下２つのサービスを使って実装しました。実装方法は探せば他にもゴロゴロ転がってます。
[LINE Notify](https://notify-bot.line.me/ja/)
[Google Apps Script](https://workspace.google.co.jp/intl/ja/products/apps-script/)

参考URL：https://sp7pc.com/gadget/line/23926
)

### 設定手順
主に以下URLに沿って設定します。ちなみに私は「本文あり」としました。
https://sp7pc.com/gadget/line/23926

ただし、当投稿では以下２つの問題の解決をアドオンします。
- 既読メールの受信に気づけない問題
- App Script上の時刻がアメリカ時間になってしまう問題

#### 既読メールの受信に気づけない問題への対処
App ScriptがGmailからメールをフェッチしてくる条件を変更します。
~~~
//検索条件指定
var strTerms = '(-セキュリティ通知 in:inbox OR in:sent after:'+ time_term + ')';

~~~
**is:unread**を削除します。
これがあることで未読メールだけしかフェッチしないため、指定すると今回の既読メールスルー問題を解決できません。
また、**-セキュリティ通知**で初めての端末でのログイン時に通知されるメールを除外、
**in:inbox OR in:sent**で、検索条件を受信トレイと送信済に限定しました。これを指定しないと、**作成中の下書きまで拾ってしまいLINE通知がひどいことに**なります。

#### App Script上の時刻がアメリカ時間になってしまう問題
こちらの記事で紹介されている方法を採ります。
https://masa-enjoy.com/gas-dateobject-timezone
- appsscript.jsonの有効化
- TimeZoneを”Asia/Tokyo”に変更

#### メール受信日時の月（Month）が前月になってしまう問題
JavaScriptのgetMonth仕様の問題です。
getMonthで取得する変数をNumberで数値に変換し、+1することで修正します。
~~~
 valMsgs[i] = " " + (Number(myMsgs[i].slice(-1)[0].getDate().getMonth()) + 1) + "/"+ myMsgs[i].slice(-1)[0].getDate().getDate()
~~~
設定は以上で終了です。
動作確認は、PTAメールアドレスにて、自分自身にメールを送信することで確認しました。

## まとめ
ファーストステップとしてGmail-Line連携を行いました。
今後は年間スケジュールの管理とメンバーのタスク管理を何かのサービスで実現したいなー
VMware製品の評価ライセンス入手方法 (VMUG Advnatage)

# 1. はじめに
VMware仮想環境のホームラボの構築について以前の投稿に関連して、「[VMUG Advantage](https://www.vmug.com/membership/vmug-advantage-membership/)」特典での評価ライセンスの入手方法(有償)についてご紹介します。

実は先日私も更新用ライセンスキーをダウンロードしようとしたのですが、なかなかダウンロードサイトが見つけられず迷子になってしまいました。本記事は自分のための備忘録でもあります。

https://qiita.com/sanjushi003/items/4d20c85b80032e6f6b25

##### VMUG Advnatage 評価ライセンスダウンロードサイト (すでにVMUG Advantageに登録済みの方はこちら)

https://vmugadvantage.onthehub.com/

本記事を執筆している2022年3月時点では、次のVMware製品評価ライセンス(およびVMware資格試験の割引コード)が入手できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/3dace9a1-2407-894b-bada-636303245ca3.png)

# 2. そもそもVMUGって？
「[VMware User Group (VMUG)](https://www.vmware.com/content/microsites/learn/ja/vmware-usergroup.html)」 はVMware仮想化製品について情報交換したり議論したりする素敵なユーザーコミュニティです。もちろん参加無料です！

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/07a11f50-1524-4c97-3c8c-40320e83492d.png)](https://www.vmware.com/content/microsites/learn/ja/vmware-usergroup.html)

#### VMUG Advantage について

さらに有償ですが「[VMUG Advantage](https://www.vmug.com/membership/vmug-advantage-membership/)」にも登録することで、さまざまなVMware製品の検証ライセンスを入手することができます。年単位の登録になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/951dfa29-0e08-e5b6-8d63-06ac2a7d50e6.png)
> 通常のVMUGとVMUG Advantageの違い

VMUG Advnatageへの登録はこちらから。
https://www.vmug.com/membership/vmug-advantage-membership/

# 3. 評価ライセンスのダウンロード方法

VMUG Advantage に登録することで、1年間有効な評価ライセンスをダウンロードできるようになります。
有効期限が切れた場合は再度評価ライセンスのダウンロードすることで有効期限延長することができますが、その時にもVMUG Advantageに登録しておく必要があります。

「[VMUG Advnatage 評価ライセンスダウンロードサイト](https://vmugadvantage.onthehub.com/)」にログインして、必要な評価ライセンスを選択していきます。またVMware製品毎に簡単な製品アンケートに回答する必要があります。

下図は「[VMware Site Recovery Manager](https://www.vmware.com/jp/products/site-recovery-manager.html)」の評価ライセンスをダウンロードした際のスクリーンショットです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/aa24afe2-565d-5e9f-3a45-d4033dc7b972.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/445dc68a-f1e9-0f37-9c16-6d8b5435f8f2.png)

# 4. 参考記事

https://qiita.com/sanjushi003/items/ba6426b202215f39ba22

https://qiita.com/sanjushi003/items/175aad0ccdbb3488bfda
CentOS7 RAID(VROC)環境でのインストールトラブル

2022/3/1

### ■結論：無難に、DVD版でインストールを進めた方が早い。
※Minimal版でも成功する方法はある様です。

##### ■トラブル症状：Minimal版で、インストールを始めると、最初の画面が表示された直後に<BR>　　　　　　　　エラーで、インストーラーが停止します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/8a21e08a-0a37-13c5-56ed-841030360b41.png)

警告メッセージ例
~~~
File "/usr/lib/python2.7/site-packages/blivet/devices/storage.py", line 839, in isNameValid 
    if name.startswith("cciss/"): 
File "/usr/lib/python2.7/site-packages/blivet/devices/device.py", line 83, in __init__ 
    if not self.isNameValid(name): 
File "/usr/lib/python2.7/site-packages/blivet/devices/storage.py", line 131, in __init__ 
    Device.__init__(self, name, parents=parents) 
~~~


### ■メディアの選択での注意事項
以下のメディアの選択で
- × CentOS-7-x86_64-Minimal-2009.iso　にてインストールを進めてしまったのが問題でした。
- 〇 CentOS-7-x86_64-DVD-2009.iso を選択して進めるべきです。
　
※但し、最近のDVD版は、容量が大きくなっており、ダブルレイヤーのDVDが必要となっています。
　その為、USBにてBootをするのがおすすめです。
　Rufusというツールを使用しました。https://rufus.ie/ja/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/0df67568-dd43-f284-5e63-bc3e8954e23e.png)
ImageJ と cellpose を使って、細胞画像の輝度値を測定する。（４）




# 目的
顕微鏡撮影した細胞画像から、細胞膜領域と細胞質基質領域の範囲を選び、その平均輝度値を求めたい！

使用するアプリケーションは、以下の通りです。
- Fiji (ImageJ)　　　　　        
-画像解析ソフト
- anaconda 　　　　　　　　　　　　　　
-Python を動かすところ
- cellpose　　　　　　　　　　　**←今回は、これを動かしてみます！**
-Python で書かれた細胞画像の分節化に特化した、deep-leaning に基づくアルゴリズム

上記アプリケーション（プラグインを含む）のインストールや、解析に必要なマクロを記録していきます。

### PC の環境
Windows 10

# この記事の範囲
cellpose で細胞画像のSegmentation を行う。

# 前準備（imagej_roi_converter を Fiji にインストールする）

cellpose で細胞画像の Segmentation をした後、ImageJ (Fiji) に結果を持ってきて、更なる解析を行いたいと思います。
例えば、不要な領域を消去したり、作成した関心領域（ROI）の平均輝度値を求めるなど。
そのため、cellpose の結果をImageJ の ROI Manager に登録させるプラグインをインストールする必要があります。

まず、以下のリンクに行きます。

[Github での cellpose のページ](https://github.com/mouseland/cellpose)


このページには、cellpose のアップデート情報や困ったときのヒントが載っています。
ここに、上記の ImageJ に結果を登録させるプラグインもあるので、ここからダウンロードをします。

1. ページの右上にある、緑色の[Code▼]をクリックして、Download ZIP をクリックし、ダウンロードします。

2. ZIP ファイルを展開します。フォルダは、どこでも大丈夫です。

3. 展開した "cellpose-master" フォルダの中にある、[imagej_roi_converter.py]　を、C:\Users\[your name]\Fiji.app\plugins に格納します。
なぜ、このフォルダに入れるのか、については、
[ImageJ と Cellpose を使って、細胞画像の輝度値を測定する。（１）](https://qiita.com/Naka24-sun/items/e1cec6febf3a0cac3859)
に、記載しています。

4. Fiji を起動して、メニューバーの Plugins を見ると、一番下に[imagej_roi_converter] が追加されています。

# cellpose で Segmentation をやってみる。
##### 注意！
2022年3月時点での最新版 cellpose (v1.0) で操作しています。cellpose をアップデートすると、画面構成が変わることがあります。


1. cellpose を起動します。
cellpose の起動の仕方は、[ImageJ と Cellpose を使って、細胞画像の輝度値を測定する。（3）](https://qiita.com/Naka24-sun/items/a717d2dc1b3519112fff) に記載しています。

2. Segmentation をさせたい画像を、cellpose にドラッグ&ドロップします。
この操作で、画像を load することができます。

3. 下に表示されている赤い丸は、細胞の大きさを示します。画像の中の細胞の大きさに合わせる必要があります。条件設定の画面の中央らへんに、`cell diameter (pixels) (click ENTER)` とあるので、細胞のおおよその大きさ (pixel数) を入力して Enter を押します。この値は、計算結果に大きく影響します。

4. モデルを設定します。細胞質を Segmentation したい場合は、`cyto`　もしくは `cyto2` を選択します。核を Segmentation したい場合は、`nuclei` を選択します。

5. Segmentaion をさせたい細胞や核の領域が、背景より暗い場合は、`invert grayscale` にチェックを入れます。

6. `run segmentation` をクリックすると、計算を始めます。結果が予想と異なる場合は、条件を変えて試してみます。

7. 計算結果を保存する場合は、`File` > `Save Outlines as text  for imageJ` を選択します。すると、元画像のあるフォルダに [元画像のファイル名_cp_outlines.txt] が保存されます。


- 今回は、グレースケールの画像を用いた場合の設定について記載しました。RGB のマルチチャンネル画像にも対応しているようですので、その場合は設定を変更させてください。


# cellpose の結果を Fiji に反映させる

上記で得られた Segmentation の結果を、Fiji の ROI Manager に出力させます。

1. Fiji で、Segmentation に用いた画像を開きます。

2. Fiji のメニューバーから、Plugin > imagej_roi_converter をクリックします。

3. cellpose で出力した、[元画像のファイル名_cp_outlines.txt] を選択します。

4. ROI Manager に Segmentation 結果が ROI として登録されます。


不要な ROI は消去し、細胞領域もしくは核領域の平均輝度値を求めることなどができます。


# 良好な Segmentation 結果を得るために

cellpose での設定の仕方（cell diameter など）もとても大事ですが、他の deep-leaning による画像認識と同様、cellpose も画像のコントラストなどに大きく影響を受けます。

よって、cellpose に画像を load する前に、Fiji で画像を前処理しておくことをおすすめします。

例えば、Fiji のメニューバーから Process > Enhance Contrast... を起動し、輝度値の分布を標準化させたり、ヒストグラムを平坦化させたりし、コントラストを強調させることで、良好な Segmentation 結果が得られることがあります。

また、メディアンフィルタをかけて背景のノイズ消去をしたり、ガウシアンフィルタをかけて画像の輪郭を滑らかにしたりすることも有効だと思います。


次回、細胞領域の Segmentation 結果から、細胞膜領域を選択する Macro を記載する予定です。


以上！
Agora.ioでカメラ映像にWaterMark(透かし)を入れる方法

Agora.ioではWebSDKでカメラ映像を取得するAPIが用意されています。ですが、今回の件名にあるように少し映像を加工して配信したい場合もあります。
そのような要件に対応すべく、加工した映像を配信するAPIも用意されています。
この記事では例としてWaterMark(透かし)を入れる方法を解説します。 　　

サンプルは[Github](https://github.com/fu-jimoto/AgoraIO-WaterMark-Web)に公開しています。

## 実装方法
### カメラ映像の取得
AgoraのAPIでカメラ映像取得する場合は[createCameraVideoTrack](https://docs.agora.io/en/Video/API%20Reference/web_ng/interfaces/iagorartc.html#createcameravideotrack)を利用しますが、今回は加工をする為、getUserMediaを利用します。
canvas上にカメラ映像と画像を描画しています。

```javascript
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const canvasStream = canvas.captureStream(30);

//中略

async function createCustomVideo() {

  const video = document.createElement("video");
  const stream = await navigator.mediaDevices.getUserMedia({
    video: { width: 480, height: 320 }
  });

  var image = new Image();
  image.src = 'sakura.png';

  video.srcObject = stream;
  video.onloadedmetadata = () => {
    video.play();
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    render();
  };

  function render() {
    ctx.drawImage(video, 0, 0);
    ctx.drawImage(image, 0, 0, 150, 150);
    window.requestAnimationFrame(render);
  }

}
```

### 加工した映像の配信
加工した映像を[createCustomVideoTrack](https://docs.agora.io/en/Video/API%20Reference/web_ng/interfaces/iagorartc.html#createcustomvideotrack)に渡します。


```javascript
  [ options.uid, localTracks.audioTrack, localTracks.videoTrack ] = await Promise.all([
    // join the channel
    client.join(options.appid, options.channel, options.token || null),
    // create local tracks, using microphone and camera
    AgoraRTC.createMicrophoneAudioTrack(),
    AgoraRTC.createCustomVideoTrack({
      mediaStreamTrack: canvasStream.getVideoTracks()[0],
    })
  ]);
```

### 実行結果
このように春らしくサクラの画像が映像の上に重なって表示されます。
![スクリーンショット 0004-04-01 10.26.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/9cda38f8-76a9-f5a7-22f0-d97d0923e3d0.png)

## その他の参考
Agora社のGithubには動画ファイルを映像ソースとして配信するサンプルも提供されています。
サンプルは[Github](https://github.com/AgoraIO/API-Examples-Web/tree/main/Demo/customVideoSource)にあります。

## 最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=9981d35010da673ea587)
[<img width="912" alt="Agoraの詳細はこちら" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5865441c-9d31-c702-3698-3aeb84927f28.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=9981d35010da673ea587)
HTML & CSSとは

# はじめに
今日、よく目にする企業などの紹介に使用されるホームページがどのようにして構成されているかご存じでしょうか。

ホームページは様々なプログラミング言語によって構成されていますが、今回はその基礎となる **HTML**と **CSS**について紹介していきます。

# HTML & CSSとは？
## HTML
木を例で言うと **太い幹**にあたる部分です。

表示したい文字や画像を要素ごとに入力し表示することができます。

HTMLでは、文字を表示するpタグ、画像を表示するimgタグといったそれぞれの役割をもったタグというものを用いて画面上に表示します。

基本的には表示したい文字、画像などをこのタグといわれるもので囲っていきます。

HTMLによるプログラムの場合、下図のようになります。






![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609382/89ceb361-34fb-ad34-70c0-0cd0655653da.png)


### 要素
HTMLの主な要素はhtml要素、 head要素、body要素の三つの要素から成り立っています。

#### html要素
html要素はhtml文書であることを示すものです。Webページ中身全体をこのhtmlタグで囲います。
```html
<html>
</html>
```

#### head要素
head要素では、作成しているWebページの言語やcssファイルの読み込みなど、文章として反映されない部分を書き込みます。タイトルの部分はブラウザ上部のタブにタイトルとして表示されます。head要素の中身は、どのWebページを作成する際もだいたい同じなので覚える必要はありません。
  
```html
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>タイトル</title>
    <link rel="stylesheet" href="css/test.css">
    <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  </head>
```

#### body要素
body要素は、Webページの見出しや画像など直接反映される部分を書き込む要素です。

以下のようにタグを用いて構成していきます。h1タグは「見出し」、ul,liタグは「箇条書き」を表すタグとして用いられます。このほかにも様々な役割を持ったタグが多く存在します。
```html
<body>
    <header> 
    </header>
    <main>
    <h1>プログラミング言語</h1>
    <ul>
      <li>HTML & CSS</li>
      <li>Javascript</li>
      <li>PHP</li>
      <li>Python</li>
    </ul>
    </main>
    <footer>
    </footer>
  </body>
```




## CSS
HTMLによって構成された要素、タグに対して細かい部分を指定する、木における **枝**に当たる部分です。

具体的には、文字の色、余白、大きさなどを指定できることによって、全体的に見やすいレイアウトにすることができます。

cssの場合、まず選択したいタグを入力し{}の中身に文字の大きさや色を指定します。

下の画像のh1の部分を **セレクタ**、colorを **プロパティ**、redの部分を　**値**といいます。この場合、h1の文字の色を赤色にするというプログラムになります。

このようにcssではセレクタを指定しプロパティとその値を入力していきます。
```css
h1 {
color: red;
}
```

作成したcssファイルをWebページに反映させるには、以下のようなプログラムをhtmlファイルのhead部分に書きます。style.cssの部分は作成しているcssのファイル名を入力します。
```css
<link rel="stylesheet" href="style.css">
```



CSSを適用すると文字の色や配置を指定でき下図のようになります。このようにページの見やすさを重視するという点でCSSは非常に重要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609382/0815a99a-f656-2498-e051-a19b50700cec.png)




## HTML & CSSを用いたWebページの書き方
Webページを作成するには以下の2つが必要です。
<ul>
<li>エディタ</li>
<li>ブラウザ</li>
</ul>

エディタとはプログラムを書き込むノートのようなものです。このエディタを使用しhtml、cssファイルを編集していきます。
プログラムをエディタに記述する作業を **コーディング**と言います。コンピューターに、こう動いてほしいというのをプログラミング言語を用いて言語化する作業です。

ブラウザとは、GoogleやMicrosoft Edgeといったインターネットにつながるものです。エディタで作成したファイルをブラウザを使用して確認します。








# まとめ
Webページの構成において、ほかにも様々なプログラミング言語がありますが、HTMLとCSSがプログラミング学習において初心者が学ぶべき基礎となる言語だということは理解していただけたかと思います。

このスキルを身に付け新たなことにチャレンジしてみてはいかがでしょうか。
Core Web Vitals（コアウェブバイタル・CWV）改善の施策を考える

## Core Web Vitals（コアウェブバイタル・CWV）改善の施策を考える

### はじめに
　Core Web Vitals（コアウェブバイタル・CWV）のスコアを改善する機会があったため、勉強も兼ねてスコア改善するためにどのような方法があるかをまとめたいと思います。
コアウェブバイタルは
・LCP（ページの読み込み速度）
・FID（インタラクティブ性、応答性）
・CLS（ページレイアウトなどの視覚的安定性）
の3つがありますが、今回は特にLCPの改善を中心にまとめました。
![Qiita](https://peraichi.com/univ/wp-content/uploads/2020/12/Screen-Shot-2020-12-14-at-14.17.08.png "cwv")

### スコア改善を検討した結論

　・施策を適用すれば必ずスコアが改善するとも限らないので、施策を入れた場合と入れていない場合で改善が見られるかを何度かスコア計測して確認してみることが大事。
　・スコアを改善する施策は色々あるが、手間と後の保守性を考えた施策を選ぶべき


### スコア改善の施策一覧

#### LCP改善の考え
　ファーストビュー（ユーザーがページを開いて最初に表示される部分）の表示速度を上げることでスコアの向上に繋がる傾向があるため、特にページ上部の読み込み速度を上げることが重要となってきます。ただ、前ページへ戻った時などは、ページの途中がファーストビューになることも考えられるため、ページ上部の表示だけ考えればよいという訳ではなさそうです。
スコア計測の方法は、PageSpeed InsightsやLighthouseを使用することで簡易的に計測出来ます。

##### ・画像のlazyload
　JavaScriptライブラリを使用し、ブラウザの表示領域内の画像のみを読み込み、表示領域外にある画像は読み込ませないことで、無駄な読み込みを減らすことで画面の表示速度を上げる。
基本的には画像の読み込みをさせている部分に「class="lazyload"」を追加するだけなので手間は掛かりにくい。初期表示の部分にlazyloadをしてしまうと逆に表示が遅くなったり画面崩れに繋がるため注意が必要。

・headタグ内で読み込ませていたJavaScriptファイル、scriptをbodyタグ内に移動させる
　JavaScriptファイル（以降、jsファイルと記述）の読み込み処理をHTML内で行なうと、その読み込み中はレンダリングが止まってしまう。そのため、すぐに使用することの無いjsファイルについてはheadタグ内ではなくbodyタグ内、特に閉じタグ付近に記載することでページ表示速度は向上する。jsファイルの読み込み場所を後方にすることで期待する挙動が得られなくなる可能性もあるため確認が必要。

##### ・ファーストビューに表示される画像のpreload
　ファーストビューに表示される画像において、読み込まれるタイミングが遅いものはそれだけ表示が遅くなってしまう。そのためファーストビューに使用される画像を優先的に読み込ませることでファーストビューの表示速度を向上させることが期待できる。追加することは、先読みさせたいリソースを、以下のようにheadタグ内に記載するだけです。
```
 <link rel="preload" href="{先に読み込ませたいリソース}" as="image">
```
##### ・CSSファイルの遅延読み込み
　HTMLファイル内では、通常複数のCSSファイルを読み込むことになる。ページ下部のみで使用されるセレクタなど、初期表示には不要なCSSファイルを遅れて読み込ませることで、その分ファーストビューの表示速度を向上させることが期待できる。
遅延読み込みさせたいCSSファイルをbodyタグの閉じタグ付近に記載する。
※一部のファイルを遅延読み込みさせることで、CSSの読み込み順、読み込みタイミングが変わってしまう恐れがある。また、遅延させるファイルのCSSは読み込まれるタイミングが遅くなるため、その分CLSが悪化しないか注意が必要。


```
<script>
    var style_link = document.createElement('link');
    style_link.rel = 'stylesheet';
    requestAnimationFrame(function() {
        var href_paths = [
            '[CssFilePath]',
            '[CssFilePath]',
            '[CssFilePath]'
        ];
        href_paths.forEach(function (path){
            elm = style_link.cloneNode(false);
            elm.href = path;
            document.head.appendChild(elm);
        })
    });
</script>
```

##### ・js, CSSファイルのminify化
　通常、js, CSSファイルは改行して作成するのだが、コード中の改行を無くして1つのファイルのコードを1行にまとめる（minify化）ことで、ファイルの容量を減らし、処理速度を向上させることが期待できる。圧縮ツールはネットで検索すると多くヒットします。
　1行にまとめて容量を圧縮しているので、データ量の多いファイルのminify化が効果的です。逆に、もともと容量の小さい数十行程度のファイルはminify化しても効果は薄いです。
　ただこの施策は、1行にまとめることで後からソースを変更する場合にとてもコードが見づらく、保守性が悪くなってしまうのが難点です。そのため、minify化を行う場合は、以下のような工夫が必要と考えられます。
・もとのminify化する前のファイルは削除せずに取っておき、ソースを変更する際はminify化前のファイルを編集して、その都度minify化して使用する。（バンドル化のツールとしてはwebpackなどがあります。）
・minify化するファイルは外部ソース等、ソースを変更する機会が少ないものに限ってminify化を行う


### おわりに

　施策を入れれば必ずスコアが改善するとは限らないところが難しいところだと思いました。手間を掛けて施策を適用しても改善しないこともあれば、反対にコードを数行追加するだけで改善が見られることもあるのが面白いなと思います。今後も色々試していきたいです。
別サーバーのMySQLと同様のスキーマをローカル環境に構築する方法

## 初めに 

Workbenchを使用して別サーバーのMySQLのスキーマをローカルにDumpし、そのDumpしたファイルをローカルのMySQLにimportする方法を備忘録として投稿する。

## 環境
■ コピー元のMySQLのバージョン
5.7.12
■ コピー先のMySQLのバージョン
5.7.37
■ Workbenchのバージョン
6.3
※バージョンが大きく異なると、MySQLの仕様の違いによりDump時にエラーが出力される可能性がある。

## コピー元のMySQLのスキーマ―をDump
まず、Workbenchを使用してコピー元のMySQLにアクセスする。
次に上部バーにある「Server」というタブをクリックし、「Data Export」を選択。
![スクリーンショット 2022-03-31 144340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/10758176-eaeb-6b0b-18ee-5feaa4203409.png)

次にDumpしたいスキーマと保存したいローカルのフォルダを選択。
※スキーマ名は諸事情により加工しているが、実際は正常にスキーマが表示されている。

![スクリーンショット 2022ds-03-31 144528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/6324c461-831b-166c-90ef-c8715fa0ac51.png)

上記を選択したら、右下の「Start Export」をクリック。
すると、以下の画像の様にDumpが開始される。
![スクリーンショット 2022-03-31 144959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/0e22a473-92ba-415f-7ef1-63b7177dd890.png)

## コピー先のMySQLにスキーマのみを作成

※Dumpしたファイルにスキーマ名が記載されている場合は、ローカルでスキーマをあらかじめ作成しておかないとimport時にエラーになる。
Workbenchを使用してコピー先のMySQLにアクセスする。
「SCHEMAS」という所で右クリックして「Create Schema」をクリック。


![スクリーンショット 2022-03-31 152945.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/09d9659e-f900-09f3-6901-dc34009dfc3f.png)

下記画面に遷移するので、コピー元のスキーマと同じ名前のスキーマを作成する。
![スクリーンショット 2022-03-31 153011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/4ff7eeba-51f3-5efa-f550-9ecbe57f15e2.png)


## コピー先のMySQLにスキーマをimport

最後に、上部バーにある「Server」というタブをクリックし、「Data Import」を選択。
![スクリーンショット 2022-03-31 150044.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/b6daa7df-c7ad-22b1-be00-97ada99e9503.png)

先ほどローカルにExportしたフォルダとスキーマを選択し、「Start Import」をクリック。
![スクリーンショット 2022-0f3-31 150201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229062/16c5cee4-443a-afd7-042a-feef66719b29.png)

Export時と同じように処理を待つと、コピー先のスキーマがImportされていることが分かる。
Pythonanywhereのデプロイで　ModuleNotFoundError: No module named ''になった話

今回、フロントエンドにReact.jsの画面・バックエンドにDjango/rest_frameworkを使用したポートフォリオだったり自己紹介だったりを掲載するサイトを作成。
react.jsのデプロイはVercelでつつなくデプロイしたものの
Djangoに手間取りました。基本的な理解が足りてないような気もしています。



# つまづいたエラー
![スクリーンショット 2022-04-01 10.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610556/c8f607d6-90a8-9496-cadc-d84d3dba4663.png)

###### 対応
Bash コンソールからbash ⇨ pythonanywhere内の仮想環境で

 python -m pip install django-cors-headers

###### 結果
Requirement already satisfied　の羅列でもうインストールされているといった結果。



##### 今回の学び
１.インストールするコンソール
そもそもインストールする場所が違いました。

###### 対応
　　![スクリーンショット 2022-04-01 10.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610556/8d76fbe9-f897-c680-4db4-541ec21dc390.png)

ここのコンソールを開き・・・
 python -m pip install django-cors-headers

###### 結果
Successfully installed

無事、rest_frameworkの管理画面を開くことができました、、、、、（CSSは効いてないようなので別でやります、、）
とりあえず、Dockerが使えるようになる記事

## この記事のゴール
この記事のゴールは細かい説明は省いて、Dockerでコンテナ（サーバー）を動作させるまでをゴールとしております。
またDockerのインストールに関しては、この記事の範囲外としております。

## Dockerとは？
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2580122/cd5fa4a9-a7fc-691e-5c8e-cabbba79effd.png)

>Docker（ドッカー）とは軽量なコンテナ型アプリケーション実行環境です。Dockerの説明を聞くと難しく感じるかもしれませんが、Dockerを利用することで、OS内部に独立したアプリケーションの実行環境（コンテナ）を生成することが出来、いつでもその環境を立ち上げることが可能になります。
-- <cite>[【初心者向け】Docker（ドッカー）とは何か？](https://aiacademy.jp/media/?p=1106)</cite>

## 何が便利？
このDockerが最強なのは、下記の部分です。
1. コンテナを立ち上げるための必要な処理などを全て１つのファイルで管理→Gitなどのバージョン管理ツールで管理できる。
2. コンテナの立ち上げもコマンド**１つ**で完了

## Dockerでコンテナを立ち上げるまで
では、Dockerの概要について理解できたところで、続いてはコンテナを立ち上げるまでにどんな作業が必要なのかを見ていきましょう。

[手順]
① Dockerfileを作成する。
>Dockerfile:　Dockerのコンテナを立ち上げるまでの手順書

例： Nginx + PHP環境のDockerfile
```Dockerfile
FROM nginx:alpine

# php install
RUN apk update && apk upgrade && apk add php8 php8-fpm php8-curl php8-iconv php8-mbstring php8-openssl php8-phar php8-zip bash

# php8のシンボリックリンク
RUN ln -s /usr/bin/php8 /usr/bin/php

# composerのインストール
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" 
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" 
RUN php composer-setup.php 
RUN php -r "unlink('composer-setup.php');" 
RUN mv composer.phar /usr/local/bin/composer

EXPOSE 80
```

② Dockerfileを使い、イメージをビルドする。
> イメージ：　Dockerfileから作成した、コンテナの元(OSのzipファイルみたいなもの？)

↓Dockerfileと同じ階層に移動して、下記を実行
```shell
sudo docker build . -t {image-name}
```

③ ビルドしたイメージを使い、コンテナを起動する。  

例：コンテナのポート80番とローカルのポート80番を対応させて起動している。
```shell
sudo docker run -d -p 80:80 --name {container-name} {image-name}
```
Gitlab のアップデート　13.12.6→14.8.2 

インストール 作業メモ [22/04/01]

#### Apache & Subdirectry 運用設定です。
- Ubuntu 20.04.2 LTS
 - GitLab Community Edition 13.12.6 からのUpdate

### 結論：アップグレードパスに沿って、アップデートすれば問題無し

何も考えずに、以下のアップグレードのコマンドを実行するとエラーが発生します。
~~~
sudo apt update && sudo apt install gitlab-ce
~~~

エラーでアップデートに失敗しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/31b823f0-62d2-6801-899a-83efa2db508f.png)

#### ■アップグレードパスを確認
https://docs.gitlab.com/ee/update/index.html#upgrade-paths
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/01053e2b-fadb-e7c9-597a-b2727019ae41.png)


自分の場合は、13.12.6[現Ver] → 13.12.15 → 14.0.12 → 14.6.2 → 最新Ver　と計画
試しに、以下のバージョン指定でアップデートを試みます。
~~~
sudo apt update && sudo apt install gitlab-ce=13.12.15-ce.0
~~~

■バージョンアップに成功しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/3e327824-ae42-60bc-be95-54cf51c35166.png)

■引き続き、以下のバージョンアップを実行しました。
~~~
sudo apt update && sudo apt install gitlab-ce=14.0.12-ce.0
sudo apt update && sudo apt install gitlab-ce=14.6.2-ce.0
sudo apt update && sudo apt install gitlab-ce
~~~


■ヘルプから、バージョンの再確認
![2022-04-01_10h24_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166558/41c2cbcf-680e-f8a7-1a5a-bdeea1a80226.png)
Ruby on Rails 事始め

# 本記事の対象者

これまでのRuby関連の知識として、下記のRuby製のＯＳＳを触ったことがある。

* [Redmine](https://qiita.com/EasyCording/items/123be275d5c12e7c49f6)をSynology-NASで立ち上げることができた　→　[DSMのDockerを使用](https://qiita.com/EasyCording/items/b93c3e4fe5e44a8b17ac)
* GitlabをAWS-ECサーバーに立てることができた　→　UBUNTU上のDocker-Composeを使用

これからRubyを学ぶ上での、自分の目標設定

* RubyでWEBページが、サクッと作れること
* Redmineのプラグインが作れること
* Reactのような、最新のマテリアルデザインを取り入れたい
* React-Nativeで、スマホアプリも開発したい

# 反省点

* RORを始めるにあたって、これまで書籍等を読んできたが、そのたびに撤退させられている。
* GEMやBundleといった、Rubyの[環境整備](https://qiita.com/EasyCording/items/88ce1aae87ca794f5fe0)が複雑になる　→　一旦、エラーが出始めると、まったく太刀打ちできなくなる。
* [RORを学ぼう](https://qiita.com/EasyCording/items/dafd9d41a3575d146dbe)としても、命名に関する取り決めが先に来てしまう　→　他のプログラム言語の知識が、逆に障害になってしまう。

# 取り組み方

* 書籍丸ごとを理解するにあたり、チュートリアル含めて全体のボリューム感が多すぎる。
* アプリ開発を先行し 開発環境の設定に関する知識は、後で戻りながら知識をつけた方が良い。

# PC

* RUBYを始めると、最初に躓く部分であるが、基本的にはWindowsには不向きである。
* WINDOWS-PCを使っている前提で話をするが、真っ先にDockerを使うべきである。

# STEP1

* Docker Desktopを入れること　→　デスクトップPCのタスクバーで、クジラがちゃんと動いていることを確認する
* 開発環境には、ソースコード側とコンソール側の使い分けが必要　→　ソースコードはVSCODEにCOPILOTを入れて操作する。実行環境はDOCKER DESKTOPのコンソール（ＣＬＩ）を使うこと

# STEP2
* Dockerを動かすために必要な[四種の神器](https://zenn.dev/tmasuyama1114/articles/rails-docker-5x-how-to) →　これでいい、逆にこれ以外は不要である。
```shell.sh
Dockerfile
docker-compose.yml
Gemfile
Gemfile.lock
```
* Dockerの操作
以下は、windowsのコマンドラインからの操作
まず、DOCKERのコンテナがどういう状態かを確認する
```shell.sh
docker ps
docker inspect
```
* コンテナの立ち上げ
```shell.sh
docker-compose build
docker-compose up -d
```

* ここまでできたら、今度はDocker desktopでコンテナの状態を確認する
　→　コンテナ、イメージに関してはGUI上ですべて操作できる。
* CLIボタンで、コンテナにログインする→　ここからが開発のスタートである
　→　基本的にdocker-compose内で、VOLUMEを共有すれば、VSCODEのソースと、コンテナ上のソースは、同一の物を触っていることになる。

# STEP3
* ここからの手順は、RAILSの一般的な流れである。
* RAILSをニューして、データベースを作る。

```
rails　new　名前
rails　db:create
```
* データベースを別のコンテナにしている場合は、docker-compose内で宣言すること
* 既存のDBにつなぐ場合は、config/database.ymlを触ることになる

# まとめ

　上記の部分が、なかなか書籍を見ていても、理解できない部分である。
　つまり、RORはDOCKERの知識とセットで学ぶべき言語なのである。
grep, sedを使用して複数ファイル内の特定の文字列を一括置換

（自身の備忘録用です）

特定の文字列が含まれるファイルを一括検索し、任意の文字列に置換するコマンドです

+ -i：ファイルの内容を上書き

```
grep -r [検索文字列] ./ -l | xargs sed -i -e 's/[検索文字列]/[置換文字列]/g'
```
爆速でするNuxtとSkywayの連携

こんにちは！関西の大学に通うキンジョウです！もう春ですね。桜がとても楽しみです！！

## 今回は、NuxtとSkywayを連携をやっていきたいと思います。

### 成果物
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Skyway使って通信試してみた<br>意外と簡単で、おもしろい！ <a href="https://t.co/OBqYIl0Uhw">pic.twitter.com/OBqYIl0Uhw</a></p>&mdash; キンジョウ/金城翔太郎 (@kinjyo1130) <a href="https://twitter.com/kinjyo1130/status/1508830247969439749?ref_src=twsrc%5Etfw">March 29, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じで通信できることがゴールです！

## Nuxtのセットアップ

```
$ yarn create nuxt-app skyway-nuxt
$ cd skyway-nuxt
``` 

サーバーを起動する！
```
$ yarn dev
```

http://localhost:3000

にアクセスできたら大丈夫です！

## SkyWayのセットアップ

https://webrtc.ecl.ntt.com/

![スクリーンショット 2022-04-01 9.39.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/4f5d5d31-3c75-db34-5e64-dbdfd7d3a3a2.png)

Commuity Edition(無料版)で登録してください！
![スクリーンショット 2022-04-01 9.45.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763535/7b967d63-21e2-b6e2-fed3-675f35d4d70f.png)

:::note warn
注意
ここに登録してない場合は正常に動いてくれないので、忘れずに登録してください。
:::

できたら、次は[JavaScript SDK](https://webrtc.ecl.ntt.com/api-reference/javascript.html)を読み込んでいきます

```
$ yarn add skyway-js
```

```index.vue
import Peer from 'skyway-js';　//追加する
```

### script部分のコードです

```pages/index.vue
<script>
import Peer from 'skyway-js'
export default {
  data() {
    return {
      localStream: '',
      APIKey: '',// ここには自分のAPIキーを入れてください。
      peer: '',
      peerId: '',
      theirId:'',
      theirVideo;'',
      myVideo:''
    }
  },
  methods: {
    makeCall() {
      const mediaConnection = this.peer.call(this.theirId, this.localStream)
      this.setEventListener(mediaConnection)
    },
    setEventListener(mediaConnection) {
      mediaConnection.on('stream', (stream) => {
        const videoElm = this.theirVideo
        videoElm.srcObject = stream
        videoElm.play()
      })
    },
  },
  mounted() {
    this.peer = new Peer({
      key: this.APIKey,
      debug: 3,
    })
    navigator.mediaDevices
      .getUserMedia({ video: true, audio: true })
      .then((stream) => {
        const videoElm = this.myVideo
        videoElm.srcObject = stream
        videoElm.play()
        this.localStream = stream
      })
      .catch((error) => {
        console.error('mediaDevice.getUserMedia() error:', error)
      })
    this.peer.on('open', () => {
      this.peerId = this.peer.id
    })
    this.peer.on('call', (mediaConnection) => {
      mediaConnection.answer(this.localStream)
      this.setEventListener(mediaConnection)
    })
  },
}
</script>
```

### HTMLのコードです

```pages/index.vue
<template>
  <div>
    <video v-bind="myVideo" width="400px" autoplay muted playsinline></video>
    <p>{{ peerId }}</p>
    <input  v-bind="theirId" />
    <button @click="makeCall()">発信</button>
    <video v-bind="theirVideo" width="400px" autoplay muted playsinline></video>
  </div>
</template>

```

# 試し方

- 二つタブを開いて、両方に表示されるpeerIdを、表示されたpeerIdを表示されなかったタブにinputに入力する。
- 発信ボタンを押す

# 最後に
簡単にビデオ通信ができるので、おすすめです！！
ここまで読んでくださり、ありがとうございました！！
Elastic Cloud に API でデータを投入する

blog-apr0102 というエンジンを作成します。
![cloud_apr0100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8dcd120d-dfed-e20e-3c4d-27431c3859f8.png)

Credentials で private-key を調べます。
![cloud_apr0101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9793cdd0-5dd4-59f6-c00b-221130a3ba20.png)

```bash:curl_insert.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-***********"
NAME_ENGINE="blog-apr0102"
#
echo ${PRIVATE-KEY}
#
curl -X POST ${HOST}'/api/as/v1/engines/'${NAME_ENGINE}'/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer '${PRIVATE_KEY} \
  -d@all_data.json
```

```json:all_data.json
[
{
	"id": "t001",
	"name": "山本太郎",
	"title": "My Name Is Yamato",
	"content": "I love dog",
	"tags": ["red", "green", "blue"]
},
{
	"id": "t002",
	"name": "田中康夫",
	"title": "My Name Is Tanaka",
	"content": "I love cat",
	"tags": ["Earth", "Moon", "Mars"]
},
{
	"id": "t003",
	"name": "渡辺五郎",
	"title": "My Name Is Watanabe",
	"content": "I love fish",
	"tags": ["apple", "orange", "banana"]
}
]
```

実行結果
![cloud_apr0102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/dca8ad91-736f-6cad-e13f-c2da84dd04f5.png)

## データの読み込み ##

Httpie

```bash:http_read.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-******"
NAME_ENGINE="blog-apr0102"
#
http GET ${HOST}'/api/as/v1/engines/'$NAME_ENGINE'/documents/list' \
	'Authorization: Bearer '${PRIVATE_KEY} < query00.json
```

```json:query00.json
{
  "page": {
    "size": 5
}
}
```

Curl

```bash:curl_read.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-******"
NAME_ENGINE="blog-apr0102"
#
#
curl -X GET ${HOST}'/api/as/v1/engines/'$NAME_ENGINE'/documents/list' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer '${PRIVATE_KEY} \
-d '{
  "page": {
    "size": 5
  }
}'
```


## 参考 ##
Engines を API で取り扱う方法
参考ページ
[Engines API](https://www.elastic.co/guide/en/app-search/current/engines.html#engines)

Create

```bash:create_engine.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-********"
#
curl -X POST $HOST'/api/as/v1/engines' \
	-H 'Authorization: Bearer '$PRIVATE_KEY \
	-d '{"name": "blog-apr0102"}'
```

List

```bash:list_engines.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-*******"
#
http $HOST'/api/as/v1/engines' \
	'Authorization: Bearer '$PRIVATE_KEY
```

Delete

```bash:delete_engine.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-******"
NAME_ENGINE="blog-apr0102"
#
curl -XDELETE $HOST'/api/as/v1/engines/'$NAME_ENGINE \
	-H 'Authorization: Bearer '$PRIVATE_KEY
```

## 参考 ##
Python3 の例はこちら
[Python3: Elastic Cloud に API でデータを投入する](https://qiita.com/ekzemplaro/items/582e42f93aee9afdd85d)
XCharts2.0

作者は中国系


https://github.com/XCharts-Team/XCharts/tree/2.0


# CSV 

https://qiita.com/Kirikabu_ueda/items/23b4827abf5b8b6251bc

# XML

https://qiita.com/calmbooks/items/e45463bd93b1c018f743
Lima + Dockerでマウントしたディレクトリにnpm installできなかった

## やろうとしていたこと

Graviton2インスタンスのLambdaで利用するライブラリをLambda Layerに配置すべく、Lambda (Amazon Linux)のイメージを利用してLayer用のzipを作成。
実行環境はタイトルの通りLima + Docker。

### コンテナ上でやろうとしたこと

1. `workspace` をマウント
1. マウントしたディレクトリに `nodejs` ディレクトリを作成して、そこで `npm install`
1. `nodejs` ディレクトリを `zip`

```
├── Dockerfile
├── docker-compose.yml
└── workspace
    ├── lambda-layer.zip
    └── nodejs
        └── node_modules
```

## 起きたこと

`npm install` で権限エラー。 `(l)chown` が叩けない旨のメッセージが表示される。

実際、マウントしたディレクトリ以下では `chown` ができない。
一方、ファイル作成等はでき、書き込み権限やオーナーは問題ない。

## 原因

[chown/chmod on mounted directory: Permission denied #231](https://github.com/lima-vm/lima/issues/231)

## 回避策

### 別の場所でインストールして、 zipだけをマウントしたディレクトリに吐き出す

前述の通り権限・オーナーには問題がないので、必要なzipだけを吐き出す。

### グローバルインストール (`-g`) して、〃

グローバルインストールで権限等の問題が起きる場合は公式を参照。

https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
パスワードの日本語化

---
## はじめに

今日は何の日～♪
2022年04月01日です。

Webサイトのパスワードって日本語化できるんとちゃうん?と思ったんですよ。

Webブラウザを起動している時点で、OSは起動済みだし、IMEも起動済みだし、、、今どきはパスワードは覚えられないから、コピー&ペーストだし、そうなるとパスワードって日本語化できないかな。と思ったんですよ。

近い将来、

- パスワードには「英大文字」「英小文字」「数字」「記号」の3種類

とかではなくて、

- パスワードには「ひらがな」「カタカナ」「漢字第一水準」「漢字第二水準」...の3種類

を使ってください。・・・とかになるかもしれない。(嘘) ;-p

---
## 事前準備(パスワード)

メモ帳(notepad)を開いて、日本語のパスワードを用意する。

このパスワードを**コピー&ペースト**して、

1. パスワード変更してからの
2. ログアウトしてからの
3. ログイン

を試してみる。

今回は「こんにちは日本語」にした。

![pass.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/467c3901-773d-304f-bd96-afc09b5be797.jpeg)


---
## 事前準備(Webサイト側の対応確認)

パスワードを日本語にするという事は、Webサイト側にとっては想定外かもしれない。

そうなると、パスワードが壊れて(認証DBにはUTF-8でログイン画面はShift_JISで認証エラーが起きるとか)ログインできなくなるかもしれない。

- **パスワード・リマインダ機能を確認すること**

- パスワードリマインダでは、**新規パスワードが設定できるタイプ**であること

過去のパスワードを教えてくれるタイプでは**ダメ**。(パスワードは既知なのに日本語化したのでログインできなくなっているんだから、既存のパスワードを教えてもらうようなパスワード・リマインダ機能のWebサイトでパスワードの日本語化を試してはダメ)

---
## 実験結果(2022年03月～04月)

2022年03月にいくつかのWebサイトで試してみた。

---
### Amazon

できた。

---
### Twitter

できた。

---
### Facebook

できた。

---
### 楽天

できなかった。

コピー＆ペーストができないようにWebブラウザの制御をしているので、面倒なので、やめた。

![楽天.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/ea01c076-ee8b-10aa-f8a2-f52b86142803.jpeg)

HTTPリクエストを書き換えて、、、とかは面倒なので、やめた。

---
### PayPal

できなかった。

いわゆる半角文字しか受け付けないようで、いわゆる全角文字をコピー＆ペーストしたら、こんなエラーが出たので、やめた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/9a40683c-08d9-8be5-2ad0-95859cb0a881.png)

HTTPリクエストを書き換えて、、、とかは面倒なので、やめた。

---
### その他

あまり、マイナーなWebサイトだと、私がどんなマイナーなWebサイトに会員登録しているのかバレるのは嫌なので、この辺にしておく。

---
## 蛇足

OSが起動する前のBIOSパスワードとか、OSへのログイン画面へ使うパスワードとかは、日本語化しない方がいいと思いますよ。

---
## 以上