OmniAICreator/Qiita-1.07M huggingface dataset:
Catalyst9800　初期設定でハマったこと

CiscoWLCは良く触って来ましたが、Catalyst9800からだいぶ変わりました。
基本設定は色々なサイトで記載があるので、ハマったことランキング上位を記載します。
無線APもCatalyst9100を使用すれば良かったのかもしれないですが、
Aironet1830シリーズだったのが悪かったかもしれません。。。

3位　新規接続でGUIがおかしい
　　192.168.1.1でMgmtポートで接続できるのですが、国番号が選べない！
　　たぶんブラウザが悪かったんだと思いますが、
　　CLIで接続して、J4を設定しました。
　　国番号の設定が出来ないと、GUIの設定画面に行きません。


2位　joinしない
　　Aironet1830シリーズはMobiliteExpressが起動して、capwapの設定に行きつくまで面倒。
　　DHCPでオプション43出せばjoinすんじゃないのーーー。　　
　　こちらも、capwapの設定をCLIで設定しました。

1位　まだ、joinしない
　　この1行かよ！

　　__wireless management interface vlan 1__

　　Google先生に色々聞いたのですが、教えてもらえず。。。
　　ベンダー問い合わせで教えてもらいました。
　　この1行でCatalyst9800のL3部分とWLCの設定を関連付けする必要があるようです。
【Flutter】google_maps_flutterパッケージとgoogle_mobile_adsパッケージを同時に使うとAndroidだと地図を手動で動かせない

# はじめに
タイトルにあるように、google_maps_flutterパッケージとgoogle_mobile_adsパッケージを同時に使うとAndroidだと地図を動かせなくなります。iOSは動きます。

# 更新履歴
2022.2.15 初回投稿

# 環境
- Flutter (Channel unknown, 2.8.1, on macOS 11.6 20G165 darwin-x64, locale
    ja-JP)
- Android toolchain - develop for Android devices (Android SDK version 31.0.0)
- Xcode - develop for iOS and macOS (Xcode 13.2.1)
- Chrome - develop for the web
- Android Studio (version 2021.1)
- VS Code (version 1.64.2)

# 参考にしたサイト
https://pub.dev/packages/google_maps_flutter

# package
https://pub.dev/packages/google_maps_flutter
https://pub.dev/packages/google_mobile_ads

# やりたいこと
GoogleMapとadMobを一緒に表示させて、地図を手動で動かしたい


# 手順
パッケージページにあるようにHybrid Compositionを適用するだけです。

```main.dart
void main() {
  if (defaultTargetPlatform == TargetPlatform.android) {
    AndroidGoogleMapsFlutter.useAndroidViewSurface = true;
  }
  runApp(MaterialApp(home: MapsDemo()));
}

```
以上
jetson nano

#前提
JetsonNano　：ラズパイみたいなやつ、nVIDIA
OS(Ubuntsuベース）:　https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write

JetBot:　車型の物、上段ボードJetsonNanoo
JetPack : JetpackはJetson向けにCUDA、cuDNN、TensorRT、DeepStream、OpenCVをパッケージしたソフトウェアです。

https://developer.nvidia.com/embedded/jetpack

https://jetbot.org/master/software_setup/sd_card.html

#電源(jetbot)

車型のものをJetBotと呼ぶ。

H/Wは二段になっている。下の段に電源ジャックがある。
<font color="DeepPink">この電源は12.6Vで、これをJetsonNanoにつなぐと電圧が高すぎるので故障する。</font>
モバイルバッテリー（18650リチウムイオンバッテリー）も繋いでいる。上下のボードをつなぐケーブルに注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/8fed21b1-5dab-3726-bf5a-491a20619f18.png)

#jetsonNanoの電源
仕様：５V、２A（デフォルト）設定で４Aに変更できる。

電源供給は、JetsonNanoの電源ジャック、USB-Aポートに二つ。
これはジャンパーで切り替える（現在はUSB-A)
USB-Aだと、電圧不足になりがち。
↓
つまり、JetBotボードの電源とあわせて３系統存在する。

# wifi 
後付け
https://qiita.com/akinko/items/c01ed6b891f2117f5ed9

#sdカード
64GB以上が望ましい。

#jetpack4.5
https://qiita.com/y4su0/items/292fda9704e0de8d59c6

https://wisteriahill.sakura.ne.jp/CMS/WordPress/2019/07/07/nvidia-jetson-nano-set-up-configration/

# 参考
https://o-maguro.hatenablog.com/entry/2020/02/08/150608
tfstateファイルが更新されない

#結論
backendを追加したからでした。

```backend.tf

terraform {
  backend "s3" {
      bucket = "buket-name"
      key = "pass/to/terraform.tfstate"
      region = "ap-northeast-1"
  }
}

```

これを追加することでtfstateファイルがs3に保存されるようになります。
私の想定していた動きとしてはローカルのtfstateにも保存されs3にも保存される
という動きを想定していたのですがs3に保存されるのみでした。

# terraform init時
backendを追記すると以下のように聞いてくれています。

```terraforminit.sh

$ terraform init

Initializing the backend...
╷
│ Error: Backend configuration changed
│ 
│ A change in the backend configuration has been detected, which may require migrating existing state.
│ 
│ If you wish to attempt automatic migration of the state, use "terraform init -migrate-state".
│ If you wish to store the current configuration with no changes to the state, use "terraform init
│ -reconfigure".

```

backendを変更する場合は-migrate-state
変更せず保存する場合は-reconfigure
を付けて実行します。

-migrate-stateを付けてterraform initを実行し変更すると
ローカルに保存していたtfstateファイルが
s3に保存されるようになったりと保存場所、参照場所を変更することが出来ます。
JavaScript で非同期処理のリトライ

JavaScript で 非同期処理 + リトライ の仕組みを作ったら意外とややこしかったのでメモ。

## 実装
``` js
function retry(func, onError) {
  function _retry(e) {
    return onError(e)
      .catch((e) => {
        throw e
      })
      .then(func)
      .catch(_retry)
  }
  return func().catch(_retry)
}
```

- `func`
    - 失敗したときに再試行したい何らかの非同期関数を指定する (Promise を返す必要がある)
    - resolve するとその結果が返る、reject すると `onError` 実行後にリトライされる
- `onError`
    - `func` が失敗した際に、再試行の前に実行したい何らかの非同期関数を指定する (Promise を返す必要がある)
    - resolve するとリトライされる、reject すると例外を投げて止まる

(2024.01 追記) TypeScript + async/await で書いてみるとこんな感じ？ ※ 動作未確認

``` typescript
async function retry<T>(
  func: () => Promise<T>,
  onError: (e: Error) => Promise<void>
): Promise<T> {
  async function _retry(e: Error): Promise<T> {
    await onError(e)
    try {
      return await func()
    } catch (e) {
      return await _retry(e as Error)
    }
  }
  return await func().catch(_retry)
}
```

## 使用例

### 基本形
失敗したら1秒待ってから再試行を無限に繰り返すパターン

``` js
// 失敗したときに再試行したい何らかの非同期関数
async function f() { ... }

// setTimeout を Promise で包んだだけのやつ
function sleep(msec) {
  return new Promise((resolve) => window.setTimeout(resolve, msec))
}

const result = await retry(f, (e) => {
  console.error(e)
  console.log('sleep 1sec and retry')
  return sleep(1000)
})
```

### キャンセル
再試行するかどうかをユーザに確認して、キャンセルした場合はデフォルト値 (この場合 `null`) を結果として返すパターン

``` js
// 失敗したときに再試行したい何らかの非同期関数
async function f() { ... }

let canceled = false
const result = await retry(
  () => (!canceled ? f() : Promise.resolve(null)),
  (e) => {
    console.error(e)
    canceled = !window.confirm('try again?')
    return Promise.resolve()
  }
)
```

### 試行回数制限
再試行の回数制限を超えたらエラーを投げるパターン

``` js
// 失敗したときに再試行したい何らかの非同期関数
async function f() { ... }

// setTimeout を Promise で包んだだけのやつ
function sleep(msec) {
  return new Promise((resolve) => window.setTimeout(resolve, msec))
}

const maxRetry = 3
let retryCount = 0
const result = await retry(f, (e) => {
  if (retryCount++ < maxRetry) throw e
  console.error(e)
  console.log('sleep 1sec and retry')
  return sleep(1000)
})
```

