OmniAICreator/Qiita-1.07M huggingface dataset:
製造業の人に役立つかもしれない情報

## はじめに
筆者は現在メーカーで働いていますが、本格的にコードを書くようになったのは会社入ってからでした(学生時代もちょっとだけ経験したが、大体先輩のコピペ)。

機械学習が普及してきたことから、新しくメーカーに入社した人で上司に言われて~~脅されて~~コード書く必要に迫られた方もいるのでは、と思っています。

自分と同じ立場だった人に向けて、少しでも役立つことが出来たらと。

https://qiita.com/official-events/3f21c92121aa125807b4

## 対象
* メーカーに入社して、機械学習等の業務に触れることになった人
* プログラミング？IT？言葉は聞くけど何それ？だけど勉強する必要がある人


## まとめ
参考になりそうな記事をまとめてみました。Qiita以外の記事も入れています。

#### 製造業でITやプログラミングの知識が必要な理由
[製造業、工場勤務の方もプログラミングを学んだ方が良い！？ITエンジニアへの転職も](https://aoblog-miz.com/factory-workers-learn-programming/)
[製造業DXを推進する人材の条件は？](https://www.brainpad.co.jp/doors/news_trend/wp_on_manufacturing_industries_4/)
[製造業における2022年の3大AIトレンド](https://qiita.com/Dataiku/items/24a66032ca061ca08801)

#### 勉強方法・参考書
製造業に特化した勉強方法ではないですが、初めての人には参考になると思います。
[Udemyで営業事務が機械学習を学んでみた](https://qiita.com/hymhtm/items/81e0e8692748e7f91318)
[僕が本気でオススメするPythonと機械学習の良書12選](https://qiita.com/tani_AI_Academy/items/625915dc034a6993d521)
[エラーメッセージの読み方と対処, 検索や質問の原則](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)
[プログラミングの効果的な勉強法は？目的を決めて継続するのが鍵](https://and-engineer.com/articles/YZ4OoxEAACMAmxjm#heading3-14)

#### 統計関連
品質管理でも、統計の知識は重要だと感じました。学生の時に授業は受けていましたが、難しいなと思っていました(今も正直苦手…)
[23-1. 検定とは](https://bellcurve.jp/statistics/course/9309.html)
[統計的検定とは？具体例と種類について見ていこう！](https://toukei-lab.com/%E6%A4%9C%E5%AE%9A)
[マーケターなら押さえておきたい「統計検定の基礎」とは？](https://kotodori.jp/user-research/analytics/basics-of-statistical-tests/)
[「相関係数」を正しく理解しよう](https://analysis-navi.com/?p=1142)

#### 機械学習
[データ分析で頻出のPandas基本操作](https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a)
[何の知識もない初心者が機械学習をとりあえずやってみる](https://qiita.com/pon187/items/534285361498a078aaa4)
[機械学習の情報を手法を中心にざっくり整理](https://qiita.com/ishizakiiii/items/f6909696c616fd6294ca)
[アイリスデータセットで機械学習を簡単に体験する](https://www.gadget-alamode.tech/python-iris_dataset/)
[【第１回カリフォルニア住宅価格の予測】 前処理無しで精度を確認](https://zerofromlight.com/blogs/detail/65/)

#### 製造業からデータサイエンティストになった人の話
本格的に取り組もうと、転職するまでの領域に至った人もいます。製造業とのギャップも書いてあったりしてなるほど、と思って読んでいました。
[半導体生産技術者がデータ分析業界に飛び込んでみて感じたこと](https://qiita.com/banquet_kuma/items/7d44d0e777bcc5ac8b67)
[製造業R&Dからデータサイエンティストへの転職について](https://qiita.com/Spica09/items/38ca50672f10c09ee171)
[データサイエンティスト職に未経験が転職活動した結果](https://qiita.com/takuya66520126/items/e3b52e8786e5052c4a19)

## まとめ
少しでも上記の内容が役に立てば幸いです。
**勉強して無茶苦茶詳しくなったら、今度は自分に教えてほしい。**
自家製サーバー 〜オレオレ証明書を添えて

## 概要
何気なく使っている「サーバー」を自分(OS:mac)で組み立ててみる。尚、今回はJavaScriptで話を進めて、`server.js`ファイルに記述する。

### 使用モジュール
- Express
- fs
- log4js
- https

### 手を動かす
何事も自分で作ってみると理解が深まるもの。黙って考えてないで、詰まったら以下コマンドで逐一確認する。
```
node server.js
```

### ディレクトリ構成
```
| - server.js
| - privatekey.pem
| - cert.pem
```
## 実装の前に
### httpsって何？
node.jsでHTTPSサーバ(SSL)を作成するには、httpsモジュールを使用します。HTTPSサーバは、SSLにより、経路を暗号化し、サーバ-クライアント間の盗聴を防ぎます。また、サーバ証明書により、サーバの真正性を保証します。

### OpenSSLって何？
OpenSSLは「SSL（Secure Sockets Layer）」という暗号化通信のためのプログラムです。今回のhttpsサーバーにおける秘密鍵と証明書の生成を担っています。
```
brew install openssl
```
### OpenSSLで秘密鍵と証明書を発行
くれぐれも「オレオレ証明書」は本番環境では使用しないようにしましょう。
```
openssl genrsa -out privatekey.pem 2048

openssl req -batch -new -key privatekey.pem -out cert.pem \
-subj "/C=(Country Name)/ST=(State or Province Name)/L=(Locality Name)/O=(Organization Name)/OU=(Organizational Unit Name)/CN=(Common Name)"

openssl x509 -in cert.pem -out cert.pem -req \
-signkey privatekey.pem -days 73000 -sha256
```

## 作ってみる
```server.js
const express = require("express");
const fs      = require("fs");
var log4js    = require("log4js");
const app     = express();
const portNo  = 3030;

const server = require("https").createServer(
  {
    key: fs.readFileSync("./privatekey.pem"),
    cert: fs.readFileSync("./cert.pem"),
  },
  app
);

const logger = log4js.getLogger("server");

logger.level = "all";
server.listen(portNo, () => {
  logger.debug("起動しました", `https://localhost:${portNo}`);
});
```

`node server.js`で実行して上手くいきましたか？

## まとめ
`openssl`コマンドのオプションについては随時解説を入れていきます。自分でサーバーを立てることができるとなんだか嬉しいですね。何事も自分で作ってみることが大事だと思います。
.sshフォルダのアクセス権限が終わってたので無理やりgit cloneする

## 環境 
Windows10


# 原因
.sshのファルダの権限が，744になっていた．そのためSSHするときに以下のエラーが出た．
```
Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
```
Windowsだったため権限の変更が分からなかったため(ICACLSがどちゃくそ面倒そうだった)試行錯誤してSSHする．

# 解決手段
試しにSSHでオプションで秘密鍵を指定してログインしたところ成功した．
`ssh -i ~/.ssh/秘密鍵 user@y.y.y.y`

なのでgit cloneする時に秘密鍵を指定しました．指定する方法として2つある．

1. 永続的に指定する方法が`git config core.sshCommand`で指定する．

```
$ git config core.sshCommand="ssh -i ~/.ssh/id_rsa_example" clone (clone先) (保存する場所)  
```

1. 一時的に秘密鍵を指定する方法が`git -c core.sshCommand`で指定する．


```
$ git -c core.sshCommand="ssh -i ~/.ssh/id_rsa_example" clone (clone先) (保存する場所)  
```
Class "App\Http\Controllers\DB" not foundの対処法

# エラーの背景
このようなタイプのエラーは```Facadeで指定できていない```のが原因です。



```XXXController.php
//省略
use Illuminate\Support\Facades\DB; //これを追加

class TaskController extends Controller
{
    public function index()
    {
     
    $tasks = DB::table('tasks')->get(); //DBは省略形
    return view('task.index', ['tasks' => $tasks]);    
    }
```
***use Illuminate\Support\Facades\DB;が必要***です。
***DBは省略形なので上のFacadesが必要***です。
GoogleスプレッドシートTips

# 条件付き書式

## 背景色変更

### 任意のセルのOR条件判定

例えば `[キーワード]：Ａ` か `[キーワード]：A` にマッチするセルの背景を変えたい場合以下で検索（セルの書式設定の条件...をカスタム数式）

```
=REGEXMATCH(INDIRECT(ADDRESS(ROW(),COLUMN())),"\[キーワード\]：(?:Ａ|A)")
```

### チェックボックスでチェックのついた行だけ背景色変える

例えば、B列のチェックボックスのチェックが付いていた場合、該当行の背景色を変える（セルの書式設定の条件...をカスタム数式）
2行目から反映。

```
=$B2=TRUE
```

### 特定のセルについて行の背景を変える

例えば、E列の各行について 最高 だったら背景色を変える場合（セルの書式設定の条件...をカスタム数式）
2行目から反映。

```
=COUNTIF($E2,"最高")>0
```

### 特定のセルについてある文字列を含む場合行の背景を変える

例えば、I列の各行について文字列の一部に 最高 を含んでいたら背景色を変える場合（セルの書式設定の条件...をカスタム数式）


```
=FIND("最高",$I2)
```

# 自動計算

## 連番

### 特定の列空白じゃなかった場合に連番を自動計算

各行のB列の値が空白なら空白のまま、そうでないなら各行のA列のを見て何かしてる...
2行目から反映。

```
=ARRAYFORMULA(IF(ISBLANK(B2:B),"",ROW(A2:A)-(ROW()-1)))
```

## ハイパーリンク

ハイパーリンクを数式で設定

```
=HYPERLINK("https://{fqdn}/path","表示文字列")
```
EC2の起動停止だけを許可したい

# はじめに
特定のユーザーにマネジメントコンソールからEC2の起動停止だけを許可したいというユースケースがあって専用のポリシーを作成しました。「起動」はインスタンスの構築の意味ではなく、サーバの電源オンのほうです。

# IAMポリシーの作成

作成したIAMポリシーがこちらです。実際にはIAMロールにアタッチして利用しています。
```json:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:ap-northeast-1:111111111111:instance/i-AAAAAAAAAA"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "cloudwatch:*",
                "compute-optimizer:GetEC2InstanceRecommendations",
                "compute-optimizer:GetEnrollmentStatus"
            ],
            "Resource": "*"
        }
    ]
}
```

## このポリシーで実現したこと
* 対象のインスタンスi-AAAAAAAAAAを起動停止再起動できるようにするため、下記の権限を付与する。
    * ec2:RebootInstances
    * ec2:StartInstances
    * ec2:StopInstances
* 上記だけでも機能は満たせそうなものですが、マネジメントコンソールの画面にエラーがたくさん出てしまうのを防止するために下記の権限を付けました。このままだと、他のEC2も閲覧出来てしまいますので、必要に応じて対象リソースの絞り込みを入れます。
    * ec2:Describe*
    * cloudwatch:*
    * compute-optimizer:GetEC2InstanceRecommendations
    * compute-optimizer:GetEnrollmentStatus

# おわりに
今後もバリエーションが増えそうなので、再利用のためにまとめました。これにより非IT部門の担当者が好きなタイミングでサーバを立ち上げて利用できるようになりました。
DB120リトライ

AtherosのAR9342なターゲットをリトライしてみました。

いろいろ考えて、こうやってオンボードでflashromで書き込みできるようにしました。

![写真（2022-04-19 16.34）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/3b8dd571-96f0-bb4b-ed40-84c427c99e4a.jpeg)

R236の0Ωを外すとSPI Flashの電源が切り離せます。

u-boot_modでシリアルコンソールが115200で使えない問題はPLL周りかとおもったのですが、正しく設定してもだめだったので強制的に9600にして使えるようにしました。

u-boot_modではPLLの設定をFlashに保存しているのですが、リカバリーモードが悪さをして正しく設定できてませんでした。

残りはネットワークですが、u-boot_modにはQCA8337なコードは入っていませんでした。

Ethernetは以下のようになっているようです。

![スクリーンショット 2022-04-21 7.11.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/809d1380-b57c-3ca0-adf9-ca0f44747212.png)

![スクリーンショット 2022-04-21 7.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/51d376ab-e15f-f401-91ea-a7f4cc1bb9f5.png)

GMAC0がRGMIIでQCA8337のPort 0に接続されているようです。

QCA8337はAtheros時代にAR8337として出していいたものを買収後に型番を変えて出したものです。おそらくAR8337が0x1301でQCA8337が0x1302ではないかと思われます。AR8337はAR8327の後継だったと思われます。

いろいろやってみたのですが、u-boot_modでネットワークが使えるようにならなかったので、発想を変えてFreeBSDで試してみることにしました。

ZRouterのビルド設定は以前作ってあったので、ビルドしたものをu-bootと引っ付けてflashromで焼きます。

atherosのSOCなのでhintsを本家のsys/mips/confを参考にZRouterのhintsを調整してみたところ、デバイスは認識されるようになりました。

http://dmesgd.nycbug.org/index.cgi?do=view&id=6530

まだネットワークが使えなかったのですが、RT3883+AR8327のパターンと同じRGMIIの設定をしたところpingが通りました。

u-bootが使えなくてもFreeBSD上のリモートアップグレード(reupgrade)が使えるのでなんとかなりそうです。

使ってない内蔵のSwitchとifを外しました。

http://dmesgd.nycbug.org/index.cgi?do=view&id=6543

AR9342もAR8337は買収直前に作られたチップでなんとなく、混乱してるふうがあります。

RalinkとAtherosのあった時代はよかったです。

LEDは不思議な制御でした。

|GPIO 3|GPIO 16|GPIO 17|D3|D1|
|:--|:--|:--|:--|:--|
|IN|0|1|赤|緑|
|1|0|1|赤|緑|
|0|IN|IN|赤|赤|
|1|IN|IN|赤|消灯|
|IN|IN|IN|赤|消灯|
|1|0|IN|赤|緑|
|1|0|1|赤|緑|
Arduinoでウォッチドッグタイマと外部入力割込みどちらも使えるsleepを作成した

ATtiny84で現在開発をしているのですが、
意外とsleepの機能でウォッチドッグタイマと外部入力割込みが
どちらも使えるものがなかったので以下のそのやり方を記載します。

ちなみにこのプログラムは、16秒間待機後に自動で起動する　or
プッシュボタン（Pin5）を押せば起動
となります。

起動後はLEDを500ms点灯させ、またsleepに入ります。

ちなみにATtiny84のピンアサインは以下のURLを参考にして下さい。
https://create.arduino.cc/projecthub/Arnov_Sharma_makes/programming-attiny84-088482

## 電子回路
![スクリーンショット 2022-04-22 17.27.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/2fa0e3f2-fe7b-b981-8551-f6dc24b876a1.png)



## プログラム
```c
#include <avr/sleep.h>  // スリープライブラリ
#include <avr/wdt.h>    // ウォッチドッグタイマー ライブラリ

volatile int sleep_flg=0; //スリープ状態フラグ
volatile int counter;     //スリープ起動回数

const int LED_PIN   = 7;
const int PUSH_PIN  = 8;

int count_max=2;        //8sec * 2 = 16 sec 

//watch dog timer setup
void wdt_set(){
  wdt_reset();  //ウォッチドッグカウントリセット
  cli();        //割込み禁止
  MCUSR = 0;    //MCUステータスの初期化
  WDTCSR |= 0b00011000; //ウォッチドッグの設定変更開始フラグ
  WDTCSR =  0b01000000 | 0b100001;//ウォッチドッグ・割込み許可  | 8秒に設定
  sei();        //割込み許可
}

//watch dog timer unset
void wdt_unset(){
  wdt_reset();
  cli();
  MCUSR = 0;  
  WDTCSR |= 0b00011000;
  WDTCSR =  0b00000000; //status clear
  sei();
}

//外部入力による割込み
void wakeUp(){
  sleep_flg=0;          //スリープフラグ　0=中断　1=継続
}

//ウォッチドッグによる割り込み
ISR(WDT_vect){
  counter ++;
  if(counter >= count_max){
    sleep_flg=0;  //スリープフラグ　0=中断　1=継続
    counter = 0;  //カウント数リセット
  }
}

//status reset
void init_status(){
  counter=0;
}

//sleep arduino
void sleep(){
  wdt_set();            //ウォッチドッグの初期設定
  ADCSRA &= 0b01111111; //AD変換無効化
  sleep_flg=1;          //スリープフラグ　0=中断　1=継続
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set sleep mode
  attachInterrupt(0,wakeUp, LOW); //Lowになった時にwakeUp関数起動
  while(sleep_flg){
    noInterrupts();   //cli();
    sleep_enable();   //スリープを有効化
    interrupts();     //seii();
    sleep_cpu();      //cpu sleep
    sleep_disable();
  }
  ADCSRA |= 0b10000000;    //AD変換有効化
  wdt_unset(); //watch dog timer unset
  detachInterrupt(0); //unset level interrupt
}

void setup(){
  //ピン初期設定
  pinMode(LED_PIN,OUTPUT);
  pinMode(PUSH_PIN,INPUT_PULLUP);
}

void loop(){
  init_status();
  sleep();//スリープ開始
  //LED点灯
  digitalWrite(LED_PIN, HIGH);
  delay(500); 
  //LED消灯
  digitalWrite(LED_PIN, LOW);
}
```
SpriteAtlasに含まれるSpriteを全部取得して表示する

## 環境
Unity 2020.3.X

## コード

実際に書いたコードはこんなんじゃないですが、大体こんな感じのものを書いたよっていうやつ。
ベタ書きなので、誤字とかあるかもしれないですし動作確認はしてません。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;

public class SpriteAtlasChecker : MonoBehaviour 
{
    [SerializeField] private Image m_Image;
    [SerializeField] private SpriteAtlas m_Atlas;

    public Start()
    {
        StartCoroutine(DisplaySprites());
    }

    private IEnumerator DisplaySprites()
    {
        var sprites = new Sprite[m_Atlas.spriteCount];
        m_Atlas.GetSprites(sprites);
        foreach(var sprite in sprites)
        {
            m_Image.sprite = sprite;
            yield return new WaitForSeconds(3);
        }
    }
}


```


## 何故必要だったか
Unityのアップグレードでアセットバンドルのチェックしようとなったので、確認ツールを作る過程でこういうのが必要になりました。
だいたいのJS処理系で console.log の this が不要になっていた件

## 最近、こういうコードを見ておったまげた

```js
incarnatePromise()
  .then(console.log)
  .catch(console.error);

ary.forEach(console.log);
```

何におったまげたかというと、 「`console.log` をそのまま関数として扱ってる」　という点ですね。端的に書くと以下のようになります。

```js
// （普通）メソッドとして扱う (this = console)
console.log("Hello")

// （おったまげ）関数として扱う (this = undefined)
const {log} = console
log("Hello")

// ↑は要するにこれ
(console.log)("Hello")
```

これ、以前だったら動く保証はありませんでした。実際になにかのブラウザでエラーになってました。

`console.log` を関数として扱いたいなら、厳密にはこういうふうにする必要があるはずです。

```js
// this を console に固定
const log = console.log.bind(console)
```

## console.log の this が不要な処理系

じゃあ今、どのブラウザが this が `undefined` な `console.log` に対応しているかというと、手元にあるものを調べた感じ、全部いけるようです。

```js
// テストコード
(console.log)("Hello") // => "Hello"
```

- Google Chrome (Edge Chromium) 100.0.x: OK
- Firefox 99.0.1: OK
- Safari 15.4: OK
- IE 11: OK

Node.js も見てみましょう。

- Node.js 4.0.0: OK
- Node.js 5.3.0: OK
- Node.js 9.11.0: OK
- Node.js 17.9.0: OK

Node.js には内部的に [Consoleクラス](https://github.com/nodejs/node/blob/master/lib/internal/console/constructor.js) があり、それ自体は this は必須なんですが、 [`global.console` については　this が不要になるようにしている](https://github.com/nodejs/node/blob/master/lib/internal/console/global.js) ようです。

## そもそも私の思い違いか？

私の思い違いかと思ってネットを検索してみたところ StackOverflow で似たような質問があったので思い違いでは無いようです。

- [console.log() called on object other than console](https://stackoverflow.com/questions/39499845/console-log-called-on-object-other-than-console)
- [Uncaught TypeError: Illegal invocation in JavaScript](https://stackoverflow.com/questions/8904782/uncaught-typeerror-illegal-invocation-in-javascript)

昔のGoogle Chromeではどうやら　`(console.log)("Hello")` は動かなかったようですね。

今のブラウザ環境を前提にするのであれば、 `console.log` をそのまま関数として扱っても実害は少なさそうです。
laravel8 vue3 を conoha から awslightsail に移転

# vue3 を conoha から awslightsail に移転してみた

特に移転する必要はなかったが、万が一のために移転の技術だけは身につけておかないとと思いやってみた。

2時間かからなかったな。
conoha 側はそのまま awslightsail 側にも同じのを作っちゃえば
データはmysql,redisに格納されるわけだから問題なく移転できる。


# (conoha) 移転前のサービス構築環境

・vue3
・laravel8
・redis (外部接続)
・mysql（接続元IP制限）
・gcp (鍵ファイル.json)

上記のような構成のサービスを conoha から lightsailに移動する。


# lightsail側の設定

・php8
・nginx

はインスコ済み
node.js と vue、laravelはインスコも設定は一切していない。


# ファイルを圧縮し、SCP接続で移動

conoha → lightsail
https://qiita.com/ma7ma7pipipi/items/1f1f75f1a4770d6c44c0

この際、permission dennied が出たので、
lightsail側で tmp フォルダを作って 

```
chmod 777 tmp
```



(conoha) ファイルを圧縮して送る
```
tar cvzfp twikon.club.tar.gz twikon.club
scp -i id_rsa -pr /var/www/html/twikon.club.tar.gz hideki@xx.xx.xx4.2xx:/home/hideki/tmp
```

(lightsail)tmpフォルダからメインフォルダに移動し、解凍（パーミッションそのままで）
```
mv tmp/twikon.club.tar.gz /var/www/html/
tar xvzfp twikon.club.tar.gz
```

これで解凍完了。

awslightsail側のnginxの設定をconohaと同様の設定に変更し、
一応見れるかを確認。


すると以下のエラーが

・Redisエラー

redisが無いよ

```
sudo yum install php81-php-redis
```

`解決`


・mysql接続エラー
接続元IP制限をしているので、接続許可をしてやる。
https://qiita.com/ma7ma7pipipi/items/3757fef14fd6de2b94b5


lightsail側
あれ？mysql -v が動かないぞ。
ということで、一応使えるようにインスコ。

```


# インストール
sudo yum install -y mariadb-server

# 起動
sudo systemctl start mariadb

# 有効化
sudo systemctl enable mariadb
sudo systemctl is-enabled mariadb

```




# ハマった点

あれ？lightsailから外部へのDBには接続できないのか？

（conohaへの自作DBへの接続もできた）

理由 mysqlサーバー側で許可ユーザー名を間違えていた。
エラー文

```
Access denied for user ec2-xx-xx-xxx-xxx.ap-northeast-x.compute.amazonaws.com'
```
CLI から VSCode を開いて SSH 接続先のファイルを直接開きたい！

Visual Studio Code にはリモートのファイルを直接編集できるプラグイン `Remote Development` があります。

今回はコマンドラインを使用してリモートのファイルを直接 VS Code で開く方法をご紹介します。

## 前提

- ローカル端末からリモート端末へ SSH 接続できる
- Remote Development プラグインを導入している

プラグインの導入方法については、こちらの記事が参考になるかと思います。

https://webbibouroku.com/Blog/Article/vscode-remote-ssh (日本語)
https://code.visualstudio.com/docs/remote/ssh (公式サイト・英語)

## 方法

コマンドプロンプトでの方法をご紹介します。

### Visual Studio Code に PATH が通っていることを確認

コマンドプロンプトを開き、次のコマンドを実行します。

```cmd
code --version
```

以下のようにバージョン情報が出てくれば PATH は通っています。

```text
1.66.2
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x64
```

### 接続してみる

リモートのサーバへ接続してみましょう。

```cmd
code --remote ssh-remote+[SSH での接続文字列] [開きたいパス]
```

例えば、普段 SSH コマンドで `ssh someuser@192.168.1.1` と入力し `/var/www/html` を参照する場合は次のようなコマンドとなります。

```cmd
code --remote ssh-remote+someuser@192.168.1.1 /var/www/html
```

`.ssh/config` を設定して `ssh my-server` で接続している場合は、次のようなコマンドとなります。

```cmd
code --remote ssh-remote+my-server /var/www/html
```

SSH 鍵を使用して接続している場合は `.ssh/config` を記載したうえで、上記のコマンドでアクセスしてください。

他にこのような書き方もできるようです。

```cmd
code --folder-uri vscode-remote://ssh-remote+my-server/var/www/html
```

参考記事

https://github.com/microsoft/vscode-remote-release/issues/585

### 各種設定

接続に成功すると Visual Studio Code が開き、プラットフォームの設定画面が出てきますので、リモート端末のプラットフォームを指定します。
リモート端末が Linux で動いている場合は Linux を選択してください。

あとはディレクトリの信頼設定などをして完了です。

実際にファイルを編集して保存すると、現在ログインしているユーザでファイル書き込みがされます。
保存の際にエラーが発生する場合は、そのファイルに書き込み権限があるかどうか確認してください。

### Git Bash for Windows を使用している場合

コマンドの先頭に `MSYS_NO_PATHCONV=1` を付けてください。
私の環境では、パス先頭のスラッシュを重ねる方法がうまくいきませんでした。

参考記事

https://qiita.com/sixpetals/items/a0784fa3933956463609#%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%81%A7%E5%A7%8B%E3%81%BE%E3%82%8B%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%8C%E5%8B%9D%E6%89%8B%E3%81%ABwindows%E3%81%AE%E3%83%91%E3%82%B9%E3%81%A8%E3%81%97%E3%81%A6%E8%AA%AD%E3%81%BE%E3%82%8C%E3%82%8B%E5%95%8F%E9%A1%8C

### 筆者の使い方

筆者は Git Bash を使用していますが、いつも接続するサーバやディレクトリはエイリアスの形で登録すると便利です。

ホームディレクトリの `.bashrc` にこんな感じで書いています。エイリアスはダミーです。

```sh
# VSCode remote development
function coderemote() {
    SSH_CONFIG_NAME=$1
    REMOTE_PATH=$2
    MSYS_NO_PATHCONV=1 code --remote ssh-remote+${SSH_CONFIG_NAME} ${REMOTE_PATH}
}
alias coderemote--server1='coderemote server1 /path/to/dir'
alias coderemote--server2='coderemote server2 /path/to/dir'
```

---

Visual Studio Code をコマンドで起動して楽するの、おすすめです！
みなさんもやりましょう(●'◡'●)
Jakarta EE(Java EE)とSEとは、そもそも何か？ 違いは？

皆さま、

金曜日の夕方ですね。
Java SE Subscriptionに含まれるGraalVMの機能の事ばかり書いておりますが、Javaの事なら、何でもご相談ください。（SEライセンスの事とかでも、お気軽にお問合せください。）

昨夜、Jakarta EEについて、ご照会を受けました。
「そもそも、Jakarta　EEとJava SEとの違いは何なのか？」　 とのご照会でした。
ありがとうございます。

Jakarta EE（旧名、Java　EE）とJava　SEの違いは下記に、よく纏まっていると思います。
（Java EEからJakartaに名前が変わった歴史も、下記サイトに詳しいです。）
https://eh-career.com/engineerhub/entry/2020/07/07/103000#Java%E3%81%AE%E6%A8%99%E6%BA%96%E4%BB%95%E6%A7%98%E3%81%A8Java-SE

>・Java SE
Javaの最も基本となる言語機能とAPI、Java VMなどを含んだプラットフォーム。Java Platform Standard Editionの略称
・Jakarta EE（Java EE）
Java SEに対して、大規模なサーバサイド・アプリケーションを開発する機能を付け加えたエンタープライズ分野向けのプラットフォーム。EEはEnterprise Editionの略

で、ここからが、重要だと思います。
ポイントは下記だと思っています。（結構、多くの方が、誤解していたりします。）

・ Jakarta EEも、Java SEも仕様です。（Java EEは、SEの拡張仕様です。）

・ Jakarta EEも、Java SEも、どちらもOSSです。

・ Oracle JDKは、Java SEの仕様を元に、Oracleが開発＆販売する有料版です。

・ 一方で、Java SEの仕様に基づいた、Open JDKと言う無料版もあります。

・　Jakarta EEも仕様ですが、Jakarta EE仕様に基づき開発＆販売されている有償版としては、OracleのWebLogicやIBMのWebSpere等があります。

・ 勿論、公開されているJava EEのソースをダウンロードして、自己開発すれば、EE仕様準拠の無償版として利用可能です。
【React】プログラマー適性チェックをリリースしました。【個人開発】

## 背景

このたび、個人ブログのWordpressサイト(https://hinoshin-blog.com/)のサブディレクトリにReactアプリを実装しました。

サブディレクトリにサービスを置いて、万が一にもバズるとSEO的に莫大な効果が得られます。

なので、需要はあるのかなと思い本記事を執筆しました。

とは言っても、当たり前のことしかやってないので、多くの人は「そんなの知ってるよ。。」となるかもです。

そんな方は、僕が今回リリースしたプログラマー適性チェックを一度やってからブラウザバックしてくてください。

プログラマー適性チェック
https://hinoshin-blog.com/programmer-aptitude-check/


## Reactアプリの概要

今回作ったアプリは、めちゃくちゃ簡単な機能しかないです。

機能自体は30分もあれば作れる内容です。

具体的には、プログラマーの適性を診断するアプリになります。

目的は被リンクを獲得することなので、最低限の機能しかないです。

「興味があるからやってみたい！」という方は、このリンクから飛べます。

プログラマー適性チェック
https://hinoshin-blog.com/programmer-aptitude-check/

## 実装方法

実装方法としては、めちゃくちゃ簡単です。

具体的な手順は次の通りです。

1. create-react-appで雛形を作成
2. 普通にアプリを作る
3. buildする
4. Buildフォルダの名前を使いたいURL名にする(今回の場合は、"programmer-aptitude-check")
5. FTPを使ってpublic_html配下に置く
以上

ハマりどころとしては、packge.jsonに以下の記述を追加しないとパスが通らないので注意。

```"homepage": “./“```

## 最低限のSEO対策

今回は"プログラマー適性チェック"のキーワードを狙いました。

その際に行った最低限のSEO対策は次の通りです。

1. タイトル,h1,h2タグにキーワードを含める
2. meta descriptionにキーワードを含める
3. メタキーワードを設定する
4. OGPを設定する

## おわりに

ぜひ、みなさまのお力でこのアプリを広めていただきたいです。

一度診断して、それをSNSでシェアするだけでOKです。

というか、あなたも自分がどのくらいプログラマーとしての適性があるか知りたいですよね？

最短1分で終わりますので、お願いします。

というのは半分冗談ですので、興味のある方だけどうぞ。

プログラマー適性チェック
https://hinoshin-blog.com/programmer-aptitude-check/

おわり
sass(scss)に初見殺しされた話

# ことの始まり
progateでsassを習ったので早速使って見ようとした
しかし､表示されるページに変化がない!

## 自分の環境
* win10
* VSCode
 

## 原因
**sass(scss)の仕様を詳しくしらなかった**
sass(scss)はコンパイルする必要がある

## 対処法
1: vscodeの場合は以下の拡張機能をダウンロードする
* Live Sass Compiler
![スクリーンショット (2613).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421721/97d1a49c-eb84-716c-6bb5-6011b7a3f306.png)

2: `html`ファイルの`<head>`の部分に以下の2行を追加
```html:
<link rel='stylesheet' href='https://unpkg.com/ress/dist/ress.min.css'>
<link rel='stylesheet' href='styleSheetのパス'>
```
`<link rel='stylesheet' href='https://unpkg.com/ress/dist/ress.min.css'>`
の部分はブラウザごとにスタイルが崩れるのを防ぐために必要らしい

3: `.sass`もしくは`.scss`のファイルをいじる
4: vsCodeの`watch sass`をクリック
![スクリーンショット (2615).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421721/02f40a3c-8100-7e90-2204-6146ccde567e.png)

参考
--
https://miya-system-works.com/blog/detail/vscode-sass-compiler/

https://qiita.com/Y_ASAMOTO/items/d5f33ecf5bfbb7f028a5
TypeScriptのジェネリクスまとめ

# ジェネリクスとは
型を引数として受け取ることができる。同じ処理を違う型で実行する際に便利。
下記の記事が非常にわかりやすい。

https://qiita.com/k-penguin-sato/items/9baa959e8919157afcd4

```ts
function copy<T>(value: T): T {
    let user: T;
    return value;
}
console.log(copy<string>('hello').toUpperCase);
console.log(copy<number>(6).valueOf);
```
copy()の引数や戻り値をstringかnumberか指定して実行することができる。

下のようにオブジェクトを引数として取る場合、ジェネリクスを省略してもnameプロパティを使用することができる。
name: stringのオブジェクトだと型推論してくれる。
```ts
// 厳密にはこう
console.log(copy<{name: string}>({name: 'Quill'}).name);
// こっちでもOK
console.log(copy({name: 'Quill'}).name);
```

## 型パラメータに制約をつける
より厳密に制約を設ける場合はextendsを使用する。
```ts
function copy<T extends {name: string}>(value: T): T {
    let user: T;
    return value;
}
console.log(copy({name: 'Quill'}).name);
```

## keyof演算子
keyof演算子を使うことでオブジェクトプロパティのキーのユニオン型を作ることができる
```ts
type K = keyof { name: string; age: number }
```
```ts
type K = "name" | "age"
```

```ts
function copy<T extends {name: string}, U extends keyof T>(value: T, key: U): T {
    value[key];
    return value;
}
console.log(copy({ name: 'Quill', age: 38 }, 'name'));
```
U extends keyof Tは「オブジェクトTのキー」をUとして定義している

## クラスへジェネリクスを使用する
```ts
class LightDatabase<T extends string | number | boolean> {
    private data: T[] = [];
    get() {
        return this.data;
    }
}
const stringLightDatabase = new LightDatabase<string>();
stringLightDatabase.get();
```

## インターフェースにジェネリクスを使用する
```ts
interface TmpDatabase<T> {
    id: number;
    data: T[];
}
const TmpDatabase: TmpDatabase<number> = {
    id: 3,
    data: [32]
}
```

## Utility型
```ts
interface Todo {
    title: string;
    text: string;
}
type Todoable = Partial<Todo>
type ReadTodo = Readonly<Todo>
```
```ts:型
type Todoable = {
    title?: string | undefined;
    text?: string | undefined;
}
type ReadTodo = {
    readonly title: string;
    readonly text: string;
}
```
配列の型を定義する際はジェネリック型のArrayを使うことができる。
Arrayなどのジェネリック型はTypeScriptに内蔵されている。
```ts
const vegetables: Array<string> = ['Tomato', 'Broccoli'];
```

## 型パラメータにデフォルト値を設定する
```ts
interface ResponseData<T extends { message: string } = any> {
    data: T;
    status: number;
}
let tmp2: ResponseData;
```

## Mapped Types
inを使うことでfor文で型を扱える。
ハイフン-をつけるとVegetablesインターフェースでtomatoに指定していたreadonlyをMappedTypesでは無効化することができる。
```ts
interface Vegetables {
    readonly tomato: string;
    pumplin?: string;
}
let tmp3: keyof Vegetables;
type MappedTypes = {
    -readonly [P in keyof Vegetables]?: string
}
```

## Conditional Types
三項演算子のようなものを使用することで型のif文を定義することができる。
```ts
type ConditionalTypes = 'tomato' extends string ? number : boolean;
let aa: ConditionalTypes; // number型

type ConditionalTypes2 = string extends 'tomato' ? number : boolean;
let bb: ConditionalTypes2; // boolean型
```
【Git】pushしたときに「The current branch hogehoge has no upstream branch」と怒られた

# はじめに

プログラミング初学者です．Gitでpushしようとしたときに起きたエラーとその解決法を共有します．



# 環境

- Git 2.19.0（2022/4/22現在，2.36.0が最新だそうなのでかなり古いですね…）

```sh:ターミナル
$ git --version
git version 2.19.0
```



# 発生したエラー

```sh:ターミナル
# 現在のブランチの確認
$ git branch
* hogehoge
  main

# pushしようとするとfatal（致命的！）だと怒られました
$ git push
fatal: The current branch hogehoge has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin hogehoge


```

`hogehoge`ブランチには上流ブランチが設定されてないよと言っています．上流ブランチについては参考文献をご参照ください．



# 解決方法

Gitの提案通り`--set-upstream`オプションを付けると上流ブランチの設定をしつつpushすることができます．

```sh:ターミナル
git push --set-upstream origin hogehoge
```

さらに`--set-upstream`と`-u`は同じ意味です（私はハイフンの位置や数を覚えられないので`-u`を使っています）．

```sh:ターミナル
git push -u origin hogehoge
```



上流ブランチの設定は初回のみ必要なので，次回からは`git push`のみでpushすることができます．

また，push時以外に上流ブランチを設定することも可能ですが（参考文献をご参照のこと），pushのときについでに設定する方法が一番楽だと思います．



# ちなみに

各ブランチの上流ブランチを確認するには`git branch`に対し`-vv`オプションを用います．

```sh:ターミナル
$ git branch -vv
* hogehoge 28e9416 Initial commit
  main     28e9416 [origin/main] Initial commit
```
`main`には`[origin/main]`という上流ブランチが設定されていて，`hogehoge`には上流ブランチが設定されていないとき，上のような表示になります．



# 参考文献

- [VSCodeのGitでpushする時の「The current branch 'master' has no upstream branch...」メッセージの解決策](https://qiita.com/kat_log/items/450ce1f740d4646c8870)
- [上流ブランチがなくてエラーになった時の対応方法](https://qiita.com/ponsuke0531/items/410735b544795506fdc5)
- [Git用語：上流ブランチとは？](https://www-creators.com/archives/4931)
- [git branch コマンド](https://qiita.com/chihiro/items/e178e45a7fd5a2fb4599)
DockerのCentOS7コンテナにMySQLをインストールできなかった

## 概要
DockerでCentOS7のコンテナを作成。
コンテナ内でMySQLをインストール・・・したいけどできん！？

Dockerfileにインストールのコマンドを書いたけどインストールされていないようだったので、コンテナ内のシェルでインストールコマンドを実行することにした。

しかし、そこに現れたのは・・・

エラーでござんす。

## エラー内容
```
# yum -y install mysql-community-server
（略）
The GPG keys listed for the "MySQL 5.7 Community Server" repository are already installed but they are not correct for this package.
Check that the correct key URLs are configured for this repository.


 Failing package is: mysql-community-libs-5.7.37-1.el7.x86_64
 GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
```

この記事に感謝！
https://blog.katsubemakito.net/mysql/mysql-update-error-gpg

GPGキーなるものが原因らしい。
### GPGキーの有効期限切れ
>RPMやyumではパッケージが改ざんされているか検証するためにGPGキーを利用していることがあるのですが、このGPGキーには有効期限が設定されている関係で一定期間が経つと検証が行えなくなりインストールが停止してしまいます。パッケージを作成する際にGPGキーを別の物に変更した場合も同様の現象になります。

## 解決策
1. 新しいGPGキーをインストール
1. MySQLをインストール
```sh:新しいGPGキーをインストール 
# 実行後何も表示されないが、インストールされてるみたい
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

# 改めてMySQLをインストール
yum -y install mysql-community-server
（略）
Completed!

# インストールできたかの確認
sh-4.2# mysql --version
mysql  Ver 14.14 Distrib 5.7.37, for Linux (x86_64) using  EditLine wrapper
sh-4.2# mysqld --version
mysqld  Ver 5.7.37 for Linux on x86_64 (MySQL Community Server (GPL))
```

インストールできたぜ！！

## 環境
### ディレクトリ構成
以下のような構成で作成しました。

```
.
├── Dockerfile
└── hello.html
```
### Dockerfile
```dockerfile
FROM centos:centos7
# システムのパッケージを更新する
RUN yum update -y && \
    yum install -y epel-release && \
    yum upgrade -y && \
    yum install -y nginx

RUN yum remove mariadb-libs && \
    rm -rf /var/lib/mysql/

RUN yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm && \
    yum -y install mysql-community-server

ADD hello.html /usr/share/nginx/html/

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

RUNを分けているのは、ビルド時にどこのスクリプトで落ちるかをわかりやすくするために。
【Python】csv.DictReaderで数値（int型のデータ）を読み込む

# はじめに

プログラミング初学者です．CSVファイルをPythonのcsv.DictReaderで読み込む際に起きたエラーとその解決法を共有します．



# 環境

- Python 3.9.4

```sh:ターミナル
$ python3 --version
Python 3.9.4
```



# エラー発生時のコード

- 読み込み対象のファイル

```csv:food_calories.csv
food,calorie
ramen,443
coffee,7
cheesecake,281
hamburger,300
chickencurry,690
```



- 先のCSVファイルを読み込むコード

```python:add_calories.py
import csv

sum_of_calories = 0

with open("food_calories.csv") as file:
    data = csv.DictReader(file)
    for row in data:
        name = row["food"]
        calorie = row["calorie"]

        print("name : %s, calorie : %d" % (name, calorie))

        sum_of_calories += calorie

print("sum = %d" % sum_of_calories)  
```



# 発生したエラー
次のエラーが発生しました．

```sh:ターミナル
$ python3 add_calories.py
Traceback (most recent call last):
 File "/hogehoge/add_calories.py", line 11, in <module>
  print("name : %s, calorie : %d" % (name, calorie))
TypeError: %d format: a number is required, not str
```



# 解決方法

csv.DictReaderは読み込んだデータを文字列（str型）として扱うので，int型に変換する必要がありました．

```python
calorie = int(row["calorie"])
```



# 実行結果
プログラムを動かすことができました．

```sh:ターミナル
$ python3 add_calories.py
name : ramen, calorie : 443
name : coffee, calorie : 7
name : cheesecake, calorie : 281
name : hamburger, calorie : 300
name : chickencurry, calorie : 690
sum = 1721
```



# 参考文献

- [摂取カロリー早見表](https://www.tanita.co.jp/content/calorism/table/index2.html)
- [PythonでCSVファイルを読み込み・書き込み（入力・出力）](https://note.nkmk.me/python-csv-reader-writer/)
【Python】クラスオブジェクトの中身を確認する2つの方法

# はじめに

プログラミング初学者です．Pythonでクラスオブジェクトをそのまま出力しても中身が確認できないことを知りこの記事を執筆するに至りました．



# 環境

- Python 3.9.4

```sh:ターミナル
$ python3 --version
Python 3.9.4
```



# クラスオブジェクトをそのまま出力するとどうなるか

こちらのプログラムを動かしてみます．

```python:weather.py
class Weather:
    def __init__(self, name, weather, temperature):
        self._name = name
        self._weather = weather
        self._temperature = temperature

tokyo = Weather('東京', '晴れ',  25)

print(tokyo)
```



するとこのようになります．

```sh:ターミナル
$ python3 weather.py
<__main__.Weather object at 0x102ab6b20>
```



`__main__.Weather`はクラスの名前，`0x102ab6b20`はアドレスを示しています．つまりこの出力では「このアドレスにあるこんなクラス名のオブジェクトだよ」ということしか分からず，中にどんなデータが入っているかを確認することができません．



これに対し，2つの対処法をご紹介します．



# クラスオブジェクトの中身を見る方法①

`__str__`メソッドを用います．このように使います．

```python:weather.py
class Weather:
    def __init__(self, name, weather, temperature):
        self._name = name
        self._weather = weather
        self._temperature = temperature

class StrWeather(Weather):
    def __str__(self):
        return '地名：%s, 天気：%s, 温度：%d' % (self._name, self._weather, self._temperature)

tokyo = Weather('東京', '晴れ',  25)
str_tokyo = StrWeather('東京', '晴れ',  25)

print(tokyo)
print(str_tokyo)
```

`__str__`メソッドはクラスで定義し，その戻り値は文字列にする必要があります．



すると実行結果はこのようになります．

```sh:ターミナル
$ python3 weather.py
<__main__.Weather object at 0x10e2b2b20>
地名：東京, 天気：晴れ, 温度：25
```

中身を確認することができました．



# クラスオブジェクトの中身を見る方法②

`vars()`という関数を用います．このように使います．

```python:weather.py
class Weather:
    def __init__(self, name, weather, temperature):
        self._name = name
        self._weather = weather
        self._temperature = temperature

tokyo = Weather('東京', '晴れ',  25)
vars_tokyo = vars(tokyo)

print(tokyo)
print(vars_tokyo)
```



すると実行結果はこのようになります．

```sh:ターミナル
$ python3 weather.py
<__main__.Weather object at 0x10a63fb20>
{'_name': '東京', '_weather': '晴れ', '_temperature': 25}
```

簡単に中身を確認することができました．



# 参考文献

- [Python - デバッグ - オブジェクトの中身を見る](https://freebsd.sing.ne.jp/lang/python/09/04.html)
- [Pythonの特殊メソッド__str__の使い方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/20615)
【AWS】ECSについて学んだことをまとめてみた。

こんにちは、k_uki512です。
現在「AWSではじめるクラウド開発入門」という書籍の6章を進めています。
ここでは、ECSとは何かについてまとめていきたいと思います。
## ECSとは？
### 結論
Dockerを使ってAWSに計算機クラスタを作成するためのツールのことです。
Dockerfileに記述した内容で計算機クラスタのインスタンスを操作することができます。
また、ECSでは計算の処理の単位を<b>ジョブ</b>といいます。

### ECSの動作の流れ
- タスクが投入されるとあらかじめ指定しておいたDockerイメージを外部レジストリからダウンロードしてきます。
（外部レジストリはDockerHubや、AWSが用意したDockerレジストリの<b>ECR</b>などがあります。）
- 計算負荷が小さい仮想的なインスタンスを選別し、その中にDockerイメージを配置することで計算タスクを実行します。
- クラスター内のインスタンスの計算負荷を監視し、負荷に応じてインスタンスを起動したり、停止したりします。この動作のことを<b>スケーリング</b>といい、インスタンスを立ち上げる行為を<b>スケールアウト</b>、インスタンスを停止する行為を<b>スケールイン</b>といいます。
![AWS6章.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2341225/28f8a3a0-bb90-0314-8223-a6544c4e981c.jpeg)
【mypy】リストに複数の型のデータを入れてはいけない【Python】

# はじめに

プログラミング初学者です．Pythonで書いたコードをmypyでチェックした際に起きたエラーとその解決方法を共有します．



# 環境

- Python 3.9.4
- mypy 0.940

```sh:ターミナル
$ python3 --version
Python 3.9.4

$ mypy --version
mypy 0.940
```



# mypyエラー発生時のコード

キャラクターの名前と身長を格納したリストを身長順に並び替えるというプログラムです．

```python:sort.py
kimetsu_height: list[list[str, float]] = [
    ['tanjiro', 165],
    ['nezuko', 153],
    ['zenitsu', 164.5],
    ['rengoku', 177],
    ['inosuke', 164]
]

sorted_kimetsu_height = sorted(kimetsu_height, key=lambda x: x[1])

print(sorted_kimetsu_height)
```



また，実行結果は以下の通りです．プログラムとしては問題なく動いています．

```sh:ターミナル
$ python3 sort.py

[['nezuko', 153], ['inosuke', 164], ['zenitsu', 164.5], ['tanjiro', 165], ['rengoku', 177]]
```



# 発生したmypyエラー（エラー①）

次のようなエラーが出ました．

```sh:ターミナル
$ mypy sort.py
sort.py:1: error: "list" expects 1 type argument, but 2 given
Found 1 error in 1 file (checked 1 source file)
```



# エラーに対する解決方法

リストには一つの型のデータしか入れられないことが原因でした．

```python
['tanjiro', 165]
```

上記のように，リストに複数の型のデータを入れてはいけないそうです．

そこで，代わりにタプルを用いました．タプルには複数の型のデータを入れることができます（詳しくは参考文献をご参照のこと）．

```python:sort.py
kimetsu_height: list[tuple[str, float]] = [
    ('tanjiro', 165),
    ('nezuko', 153),
    ('zenitsu', 164.5),
    ('rengoku', 177),
    ('inosuke', 164)
]

sorted_kimetsu_height = sorted(kimetsu_height, key=lambda x: x[1])

print(sorted_kimetsu_height)
```



すると，mypyテストをクリアすることができました！

```sh:ターミナル
$ mypy sort.py
Success: no issues found in 1 source file
```



プログラムも問題なく動きます．

```sh:ターミナル
$ python3 sort.py
[('nezuko', 153), ('inosuke', 164), ('zenitsu', 164.5), ('tanjiro', 165), ('rengoku', 177)]
```


# 参考文献

- [『鬼滅の刃』キャラの身長を一覧で比較　最も低いor高いのは？](https://magmix.jp/data/kimetsu/kimetsu-character/kimetsu-shincho)
- [Pythonで型指定するTypingの基本的な使い方まとめ](https://deecode.net/?p=530#List_Tuple_Set_Dict型のTyping)
Amplify Consoleでドメインに紐付いているバージョンをCLIで変更する

AWS Amplify Consoleではドメインに対してデプロイの紐付けを行うことができます。
これにより複数のバージョンをビルド・デプロイしておき、関連付けを変えるだけでバージョンの差し替えが可能です。

ウェブコンソール上で簡単に変えることもできますが、複数のアプリを一括で変更したい際や、CIに組み込んで自動で変更を行いたい場合にはAWS CLIを利用すると可能になりました。

![Screen Shot 2022-04-22 at 15.10.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/c7ba56dd-9aeb-796d-ee3a-6b958b165713.png)

変更自体は下記のように `amplify update-domain-association` を呼ぶと可能です。　

```console
$ aws amplify update-domain-association --app-id ${APP_ID} --domain-name ${DOMAIN} \
 --sub-domain-settings "[{"branchName": "release/'v1.0.0'", "prefix": ""}]" > /dev/null
```


```bash
#!/usr/bin/env bash
#set -xe
set -e
# Amplifyでのブランチ関連付けを一括で変更するスクリプトです

APP_ID=xxxxxxxx  # AmplifyのアプリID

TARGET_VERSION=${1-v2.0.0} # 切り替えを行いたいバージョン
DOMAIN_SETTINGS_JSON='[{"branchName": "release/'${TARGET_VERSION}'", "prefix": ""}]'

echo ${DOMAIN_SETTINGS_JSON}

DOMAIN=$(aws amplify list-domain-associations --app-id ${APP_ID} | jq -r '.domainAssociations[].domainName' &)
VERSION=$(aws amplify list-domain-associations --app-id ${APP_ID} | jq -r '.domainAssociations[].subDomains[].subDomainSetting.branchName' &)

## 現在設定の表示
echo Current Assosiation
wait
echo ${DOMAIN}  '  => ' ${VERSION}

## 関連付けを更新
aws amplify update-domain-association --app-id ${APP_ID} --domain-name ${DOMAIN} \
 --sub-domain-settings "${DOMAIN_SETTINGS_JSON}" > /dev/null

## 変更の確認
VERSION=$(aws amplify list-domain-associations --app-id ${APP_ID} | jq -r '.domainAssociations[].subDomains[].subDomainSetting.branchName' &)
echo ${DOMAIN}     '  => ' ${VERSION}
```



実行するとこんな感じです。

```console
$  ./change_amplify_version.sh v2.0.0
[{"branchName": "release/v2.0.0", "prefix": ""}]
Current Assosiation
testing.example.com   =>  hotfix/v1.12.7
Current Assosiation
Current Assosiation   =>  release/v1.12.7
```
AtCoder B - Count Balls

## 問題

https://atcoder.jp/contests/abc158/tasks/abc158_b


```Python

n, a, b = map(int, input().split())
ans = 0

ans = n // (a + b) * a  #商でn内にある青の数

rem = n % (a + b) #あまりで青の数。あまりはかなら

ans += min(rem, a) #余ったボールの数と青いボールの数の小さい方を足す。余ったボールは青いボールから始まる。

print(ans)

```
AnafiをROSで動かしたい 2

# AnafiをROSで動かすために環境構築
parrot社のドローン anafiをROSで動かせるようにしたくて奮闘中です．まだまだ開発段階ですが，少しずつまとめていきたいと思っています．わからないことが多いので，間違っていたり足りないところがあれば指摘してください．

## 参考にしているもの
GitHubでanafiのパッケージをROSとbridgeしているものがありました．
https://github.com/andriyukr/olympe_bridge
こちらを元に開発していきたいと思っています．

##　前回の続き
前回：https://qiita.com/taikitikun/items/c99eee17d9c9255f0fb1
では，Parrot Ground SDKのダウンロードで終了しました．
今回は，ROSでのワークスペースの作成やパッケージのインストール，構築についてまとめていきたいと思います．ROS環境の構築などは，他サイトを参照してください．

## anafi_bridgeパッケージのインストール
まず，使用環境として，LinuxのバージョンはUbuntu18.04とUbuntu20.04では動作確認できました．pythonはpython3を使っていきます．

ワークスペースにレポジトリの複製

    cd ~/catkin_ws/src
    git clone https://github.com/andriyukr/olympe_bridge.git
    sudo chmod -R 777 olympe_bridge/

実際に実行するときのコマンドは以下となります．

    source ~/code/parrot-groundsdk/./products/olympe/linux/env/shell
    roslaunch olympe_bridge anafi.launch

おそらくいくつかのエラーが出ると思うので，私が確認したエラーと対処を次にまとめていきます．

---
Issue:
 
    ModuleNotFoundError: No module named 'roslaunch'
Solution: Set up ROS environment

    echo 'source /opt/ros/noetic/setup.bash' >> ~/code/parrot-groundsdk/./products/olympe/linux/env/shell
    echo 'source ~/catkin_ws/devel/setup.bash' >> ~/code/parrot-groundsdk/./products/olympe/linux/env/shell
    source ~/code/parrot-groundsdk/./products/olympe/linux/env/shell

---
Issue:
    
     RLException: [anafi.launch] is neither a launch file in package [olympe_bridge] nor is [olympe_bridge] a launch file name The traceback for the exception was written to the log file

これはおそらくpythonのPATHがうまく設定できていないからだと思います．なので，以下のようにpython3のPATHを通してあげます．

    export PYTHONPATH=/home/tai/code/parrot-groundsdk/out/olympe-linux/final/usr/lib/python/site-packages:/opt/ros/noetic/lib/python3/dist-packages:/home/tai/catkin_ws/devel/lib/python3/dist-packages

私の場合はanafiの実験をする際に毎回打っていますが，面倒な方はシェルで設定しても構いません．
pythonのPATHが変わった関係で，いくつかAttributeErrorが発生すると思うので，発生した場合はpip install ~~　をしてあげてください．

--- 
## 最後に
ここでは，前回に続いてanafi_bridgeのインストールについてまとめました．
次回からはROSでparrot-sphinxを使ったシミュレーションでの操作についてまとめていきたいと思います．

## 参考
    
https://github.com/andriyukr/olympe_bridge
https://developer.parrot.com/
saved_change_to_{カラム名}?について

## saved_change_to_{カラム名}?
あるカラムの値が変更されたときに何らかのメソッドをコールバックする際によく使われるメソッドです。

例えば、以下のように書くとします
```
validate :validate_change_name, if: :saved_change_to_name?

def validate_change_name
  p "名前が変更されました"
end
```
このようにすることによって、```name```カラムの変更されたあとの処理を書くことができます

【参考資料】

https://masarufuruya.hatenadiary.jp/entry/2020/05/08/093857
言語チェンジする人は読まなきゃヤバい!LaravelとRailsのコマンドの比較

# この記事を書いている人
Railsを学習してからLaravelで実務案件に入りました。

# LaravelとRailsを比べる
LaravelとRailsは兄弟フレームワークのような存在で
コマンドや環境、特徴は違うけど本質的な部分は同じです。

RailsからLaravel、またはその逆で学習、仕事する人の参考になれば嬉しいです。

# 有益な記事
有益そうな記事がありました。
Railsは見つかりませんでした。汗

⚫︎Laravel

https://qiita.com/shimotaroo/items/6a909797e0139517b1bd

下でもコマンドは紹介します。最低限知っておいた方がいいコマンドです。

# サーバーの起動

⚫︎Laravel
```
 $ php artisan serve
```

⚫︎Rails
```
$ rails s
```

## バージョンの確認
⚫︎Laravel
```
$ php artisan --version
```

⚫︎Rails
```
$ rails -v
```

## コマンド確認
コマンドを調べる時に使います。

⚫︎Laravel
```
$ php artisan list
```

⚫︎Rails
```
$ rails -T
```

# モデル、マイグレーション 
モデル名の最初は大文字です。　
ex) User 

### モデル作成

⚫︎Laravel
```
$ php artisan make:model モデル名
```
実務では

```
$ php artisan make:model Models/モデル名
```
Appは以下のModelsにモデルを作ります。

⚫︎Rails
```
$ rails 　g model モデル名
```

### モデルの削除
⚫︎Laravel
```
手動で削除
```

⚫︎Rails
```
$ rails 　d model モデル名
```

### マイグレーション作成

⚫︎Laravel
```
$ php artisan make:migration [migration_name]
```

⚫︎Rails
```
$ rails g migration [migration_name]
```

### マイグレーション実行

⚫︎Laravel
```
$ php artisan migrate
```

⚫︎Rails
```
$ rails db:migrate
```

# データベースを接続
データベースの中を簡単に動かせたりします。

⚫︎Laravel
```
$ php artisan tinker
```

⚫︎Rails
```
$ rails console
$ rails c
```

# ロールバック

⚫︎Laravel
```
$ php artisan migrate:rollback
```

⚫︎Rails
```
$ rails db:rollback
```

# コントローラー

コントローラー作成

⚫︎Laravel
```
$ php artisan make:controller コントローラー名
```

⚫︎Rails
```
$ rails g controller コントローラー名
```

# DB操作

⚫︎Laravel
```
$ php artisan tinker
```

⚫︎Rails
```
$ rails console
```

# DBをリセットして、すべてのマイグレーションを最初から実行し直す
⚫︎Laravel
```
php artisan migrate:refresh
```
⚫︎Rails
```
rails db:migrate:reset
```

# seeder関連
⚫︎Laravel
```
$ php artisan make:seeder UsersTableSeeder
$ php artisan db:seed --class=UsersTableSeeder
```
⚫︎Rails
```
$ rails db:seed
```

### 注意コマンド
***DB内のすべてのテーブルを削除し、新しいマイグレーションファイルを実行してDBを再構築***
⚫︎Laravel
```
php artisan migrate:fresh --seed
```
⚫︎Rails
```
rails db:reset db:seed
```
シーダーを実行してDBに初期データを挿入
DBを完全にリフレッシュし、初期状態に戻せます。
ただし、実行する前に注意が必要であり、
データベース内のすべてのデータが削除されるため、必要なバックアップをしてから実行した方がいいです

# 今後
コマンドは今後も更新していきます。


# 参考資料

https://qiita.com/rf_p/items/59979fd5107556659a8d
統計的仮説検定(2022.4.22)

# 背景
先日まで「とけたろうさんのチートシート」を参考に学習させてもらっていました。例題も豊富でとても良いのですが、Pythonで学習したい私は、それからPythonでの計算方法を調べるというステップを踏んでいまして理解するまでに少し時間がかかるのがネックでした。そういえばプロ棋士の谷合さんが「Pythonで理解する統計解析の基礎」を出版されていたのを思い出しました。今回は、こちらから引用（ほぼそのままですが）させて頂きたいと思います。

# 問題
Aさんはよく学校帰りにコンビニでフライドポテトを買って帰ります。このフライドポテトの重さの平均は130gと公表されていますが、とある日、Aさんがフライドポテトの重さを量ってみたら122.02gしか入っていませんでした。このコンビニのフライドポテトは実際には平均が130gより少ないのではないかと疑い始めたAさんは、その日から2週間毎日ポテトを買い、重さを量ることにしました。そして2週間後、集まった14個の標本の平均を計算したところ128.451gとなりました。14個の標本平均が130gより明らかに少ないと思ったAさんはコンビニにクレームをつけにいったのですが、ただの偶然だと一蹴されてしまいました。はたして14個の標本の平均が128.451gとなったのは本当にただの偶然なのでしょうか。

# 解答
まずは標本の平均を算出します。必要なライブラリをインポートしてデータを読み込んでいます。
```Python
import numpy as np
import pandas as pd
from scipy import stats

%precision 3
np.random.seed(1111)

df = pd.read_csv('python_stat_sample/data/ch11_potato.csv')
sample = np.array(df['重さ'])
s_mean = np.mean(sample)
s_mean
```
確かめたい事は母平均が130gより少ないかどうかです。前提として正規分布に従っていて、母分散は9とわかっているとします。
まず、「母平均が130g」という仮定をします。この時、フライドポテト14個の標本は N(130,9) に従い、標本平均 X¯ は N(130,9/14) に従うことになります。
ここでは、公表している母平均130g、母分散9の正規分布と、自分で集めた標本の正規分布を比べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/59213633-da61-0275-fd17-9c2bdd2888c1.png)

標本分布より臨界点を算出します。
```Pythont
rv = stats.norm(130, np.sqrt(9/14))
rv.isf(0.95)
```
臨界点は128.681になります。
検定量であるZ値を求めます。Z値は次のように求められます。
$$
Z=\frac{\bar{X}-\mu}{\sqrt{\frac{\sigma^2}{n}}}
$$
```Python
z = (s_mean - 130) / np.sqrt(9/14)
```
検定量は「-1.932」となりました。
次に臨界値を求めます。この場合、臨界値は標準正規分布の5％の地点です。
```Python
rv = stats.norm()
＃rv.isf(0.95) ＃逆生存関数
rv.ppf(0.05)
```
検定量が臨界値より小さくなりました。これより、帰無仮説は棄却されます。
最後にp値を求めます。p値は標準正規分布における検定量Zまでの面積です。
```Python
rv.cdf(z)
```
p値が有意水準0.05より小さい値になったので、p値でも帰無仮説は棄却されました。

# 参考
[谷合(2020),Pythonで理解する統計解析の基礎,技術評論社](https://www.amazon.co.jp/dp/4297100495/ref=cm_sw_r_tw_dp_DHX9G4SFVTA5A0VKGQ6K)

# 感想
統計自体素人な私にとって、プログラミングをしながら統計を学ぶのに理解に苦しんでいます。前回までは実際、問題を解いてからプログラミングに落とし込んでいました。ただ、私の様にこんがらがったニューロンの構造を持った私には体系的に理解するのが難しく、場当たり的になっています。今回は、昔見かけた谷合棋士の著書を思い出し、参考にさせて頂きました。自分で書いた記事をまとめられるように考えて行きたいと思います。
FFIやFiddleで自動生成したメソッドをYardドキュメントに掲載させる

不完全な情報だが、ググっても出てきにくい情報だと思うので、忘れる前にメモする。

Rubyは動的な性質の強い言語で、動的にメソッドを定義する機会は多い。Ruby-FFIやFiddleはC言語の関数をRubyから呼び出すためのライブラリで、メソッドをモジュールに動的に追加する。そのため生成されたメソッドはYardドキュメントに掲載されない。（ユーザーはFFIやFiddleで追加されたメソッドを直接呼び出すべきではなく、きちんとエラー処理などを施したラッパーメソッドを作成してそれを呼び出すべきだ。だからYardで生成したドキュメントにそういったメソッドは載せるべきではない、という話があるが、今回それはおいておく。）

Yardにはマクロ機能がついており、これを利用すれば、かなり高い完成度でFFIやFiddleのドキュメントを自動生成できる。

具体的には下記のように、`attach_function` メソッドを再定義し、そこにマクロを追加する。

（ここでは、目的の関数が見つからなくてもRubyが停止しないようにしているが、それはこの記事には関係ない）

```ruby
module HTS
  module LibHTS
    extend FFI::Library

    begin
      ffi_lib HTS.lib_path
    rescue LoadError => e
      raise LoadError, "#{e}\nCould not find #{HTS.lib_path}"
    end

    # @!macro attach_function
    #   @!method $1(${2--2})
    #   @return [${-1}] the return value of $0
    def self.attach_function(*)
      super
    rescue FFI::NotFoundError => e
      warn e.message
    end
  end
end
```

これでYardが `attach_function` で追加したメソッドを補足してくれるようになる。`$1` `${2--2}` などは、公式ドキュメント参照。この記事は以上です。

公式ドキュメント `@macro`：

https://rubydoc.info/gems/yard/file/docs/Tags.md#macro

参考元：

https://stackoverflow.com/questions/28413074/yard-doc-and-define-method
Scalaの勉強はじめました 10 〜関数型プログラミング編 コレクション〜

## はじめに
N予備校で「Scala応用」コースを受講しています。

## Seq
`Seq`型の中身は、`List`型。

```scala
1::2::3::Nil
```
空のリストを表す`Nil`に、`::(コンス)`というケースクラスを使って`1,2,3`の値を追加する。

## Array
メモリを最初に確保して、高速に処理できるようにする。
追加などを行うと、再度メモリを確保しようとするので、負荷がかかる。

```scala
Array(1, 3, 4).toList
```

`List`型にすると、`map`や`flatMap`などが使える。

## Range
範囲を表す、`to`や`until`を利用するときに使う。

```scala
1 to 5 // Range(1,2,3,4,5)
(1 to 5).toList // List(1,2,3,4,5)
1 until 5 // Range(1,2,3,4)
```

## Set
要素の集合。可変と不変の2つがある。
指定がない場合は、不変の`Set`。
要素の重複を許さない。

```scala
val s = Set(1,1,2,2,,3) // Set(1,2,3)
```

```scala
val s1 = Set(1,2,3)
val s2 = Set(3,4,5)
// 和集合
s1 ++ s2 = Set(5,1,2,3,4)
// 差集合
s1 -- s2 = Set(1,2)
```

## Map

```scala
val m = Map("a" -> 1, "b" -> 2, "c" -> 3) // Map(a -> 1, b -> 2, c -> 3)
```

`->`で繋ぐと、2要素のタプルを作ることができる。

```scala
"a" -> 1 // (String, Int) = (a, 1)
```

```scala
m.get("a") // Some(1)
m.get("e") // None
m.toList // List[(String, Int)] = List((a,1), (b,2), (c,3))
```

`get`で取得すると`Option`型で返ってくる。

## スタックとキュー
### スタック
後入れ先出し (LIFO: Last In First Out) のコレクション
`push`メソッドで、追加。
`pop2`メソッドで、先頭の値と残った要素を持つStackをタプルとして取得。
つまり、1, 2 の順で要素を入れた後、 2, 1 の順で要素を取り出す

### キュー
筒状の形をしたものに要素を詰め込み、反対側の穴から要素 を取り出すイメージ。
先入れ先出し(FIFO: First In First Out) のコレクション
`enqueue`メソッドで`Queue`に要素を入れる。
`dequeue`メソッドで先頭の値と残った要素を持つ`Queue`を取得する。
1, 2 という順で要素を入れた後、 1, 2 という順で要素を取り出すことになる。

## リストの結合
```scala
List(1,2) ++ List(3,4) 
```

`++`はメソッド。
`List(1, 2).++(List(3, 4))` と同義。

### mkString
文字列を生成する。
```scala
List(1, 2, 3, 4, 5).mkString // "12345"
List(1, 2, 3, 4, 5).mkString(",") // "1,2,3,4,5"
```

## 畳み込み
### foldLeft
```scala
List(2, 3, 4).foldLeft(0)((x, y) => x + y)
```

最初の引数が初期値。ここでは`0`。
最初に`0`を足して、`2`と`3`と`4`を足す。

```scala
def reverse[T](list: List[T]): List[T] 
  = list.foldLeft(Nil: List[T])((a, b) => b :: a)
```
初期値`Nil`の配列`a`に`b`を追加していく。

### foldRight
```scala
List(1, 2, 3).foldRight(0)((y, x) => y + x)
```
`foldLeft`とは逆に、`3`から足していく。


## まとめ
リストや配列への追加ってやり方が言語によって微妙に違ってくるのでなかなか混乱します。
Git で "fatal: unsafe repository" エラーが出たときの解消法

# はじめに

~~~
git.exe pull --progress -v --no-rebase "origin"
fatal: unsafe repository ('//192.168.56.xxx/Develop$/repo1' is owned by someone else)
To add an exception for this directory, call:

git config --global --add safe.directory '%(prefix)///192.168.56.xxx/Develop$/repo1'


git did not exit cleanly (exit code 128) (109 ms @ 2022/04/22 12:44:50)
~~~

ある日、TortoiseGitでpullしたら上記のようなエラーが出た。どうやら Git for Windows ver2.35.2 から変更されたらしい。

# 環境
今回の問題解決にはあまり関係ないが紹介しておく。ちょっと特殊。
リモートにあるKVMのゲストOS(Ubuntu)にソースや実行環境(Docker)があり、それをローカルのWindows11からRemote Viewer(Spice)でつなげて、Ubuntu上の Visual Studio Code でソースの編集を行う。
Ubuntu と Windows は Sambaでもつなげていて、ちょっとややこしいGitの操作はWindows上のTortoise Git で行う。

# 解決方法
上記のエラーメッセージにも書いてあるが、設定ファイルに safe.directory を追加するコマンドを実行すれば完了。ただし注意点があるので記載する。

#### Windows上で行う
リモートのLinuxではなく、ローカルのWindowsでコマンドを実行する必要がある。

#### シングルクォーテーションはNG
試したところシングルクォーテーションでは有効にならなかった。ダブルクォーテーションかクォーテーションなしでコマンドを実行する。%(prefix)の部分は何かに置き換えろ、というわけではないので、そのまま打ち込んでOK。
~~~:Command Prompt
C:\> git config --global --add safe.directory %(prefix)///192.168.56.xxx/Develop$/repo1
または
C:\> git config --global --add safe.directory "%(prefix)///192.168.56.xxx/Develop$/repo1"
~~~

#### リポジトリが複数ある場合
リポジトリが複数入っている上位ディレクトリを指定することはできない。リポジトリ毎に設定を行わないといけない。

#### globalな設定ファイルに追記しなくてはならない
コマンドを実行する場合は --globalオプションを必ずつけなければならない。
エディタで設定ファイルに書き込む場合は、C:\Users\ユーザー名\\.gitconfig に追記する。各リポジトリの設定ファイル(リポジトリ/.git/config)に追記しても効果はない。

# 記述例
設定ファイルはこんな感じになっている。
~~~ :C:\Users\ユーザー名\\.gitconfig
[safe]
  directory = %(prefix)///192.168.56.xxx/Develop$/repo1
  directory = "%(prefix)///192.168.56.xxx/Develop$/repo2"
~~~
Multipass使い方

## インストール

```
brew install --cask multipass
```

## セットアップ

Ubuntu VMを作成する
CPU: 1コア、ストレージ20GB、メモリ2GB の場合、このようなコマンドになる。
hogehogeには、好きな名前を入れる。
オプションの意味は multipass launch -h で確認できる

```
multipass launch --cpus 1 --disk 20G --memory 2G --name demo 22.04
```

作成されているかを確認する。

```
multipass list
```

ターミナルにログインする。

```
multipass shell hogehoge
```

退出する。

```
exit
```

## 削除

```
multipass stop hogehoge
```

```
multipass delete hogehoge
```

```
multipass purge
```

### 【追加】MySQLのShellに入る

```
mysql -u root -p
```

### 特定のディレクトリをマウント

`multipass mount [開発しているディレクトリのパス] [VM名]:[マウント先ディレクトリパス]`

```
multipass mount 開発しているディレクトリのパス VM名:~/hogehoge
```

マウントを解除する場合は、

```
multipass umount VM名:~/hogehoge
```