## 補足
キャンセルや試行回数制限も実装に含めてしまえればよかったのだけれど、パッと綺麗に作れなさそうだったので、使う側でやってしまったほうがシンプルじゃん、となりこうなった。
【Salesforce】SOQLのIN句に変数を設定する

# IN句に変数を使用せずに複数条件を設定

```:Apex
List<User> userIdList = [SELECT Id FROM User WHERE UserName IN ('taro@test.com', 'jiro@test.com')];
```

# IN句に変数を使用して複数条件を設定
リストを扱えるクラスを使用しIN句に複数条件を設定できます。

```:Apex
Set<String> userList = new Set<String>();
userList.add('taro@test.com');
userList.add('jiro@test.com');

List<User> userIdList = [SELECT Id FROM User WHERE Name IN :userList];
```
Chakra UI の extendTheme で Tab 関連のスタイル更新

Chakra UI、気に入って使わせていただいていますが、`extendTheme` を使っての既存スタイルの更新でちょっと躓いたので備忘録。

※ スタイル（テーマ）のカスタマイズの基本は[公式](https://chakra-ui.com/docs/styled-system/customize-theme)をご覧ください。

# TL;DR

- TabList や Tab などの Tabs 配下に置かれる要素のスタイルは、 *baseStyle* や 各 variant の下に書いていく
- TabList や Tab などの Tabs 配下に置かれる**要素名はキャメルケースではなく全て小文字で書く**（ここハマったポイント）
- variant 名はキャメルケースで OK

# 実装内容

```TypeScript:sample
import React from 'react';
import { ChakraProvider, extendTheme } from '@chakra-ui/react';

const verticalShadow = {
  content: `''`,
  position: 'absolute',
  top: 0,
  display: 'block',
  boxShadow: 'inset 0 0 1px rgba(0, 0, 0, .05)',
  width: '1px',
  height: '100%',
};

const theme = extendTheme({
  components: {
    Tabs: {
      baseStyle: {
        // 各 variant （variant なしを含む）共通のスタイルはここ
        tablist: { // キャメルケースではなく小文字で
          backgroundColor: '#f8f8f8',
        },
        tab: {
          _focus: {
            boxShadow: 'none',
          },
        },
        tabpanels: { // キャメルケースではなく小文字で
          // properties
        },
        tabpanel: { // キャメルケースではなく小文字で
          // properties
        },
      },
      variants: {
        // 各 variant ごとのスタイルはここ
        enclosed: {
          tablist: {
            borderTop: '1px solid rgba(45, 45, 45, .1)',
          },
          tab: {
            position: 'relative',
            borderRadius: 0,
            _selected: {
              position: 'relative',
              _before: {
                ...verticalShadow,
                left: 0,
              },
              _after: {
                ...verticalShadow,
                right: 0,
              },
            },
          },
          tabpanels: {
            // properties
          },
          tabpanel: {
            // properties
          },
        },
        newVariant: { // variant はキャメルケースで OK
          // 以下同文
        },
      },
    },
  },
});


export const StyleProvider: React.FC = ({ children }) => (
  <ChakraProvider theme={theme}>{children}</ChakraProvider>
);

```

以上

# おわりに
Chakra UI、まだまだ知らないことが多くて使い倒せていないので、今後の React 案件でバンバン使っていきたいと思います。
Railsサーバーを起動したらgem Nokogiriがエラーになった。

#突然にGemがエラーを出し始めた。(きっかけは定かではない)
Railsサーバー起動したらこんな表示が。
![スクリーンショット 2022-02-15 12.50.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468139/fac8c5e2-bc2d-0f7f-a7e8-04354983869c.png)

#原因
エラーを翻訳すると　　「nokogiri-1.10.9は拡張機能が構築されていないため、無視します。」
でもRailsサーバーは普通に使えていたので、いっとき放置していました。
ただ、起動するたびにこの表示が出て消したいと思うようになりました。

#解決法
よくよく続きを読むとかいていました。「試してみてください：gem pristine nokogiri --version 1.10.9」
ということでターミナルでコマンドを試したところ、解消されました。

~~~~
gem pristine nokogiri --version 1.10.9
~~~~

#学んだこと
英語のエラー文を読もう！ヒントがあり。
配列でのpopやunshiftなどのメソッド

## popメソッド
popメソッドは配列の最後の値を取り除くメソッドです。
ぼくなりの覚え方ですが、popには「飛び出る」という意味があるので、一番最後の端っこから飛び出るというイメージを持って覚えています。

引数に数字(例えば、今回のように2を指定し場合)を指定した場合、末尾からその数字分(今回であれば、2つ)の要素を取り除きます。
```
array = [1, [2, 3], 4]
p array.pop      # => 4
p array.pop      # => [2, 3]
p array          # => [1]

p array.pop      # => 1
p array.pop      # => nil
p array          # => []


array = [1, 2, 3]
p array.pop(2)   #=> [2, 3]
p array          #=> [1]
```

## append(push)メソッド
配列の末尾に要素を追加する
```
array = [1, 2, 3]
array.push 4
array.push [5, 6]
array.push 7, 8
p array          # => [1, 2, 3, 4, [5, 6], 7, 8]
```

## shiftメソッド
配列の先頭の要素を排除するメソッドです
```
a = [0, 1, 2, 3, 4]
p a.shift            #=> 0
p a                  #=> [1, 2, 3, 4]
```

## unshiftメソッド
配列の先頭に要素を追加するメソッドです。
```
arr = [1,2,3]
arr.unshift 0
p arr             #=> [0, 1, 2, 3]
arr.unshift [0]
p arr             #=> [[0], 0, 1, 2, 3]
arr.unshift 1, 2
p arr             #=> [1, 2, [0], 0, 1, 2, 3]
```

## sliceメソッド
指定された要素を切り取る(sliceする)メソッドです。
```
p [0, 1, 2].slice(1)    #=> 1
p [0, 1, 2].slice(2)    #=> 2
p [0, 1, 2].slice(10)   #=> nil
```

範囲指定もできます。
```
p [0, 1, 2].slice(0, 2)    #=> [0, 1]
p [0, 1, 2].slice(2..3)    #=> [2]
```

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。
アプリケーションのウィンドウサイズが変更できなくなった時の解決法

#Jetson NanoでGeanyが最大化したままボタンが消えた！


#目次
[1.問題発生](#1-問題発生)
[2.まずやってみたこと](#2-まずやってみたこと)
[3.設定を変更してみる](#3-設定を変更してみる)
[4.無事にメニュー復活](#4-無事にメニュー復活)
[5.おわりに](#5-おわりに)




#1.問題発生
　【環境】
  ・Jetson Nano＋JetPack4.6

 【第1段階】Geanyでテキストを編集中手が滑ってマウスをクリックしてしまい、
　　　　　　メニューが消えてしまった。
 【第2段階】混乱して編集画面を閉じた後に最大化ボタンを押したら、
　　　　　　Geanyからアプリが終了できなくなってしまった。

・第1段階で気が付いていればまだ元に戻せたのですが、第2段階で詰んでしまいました・・・


#2. まずやってみたこと
・パッケージの再インストール

```
sudo apt remove geany
reboot
#reboot後に
sudo apt install geany
```
ーー＞Windowsだったらこれで戻るなぁと思い、実行。
**あれ？最大化したまま起動してきた(失敗ですね)**

・Google先生に質問「ウィンドウサイズ Ubuntu　変更」
 [Ubuntu18.04デスクトップガイド](https://sicklylife.jp/ubuntu/1804/help/shell-windows-states.html "Ubuntu18.04デスクトップガイド")

**Geanyを掴む、移動するができないです・・・(またも失敗)**

##3. 設定を変更してみる
・再度Google先生に質問し、Stack overflow下記の記事を参照しました。
 [What is the location of the Geany preferences/settings files?](https://sicklylife.jp/ubuntu/1804/help/shell-windows-states.html "What is the location of the Geany preferences/settings files?")
ーGeanyの設定ファイルはどこですか？

これによると 

```
 ~/.config/geany

#または

~/.geany 
```

に設定ファイルがある模様。

・実際にみてみました

```
usr@usr-desktop:~$ cd ~/.config/geany
#(略)
usr@usr-desktop:~/.config/geany$cat geany.conf

#(略)
#ウィンドウサイズを定義している項目をさがしてみました
#[geany]　の一番下の方まで行きます
 #(略)
geometry=0;0;1920;1080;0;
 #(略)
```
どうも、ここのサイズを小さくすればよい模様。
私はviで編集し(ひとまず640x480にしました)、変更を保存しました。

#4. 無事にメニュー復活
※注意
・**編集後の起動はターミナルから”geany”を起動すること。**
Applicationsから起動したところ、もとのメニューなしの最大解像度で起動しました。

・起動後に<Edit>ー<Preference>でGeneralタブよりShutdownの
　-save window size
  -save window position
のチェックを外して「OK」、念の為メニューよりGeanyをQuit・終了します。

![normal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/ee88ca79-78a9-cd02-a63a-e7dfe477d057.jpeg)

これで無事にメニューも復活して起動できました。
（shutdownの項目は正常起動後は戻しても問題ないです)

#5. おわりに
1.設定ファイルのgeanyメニューのpositionや設定の保存を変更すれば、
　後半のメニュー変更は不要だったかもしれません。
　今は元に戻ったので、検証できていません。

2.熟練ユーザーの方には難しい問題でないかもしれませんが、
元に戻すのに小一時間ハマッたのでメモ代わりに共有させていただきます。
[javascript] isTrusted=trueな疑似クリックを作る 

# isTrusted
ブラウザ上で発生するEvent（clickとか）にはisTrustedというプロパティがついている。
https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
ユーザーが実際にElementをクリックした時はisTrusted=trueだが、例えば：

```javascript
const button = getElementById("button");
button.click();
```

などによるjavascriptで生成された疑似クリックではisTrusted=falseとなる。

# isTrusted=trueのイベントを作りたい
isTrustedはRead-onlyプロパティなので外部から変更することはできないし、そもそも疑似クリックはTrustされるべきではない（そらそう）。しかしどうしてもisTrusted=trueなクリックを作りたい時はある（ブラウザ拡張作りたい時とか）ので調べてみた。**セキュリティに関しては自己責任でお願いします**

# コード

```javascript
Element.prototype._addEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function () {
  let args = [...arguments];
  let temp = args[1];
    args[1] = function () {
    let args2 = [...arguments];
      args2[0] = Object.assign({}, args2[0]);
      args2[0].isTrusted = true;
      return temp(...args2);
    };
  return this._addEventListener(...args);
};
```

Element.protype.addEventListenerの第二引数を書き換える方法。

```javascript
const button = document.getElementById("button");
button.addEventListener("click", (e) => {
  console.log(e.isTrusted);
});
button.click();
// "true"を出力
```

書き換えた後のaddEventListenerは全てisTrusted=trueになっている！

# 参考

[このスレ](https://stackoverflow.com/a/62738815) より抜粋。他にもpuppeteerを使う方法とか別言語のスクリプトでイベント生成させる方法とかあったけど、↑が一番楽と思う。ご高覧いただきありがとうございました。
２D線分計算Class


線分と線分の交差判定や交差点、線分と点との最短距離、外積と法線を求める等の２Ｄでよく使う処理をまとめたClass


```c#:ClassLine.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//線分class
public class ClassLine
{
    public Vector2 p1;//開始点
    public Vector2 p2;//終了点

    //線分コンストラクタ
    public ClassLine(Vector2 p1, Vector2 p2)
    {
        this.p1 = p1;
        this.p2 = p2;
    }
    //複製
    public ClassLine Clone()
    {
        return new ClassLine(p1, p2);
    }
    //ベクトル
    public Vector2 v
    {
        get { return p2 - p1; }
    }
    //2点間の距離
    public float distance
    {
        get { return Vector2.Distance(p1, p2); }
    }
    //外積
    public float cross(Vector2 p1, Vector2 p2)
    {
        return p1.x * p2.y - p2.x * p1.y;
    }
    //平行
    public bool isParallel(ClassLine line)
    {
        return cross(v, line.v) <= Vector2.kEpsilon;
    }
    //法線
    public Vector2 normal
    {
        get
        {
            return Vector2.Perpendicular(v);
        }
    }
    //最近点
    public Vector2 nearestPoint(Vector2 point)
    {
        Vector2 v1 = point - p1;
        float dot = Vector3.Dot(v, v1);

        Vector2 p = p1 + v * dot / v.sqrMagnitude;
        if (Vector2.Dot(p - p1, v) < 0) { p = p1; }
        else if (Vector2.Distance(p1, p) > distance) { p = p2; }

        return p;
    }
    //線分との交差判定
    public bool isCross(ClassLine line)
    {
        Vector2 v1 = p1 - line.p1;
        Vector2 v2 = p2 - line.p1;
        Vector2 v3 = line.p1 - p1;
        Vector2 v4 = line.p2 - p1;
        return cross(line.v, v1) * cross(line.v, v2) < 0 && cross(v, v3) * cross(v, v4) < 0;
    }
    //線分との交差点
    public Vector2 crossPoint(ClassLine line)
    {
        Vector2 v1 = line.p1 - p1;
        float nume = cross(v1, line.v);
        float deno = cross(v, line.v);
        float t = 0;
        if (deno != 0)
        {
            t = nume / deno;
        }
        return p1 + v * t;
    }
    //点との最短距離
    public float distanceFromPoint(Vector2 point)
    {
        return Vector2.Distance(nearestPoint(point), point);
    }
}

```
tkinter：タイマー的なもの

```py
import tkinter as tk

class Timer:

    def __init__(self):
        self.root = tk.Tk()
        self.message = tk.StringVar()
        self.message.set("Test")
        label = tk.Label(textvariable=self.message, font=('Helvetica', 48))
        label.pack()
        self.count = 0

    def update(self):
        self.count += 1
        self.message.set(str(self.count))
        # self.label.configure(text=label_txt)
        self.root.after(1000, self.update)

    def main(self):
        self.root.after(1000, self.update)  # "Test"を描画させるために1秒後にupdateを呼ぶ
        self.root.mainloop()                # 描画処理が始まり、初期設定した"Test"が描画される


app = Timer()  # インスタンス生成：速やかに終わらせる
app.main()     # メインループ処理：描画やイベント処理を行う

```
Python:NFCとtkinter(穴埋め式)


この記事はpythonでNFCカード等を読み取れていることを前提にした記事です。
読み取りの準備等は[Python:NFC](https://qiita.com/doyodoyo/items/22c56d5d7d2e998924b9)を参考にしてください。

#tkinter & nfcpy
tkinterでnfcタグの内容を読み取ろうとするとうまく動きませんでした。
おそらく、nfcpyの読み取りで待ってしまうので、タイムアウトを設定しないといけないっぽい。
[nfcpyにおけるタイムアウト処理](https://www.kosh.dev/article/3/)を参考に下記のように一応解決できました。


##nfc_reader.py
nfc_reader.pyという名前のファイルを作って、下記のプログラムをコピペしてください。
[NFCタグ](https://www.sanwa.co.jp/product/syohin?code=MM-NFCT)のレコードを読み取るプログラムです。

```py
#nfc_reader.py

import nfc

class Reader():
    def __init__(self):
        # 表示用
        self.on = False
        self.txt = ''

    def on_connect(self, tag):
        self.on = True
        try:
            self.records = tag.ndef.records
            self.txt = self.records[0].text
        except:
            pass
        return True

    def on_release(self, tag):
        self.on = False
        # self.txt = "タッチしてください"
        return True

    def __call__(self):
        clf = nfc.ContactlessFrontend('usb')
        try:
            clf.connect(rdwr= {'on-connect': self.on_connect,'on-release': self.on_release})
        finally:
            clf.close()

    def check_loop(self):
        while True:
            self.__call__()

```

##main.py
nfc_reader.pyと同じディレクトリにmain.pyをつくり、下記のプログラムをコピペしてください。

```py
#main.py
import tkinter as tk
import time
import threading
import nfc_reader

class Display():
    def __init__(self):
        self.root = tk.Tk()
        # ラベルの設定--------------------------------
        self.labe_text = tk.StringVar()
        self.labe_text.set("表示ラベル")
        self.label = tk.Label(textvariable=self.labe_text, font=('Helvetica', 48))
        # ------------------------------------------
        self.label.pack()
        #①nfc_reader.Reader()でNFCリーダーをインスタンス化
        #self.my_nfc_readerというメンバ変数にインスタンスを入れてください。

        # ------------------------------------------
        #②インスタンスのcheck_loopというメソッドをスレッドの対象に設定
        
        # ------------------------------------------
        #③スレッドをスタート

        # ------------------------------------------
        self.update_label()
        self.root.mainloop()

    def update_label(self):
        try:
            #self.my_nfc_readerのonというメンバ変数がTrueなら内容を表示
            if self.my_nfc_reader.on==True:
                self.labe_text.set(self.my_nfc_reader.txt)
                print("on")
            #self.my_nfc_readerのonというメンバ変数がFalseならタッチしてくださいと表示
            else:
                self.labe_text.set("タッチしてください")
                print("off")
        except:
            self.labe_text.set("ボタンを押してください")
        self.root.after(100, self.update_label)

app=Display()
```
【SQL】FIND_IN_SET()とは ※主にWHERE句

#FIND_IN_SET(検索文字,カンマ区切り文字)

【カンマ区切り文字列】に、検索したい文字列が含まれてたら、1～Nまでの値を返す。

```sql

SELECT find_in_set('1', '1,2,3,4')
1
SELECT find_in_set('2', '1,2,3,4')
2
SELECT find_in_set('3', '3')
1
SELECT find_in_set('', '1,2,3,4')
0

```

#whereのFIND_IN_SET()
```php
WHERE FIND_IN_SET(?, S.archetype1_id) > 0

    ->where('FIND_IN_SET('.$id.', senyou_artifact_id)');
```



■参考サイト

https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_find-in-set
【Microsoft Azure】AZ-104 合格体験記

# はじめに
2021年11月にMicrosort社の提供するクラウドAzureに関する試験、「AZ-104」を受験し合格しました。
この記事ではAZ-104を合格するための勉強法について紹介します。

# AZ-104とは
Azure管理者向けの資格でAzureの基本的な概念の知識が必要です。

:::note warn
Azure試験の中では中級レベル(Associate)の試験となりますので、クラウドが未経験者の方は「Fundamentals」といわれるAZ-900から受験することをお勧めします。
:::

AZ-900の詳細は下記Microsoftの公式サイトをご確認ください。
[試験 AZ-900](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)

# 試験範囲
Azure の主要なインフラストラクチャーのサービスの基本概念、デプロイ、管理、監視について出題されます。

- Azure ID およびガバナンスの管理（15～20%）

- ストレージの実装と管理（15～20%）

- Azure コンピューティング リソースのデプロイと管理（20～25%）

- 仮想ネットワークの構成と管理（25～30%）

- Azure リソースの監視とバックアップ（10～15%）

# 学習開始時点での知識
AZ-900の資格は取得済みでAzureに関する業務を4年ほど経験があります。
設計構築や知識があるものは以下の通りです。

Azureセキュリティ
　- Azure Active Directory
　- Azure VPN
　- Azure Application Gateway

Azureネットワークサービス
　- Azure Virtual Network
　- Azure Network Security Group
　- Azure ExpressRoute
　- Azure Bastion
　- Azure Load Balancer
　- Azure Traffic Manager
　- Network Watcher

Azureコンピューティング
　- Azure Virtual Machines
　- Virtual Machine Scale Set

Azureストレージ
　- Azure Backup
　- Azure Files
　- Azure Blob Storage
　- Storage Account

# 学習期間
過去にAz-103を学習していたこともあり、Az-104は約1ヵ月となります。
>Az-103の学習期間は約3ヵ月(休日のみ)ですが、参考書は購入せずひたすら英語の過去問を解いていました。
>その結果、650点で不合格になっています。

# 学習方法
私の場合、仕事上でAzure Portalを操作していることもあり基本的な操作の知識はありましたので、
主に参考書（[Microsoft認定試験AZ-104:Microsoft Azure Administratorテキスト](https://onl.la/2uN4DgJ)）や[Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-104)を利用して学習を行いました。

# 学習の流れ
参考書を読み章末問題を解き間違えた部分は参考書を読み返しやMicrosoft Learnを利用し理解を深めていきました。

:::note info
参考書に記載されているポイントを押さえておくと、理解が早いと思います。
:::

試験一週間前に参考書の演習問題を解き、理解が浅い部分を何度も復習しました。

> 私は参考書を5回読み返し、演習問題は3回解きました。
> また、演習問題を解く際に答えだけを選ばず「このサービスはこういう内容だから違う」という理解をしながら解くことを意識していました。

:::note warn
本試験ではAzure Portal画面の操作問題も出題される可能性があるため、Azure Portal画面の操作方法の学習をすることをお勧めします。
:::


# 感想
業務上でAzureに携わっていても細かい内容まで理解できていませんでしたが、資格勉強をすることでより理解を深めることができました。
また、Webアプリの作成やソリューションの開発/実装の経験はありませんがAzureの知識を増やすために次回はAz-204に挑戦したいと考えていいます。
※最近英語版で受験できるようになったAz-305にも興味があるので、日本語版が対応したら視野に入れたいと思います。
Pumaが起動しない。Deployできない。その時に真っ先につぶしておきたい可能性

# 概要

- ステージングやプロダクション環境でPumaを起動しようとするとエラーが出て起動しない
- ステージングやプロダクション環境にデプロイしようとするとエラーが出て途中で終了する
- ローカルの開発環境ではエラーなくRailsが起動する

このような状況になった時、様々な原因が考えられます。
デプロイ設定やインフラが疑われますが、真っ先につぶしておきたい可能性があります。

**本当にローカルの開発環境ではエラーないの？**

この記事ではその確認方法を紹介します。

# 目次

[バージョン](#バージョン)
[エラー状況](#エラー状況)
[エラー原因](#エラー原因)
[確認方法](#確認方法)
[よくあるエラー](#よくあるエラー)
[最後に](#最後に)

# バージョン

Ruby：2.7.3
Rails：6.1.4.4
Puma：5.0
Capistrano：3.16.0

# エラー状況

Puma起動時にエラーになる

```sql
/var/www/rails/application/shared/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.5.4/lib/zeitwerk/loader/callbacks.rb:25:in `on_file_autoloaded'

Zeitwerk::NameError
```

あるいは、
Deploy途中のyarn installでエラーになる

```sql
error Command "webpack" not found.
```
（webpackerを動かすためにrailsを起動しようとして失敗）

あるいは、
Deploy途中のwheneverでエラーになる

```ruby
from config/schedule.rb:6:in `initialize'
from config/schedule.rb:6:in `require'
```
（wheneverの設定が悪いと思いきやrails起動に失敗していることがある）

# エラー原因

Railsのステージングやプロダクション環境では、Railsの起動時に大半のコードが読み込まれます。コードにシンタックスエラーなどがあると、コードの読み込みに失敗してRailsを起動することができません。

一方、開発環境（development）では、Rails起動時にコードが読み込まれる訳ではありません。大抵のコードは必要になった時に読み込まれます。Railsが起動するだけでは読み込まれないコードが多くあるのです。

そのため開発環境では一見問題なく動作しているように見えてもエラーを抱えたままといったことがあります。そしてステージングやプロダクション環境でRailsを起動した時に隠れていたエラーが表面化するのです。

# 確認方法

開発環境（development）でもステージングやプロダクション環境と同じようにRails起動時にコードを読み込ませる方法があります。

config/environments/development.rb

変更前

```ruby
config.cache_classes = false
config.eager_load = false
```

↓

変更後

```ruby
config.cache_classes = true
config.eager_load = true
```

開発環境（development）でRailsを起動してみてください。

シンタックスエラーがあったりするとエラーが出てRailsが起動しなくなるはずです。

# よくあるエラー

Railsではファイル名とクラス名が一致していないと起動時にエラーになる

例
ファイル名「hoge.rb」
クラス名「Hoge」でなければならないが
「Fuga」とか違ってたら起動時にエラーになる

# 最後に

Pumaが起動しない。Deployできない。その原因は多くの可能性が考えられます。
サーバー、ネットワーク、デプロイ、Pumaといったいった環境周りが原因かもしれません。

ローカル開発環境では動いてたのに。。。
よーく調べてみるとRubyコードの凡ミスだったということがあります。

この記事が問題の切り分けのお役に立てればと思います。
エクセルをサクラに貼り付けて、インサートデータの形にするサクラマクロ


サクラへの貼り付けは手動だよ

#マクロ本文
UTF-8 BOM付で保存してね。

``` createInsetData.mac
//キーボードマクロのファイル
ReplaceAll('\\t', '\', \'', 38);	// すべて置換
ReDraw(0);	// 再描画
ReplaceAll('^', '\\t(\'', 38);	// すべて置換
ReDraw(0);	// 再描画
ReplaceAll('$', '\'), ', 38);	// すべて置換
ReDraw(0);	// 再描画

```

#実行前後

これが

```
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3
データ1	データ2	データ3

```

こうなる

```
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 
	('データ1', 'データ2', 'データ3'), 

```
[UE4] iniファイルの管理で使うプラットフォーム名(Platform)の調べ方

# はじめに
特定のプラットフォーム毎に処理や品質設定などを変えたい場合は、[プラットフォーム名]Engine.ini といったファイルを作成・編集する必要があります。例えば、WindowsEngine.ini や AndroidEngine.ini などです。公式ドキュメントにもこう書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/bd2c188b-1bd4-b8ad-2e9e-429cfcd79905.png)
[公式ドキュメント：コンフィギュレーション ファイル](https://docs.unrealengine.com/4.27/ja/ProductionPipelines/ConfigurationFiles/)

しかし、このプラットフォーム名が具体的にどんな文字列なのかについては（恐らく諸事情で）書かれていません。なので、調べ方についてご紹介します

# プラットフォーム名(Platform)の調べ方

各プラットフォームごとに定義された ```IniPlatformName``` 関数　を見てください
おわり


…Windowsの場合

```c++:Engine\Source\Runtime\Core\Public\Windows\WindowsPlatformProperties.h
struct FWindowsPlatformProperties
	: public FGenericPlatformProperties
{
...
	static FORCEINLINE const char* IniPlatformName()
	{
		return "Windows";
	}
```

Android

```c++:Engine\Source\Runtime\Core\Public\Android\AndroidPlatformProperties.h
struct FAndroidPlatformProperties
	: public FGenericPlatformProperties
{
...
	static FORCEINLINE const char* IniPlatformName()
	{
		return "Android";
	}
```

IOS

```c++:Engine\Source\Runtime\Core\Public\IOS\IOSPlatformProperties.h
struct FIOSPlatformProperties
	: public FGenericPlatformProperties
{
...
	static FORCEINLINE const char* IniPlatformName( )
	{
		return "IOS";
	}
```

Mac

```c++:Engine\Source\Runtime\Core\Public\Mac\MacPlatformProperties.h
struct FMacPlatformProperties
	: public FGenericPlatformProperties
{
...
	static FORCEINLINE const char* IniPlatformName( )
	{
		return "Mac";
	}
```

Linux

```c++:Engine\Source\Runtime\Core\Public\Linux\LinuxPlatformProperties.h
struct FLinuxPlatformProperties
	: public FGenericPlatformProperties
{
...
	static FORCEINLINE const char* IniPlatformName( )
	{
		return IS_AARCH64 ? "LinuxAArch64" : "Linux";
	}
```

**その他のプラットフォーム** は是非ご自身の目でご確認ください！
おしまい
macOSのFinderの「フォルダへ移動...」が賢くなっていた

## はじめに

### この記事を読むとできること

macOSのFinderで、目当てのフォルダを素早く開くことができます

## 動きの概要

`フォルダへ移動`を開き、フォルダ名をタイプすると、フォルダを開きます。

![SS 2022-02-15 11.26.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/d9ccacbf-4c68-4b1a-8054-f07a6a287ccf.png)

`shift + command + G` > フォルダ名タイプで、キーボードで完結します。

## おわりに

macOS Montereyの新しい機能でしょうか？　もしかすると、前からあったのかもしれないけど、気づいていませんでした。

隠しフォルダ（`.xxxxx`）を開こうと思うと、Finderで`shift + command + .`をタイプして探さなければならず、前々からめんどうくさいとおもっていました。

Finderのカラム表示の挙動も怪しいし、戻すのにまた`shift + command + .`をタイプしなければならないし。

`shift + command + G` から隠しフォルダにアクセスできるのは、めちゃたすかります。おもわず感激してしまった。

### 参考リンク

[How to quickly navigate to a folder in macOS Big Sur and Monterey | Macworld](https://www.macworld.com/article/550348/how-to-quickly-navigate-to-a-folder-in-macos-big-sur-and-monterey.html)

やっぱりMontereyの新機能でした。

### 環境

ここで書いていることは、下記のバージョンで実施しました。

- macOS Monterey 12.2.1
- MacBook Pro (13-inch, 2020, Four Thunderbolt 3 Ports)
Reactで<br/>を使用せずに改行する

#背景

Reactのアプリケーションで、バックエンドから改行を含む文字列を変数で受け取って、フロントエンドで改行させる方法を調べていたら様々な方法があったので個人的にお気に入りな方法をまとめておく。

#実装方法
```typescript:sample.tsx
import "./styles.css";

export default function App() {
  const val: string = {バックエンドから取得する処理};
  return (
    <div className="App">
      <h1 className="text">{val}</h1>
    </div>
  );
}
```

```css:styles.css
.text {
  white-space: pre-wrap;
}
```

#参考記事
https://zenn.dev/kanasugi/articles/b0547f5ae1f522
Railsチュートリアルの2章でつまづいた話

Railsチュートリアルの基礎中の基礎（2章のgit）で躓いたので備忘録としてアップしておきます。

環境
・cloud9
・Rails 5.1.6
・Ruby 2.6.3

Railsチュートリアル Rails ver.5.1.6では手順通りにgitの設定をしても100％エラーが出ます。（僕の力量では理由はわかりません）
1のnoteの手順通りに最後まで通した後2のqiitaの通りにするとなぜかはわかりませんがうまくいきます。

1 railsチュートリアルでBitbucket、Herokuでつまづいた人が行うべきこと
https://note.com/el93019205/n/n328eac66a260

2 Railsチュートリアル 1.4.3 Push時のエラー解決方法
https://qiita.com/kmat/items/3e3b681d4ce5a2877960
粗いセグメンテーションを洗練する

#セグメンテーションマスクの境界をくっきりさせる方法です
オリジナル
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ff68a198-506b-7b25-f4f9-64d5dbb598dd.jpeg", width=400>
マスク／洗練されたマスク
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/bf429efe-4f8a-a615-cb7a-580953b51444.jpeg", width=400> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/cf824146-10bc-27d6-baa7-57f76fdbdd68.png", width=400>

#もっと綺麗なセグメンテーションが欲しい
セグメンテーションの結果が、あまり鮮明でない場合があります。
これは、入力画像サイズの制限やセグメンテーションモデル自体の性能によります。

#CascadePSPで境界を洗練
セグメンテーションマスクの境界を洗練するための機械学習モデルです。

https://github.com/hkchengrex/CascadePSP

#使い方

インストール

```shell
pip install segmentation-refinement
```

実行

```
import cv2
import segmentation_refinement as refine

image = cv2.imread('image.jpg')
mask = cv2.imread('mask.jpg', cv2.IMREAD_GRAYSCALE)

refiner = refine.Refiner(device='cpu')

output = refiner.refine(image, mask, fast=False, L=900) 
cv2.imwrite("out.jpg",output)
```

#モデルを組み合わせるという発想
いくつかのモデルを組み合わせて性能を向上させるアプローチは面白いですね。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Rails+CapistranoでEC2にデプロイするときにハマったメモ

## 簡潔に話すと
**Rails内のクラスファイル名とクラス名を命名規則通りにしておくべし**
## 背景
新人研修の準備として、研修用アプリのAWS内のEC2に本番環境を構築していた。
ローカルからCapistranoを使ってデプロイしようとしていた際にエラーにハマった。
## 環境
Mac
DockerDesktop
Rails　6.1.4
Capistrano　3.11.2
AWS EC2 AmazonLinux
##ハマったエラー１：yarn installで「webpack not found」
Capistranoを使ってローカルのDockerからデプロイしていたところ、yarn install の途中で「webpack not found」のエラーが発生してデプロイが完了しなかった。やむを得ず、[こちら](https://qiita.com/jesus_isao/items/c95ea253dd7a90b01ff0)を参考に yarn install の含まれる assets:precompile　をローカルで行うことでこのエラーを回避した。

##ハマったエラー2：puma:startでpumaが起動しない
その後もCapistranoのデプロイ処理を進めていたところ最後の puma:start でエラーが発生した。
pumaのログを確認してみると、それらしいエラーログを発見。
どうやら「Zeitwerk」の「on_file_autoloaded」でコケているみたいだった。
まずは「Zeitwerk」がよくわかっていないので、何をしているものなのか調べてみた。

[定数の自動読み込みと再読み込み (Zeitwerk)](https://railsguides.jp/autoloading_and_reloading_constants.html#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E6%A7%8B%E9%80%A0)
>通常のRailsアプリケーションでrequire呼び出しを行うのは、libディレクトリにあるものや、Ruby標準ライブラリ、Ruby gemなどを読み込むときだけです。そのため、これらのような自動読み込みパスに属さないものについてはすべて後述します。
Railsではこの機能を提供するため、いくつものZeitwerkローダーを開発者の代わりに管理しています。

どうやらrequireなどの参照関係の読み込みに関する処理をしてくれている模様…
>2 プロジェクトの構造
Railsアプリケーションで使うファイル名は、そこで定義されている定数名と一致しなければなりません。ファイル名はディレクトリ名と合わせて名前空間として振る舞います。

>たとえば、app/helpers/users_helper.rbファイルではUsersHelperを定義すべきですし、app/controllers/admin/payments_controller.rbではAdmin::PaymentsControllerを定義すべきです。

ここの記述で心当たりが浮かんできた。
そういえば研修のサンプルとしてテキトーな名前のrbファイルを配置していた気がする…
![スクリーンショット 2022-02-14 11.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815054/bc733c23-575c-8625-fb67-dc651cdcf13d.png)
**あったぁぁぁぁぁぁーーーーーー！**
※画像は再現イメージです

早速、このファイルを削除してからもう一度デプロイしてみる…
**通ったぁぁぁぁぁぁーーーーーー！**

その後、yarn install に関しても同じ原因だったことがわかりました。
Railsの命名規約はきちんと守りましょう。

## 参考
- [capistranoのassets:precompileをローカル側で実行し、各Webサーバーにはコンパイル済みファイルを配る](https://qiita.com/jesus_isao/items/c95ea253dd7a90b01ff0)
- [定数の自動読み込みと再読み込み (Zeitwerk)](https://railsguides.jp/autoloading_and_reloading_constants.html#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E6%A7%8B%E9%80%A0)
インターフェースに静的メソッドを作りたくなったら

# インターフェース
ガチのinterfaceだと無理なのでclassをインターフェースとして作成する

```cs
public class ISomething {
	protected delegate void StaticFuncDelegate(string arg);
	protected static StaticFuncDelegate func;

	public static void StaticFunc(string arg) {
		func?.Invoke(arg);
	}
}
```

# インターフェースを実装する
```cs
public class SomethingImpl : ISomething  {
	public SomethingImpl {
        Initialize();
    }
    public void Initialize() {
        func = StaticFuncImpl;
    }
    private static void StaticFuncImpl(string arg) {
        System.Diagnostics.Debug.WriteLine("called.");
    }
}
```

# 使う人

```cs
public class Caller{
    public void CallFunc() {
        ISomething.StaticFunc("なんか");
    }
}
```

# 何がやりたかったのか

各部品からメインループにメッセージをポストしたい。が
メインループと部品は切り離したかった。
部品側でインスタンス持ち回りはしたくない。
メッセージキューの実体はメインループ実装先に置きたい。

`SendMessage(msg)`の実装をメインループ実装先に置いて
部品からSendMessage(msg)とすれば
メインのメッセージキューに積まれるようになる。
【SQL】カンマ区切りの複数idとテーブルをjoinする方法

#コード
```SQL
    from V_chara_data C
正規表現で使う方法
    LEFT JOIN V_zokusei_data Z on C.zokusei_id REGEXP CONCAT('(^|,)', Z.id, '(,|$)')
FIND_IN_SETでの方法
    LEFT JOIN V_zokusei_data Z ON FIND_IN_SET(Z.id,C.zokusei_id)
コードイグナイターの方法
    ->join('wp_skill_data SK','find_in_set(SK.id,V.skill_id)','left')

GROUP BY C.id
```
Raspberry Pi4をAmazonプライムビデオ専用機に2

# Raspberry Pi4をAmazonプライムビデオ専用機に2

なんのことはないですが、1年ほど使用していて動作が不安定になってきたので
最新のLineageOSを再導入してみました。
目的は、Raspberry Pi4をAmazonプライム専用機として最導入しただけです。

## 1.Raspberry PiにLineageOSを導入

### 1.1 LineageOSのダウンロード
[LineageOS 18.1 (Android 11) for Raspberry Pi 4](https://konstakang.com/devices/rpi4/LineageOS18/)

上記サイトから「lineage-18.1-20210214-UNOFFICIAL-KonstaKANG-rpi4.zip」をダウンロードして、展開しておきます。

### 1.2 MicroSDカードへの書き込み

前回、同様にこのimgファイルをMicroSDカードに焼くには、[balenaEtcher](https://www.balena.io/etcher/)を使います。(v1.5.109からv1.7.3に変わっていた))

balenaEtcherを起動し[Select images]を押し、先程解凍したimgファイルを指定し、[Select drive]にて「LineageOS」をインストールするMicroSDカードを指定し、[Flash!]を押す。
ここまでは前回と何も変わらずですね。

数分待つと

### 1.3 LineageOSセットアップ

Raspberry pi4にモニター、キーボード、マウスを接続し、MicroSDカードを「Raspberry Pi4」に接続し起動します。

Raspberry pi4を起動すると初期セットアップが始まりますので、言語では「日本語」を選択し、Wifiの設定、Timezone、日付と時刻を設定します。

その後、LineageOSが起動します。

## 2. カスタムOSインストール

### 2.1 MicroSDのFSリサイズのダウンロード
他端末でブラウザで[LineageOS 18.1 (Android 11) for Raspberry Pi 4](https://konstakang.com/devices/rpi4/LineageOS18/)にアクセスし、サイトに記載している以下リンクを辿りlineage-18.1-rpi-resize.zipをダウンロードする。
Q: Settings -> Storage shows total system size of 7 GB. There’s unallocated space on my sdcard. What should I do?
A: This is a 7 GB image, remaining space on your sdcard will remain unallocated. Easiest way to extend /data partition is to simply flash my resize zip in TWRP.

### 2.2 Google Play のダウンロード
他端末でブラウザで[ここに](https://sourceforge.net/projects/opengapps/files/arm/test/)にアクセスして、pico版の「open_gapps-arm64-11.0-pico-20220211.zip」をダウンロードします。

### 2.3 ダウンロードしたファイルをUSBメモリにコピー
ダウンロードした以下ファイルをUSBメモリにコピーしておく。
lineage-18.1-rpi-resize.zip
open_gapps-arm64-11.0-pico-20220211.zip

### 2.4 再起動設定
「システム」→「ジェスチャー」→「電源ボタンメニュー」を選択し、「高度な再起動」を有効にする。

### 2.5 Recoveryモードでの起動
ダウンロードが終了したら、キーボードの「F5」キーを長押し、「再起動」を選択し「リカバリ」を選択する。

### 2.6 MicroSDのFSリサイズのインストール
[Install]→[Select Storage]からUSBメモリを選択してUSBメモリ内の[lineage-18.1-rpi-resize.zip]を選択してインストールします。
インストールが完了したら再起動します。

### 2.7 Google Play のインストール
[Install]→[Select Storage]からUSBメモリを選択してUSBメモリ内の[open_gapps-arm64-11.0-pico-20220211.zip]を選択してインストールします。
インストールが完了したら再起動します。

## 3. Amazonプライムビデオの設定

### 3.1 Googleアカウント設定
設定画面(初期画面から右にスライドし、右下の歯車を押す)→「アカウント」→「アカウントを追加」を押しGoogleアカウントを設定します。

### 3.2 GooglePlayからAmazonプライムビデオをインストール
ホーム画面にてホームボタンを上にドラッグすると現在インストールされているアプリの一覧が出てきますので、「Playストア」を押し[Amazonプライムビデオ]をインストールします。
その後、Amazonプライムビデオを起動し、Amazonプライムアカウントを設定し使用できるようになります。
【Power Automate】承認要求の取り消しについて

# 要求をキャンセル

Teams の [承認] 機能で [要求をキャンセル] を選択することで、承認要求を取り消すことができるようになっているのですが…。

![pa001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/619dc166-9cfc-7d9e-b321-45e9db7e8fd7.png)

要求をキャンセルした場合、[結果] が空で返ってきます。
これを考慮した設計をしていないと、要求をキャンセルしたはずなのに、承認された際の動作をしてしまう！なんてことが起こります。

## 対処方法

以下のテンプレートを利用した場合を例に説明します。

![pa002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/7e7a5020-e47d-70eb-9830-d41d74600f73.png)

承認者に指定した全員からの結果の中に、一件でも **却下 (Reject)** が含まれていれば **承認 (Approve)** としない判定をしています。そのため、要求をキャンセルした場合には **却下 (Reject)** が含まれておらず、 **承認 (Approve)** 扱いになってしまいます。

**承認 (Approve)** or **却下 (Reject)** の判定する前に、[結果] が空かどうか判定する必要があります。

![pa003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/3c67a80a-bf18-dd86-39bf-53c279ff2c0a.png)
VisualStudio for Mac 2019 にて新しいファイルがコミットできない場合の応急処置

VisualStudio for Mac 2019にて
新しいフォルダを作成し、そこに新しいファイルを作成するが、新しいファイルのみコミット内容に含まれない場合の応急処置
既にローカルのマスターに反映されているフォルダにファイルを作成してそれをVisualSturio上で新しく作成したフォルダにドラッグアンドドロップしたらコミット内容に含まれまる

根本的な解決にはなっていないのでとりあえずの応急処置として、、
commit間の差分をzip出力する

#はじめに
commit間の差分ファイルをzip化する必要があり、また同じことをする際に忘れている自信があるので
この記事で保管することにする。

細かいことまで理解していないが、
これでお目当ての差分が抽出でき、zip化できたので脳死でコマンドを叩くことにする。

# コマンドテンプレ
```
$ git archive {ブランチ名} `git diff --name-only {コミットIDから} {コミットIDまで} --diff-filter=d` -o {出力ファイル名.zip}
```

# 具体例
```
//コミット履歴を取得
(develop) $ git log
>commit hogehoge2
>commit hogehoge1

//コミット間の差分をzipにする
$ git archive develop `git diff --name-only hogehoge1 hogehoge2 --diff-filter=d` -o fugafuga.zip
```

# 参考
https://www.granfairs.com/blog/staff/git-archivediff
postgresDB initdbコマンド実行時「bash: initdb: コマンドが見つかりませんでした...」と出力される

# 環境
Oracle Linux7.9
Postgres 11.15

#　事象
[postgres@OL79 ~]$ initdb -D /home/postgres/data --no-locale
bash: initdb: コマンドが見つかりませんでした...

英語なら"command not found"と出力される事象。

# 対策
インストールユーザ（postgresユーザ）で下記コマンドを実行してパスを通す
```export PATH=/usr/pgsql-11/bin:$PATH
```

または上記内容をpostgresユーザの.bash_profileに追記し、sourceコマンドで反映させる

```[postgres@OL79 ~]$ vi ./.bash_profile 
[postgres@OL79 ~]$ source ./.bash_profile
```

# 参考
・Linux入門 ~「パスを通す」とは~
https://qiita.com/Naggi-Goishi/items/2c49ea50602ea80bf015
公式ドキュメントでよく出てくるであろう英単語集（随時更新）

## この記事の目的

MongoDBのセキュリティアンケートのドキュメントを読む機会があり、いくつか覚えのない単語に遭遇した。この先もこれらの単語に遭遇するかもしれないのでメモを残しておく。

- Primer　手引き
- Terminology 用語
- authentication　認証
- authorization　承認
- encryption　暗号化
- decrypt　復号化
- underlying infrastructure 基盤のインフラ
- hierarchy　階層
- X is built atop of Y　XはYの上に構築される
- dedicated  専用の
- solely　専用の
- enabled　有効になる
- domain 領地
- opt 選ぶ
- atlas 地図帳
- Realm　領域
- dynamo 発電機
- span またがる
- initiate 開始する
- on-prem オンプレミス
- IN-TRANSIT データ送信中
- AT-REST　停止中
- control plane　コントロールプレーン
- ciphers　暗号
- deprecated　非推奨
- industry　standard　業界標準
- capability 機能
- implemented　実装されている
- A maintains Aが管理している
- then　次に
- irrecoverable　回復不能
- plaintext　平文
- paged to A Aにページングされる


- decouple
分離
生産性を分ける社員の自律レベル（社畜レベル）



エンジニアのあなたはどの社畜レベルになるかな？

![写真 2022-02-13 12 25 13 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/7f0dc91a-b6de-a870-54dd-5192a85b05ee.jpeg)

この本を読んでたら「自律レベル」という名の「社畜レベル」みたいなレベル分けが出てきたので書いておくよ！

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

### LEVEL 1 - 規則意識 ルール・規則に従う

最も自律レベルが低い段階は、「規則意識」による自律です。「ルール・規則に従わなければならない」という義務感で仕事を進める状態です。行動を規定する「型」がなければ仕事が進められないというレベルであり、その意味では自律しているとは言えません。上司の定めた役割やルールをただ踏襲するだけで、責任感などの自負心や仕事への意欲も生まれていません。自律の中でも最も内発的なモチベーションが低い状態です。上司や先輩に言われたとおりに行動する状態であり、まだ主体的な姿勢は見られません。

### LEVEL 2 - 責任意識 責任感・プライドを感じる

「責任意識」によって仕事を進めるというレベルです。責任感・プライドを感じて、自らの役割を果たすために仕事をしている状態です。このレベルになると、一つひとつ指示・命令をされなくても自ら仕事を進めます。その意味で、このレベルにある社員を「自律している」と評価する方もいるかもしれません。しかし、自律レベルは相対的に低く、これまでの研究では最適な状態とはされていません。
その理由は、自律的な行動が生まれるときの本人の心理状態にあります。LEVEL2の状態で自律的に働く社員は、言ってみれば心理的なプレッシャーに背中を押されている状態です。「チームの一員として責任を果たさなくてはいけない」「みんなの前で恥をかきたくない」「能力が低いと思われたくない」といった気持ちで仕事に従事します。仕事そのものに価値を感じているわけではなく、やらなければ自分の評価が落ちるような義務・責任が発生しているから仕事を進めていきます。このような状態は “Driven to Work” と表現されます。「仕事に駆り立てられている」「仕事に追われている」という状態であり、緊張やストレスを感じやすく、仕事において、持続的な効果が見込みにくいとされています。本人のメンツが保たれるレベルのパフォーマンスを達成すると、それ以上は控えてしまうためです。

### LEVEL 3 - 価値理解 仕事の価値を理解する

さらに「自分自化」が進みます。「価値理解」のレベルです。自分にとっての仕事の価値や重要性を理解し、その価値を生み出すために自ら取り組んでいる段階です。例えば、仕事の経験を積むことが将来的に自分にとってどのような意味や価値をもたらすのか、それが理解できている状態です。ただし、この段階ではまだポジティブな感情が醸成されているわけではありません。頭では仕事の重要性を理解していても、気持ちがついてきていない状態です。例えば、親から「将来にとって大事だから勉強しろ」と言われ、日々勉強に励む子供のイメージです。子供は、勉強自体を楽しんで行っているわけではありません。このレベルにある社員は「重要な仕事である」「自分にとってやった方が得なのだ」と自己を説得しながら、仕事を進めていきます。その意味で、切迫感や緊張感などのストレスを感じており、自律レベルが十分に強い状態とは言えません。

### LEVEL 1 - LEVEL 3

LEVEL1 から LEVEL3 までのステージにおける自律は、セルフマネジメン型の自律と言えます。やるべきことを正しくやろうという「真面目さ」が原動力となって仕事を進めていきます。仕事のなかで発生するタスクを、自分にとって意味のあるものだと認識できておらず、認識できていたとしてもポジティブな感情でそれを捉えることができていない状態です。

### LEVEL 4 - 価値実感 気持ちが動かされる

「価値実感」のレベルです。仕事に自分なりの価値を認識し、さらにその価値を実現していくことに対して、自分の気持ちをも高めることができている状態です。仕事の「自分自化」が進んでいることで、仕事を自分なりに解釈し、自分の仕事の主体者として認識できているような状態と言えます。

このレベルにある社員は、仕事を通して自分が成長していることを強く実感するなど、自分の影響力大きくなっていくような感覚を持っています。仕事に意義を感じ、楽しさを覚えるようになっているでしょう。

### LEVEL 5 - 価値体現 楽しさ・面白さを感じる

最後は「価値体現」のレベルです。誰に何を言われるまでもなく活動している状態です。すでに価値を実現することの喜び・面白さ楽しさをしっており、その感情をもう一度味わいたいと、新たな取り組みや試行錯誤を自発的に進めていきます。仕事に従事するなかで、自分の能力が十分に引き出されている感覚や、その能力によって仕事が前に進んでいる感覚を持ち、仕事に没頭しているという状態です。

### LEVEL 4 - LEVEL 5

LEVEL4 から LEVEL5 における自律は、セルフリーダーシップ型の自律と言えます。このレベルの社員にとって、仕事を推進する原動力となるのは「遊び」の感覚です。義務感や責任感によって自分を管理・統制しようとする姿勢を超えて、夢中になって仕事を進めるような状態です。仕事をしているときに充実感を覚えたり、仕事そのものが面白いと感じており、より良い価値の創出に向けて自分なりの工夫や試行錯誤を進めることができる段階です。
Cropping Image

# はじめに
画像をCroppingするコードを書いておきます。

#コード

```python
img_cropped = img[top:bottom, left:right]

# cx : cropする赤い枠の中心座標x
# cx : cropする赤い枠の中心座標y
# h : 赤い枠の高さ
# w : 赤い枠の幅


top = int(cy - 0.5 * h)
bottom = int (cy + 0.5 * h)
left = int( cx - 0.5 * w)
right = int( cx + 0.5 * w)

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/d4b7a1ac-29e8-81ba-6703-d83c583d4b3e.png)
タスク定義をプッシュした最新のイメージに変更するだけのbuildspec ファイル

#概要
CodeBuild 内で、イメージのビルドとECR にプッシュし、タスク定義のコンテナのイメージURIの変更だけをして、サービスにはデプロイしないケースを想定した buildspec ファイルです。

実行に必要なビルドプロジェクトの環境変数

|名前|説明|
|:---|:---|
|AWS_ACCOUNT_ID|AWS アカウントID|
|IMAGE_REPO_NAME|ECRのリポジトリ名|
|TASK_DEFINITION|タスク定義名|

実行に必要なIAM ポリシー

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:*"
            ],
            "Resource": "*"
        },
        {
            "Action": "iam:PassRole",
            "Effect": "Allow",
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringLike": {
                    "iam:PassedToService": "ecs-tasks.amazonaws.com"
                }
            }
        }
    ]
}
```

buildspec.yml 

```yaml
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - echo $AWS_DEFAULT_REGION
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - aws ecs describe-task-definition --task-definition ${TASK_DEFINITION} | jq '.taskDefinition | del(.taskDefinitionArn, .status, .requiresAttributes, .compatibilities, .revision)' | jq '(.containerDefinitions[] | select(.name == "'${IMAGE_REPO_NAME}'")).image = "'${REPOSITORY_URI}:${IMAGE_TAG}'"' > /tmp/taskdef.json
      - aws ecs register-task-definition --cli-input-json file:///tmp/taskdef.json
```
pyenv + virtualenv + mmcvのインストールエラー

# はじめに
Pyenv+Virtualenvで環境構築をしていて、mmcv-fullをインストールしようとしたらエラーが出た人向け。

# 現象
インストールすると、cmath系のエラーがたくさん出る。

```bash
$ pip install mmcv-full
......<省略>
de/ATen/core/aten_interned_strings.h:633:9: note: expanded from macro 'FORALL_ATEN_BASE_SYMBOLS'
      _(aten, signbit) \
              ^
      fatal error: too many errors emitted, stopping now [-ferror-limit=]
      20 errors generated.
      error: command 'clang' failed with exit status 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> mmcv-full

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
```

# 対策
SDKの参照先関係の理由が考えられるので、対策1,対策2を行った上で、Pyenvの環境を再構築する。
PyenvでPyenv installしたあとに、CommandLineToolを変更した場合などに、SDK参照先のコンフリクトが起きて発生しそう。正直詳細はわかっていないけど、下記手順で回復できた。詳しい人教えてください。

## 対策1: xcode-selectの再インストール
```
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
```

## 対策2: SDKの参照先を確認
こんなふうに表示されれば問題ない。

```bash
$ xcrun --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk
```

ちなみに、参照先を変更したい場合は、下記の様なコマンドを打つ。

```bash
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
$ xcrun --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
```

参照先をデフォルトに戻したい場合は、下記で戻せる。

```bash
$ sudo xcode-select --reset
```

## Pyenv virtualenvでの環境再構築
これは普通に削除して、再インストールする。

```bash
$ pyenv virtualenv-delete <ENV_NAME>
$ pyenv uninstall <BASE PYTHON VER>
$ pyenv install <BASE PYTHON VER>
$ pyenv virtualenv <BASE PYTHON VER> <ENV_NAME>
```

# 結果
```bash
$ pip install mmcv-full
Collecting mmcv-full
  Using cached mmcv-full-1.4.4.tar.gz (420 kB)
Requirement already satisfied: addict in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (2.4.0)
Requirement already satisfied: numpy in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (1.22.2)
Requirement already satisfied: packaging in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (21.3)
Requirement already satisfied: Pillow in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (9.0.1)
Requirement already satisfied: pyyaml in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (6.0)
Requirement already satisfied: yapf in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from mmcv-full) (0.32.0)
Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in ./.pyenv/versions/3.8.12/envs/py38-mmdetection/lib/python3.8/site-packages (from packaging->mmcv-full) (3.0.7)
Using legacy 'setup.py install' for mmcv-full, since package 'wheel' is not installed.
Installing collected packages: mmcv-full
    Running setup.py install for mmcv-full ... done
Successfully installed mmcv-full-1.4.4
```

無事にインストールできました。
Power Automate Desktop Tips - 空白文字を置換する -

#概要
タイトル通りですが、「テキストを置換する」アクションで
空白文字を使う方法の備忘録です。

#方法
例えば、「テキストを置換する」アクションで、
（正規表現を使わずに）ある文字列を違う文字列に置換するなら、
以下のような感じで入力すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/5dd442cd-7232-5340-45f8-b388f6e6e7a2.png)

で、今回は半角の空白文字を全角の空白文字にしたかったので、
検索するテキストに半角の空白を、
置き換え先のテキストに全角の空白を入力してみたら、
こんな感じでエラーが表示されます・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/6111cdf0-f086-7585-b2a5-d607b1bd5713.png)

「中田　」や「hogehoge 」というように、文字列の後に空白文字がある場合は
エラーも表示されず、処理も正常に実行できました。
どうやら空白文字だけ入力されているとエラーとなるみたいですね。

空白文字だけを検索したい、空白文字に置換したい場合には、
「%' '%」や「%'　'%」と入力するとできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/857936c0-09c7-b6ec-d891-2b789a3d79a2.png)
Salesforce Knowledgeの一括更新


[ナレッジの一括更新](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000E0MBySAN)

この質問に対する回答を考えました。

残念なことにこのヘルプを読む限りはデータローダでステータスをドラフトにすることはできないと書かれています。

You may be able to leverage the Apex Knowledge Management Publishing Service Class in order to set articles to draft, update them, and then re-publish but doing so would require the creation of a client tool to manage this overall process which is not supported. 

[Update Knowledge Base articles with Data Loader](https://help.salesforce.com/s/articleView?id=000312783&type=1)


探してみるとApexで一括更新ができるらしい。

[How to mass update Knowledge Article in Salesforce?](https://www.sfdcpanther.com/how-to-mass-update-knowledge-article-in-salesforce/)

このようなコードを匿名windowで処理させるとドラフトの記事が新規に作成されました。

```
KbManagement.PublishingService.editOnlineArticle('kA02x0000001qpuCAA',false);
```
 
ここで、Idと思って値をセットしていたのですが、 Invalid Idエラーになりました。 

[PublishingService.publishArticle Invalid Id](https://salesforce.stackexchange.com/questions/268212/publishingservice-publisharticle-invalid-id) 

これを読むとここにセットする値はオブジェクトのIdでなくKnowledgeArticleIdだったようです。
先ほどのApexも、もしかしたら同じエラーだったかもしれないです。

例えば、ExcelにKnowledgeArticleId列を作って
="KbManagement.PublishingService.editOnlineArticle('" & A1 &"',false);" みたいな数式を作ります。

この数式をコピーして、違う列に文字列として保存します。
この文字列の式を匿名windowで処理させたら、Apexのコードをかかなくても(Testクラスが無くても）ドラフトの記事を作ることが可能になると思いますね。

残念がらApexを使ったせいで、この回答は不採用でした....


# もっといい案はないのかな？

このApexコードを使って Apex REST API化できればKnowledgeArticleIdを使ってもっと手軽に一括更新ができるような気がします。
ちょっと時間があれば作ってみたいですね。


# 関連情報

+ [ナレッジ記事に対するHerokuツールの更新のトラブルシューティング](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C6xMsSAJ)
+ [Create a Lightning Knowledge Article URL that doesn't change](https://help.salesforce.com/s/articleView?id=000320825&type=1)