OmniAICreator/Qiita-1.07M huggingface dataset:
VS CodeでUnityをデバッグする方法（2022年版）

# きっかけ
いつの間にか、従来から使っていたVS CodeのExtensionであるDebugger for Unityが非推奨になっていた。非推奨でも使えればいいのだが、Unityのバージョンアップや何やらしている間にいつの間にか使えなくなっていた。

![スクリーンショット 2022-08-27 23.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/5c6b79b3-ef07-27f2-1112-d40bb6f78648.png)

Visual Studioを使ってもいいのだが、VS Codeに慣れてしまったので戻りたくなかった。が、エンジニアとして開発中のアプリのデバッグができないのは致命的なので、なんとかしたかった。

# 解決策
ExtensionでDebugger for Unityがもう一つあり、こちらを使うことで解決できた。検索で先に出てくるのは非推奨版なので注意（どちらにせよ、公式でサポートはされていないのでこちらもいつまで使えるかはわからないが）。
※非推奨版がインストールされている場合はアンインストールを先にしておくこと！

![スクリーンショット 2022-08-27 23.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/a346859f-771c-37f0-e645-911c1a3026f8.png)

# 使い方
従来のものとほとんど同じだが、一応記載しておく。
事前に上記で紹介したExtensionを入れておくこと。

1. VS Codeのデバッグタブに移動する
1. create a launch.json fileをクリックし、コマンドパレットからUnity Debuggerを選択する
<br>※すでに何らかの言語でデバッガが設定されている場合は、デバッガ選択のプルダウンのAdd Configurationを選択するとインテリセンスで新たなデバッガの設定を追加できるので、Unity Debuggerを追加する。
![スクリーンショット 2022-08-27 23.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/48d60a10-34ed-1464-eedf-d1f10ba7353a.png)
1. launch.jsonファイルが作られ、Unity Debuggerがデバッガに設定されるのでソース側で任意の場所にブレークポイントを設定する
1. Unityエディタの右下にある虫のアイコンをクリックしてデバッグモードにする![スクリーンショット 2022-08-27 23.57.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/07cd1957-7904-cf30-9515-7387ec1b32c9.png)
1. デバッガの再生ボタンをクリックする（Unityエディタの虫アイコンが青色になる）![スクリーンショット 2022-08-27 23.59.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/00809e73-8c65-6f39-c62e-45ee49a625fe.png)
1. UnityエディタをPlayModeにすると、ブレークポイントの箇所で処理が止まり、デバッグを行える

# 参考記事
[VSCodeでUnityのデバッグが出来なくてハマったのを解決したメモ](https://note.com/rinne_tonari/n/nf61a749584f2)
最初怖かった三項演算子はとても便利だった

はじめに
--
Reactでコードを書いていると、わからないことが溢れ出てくるので色々調べたり参考にすることが多いです。
その中で三項演算子を使用する場面が多いなぁと思ったので、ちゃんと理解して使うためにも言語化したことを備忘録として残したいと思います。

三項演算子とは
--
最初に記述する条件式の結果によって、実行する式が変わる演算子です。
真の際は左辺が実行され、偽の際は右辺が実行されます。

下記が構文です。
初めてみた時、構文を知らなかったから"?"と":"が怖かった。。
~~~
条件式 ? 真の時の式 : 偽の時の式
~~~

ifの代替としてよく使われるのですが、やっぱり1行でスマートにまとめられるのはとても便利だなぁと書いていて感じます。

[公式ドキュメント](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)の例がシンプルでわかりやすかったので引用させていただきます。
（mdnが公式ドキュメントだと思ってるんですが、間違ってたらご指摘いただけると嬉しいです。）
~~~js
const beverage = (age >= 21) ? "ビール" : "ジュース";
//=>ageが21以下だった場合は偽なのでジュースが返ってくる
//=>ageが21以下だった場合は真なのでビールが返ってくる
~~~

三項演算子は連鎖をさせられる
--
ifがelse ifで繋げるのと同じで、下記のように三項演算子は繋げられるようです。

~~~
条件式1 ? 真の時の値
  :条件式2(条件式1が偽の時) ? 条件式2が真の時の値
  :条件式3(条件式2が偽の時) ? 条件式3が真の時の値
  :条件式3(条件式4が偽の時) ? 条件式4が真の時の値
  :条件式4が偽の値
~~~

連鎖をさせられるのは知らなかった。。

終わりに
--
調べてみたらreactではなくてjsの機能でした。
やっぱりjsの基礎がめっちゃ大事なんだなぁと改めて感じました。
並行で勉強していこうと思います。

参考
--
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator#%E6%9D%A1%E4%BB%B6%E3%81%AE%E9%80%A3%E9%8E%96
error: 'dir/' does not have a commit checked outの解決法

# 背景

`git add .`しようとしたらエラーが発生した

```sh
❯ git add .
error: 'dir/' does not have a commit checked out
fatal: adding files failed
```


# 解決方法を探してみる

以下の記事に書いてあった。
.gitが２つあってそれが原因らしい...?


https://lifetime-engineer.com/git-add-error/

VScode上で探しても見つからない...


# 勘違いしていた

`.git`はファイルのことではなく、`.git/`ディレクトリのことだったみたい。

```shell
# エラーで指摘されている`dir/`に移動してから
❯ ls -a
.              .git           Dockerfile     README.md      bin            db             public         tmp
..             .gitattributes Gemfile        Rakefile       config         lib            storage        vendor
.env           .ruby-version  Gemfile.lock   app            config.ru      log            test
```

...あった！ `.git`を消してみる

```
❯ rm -rf .git
```

```
❯ git add .
```
エラーが出なくなった！解決！


# まとめ
- .gitがディレクトリのことだった（Gitの基礎を理解していればハマらないことだったのかも...？）
- エディタ上で見つけられない時はターミナルなどのCLIで確認してみるのも良いかも
[Swift]ディレクトリ内のファイル・ディレクトリを一覧表示するサンプルコード

## やりたいこと

Swiftのファイル操作系、たまにしか使わなくて忘れてしまうので、備忘のためのサンプルコードを書いておきたいので書きます。
この記事では temporaryDirectory内のファイル・ディレクトリ一覧を表示する処理を記載する。
（サブディレクトリ以下表示なし、隠しファイル表示なし）

## temporaryDirectoryのファイル一覧サンプルコード

```swift
func printFiles() {
        do {
            let tempDirContentsUrls = try FileManager.default.contentsOfDirectory(at: FileManager.default.temporaryDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants])
            
            tempDirContentsUrls.forEach { url in
                print(url)
            }
        } catch {
            print(error.localizedDescription)
        }
    }
```


## 動作確認環境

Xcode: 13.4.1
iOS: 15.6.1
[Swift]ファイル・ディレクトリを削除する

## やりたいこと

ファイルやディレクトリを削除する。
（ディレクトリ削除の場合は、指定ディレクトリ配下を全て削除する。）

以下の2通りの指定方法での手順を記載する。

* path指定 (ただのString)
* URL指定 (URL型)

## ファイルパス指定でのファイルの削除方法

FileManager.default.removeItem(atPath:) を使う。

```swift
    func deleteFileOrDirectory(path: String) {
        do {
            try FileManager.default.removeItem(atPath: path)
        } catch {
            print(error.localizedDescription)
        }
    }
```

## URL指定でのファイルの削除方法

FileManager.default.removeItem(at:) を使う。

```swift
    func deleteFileOrDirectory(url: URL) {
        do {
            try FileManager.default.removeItem(at: url)
        } catch {
            print(error.localizedDescription)
        }
    }
```
## まとめ

いずれの方法も例外が投げられるので、do-catch内で try をつけて実行する必要がある。

また、削除対象としてディレクトリ指定した際は、何の確認もなく指定ディレクトリ配下が全て消えるのでパス指定には注意してください。


##動作確認環境

Xcode: 13.4.1
iOS: 15.6.1
Swiftバージョン: 5.6.1
RecyclerViewの下にボタンを配置して一緒にスクロールさせたい

# やりたかったこと
下記のような感じで、RecyclerViewのリストの一番下にボタンがあるレイアウトを作成しようとしていました。
（↓完成イメージ）
![完成イメージ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1274260/3afe79f7-b675-2693-68fd-bd1595111f0a.gif)

本来ならRecyclerViewの一部のようにボタンも一緒にスクロールされるはずです。
しかし下にボタンを配置しようとすると、RecyclerViewのスクロールタイミングとボタンがスクロールされるタイミングが異なるためおかしな挙動となってしまいます。
（下のgifだと少しわかりにくいかもしれませんが、下まで行ったスクロールを戻す時にボタンのスクロールが遅れて発生しています。）

![挙動おかしい.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1274260/e9b383fa-0955-3375-5ef8-8b01b38c2c77.gif)


# 解決策
### RecyclerViewとボタンの親ビューグループに`NestedScrollView`を適用させる

コードとしては下記のような形になります。

```main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/main_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="次へ" />

    </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
```

普通のScrollViewではなくNestedScrollViewを使うのがポイントです。
NestedScrollViewは、[公式](https://developer.android.com/reference/androidx/core/widget/NestedScrollView)によると「入れ子スクロールをサポートしてくれる」とのことです。
今回のようにScrollViewの中にスクロールされるviewがネストされているときに使うためのビューグループということですね。
（ということはScrollViewの中にScrollViewをネストする時に使ったりもするんですかね？そんなケースあるのかわかりませんが、、、）


## 参考にさせていただいたサイト
https://arcanum.hatenablog.com/entry/20160209/1455022533
Linux ポート番号の種類について（自分用メモ

●ポート番号の種類
ポート番号は16ビットで表され、0~65535番までが使用できる

種類
■Well Known Ports(ウェルノウンポート)
　System Ports(システムポート)
範囲：0−1023
システムやroot権限を持つプロセスに割り当てられたポート番号

■Registerd Ports（レジスタードポート）
　User Ports（ユーザーポート）
範囲：1024−49151
よく使われるプログラムに割り当てられたポート番号

■Dyanamic Ports（ダイナミックポート）
　Ephemeral Ports（エフェメラルポート）
　Private Ports（プライベートポート）
範囲：49152−65535
自由に使用可能なポート


ウェルノウンポートとレジスタードポートのポート番号、TCP/UDPの区別、サービス名は、IANA（アイアナ：Internet Assigned Numbers Authority）によって割当、管理されている

●代表的なウェルノウンポート

ポート番号　プロトコル　TCP/UDP
22 SSH TCP リモートホストの遠隔操作（暗号化あり）
25 SMTP TCP 電子メール送信
53 DNS TCP/UDP 名前解決
80 HTTP TCP テキストや画像などのコンテンツの送受信（暗号化無し）
123 NTP UDP 時刻の同期（ネットワーク経由でシステム時刻を同期するために使用）
443 HTTPS TCP テキストや画像などのコンテンツの送受信（暗号化あり）


※ウェルノウンポートを使用するにはroot権限が必要。Linuxの一般ユーザ権限では使用できないので注意
bitbucketのレポジトリのコードをbuildしたときにつまづいた

エラー内容

```
	fatal: could not read Username for 'https://bitbucket.org': terminal prompts disabled
Confirm the import path was entered correctly.
If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
```

https://medium.com/easyread/today-i-learned-fix-go-get-private-repository-return-error-terminal-prompts-disabled-8c5549d89045

こちらの記事に書いてある通り、以下のコマンドを走らせたらうまくいった。

```
git config --global url."git@bitbucket.org:".insteadOf "https://bitbucket.org/"

###

cat ~/.gitconfig
# This is Git's per-user configuration file.
[url "git@bitbucket.org:"]
	insteadOf = https://bitbucket.org/
```

これでエラーが消えた。ありがたい。
Unityの回転軸の原点

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png"> これどこに書いてあるの...

回転軸と座標方向のメモです。

### Unityの座標軸

Unityは左手系座標です。
一方、物理学やROSでは右手系座標です。
２つの座標系が共存することになった謎については[note](https://note.com/ninagawa123/n/ne24fcf08c36f?from=notice)で記事にしました。

https://note.com/ninagawa123/n/ne24fcf08c36f?from=notice

さて、Unityのxyz角座標のプラス方向について、それぞれデフォルトでは下記の図の通りになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/e1f750b5-fa0b-c20c-d034-dd7743ff48ae.png" width= 500>

Unityの左手座標はデフォルト位置が通常の左手系と比べるとx軸を中心に90度回転しています。これは妙な感じもしますが利点もあり、ROS等の右手座標に変換する場合にy軸とz軸を入れ替えるだけでOKとなっています。

次に、回転軸について見ていきます。

### Unityの回転軸

Unityのデフォルトではforward方向はz軸プラス方向となります。
これをベースに考えると、Z軸を中心に回転するのがロール回転となります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/56652007-f108-d4c6-f791-97d2def00f41.png" width= 500>

z軸を中心軸としたロール回転は、反時計回りがプラスとなります。
<hr>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/13070505-e7eb-e495-3d20-c41dcccf5707.png" width= 500>

ピッチ回転はx軸を中心軸とした仰角、俯角方向です。下向き俯角側がプラスとなります。
<hr>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/7123f4e3-96a5-54ea-d46d-861a7010f687.png" width= 500>

y軸を中心軸としたヨー回転は時計回りがプラスとなります。
この回転軸が車両系ロボットのナビゲーションなどでは一番使われていると思います。

<hr>

回転座標の角度の起点ですが、それぞれ図で示した軸のプラス方向が原点で0度となります。
また、それぞれの方向に対し180度を超えても角度の増減は続きます。よって、**-30度と+330度は同じ角度**を示します。


# はまりどころ
２つの座標点間の角度を求めるには、
**Mathf.Atan2(float y, float x)**
が使えます。しかし、注意点が２つあります。
まず一つ目は、引数がy,xの順であることです。うっかり逆に入力されませぬよう。
次の注意点は、計算結果が0〜+180, 0〜-180で返されることです。
前述のUnityルールの回転方向とATAN2取得の角度は直接比較することができず、変換が必要になります。


# 間違っているかも
調べた結果が間違っている場合もありますので、当記事の間違いを気づかれたらぜひコメントでお教えいただけると助かります。。
【Unity】実行画面でUndo/Redoが使える機能を実装する

様々な編集ソフトでは**Undo**(元に戻す)や**Redo**(やり直す)などの機能があります。
Unityもエディターで同様の機能が使えますが、あくまでエディターの機能です。実際の動作画面では使えません。
なので実行画面でUndo/Redoが使える機能を実装しました。

# 実装
```C#
using System;
using System.Collections.Generic;
using UnityEngine;

public class DoRecord<T>
{
    public bool enableRedo => curtIndex < size - 1;
    public bool enableUndo => 0 < curtIndex;
    public int size { get; private set; } = 0;

    private Action<T> record = null;
    private List<T> cache = new List<T>();
    private int curtIndex = -1;

    public DoRecord(T first, Action<T> record)
    {
        this.record = record;
        Reset(first);
    }

    public void Reset(T first)
    {
        cache.Clear();
        curtIndex = -1;
        size = curtIndex + 1;

        Commit(first, true);
    }

    public void Reset()
    {
        Reset(cache[0]);
    }

    public void Commit(T value, bool excute = false)
    {
        cache.Insert(++curtIndex, value);
        size = curtIndex + 1;

        if (excute) record?.Invoke(value);
    }

    public void Redo() => Do(curtIndex + 1);
    
    public void Undo() => Do(curtIndex - 1);

    private void Do(int index)
    {
        curtIndex = Mathf.Clamp(index, 0, size - 1);
        record?.Invoke(cache[curtIndex]);
    }
}
```

C#でジェネリッククラスで実装を行いました。組み込み方は次項の**サンプル**をご確認ください。

##### 1. 値の登録
UndoとRedoの実現のために、可変長配列が型に合わせた経過の値を保持しています。
**Commit**関数を実行すると値がリストに挿入され、さらにリストの（仮想的な）最大値を更新します。
Undoを実行した後にCommitが行われると上書きされる仕様となっています。

##### 2. 登録した値の再利用
クラスのコンストラクタにメソッドを渡しておくことでUndo/Redoの時に値の再利用ができます。
**Do**関数ではインデックスの丸め込みのみを行っているので、Undo/Redoが実行できるかはそれぞれのenableを確認して組み込むクラスで制御します。

##### 3. 保持した値の破棄
**Reset**関数で可変長配列の内容を破棄し、値を初期化します。
コンストラクタの時にもReset関数を使用していますが、引数に最初の値を渡すことで初期値を必ず登録します。
つまり必ず１つ以上の値は保持している状態になります。



# サンプル
``` C#
using UnityEngine;
using UnityEngine.UI;

public class Sample : MonoBehaviour
{
    [SerializeField] private ColorPanel panel = default;
    [SerializeField] private Button commit = default;
    [SerializeField] private Button reset = default;
    [SerializeField] private Button redo = default;
    [SerializeField] private Button undo = default;

    private DoRecord<Color> record = null;

    private void Start()
    {
        record = new DoRecord<Color>(panel.color, (color) => {
            panel.color = color;
        });

        commit.onClick.AddListener(() => record.Commit(panel.color));
        reset.onClick.AddListener(() => record.Reset());
        redo.onClick.AddListener(() => record.Redo());
        undo.onClick.AddListener(() => record.Undo());
    }

    private void Update()
    {
        redo.interactable = record.enableRedo;
        undo.interactable = record.enableUndo;
    }
}
```

サンプルには色情報の経過を使用しています。色の編集には[【Unity】実行画面で色を編集できる機能を作る](https://qiita.com/ogawa4283/items/46865fe257879f70e005)の***ColorPanel***クラスを使っています。

（GIFでは若干わかりにくいですが）色の編集の度にCommitを実行し、左に配置したUndoを実行すると元に戻し、右に配置したRedoを実行するとやり直します。最後にResetを実行すると最初の色に戻ります。

![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96676/abc94e54-47d8-2075-9ed9-bb1f4c4f3038.gif)

***DoRecord***クラスにはプリミティブ型やUnityコンポーネント、自作クラスなども使用できます。
どの範囲の情報を管理するかは組み込むクラスで決めることができるようになっています。
スプレッドシートでIPアドレスをオクテット毎に分割する

IPアドレスをオクテット毎に分割したいとき。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/92fa90f6-c93b-b462-0cbf-82c86b8aca35.png)

# SPLIT関数を使う
SPLIT関数を使えば、指定した文字列を特定の文字で分割できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/2265027e-f63b-98b1-f90e-06d214c268a7.png)

①`SPLIT(IPアドレスを入力したセル,".")`と入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/ebd600ec-4dff-96a5-2662-6ed2e0e3ffb6.png)

②[.]で区切られた文字が自動で右のセルにも反映される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/9e2cc8ed-8831-b4a4-2618-f4c6f8347bb2.png)

③あとは適当にセルをくっつけてNWアドレスでも作成しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/29a55e78-ea02-326f-80f5-d4fdef041e8f.png)

④適当に下まで引っ張れば完成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955768/9113f552-f882-e45c-372c-f5a71182a27d.png)

# 最後に
正規表現とかGASでやろうと思っていた自分がいた
PHP 関数の引数 2種類のnullableな型(null許容型)の宣言を両方とも書く

## デフォルト値を設定するnull許容型の宣言
PHP7.0から使える デフォルト値にnullを指定する
引数にnullを渡してもエラーにならない
```php
function showName(string $name = null) {
    var_dump($name);
}
```

## 型名の前に?を書くnull許容型の宣言
PHP7.1から使える 引数の型名の前に?を書く
デフォルト値が無いケースでは、エラーが発生する
```php
function showName(?string $name) {
    var_dump($name);
}
```

## null許容型の宣言を両方とも書く
PHP7.1から デフォルト値にnullを指定し、引数の型名の前に?を書く
両方とも記述して、デフォルト値が無いケースでも、エラーが発生しなくなる
```php
function showName(?string $name = null) {
    var_dump($name);
}
```
CloudFormation で変更なしの変更セットを流したい時

## 概要

CloudFormationのコードを書いているとリソースに変更は加えたくないけどコードの中身を整理したいときがたまにある。
そのまま変更セットを流そうとすると以下エラーで怒られてしまう。

```
The submitted information didn't contain changes. Submit different information to create a change set.
```

そのため、影響の少なそうな変更箇所が無いか探してみた。

## 変更箇所

### Parameters を追加してみる → ダメでした


```yaml
Parameters:
  Dummy:
    Type: string
    Default: dummy
```

### Outputs を追加してみる → いけた！


```yaml
Outputs:
  Dummy:
    Value: "dummy"
```



スタックの出力に変なの追加されちゃうので消し忘れの無いように、、、
(せっかく整理したのに・・・まあ影響ないけど。)
[Microsoft] Windows 11でOpenSSHサーバを動かす & トラブルシュートメモ

# はじめに

Windows 11にOpenSSHサーバをインストールしました。
意外に一筋縄ではいかなかったので、ここに記録を残します。


# 環境

* サーバ側
    * Windows 11 21H2 Build 22000.856
    * OpenSSH_for_Windows_8.1p1, LibraSSL 3.0.2
* クライアント側
    * Ubuntu 22.04.1 LTS
    * OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022



# Windows 11に OpenSSH サーバをインストールする

GUIからやると、いつのまにかメニューが行方不明になるので、PowerShell を使います。

管理者権限でPowerShellを起動します。

名前を確認します。

```powershell
Get-WindowsCapability -Online | where -Property Name -ILike "OpenSSH*"
```

インストールします。

```powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
```

# サービスを有効にする

自動起動するようにします。

```powershell
Set-Service -Name sshd -StartupType Automatic
```

起動します。

```powershell
Start-Service -Name sshd
```

とりあえずこれで繋がるはず、、、でした。

# トラブルメモ

## [トラブル] サーバ側のログが出ない

`SyslogFacility` を `LOCAL0` に変更してsshdを再起動します。

`sshd_config` ファイルは、`$env:programdata\ssh` にあります。


## [トラブル] 接続できない

### [原因] Windows側ファイアウォールが開いていない

SSH (TCP 22番）を通すようにします。

### [原因] ホストキーがない

生成します。

```powershell
sshd -A
```

## [トラブル] Too many authentication failures と言われて接続できない

### [原因] ssh_agent を使用している

既定の認証ファイルのみを使うようにしてみます。

```bash
ssh -o IdentitiesOnly=yes ホスト名
```

## [トラブル] 公開鍵で認証できない

### [原因] ユーザがAdministratorsグループに属している

いつもの `authorized_keys` ファイルを `$env:programdata\ssh` へ置きます。ファイル名は `administrators_authorized_keys` にします。

### [原因] `administrators_authorized_keys`ファイルのACLが不正

ファイルのACLを、継承を無効にし、Administrators:フルコントロール、SYSTEM:フルコントロール __のみ__ にします。

```powershell
icacls.exe .\administrators_authorized_keys /inheritance:r /grant Administrators:F /grant SYSTEM:F
```

# 感想

LinuxからWindowsへsshできるようになって、tmux の中で使えるようになりました。快適〜〜。

次は、本命 Visual Studio Code Server を動かします。
IT業界から離れたOLがSAA受かった話



お久しぶりです！

実は昨年の頭に退職しまして、エンジニアから離れた生活をしておりました。

そんな私がSAA合格した話をまとめました(✌🏻️'꒳'✌🏻️)
試験内容が変わるので、需要ありませんがｗｗ

<h5>■まず、IT業界とわたし</h5>
新卒で、サーバーサイドエンジニアとして、3年と少し勤めました！

今は違う業種で仕事してます。
前職は.NET/PHPを主にしてました。
現在は派遣OLです〜‪·͜· 



<h5>■AWSの経験</h5>
実務としては未経験です。

前職の時にインフラ勉強したいな〜とりあえずSAA受けよう！となったのが、AWSとの出会いです👍🏻🔥
テストセンターの経験として、CLFを2年ほど前に取得しています。
その後に、JAWS-UGうどん県に入りました。（関係ない）
が、仕事を休職し、退職してしまうというハードモード人生のため、SAAは受けずにずっと放置していました・・・orz



<h5>■SAAを受けようと思った理由</h5>
現職に転職して、業務を進めていくうちに、やっぱりIT業界に戻って、勉強しながら成長したいな〜〜という気持ちが強くなりました。

第一歩として、封印してたSAAを受けようと思い、ノリと勢いでkoiwaclubに課金してました。
Twitterのフォロワーさんの影響が大きいです🌟ありがとうございます！

<h5>■勉強法</h5>
①オレンジ本1周
https://www.amazon.co.jp/dp/479739739X/ref=cm_sw_em_r_mt_dp_V8B9J15T6Q1705NS09A4

分からなくても、覚えていなくても、とりあえず読み進めることを意識しました。
これだけで試験範囲網羅は難しい気がします。
が、一気にインプットできるので、わたし的にはとても助かった本です。

②koiwaでひたすら問題を解く
https://aws.koiwaclub.com/
解いたのは、#1-#135、#150-最後を2週ほど。
#136-#149は間に合わなかっただけです（ 笑 ）
模擬はやらずに、解いて解説読んで、という流れをひたすら繰り返しました。

③公式ドキュメントを読む
通勤中など。合間で読んでました。
なかなか理解できないサービスは必ず目を通して、なんとなくでも理解できるようにしました。

④ハンズオン
これは2年前にやってました。
Udemyで講座課金してました。
画面上で動かしながら、体系的に理解することを心がけてました。
おかげでkoiwa解いたときにすんなり行けた気はします🍬



<h5>■結果</h5>
無事1発合格✌🏻

![BA92AD7A-E588-42AD-B991-12F370973820.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629073/9ddb2ecf-833d-6893-0b87-f604df183401.jpeg)


<h5>■感想</h5>
一発合格してよかったです。ほんとに(T_T)

ただ、実務に利用できるレベルではないので、実際に触れながら、SAAに見合った実装力がほしいと思っています。。。笑


試験対策についてですが、他の皆さんも書かれているように、koiwaの新しい問題（#80以降）は全部解いた方がいいと思います。
前半は意味無いという方もいらっしゃいますが、そんなことは無かったかな〜とも思います。
効率重視なら#80以降のみでも問題ないのかなと🤔笑

本番は文が長い！という体験記を見かけましたが、koiwaでかなりの数の問題文を見ていたので、本番はあまり苦戦することなく解けました。

最後に、とあるサービスをほぼ理解しないままテストセンターへ突撃したところ、数問出てしまって頭が真っ白になりましたww
試験概要に書いてることは、全部触るべきでしたね（ 笑 ）





それでは！＼(^o^)／
【解決】** (DBConnection.OwnershipError) cannot find ownership process for #PID エラーが出たときの確認点 

# 現象

Ectoのテストを実行すると件名のようなエラーが発生する

# 対策

テストプログラムで、`ExUnit.Case`を使っていると、発生します。
/test/supportdata_case.exで定義されてるモジュールを使うようにします。
FooDataCaseのような名前になっていると思います。

```Elixir
defmodule Foo.BarTest do
  # use ExUnit.Case　＃←これだとエラーになる
  use FooDataCase

  test "foo 1" do
　　# some test code for ecto
  end

end
```


# (参考)エラーメッセージ例

```
    ** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.621.0>.
     
     When using ownership, you must manage connections in one
     of the four ways:
     
     * By explicitly checking out a connection
     * By explicitly allowing a spawned process
     * By running the pool in shared mode
     * By using :caller option with allowed process
     
     The first two options require every new process to explicitly
     check a connection out or be allowed by calling checkout or
     allow respectively.
     
     The third option requires a {:shared, pid} mode to be set.
     If using shared mode in tests, make sure your tests are not
     async.
     
     The fourth option requires [caller: pid] to be used when
     checking out a connection from the pool. The caller process
     should already be allowed on a connection.
     
     If you are reading this error, it means you have not done one
     of the steps above or that the owner process has crashed.
     
     See Ecto.Adapters.SQL.Sandbox docs for more information.
     code: log = log_fixture()
     stacktrace:
       (ecto_sql 3.8.3) lib/ecto/adapters/sql.ex:929: Ecto.Adapters.SQL.raise_sql_call_error/1
       (ecto 3.8.4) lib/ecto/repo/schema.ex:744: Ecto.Repo.Schema.apply/4
       (ecto 3.8.4) lib/ecto/repo/schema.ex:367: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
       (hex_reversi 0.1.0) test/support/fixtures/log_fixtures.ex:26: HexReversi.LogFixtures.log_fixture/1
       test/hex_reversi/board_history_test.exs:10: (test)
```
【Git】ブランチの管理について

# はじめ
　　最近、gitのドキュメントを読んでいます。
　　復習のため、ポイントをメモしました。
 **「git branch」**　はよく使うコマンドです。
　オプションを理解した上で使用すると、作業効率が上がります。

# 3.3 ブランチの管理

現在のブランチの一覧を表示する。↓
```
$ git branch
* master
```
**「*」** は、現在チェックアウトされているブランチ（HEADが指しているブランチ）を意味する。つまり、ここでコミットを行うと、masterブランチが一つ先に進むということである。

各ブランチにこける直近のコミットを調べる。↓
```
$ git branch -v
```

現在作業中のブランチにマージ済みのブランチを調べる。↓
```
$ git branch --merged
```
- マージされたブランチが表示される
- このリストにあがっているブランチのうち先頭に 「*」 がついていないものは、通常は 「git branch -d」 で削除してしまって問題ないブランチである。 （すでにすべての作業が別のブランチに取り込まれているので、何も失うものはない。）

マージされていない作業を持っている全てのブランチを知る。↓
```
$ git branch --no-merged
```
三桁までの金額の最小硬貨枚数を調べるコード

# 指定した金額を100,10,1円玉だけで支払う時に、それぞれ何枚ずつ必要になるか計算して表示するコード
```
import tkinter as tk

def dispLabel():
    a = int(EditBox1.get())
    A1=a//100
    A2=(a-A1*100)//10
    A3=(a-A1*100)-A2*10
    str_A1=str(A1)
    str_A2=str(A2)
    str_A3=str(A3)
    str_a=str(a)
    
    lbl2.configure(text=str_a+"は100円玉"+str_A1+"枚と")
    lbl3.configure(text="10円玉"+str_A2+"枚と")
    lbl4.configure(text="1円玉"+str_A3+"枚です。")


root=tk.Tk()
root.geometry("300x200")

EditBox1= tk.Entry(width=4)
EditBox1.place(x = 250, y = 20)

btn=tk.Button(text="計算する",command=dispLabel).place(x = 60, y = 50)

lbl1=tk.Label(text="調べたい代金はいくらですか？").place(x = 20, y = 20)
lbl2=tk.Label(text=" ")
lbl2.place(x = 20, y = 80)
lbl3=tk.Label(text=" ")
lbl3.place(x = 48, y = 100)
lbl4=tk.Label(text=" ")
lbl4.place(x = 48, y = 120)

tk.mainloop()
```
![お支払い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739883/b2e16d8e-36a7-623e-8891-2d79c79a2d18.png)
![お支払い_入力png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739883/e33e5b05-1d20-9f20-a606-52c2e3af5caf.png)

## 感想
ラベル2,3,4のコードを簡易化できないか色々試してみたい。
計算後に表示するラベル３つを、右端に揃える方法を調べたい。
エクストリームプログラミング(XP)

## XPとは

- ソフトウェア品質を向上させ、変化する顧客の要求への対応力を高めることを目的としたソフトウェア開発プロセス。
    - スクラムと同じくアジャイル開発手法の一つである。ソフトウェア開発に重きを置いている。

## XPにおける価値・プラクティス・原則

XPは価値・プラクティス・原則から構成される。

以下でそれぞれを説明する。

### 価値

自分たちにとって何が重要かという**抽象的**かつ**普遍的**な基準。

XPでは以下の価値を重要視している。

- コミュニケーション
    - チーム感覚や協力関係を維持する
- フィードバック
    - チームや個人に対するフィードバックに基づき、常に改善を行う
- リスペクト
    - チームに対する個人の貢献をリスペクトする
- シンプリシティ
    - 無駄を排除するに何ができるかを常に考える
- 勇気
    - 上の価値を実践し、チームの一員として効果的に動く勇気
    

ただ、XPは上の価値を重要だと言いつつ、価値を取捨選択すること・その他の価値を置くことを認めている。

重要なのは、**チームのふるまいをチームが重要視する価値に近づける**ことである。

### プラクティス

価値を実現するための**具体的**な取り組み。**状況に応じて**必要なプラクティスは異なる。

プラクティス数は、12→24→19と変化している。
(出典:https://slide.meguro.ryuzee.com/slides/96)

ただ、19のプラクティスになった際のドキュメントは見つけられず。

本プレゼンは、24のプラクティスを定義している**2nd Editionの区分に準拠する**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374329/d9533843-ac7f-324b-4551-5338a832256f.png)

プラクティスには大きく分けて二つ存在する。

1. 主要プラクティス
    1. すぐに導入できるもの
2. 導出プラクティス
    1. 主要プラクティスの導入を前提とするもの

(引用:[https://slide.meguro.ryuzee.com/slides/96](https://slide.meguro.ryuzee.com/slides/96))

### 原則

分野に特化した活動指針。

価値とプラクティスのギャップを埋める。XPでは**ソフトウェア開発**における14の原則を紹介している。



上の原則は以下の書籍に説明されているので、興味があれば読んでいただきたい。

[エクストリームプログラミング](https://www.amazon.co.jp/%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E3%82%B1%E3%83%B3%E3%83%88-%E3%83%99%E3%83%83%E3%82%AF/dp/4274217620)

理解のため、原則を一つだけ例示として説明する

- 相互利益
    - あらゆる活動は、関係者全員の利益にならなければならない
    - 例えば仕様書の作成は、将来の担当者の利益のために現在の担当者の負荷を強いるので、相互利益を破壊する
    - そこで、XPでは将来とのコミュニケーションの問題を相互利益になるやり方で解決する
        - 現時点で設計や実装がうまくできるような**自動テスト**を書く。
        - また、将来のプログラマーも使えるようテストを残す

## 開発プラクティスの説明

開発プラクティスのうち、主要プラクティスにあたる以下の4つについて説明する。

### 1. テストファーストプログラミング

コードを変更する前に失敗する自動テストを書くこと。

以下の課題を解決する

- スコープクリープの防止
    - プログラミングに夢中になり、余計なコードを追加することを防ぐ
- テストしやすいコードの記載
- コードの意図を示す

### 2. ペアプログラミング

ペアプログラミングとは、2人でプログラミングとプログラムの改良を同時に行うやり取りのこと。

コードが常にレビューされることになり、コードの欠陥率の減少、コードサイズの減少などの効果が期待される。

以下のことを意識しながら行う。

1. お互いのタスクに集中する
2. システムの改良について意見を出し合う
3. パートナーがはまったら主導権を握り、相手の絶望感を軽減する
4. ペアのパートナーはこまめに入れ替える(数時間ごと)

具体的なやり方は以下のページを参考のこと

[https://gist.github.com/j5ik2o/2970973](https://gist.github.com/j5ik2o/2970973)

### 3. インクリメンタルな設計

現時点のシステムのニーズを満たすため必要なシステム設計を行う。

また、システム設計は常にリファクタリングを行い、ニーズの変化に対応する。

### 4. 継続的インテグレーション

数時間以内に変更箇所を含むソースコード全体をテストするできるにする。(テスト自動化、ビルド自動化)

システムのリリース(デプロイ)が大変にならないようにする効果がある。

## 【補足】スクラムとの比較

以下のページが参考になる。

[http://agile.blog.jp/agile_scrum/14887069.html](http://agile.blog.jp/agile_scrum/14887069.html)

### 【補足】他のAgile手法とXPの取り組みの対応関係

agileallianceでは路線図のような形で、各Agile手法のプラクティスを整理している

![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1b5b2e91-4cf9-411e-925e-c6320b6139f7/Untitled.png)

(引用:[https://www.agilealliance.org/agile101/subway-map-to-agile-practices/](https://www.agilealliance.org/agile101/subway-map-to-agile-practices/))
Office&Officeアプリの起動ショートカットがいつの間にかあったみたい

# 概要
単に、不思議なショートカットを見つけたので備忘録

何が不思議って・・
- ショートカットなのに、押すキーが多過ぎ
- 特殊キーだけで起動するものもある

# ショートカット
Web版、Desktop版のどちらが起動されるか？は何かありそうだけど、不明

## Office ホーム
**CTRL + ALT + Shift + Win**
特殊キーだけで Office ホームが起動する。
E3/E5 とか契約してる企業なんかだと、操作案内する際には便利かもしれない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/88424df3-5fc4-2761-c062-440b3fe5f92f.png)


## Linkedin: CTRL + ALT + Shift + Win D
**CTRL + ALT + Shift + Win D**
同期して使うと便利な one**D**rive
企業によっては同期禁止されてて起動できない場合もある。（うちです）

## Linkedin: CTRL + ALT + Shift + Win L
**CTRL + ALT + Shift + Win L**
ネットワーク作りにはこれもいいのかも **L**inkedin
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/091445db-e7a2-bbea-e90b-da4bff51ecf5.png)


## oneNote: CTRL + ALT + Shift + Win N
**CTRL + ALT + Shift + Win N**
メモに便利な one**N**ote ただネット環境が悪いとなんかよく壊れた記憶
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3d8fdf5b-a599-dfa7-a82a-90673c1b43ad.png)


## Outlook: CTRL + ALT + Shift + Win O
**CTRL + ALT + Shift + Win O**
Teams をメインにしたいのに、会社だとメール好きな人が多い・・ **O**utlook 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/226d7b76-7dbc-dda4-5d7b-2be2366de054.png)


## Power Point: CTRL + ALT + Shift + Win P
**CTRL + ALT + Shift + Win P**
Sway が 出てきたとはいえ、発表資料はやっぱり **P**ower **P**oint
凝り過ぎて、伝えるってことが目的であることを忘れないようにしないと。
最近のデザインアイディアは便利ですよね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/5cccf52d-cdd6-7a66-15ad-4bbd148b83f9.png)

## Recently: CTRL + ALT + Shift + Win R
**CTRL + ALT + Shift + Win R**
Office 系の履歴アプリが起動する筈だが・・
自宅では何故か動かない・・Desktop App が反応するときだけ？

## Teams: CTRL + ALT + Shift + Win T
**CTRL + ALT + Shift + Win T**
基本、こんなので起動することはまずないだろう **T**eams も
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/fd079069-a928-20f4-abbc-696594878898.png)

## Word: CTRL + ALT + Shift + Win W
**CTRL + ALT + Shift + Win W**
最近は使わなくなりつつある **W**ord も
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9cee9726-8f6e-2424-b063-2a7ed3a43681.png)


## Excel: CTRL + ALT + Shift + Win X
**CTRL + ALT + Shift + Win X**
業務で使わない人はいない? e**X**cel 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7751562b-b8b4-b318-d60e-cc5ebc87b9b9.png)


## Yammer: CTRL + ALT + Shift + Win Y
**CTRL + ALT + Shift + Win Y**
**Y**ammer をブラウザで開く
社内SNSとして使ってる人達向け
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e0b18e4f-81fd-d3ae-72ee-3507b3691097.png)

# あとがき
この複雑なショートカットが何故用意されたのかがさっぱりわからないが・・
Microsoft365 と Windows の統合を見据えて、とか？
定例のミーティングのリンクをSlackに通知した 

定例のオンラインミーティングで、毎回「Zoomのリンクどこだったかいな?」ってなるのがつらくて、リマインドもかねてslackにリンクを飛ばす機能を作った。ついでに必要な資料のリンクなども送ることができる。

## できたこと
* Slackの特定のチャンネルに必要な情報入りのメンションを飛ばす
* 文面に画像やボタンをいれる
* 週一回特定の時間にメンションを飛ばす

## 前提
* Zoomのリンクは固定であること

ZoomAPIなどを利用すればいい感じにリンクを取得できるが、今回は固定されているものとしてハードコーディング

## URLを取得する
## シェルスクリプトを書く

```
#!/bin/sh
url='https://'
json=`cat slack.json | jq -c`
curl -X POST -H 'Content-type: application/json' --data $json $url
```

$urlには取得したSlackのURLをいれる

```
url='https:'
```

$jsonには取得した`--data`オプションに渡すjsonをslack.jsonファイルから取得する。`jq -c`では、フォーマットされたjsonをいい感じに1行にすることができる。

このjson変数に渡される値によって、slackに通知されるメッセージの内容を加工することができる。MarkDownを書いたり、画像を乗せたり、ボタンを設置したりはここで設定する。

```
json=`cat slack.json | jq -c
```

curlコマンドを使って、slackへリクエストを送る。

```
curl -X POST -H 'Content-type: application/json' --data $json $url
```


## jsonを作成する

`--data`オプションへ渡すjsonを作成する。

中身の説明や、プレビューなどは以下から詳細を確認することができる。



```
{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "13時から全体ミーティングです",
        "emoji": true
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "全体ミーティングの時間です。参加しましょう:loudspeaker:"
      },
      "accessory": {
        "type": "image",
        "image_url": "https://1.bp.blogspot.com/-PgPpfoGDxF0/WcB5sfrVQSI/AAAAAAABG1o/xGjjAfsxv_UddA_63hydv1M46uL0b4KHACLcBGAs/s800/kaigi_man_woman.png",
        "alt_text": "image"
      }
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Zoomに参加",
            "emoji": true
          },
          "url": ""
        },
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "議事録",
            "emoji": true
          },
          "url": ""
        },
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "案件管理表",
            "emoji": true
          },
          "url": ""
        }
      ]
    }
  ]
}
```


## cronを設定する

cronは各々の環境でいい感じに設定してください。

```
$ crontab -e
```

`crontab -l`で確認する。

```
50 12 * * 1 ./meetingNotification.sh
```
SSH 鍵作成

# SSHの鍵生成方法

```shell
MAIL=
ssh-keygen -b 4096 -t rsa -f ~/.ssh/id_rsa.${MAIL}-$(date '+%Y%m') -C "${MAIL}-$(date '+%Y%m')"
```

PEM形式で作成する

```shell
MAIL=
ssh-keygen -b 4096 -m PEM -t rsa -f ~/.ssh/id_rsa.${MAIL}-$(date '+%Y%m') -C "${MAIL}-$(date '+%Y%m')"
```

# 秘密鍵から公開鍵を作成

OpenSSH形式

```shell
ssh-keygen -yf ${private_key_file} > ${public_key_file}
```

PEM形式

```shell
openssl rsa -in ${PRIVATE_KEY_PEM}  -pubout -out ${PUBLIC_KEY_PEM}
```


# 利用


```shell
ssh -i ~/.ssh/id_rsa.${MAIL}-${DATE}
```
Goの io/fs.FS をOSのファイルシステムにマウントする

# fs.FS内のファイルを他のプロセスに渡したい

Go 1.16 で追加された `io/fs` パッケージで色々なファイルシステムに共通のインターフェイスでアクセスできて便利になりました．この`fs.FS`の中身にシェルやエクスプローラからアクセスして操作できると便利そうです．

例えば，ネットワークストレージのクライアントを Go で実装する場合 `fs.FS` インターフェイスを実装すると思いますが，そのクライアントをそのままマウントできれば他のアプリケーションからデータにアクセスできます．

# GoでFUSEを使う

大抵の環境では，ユーザプログラムがファイルシステムを提供するためのFUSEという仕組みが使えます．

Linuxの場合は，[go-fuse](https://github.com/hanwen/go-fuse) というbindingsがあります．

https://github.com/hanwen/go-fuse

専用のインターフェイスを提供する必要があってfs.FSを使うのは少し面倒ですが，高機能かつ活発に開発が続いています．

Windowsの場合は，[Dokan](https://ja.wikipedia.org/wiki/Dokan)というWindows上でFUSEのようなものを提供するライブラリがあって，[dokan-go](https://github.com/keybase/dokan-go)というbindingsもありました．

https://github.com/keybase/dokan-go

しかし，ずっとメンテナンスが止まっていて，最近の環境だとコンパイルするために少しだけ修正が必要です．

(8/28追記: DokanではなくWinFspのGoのbindingsは最近までメンテナンスされてそうでした．[cgofuse](https://github.com/winfsp/cgofuse) )

# dkango

以前から，go-fuse と dokan-go のラッパーを書いて使っていたのですが，dokan-goの本家のリポジトリはずっとメンテナンスが止まっていて，自分で修正しながら使うのも面倒になってきました．特にcgoを使っているので久しぶりに使おうとするとWindows上のgccのセットアップではまったりします．

仕方ないので，dkangoというライブラリを書きました．Goだけで実装したのでcgoは使わないです．

https://github.com/binzume/dkango

~~unsafeとsyscallの塊でそんなにテストもしてないので，クラッシュしたりするバグが残ってるかもしれません．~~ 自分でしばらく使っていますが大丈夫そうでした．

# fsmount

上記のdkangoとgo-fuseを環境に合わせて使い分けるラッパーです．

https://github.com/binzume/fsmount

fs.FSとマウントポイントを渡すだけで簡単にマウントできます．Windows以外はあまりテストしていませんが，Windows/Linux/MacOSで似たような動作をすると思います．

```go
package main

import (
	"os"
	"github.com/binzume/fsmount"
)

func main() {
	mount, _ := fsmount.MountFS("X:", os.DirFS("."), nil)
	defer mount.Close()

	// Block forever
	select {}
}
```

この例ではカレントディレクトリからFSを作って X: ドライブとして追加します．(Linuxの場合はマウントポイントとして適当なディレクトリを指定してください)

いくつかメソッドを実装すれば書き込み可能にもなりますが，そのあたりはサンプルを参照してください．

# 最後に

カジュアルにファイルシステムを実装できると色々遊べると思います．

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Windowsのエクスプローラでリバーシをプレイしている．たぶん10の30乗個近いフォルダを含むのでコピーできないです <a href="https://t.co/IKaN1XFJxU">pic.twitter.com/IKaN1XFJxU</a></p>&mdash; Kousuke Kawahira (@binzume) <a href="https://twitter.com/binzume/status/1563485032869613569?ref_src=twsrc%5Etfw">August 27, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

https://github.com/binzume/fsmount/tree/master/examples/reversi

非実用的なサンプルとしてリバーシの盤面をマウントしてみた例です．フォルダを開くごとにゲームが進みます．無駄にAIとも対戦できます．このファイルシステムはリバーシのすべての可能な状態を含んでいる上にパフォーマンスも良くないので，ディレクトリをすべてスキャンするようなソフトウェアは止めておいたほうが良さそうです．
FileオブジェクトをBASE64エンコードする方法

クライアントサイドのお話です。

フォームで取得したファイルオブジェクトをREST APIにJSON形式で送りつけたいことってありますよね。
そのままじゃ送れないのでBASE64エンコードをする必要があると思います。
意外と簡単に行かなく、めちゃくちゃ処理が重くなってはまったりしたのでここに動くソースを残します。
クライアントサイドで重い処理を動かして兵庫県警に逮捕されないように気を付けましょう。

```typescript
const uint8Array = Array.from<number>(new Uint8Array(await file.arrayBuffer()))

let encodedStr = ''

for (let i = 0; i < uint8Array.length; i += 1024) {
    encodedStr += String.fromCharCode.apply(
        null, uint8Array.slice(i, i + 1024)
    )
}

const base64 = window.btoa(encodedStr)
```
DockerのRailsアプリからRedisサーバに接続したい

## はじめに
docker環境で起動しているrailsアプリからホストで起動しているredisサーバに接続したい。
なお、前提として、dockerでのrailsアプリの環境構築が完了しているものとする。

## 環境
- ローカル環境
  - macOS
- docker環境
  - ruby 3.1.2
  - Rails 7.0.3.1

## 手順
### 1. ローカルホストでredisを起動する
まずredisをインストールするために、下記のコマンドを実行
```
brew install redis
```
インストールされているか確認する
redisがあればOK
```
$ brew list | grep redis
redis
```
redisサーバをバックグラウンドで起動
```
brew services start redis
```
redisのクライアントコマンドで以下のように、接続確認を行い、"PONG"が返ってくることを確認
```
$ redis-cli ping
PONG
```
### 2. rails側にredisを導入する
Gemfileに以下を記述し、appコンテナに入る
`bundle install` を実行する
```Gemfile
gem ‘redis-rails’
```
インストールされている確認
以下のようなものが入っていればOK
```
root@[コンテナID]:/app# gem list | grep redis
redis (4.8.0)
redis-actionpack (5.3.0)
redis-activesupport (5.3.0)
redis-rack (2.1.4)
redis-rails (5.0.2)
redis-store (1.9.1)
```
### 3. いざ！接続してみる
appコンテナに入り、`rails c`を実行しコンソールを立ち上げる。
`Redis.new`を実行する。url部分については、dockerコンテナ内からホストマシンのlocalhostに接続するため`docker.for.mac.localhost`と指定する。(参考：https://qiita.com/Asayu123/items/ccfe4ccfc417ce57f445)
ポートはデフォルトの6379としています。

```
irb(main):004:0> redis = Redis.new(url:"redis://docker.for.mac.localhost:6379")
=> #<Redis client v4.8.0 for redis://docker.for.mac.localhost:6379/0>
```
 1.のときと同様に接続確認を行う
```
irb(main):005:0> redis.ping
=> "PONG"
```
## 4. Redisを操作してみる
操作について： https://github.com/redis/redis-rb
railsコンソール上のまま、以下のように書き込んでみる。
```
irb(main):015:0> redis.set "hogekey", "Hello"
=> "OK"
```
そしてローカルから確認してみると、保存されている！
```
$ redis-cli
127.0.0.1:6379> get "hogekey"
"Hello"
```

## 番外編
### redis-cliでクライアントを立ち上げようとしたときにエラーが出る。
```
$ redis-cli ping
(error) MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
```
そもそもredisはインメモリデータベースの一種である。（そのため、高速な処理を行うことが特徴。）
ただ、サーバが停止するとメモリが解放され、データが消えてしまうので、データの永続化をおこなっている。具体的には、定期的にスナップショットを作成し、起動時にそれを読み込むことで復元をしている。今回はどうやら、そのディスクへの書き出しができないとのことでエラーが発生しているとのこと。
redisサーバを再起動することで解決。
```
$ brew services restart redis 
```
参考：
- https://www.sraoss.co.jp/tech-blog/redis/redis-persistdata/
- https://stackoverflow.com/questions/19581059/misconf-redis-is-configured-to-save-rdb-snapshots
Windows 10 のコマンドプロンプトでGeth(Go-ethereum)を起動する

自分用のメモ。

# Gethについて
正式名はGo-ethreum。
イーサリアムプラットフォーム上にブロックチェーンを構築したり、アカウントを作成して送金などの各種トランザクションをコマンドライン上で実行できる。
簡単にインストールでき、ビットコインのテストネットを使うことができるので、実際の取引は存在しない状態でいろいろいじることができる。


## Gethを起動する(コマンドプロンプト)

```
geth --networkid "10" --nodiscover --datadir E:\Users\user\Geth\private_net --http.api --http.addr --http.port "8545" --http.corsdomain "*" --http.api "eth, net,web3, personal" --miner.gaslimit "20000000" console 2››  E:\kousuke\Geth\private_net\error.log
```

## geth コマンドについて

### オプションの意味
`--networkid` ネットワークIDを明示的に設定する

`--datadir` データベースとキーストアのデータディレクトリ。Gethによって自動で作られるフォルダを指定。

`--http.api` HTTP-RPCインターフェースを介してAPIに提供される値。
web3.jsとかをコマンドラインから呼び出してブロックチェーンに対して処理を行うので、それでweb3とかを指定しているかと。

`--http.addr` HTTP-RPCサーバーを listen するインターフェース。デフォルトはlocalhost。

`--http.port "8545" ` HTTP-RPCサーバーを listen するポート番号。デフォルトは 8545。

`--http.corsdomain` CORSの設定
`--miner.gaslimit` マイニングに必要なコストの上限。




### 実行環境
geth 1.20.23

### 参考サイト

https://geth.ethereum.org/docs/interface/command-line-options

https://qiita.com/kagami-r0927/items/dfb51176eb272b03cded
Laravel8でDBの接続設定

サクラのレンタルサーバでLaravel8のDB設定を行った際の忘備録。

【環境】
・サクラのレンタルサーバ
　FreeBSD：ver.忘れた
・PHP：ver.8.0
・データベース：MySQL 

LaravelでのDBへの接続は、「.env」で設定している。
サクラのレンタルサーバは、権限の関係で「$home以下」以外は編集できない。
そのため、以下のコマンドを実行すれば.envの場所がわかる。
<pre>cd $home
find ./ -name '.env'
vi （上で検索したパス）</pre>

以下がDB関連の設定。
<pre>DB_CONNECTION=mysql
DB_HOST=hoge　　　　　　　　//変更する
DB_PORT=3306
DB_DATABASE=huga         //変更する
DB_USERNAME=ver          //変更する
DB_PASSWORD=foo          //変更する</pre>

<ul>
<li>DB_CONNECTION</li>
デフォルト値は、mysql。
サクラのレンタルサーバは、最初からMYSQLがインストールされている。
よって、変更不要。
<li>DB_HOST</li>
デフォルト値は、127.0.0.1
サクラのレンタルサーバは、WEBサーバとDBサーバが別らしいので、ループバックアドレスでは接続できない。そのため、レンタルサーバのコントロールパネルからDBのホストを調べて設定値を変更する。
なお、シングルクオートは不要。
<li>DB_PORT</li>
よくわからんけど変更不要。
<li>DB_DATABASE</li>
コントロールパネルから作成したDBの名前を入力。シングルクオートは（以下略。
<li>DB_USERNAME</li>
自分で設定したユーザ名を設定。
<li>DB_PASSWORD</li>
上に同じ

この状態でDBの接続ができるようになる。
もしここまで設定しても接続が失敗するようなら以下のコマンドを実行してcacheを消す。
<pre>php artisan config:cache</pre>
成功すれば、以下のメッセージが表示される。
<pre>Configuration cache cleared!
Configuration cached successfully!</pre>

以上。
JCenter終了問題のその後

# はじめに　
JCenterなくなる問題、なかなか大きな問題でしたね。
私の周りでは一通り対応が済んでいる状態ですが、現状ではgradleでJCenterを指定しているとdeprecatedになっていますよね。
移行してからはJCenterのその後を追っていなかったので、改めて確認してみました。

# JCenterのその後
追ってみると、以下の記載がありました。

>　We listened to the community and will keep JCenter as a read-only repository indefinitely. Our customers and the community can continue to rely on JCenter as a reliable mirror for Java packages.

> 私たちはコミュニティの声に耳を傾け、JCenter を読み取り専用リポジトリとして無期限に維持します。お客様とコミュニティは、Java パッケージの信頼できるミラーとして JCenter を信頼し続けることができます。

どうやら読み取り専用リポジトリを無期限で維持してくれるようですね。
ただ、現状Androidからの参照はdeprecatedになっていることから、JCenterの指定自体ができなくなる可能性があります。

そうなるとgradleのバージョンをあげると参照できなくなりビルドエラーなんて事もあるかもしれないので、まだ完全に移行できていない場合は早めに対応をしておいて間違いはないと思います。

# さいごに
　新しい技術が世に出回る事と同様に、JCenterのように終わりを迎えるものもあると思うと、色々思うことがありますね。
こういった形で失われていくサービスや技術に目を向けてみるのも面白いかもしれません。
WSL2のWSLg環境で could not connect to display :0 が出るようになったときの対処法

# 不具合

何日か前から別のマシン上にある複数のWSL2環境でGUIアプリを使おうとすると
```
qt.qpa.xcb: could not connect to display :0
や
Display :0 unavailable
```
のようなエラーが頻発するようになった。何回か再起動をしたら治ったりする。

# 暫定的な対処法

根本的な要因はわからないが、特に何も指定していなければ
```
$ echo $DISPLAY
:0
```
となっているはずだが、`/tmp/.X11-unix`や`/mnt/wslg/.X11-unix`の中身が本来は`X0`があるべき箇所に
```
$ ls /tmp/.X11-unix
X3
$ ls /mnt/wslg/.X11-unix
X3
```
など場合によっては他の数値のソケットファイルがなぜかできるようになっていた。

暫定的な対処法として`X3`ができていたら
```
$ export DISPLAY=:3
$ echo $DISPLAY
:3
```
とすれば再びGUIアプリが表示できるようになる。

### 追記
- https://github.com/microsoft/wslg/issues/815
- https://github.com/microsoft/wslg/issues/818
wslgでバグ報告されていたのでそのうち直ると思う。
YAHOOAPIで 不適切な表現をチェック

エロワードや誹謗中傷系のキーワードを検索することは不可能。
このAPIはあくまで "セキュリティー" という単語の代わりになにか使えるか？
などをお知らせしてくれるだけで、エロ系に対しては無反応。
ただ、laravelの`HTTP(file_get_contentsの代わり)`での使い方がわかったのでメモ。



# 校正支援 を使う


YAHOO APIキーを取得していることが条件。


```hoge.php
$app_id = "your app key";//要変更
$url = "https://jlp.yahooapis.jp/KouseiService/V2/kousei";

$res = Http::withHeaders([
    'Content-Type' => "application/json",
    'User-Agent' => "Yahoo AppID:".$app_id
    ])->post($url, [
        'id' => '1234-1',
        'jsonrpc' => '2.0',
        'method' => 'jlp.kouseiservice.kousei',
    'params' => [
        'q' => "夢を見る、セキュリティー、食べれる、遊ぶ、恋愛"
    ]

]);

print_r($res->json());

```


# 結果

```
Array
(
    [id] => 1234-1
    [jsonrpc] => 2.0
    [result] => Array
(
    [suggestions] => Array
(
[0] => Array
(
    [length] => 7
    [note] => 語末が-tyだが昨今のネット上の慣習に準ず
    [offset] => 5
    [rule] => 用字
    [suggestion] => セキュリティ
    [word] => セキュリティー
)

[1] => Array
(
    [length] => 4
    [note] =>
    [offset] => 13
    [rule] => ら抜き
    [suggestion] => 食べられる
    [word] => 食べれる
)

)

)

)
```

ものすごく微妙なAPIですね
docker

dockerコマンド

docker imags ls
docker image rm imageID
docker image prune
docker image pull imageName(docker pull centos:latest)

<img width="500" alt="image1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450388/d9d0335a-d284-1869-2f4d-d1701445043b.png">

例
docker container run -it Name sh

コンテナストップ
docker container stop containerName

コンテナ一覧
docker container ls(起動中のみ)
コンテナ一覧（停止中のコンテナも表示）
docker container ls -a
コンテナ削除
docker container rm Dockerコンテナ名
docker container prune

コンテナとイメージ（使用されていないものを削除）
docker system prune

<img width="500" alt="image2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450388/ffa1f80f-09a3-83f7-a06c-81312ffc9c21.png">






<img width="500" alt="image" src="">

dockerfile run は少なるするとイメージサイズを小さくできる
 ;\でコマンドをつなげることができる
 latest　はなるべくさける


kubectl exec -it POD sh
statsmodelsのseasonal_decomposeを活用した時系列データの可視化

# 1.時系列分析とは？
時系列分析とは、周期的なデータがありそうなデータに対して
未来の売り上げなどを予測する分析手法になります。

時系列分析に用いるライブラリの一つとして『statsmodel』というものがあり、とても便利なものになります。

今回はデータを可視化しながら解説します。

## 2.使用するデータセット

今回利用する時系列データのデータセットは、Airline Passengers（飛行機乗客数）は、Box and Jenkins (1976) の有名な時系列データです。サンプルデータとして、よく利用されます。

## 3.ライブラリの読み込み

```python
# ライブラリーの読み込み
import pandas as pd
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt
plt.style.use('ggplot') #グラフのスタイル
plt.rcParams['figure.figsize'] = [12, 9] # グラフサイズ設定
```
seasonal_decomposeは移動平均モデルを用いて、トレンド、周期性、不規則性に分解させる
ものになります。

より、洗練されたモデルであるSTLという手法がありますが、今回はより直感的に理解しやすい
移動平均モデルを使います。

plot_acfとplot_pacfというものは、自己相関係数と偏自己相関係数をプロットするものになります。

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

引用元データ
https://www.salesanalytics.co.jp/datascience/datascience003/

ここからデータを読み込みます。
これは月別の飛行機の旅客数になります。
```Python
# データセットの読み込み
url='https://www.salesanalytics.co.jp/591h' #データセットのあるURL
df=pd.read_csv(url,                      #読み込むデータのURL
               index_col='Month',        #変数「Month」をインデックスに設定
               parse_dates=True)         #インデックスを日付型に設定
df.head() #確認
```
```
	Passengers
Month	
1949-01-01	112
1949-02-01	118
1949-03-01	132
1949-04-01	129
1949-05-01	121
```
## 5.データの可視化
データをプロットし、全体を見ていきます。
ある時点で値が大きくなって、長期的に値が増加していることが分かります。
これが、季節性とトレンドになります。
```Python
plt.plot(df)
plt.title('Passengers')                            #グラフタイトル
plt.ylabel('Monthly Number of Airline Passengers') #タテ軸のラベル
plt.xlabel('Month')                                #ヨコ軸のラベル
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/e3dd98e6-fb8b-57d5-fbf9-471ccd4f8fef.png)

これらの季節性、トレンド、不規則変動を分解していきます。

## 6.seasonal_decomposeを用いたデータの分解
以下の記述で分解することが出来ました。
STL分解だとさらにきれいに分解することができます。

```python
result_decompose = seasonal_decompose(df.Passengers, model='additive',period=period)
    
result_decompose.plot()
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/25b59ee5-7454-2264-2ed7-8557b16a1637.png)
円をドルに変換するコード

# 円をドルに変換するコード
```
import tkinter as tk
import math

def dispLabel():
    a = int(EditBox1.get())
    b = int(EditBox2.get())
    A1=a//b
    A2=(a/b-A1)*100
    A2=math.ceil(A2)
    str_A1=str(A1)
    str_A2=str(A2)
    
    lbl3.configure(text="ドルに換算すると"+str_A1+"ドルと"+str_A2+"セントです。")


root=tk.Tk()
root.geometry("400x400")

EditBox1= tk.Entry(width=4)
EditBox1.place(x = 250, y = 20)
EditBox2= tk.Entry(width=4)
EditBox2.place(x = 250, y = 60)

btn=tk.Button(text="計算する",command=dispLabel).place(x = 60, y = 100)

lbl1=tk.Label(text="調べたい日本円はいくらですか？").place(x = 20, y = 20)
lbl2=tk.Label(text="今の一ドルあたりの日本円はいくらですか？").place(x = 20, y = 60)
lbl3=tk.Label(text=" ")
lbl3.place(x = 20, y = 140)

tk.mainloop()
```

![円ドル(改).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739883/95df9296-b195-b9b7-81b7-608989146b9a.png)
![円ドル(改)_入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739883/cd916490-c2e7-9e3a-876e-4113296c74af.png)

## 感想
質問文とボックスが被ってしまうことが多くて、位置調整に手間取った。
pythonを使ってslackのメッセージの送受信や画像の送信をする方法

# はじめに
slackへのメッセージの送受信についての備忘録です。
任意の画像を送信する方法についても記しておきます。
slackのトークン取得については省略します。

## pythonからslackにメッセージを送る
``` py
import reauests

def send_message_to_slack(CHANNEL, TEXT):
    TOKEN = "xxxxxx" # slackのトークン
    url = "https://slack.com/api/chat.postMessage"
    headers = {"Authorization": "Bearer " + TOKEN}

    data = {"channel": CHANNEL, "text": TEXT}
    r = requests.post(url, headers=headers, data=data)
```
pythonからslackにメッセージを送るコードです。
変数の説明は下記のとおりです。
* `CHANNEL`：送付先のチャンネル名
* `TEXT`：送付したい内容

## slackのメッセージをpythonで受け取る
``` py
import reauests

def get_new_message_from_slack(CHANNEL_URL):
    TOKEN = "xxxxxx" # slackのトークン
    url = "https://slack.com/api/conversations.history"
    payload = {"channel": CHANNEL_URL, "oldest": "1661313953"}
    headersAuth = {
        "Authorization": "Bearer " + str(TOKEN),
    }
    response = requests.get(url, headers=headersAuth, params=payload)
    json_data = response.json()
    msgs = json_data["messages"]
    return msgs
```
slackのメッセージをpythonに送るコードです。
変数の説明は下記のとおりです。
* `CHANNEL_URL`：取得先のチャンネルURL
* `msg`：取得した内容
最新のメッセージがほしい場合は`msg[0]["text"]`で取得できます。

筆者はこの関数をwhile文でループさせています。


## pythonからslackに画像を送る
``` py
import reauests

def upload_images_to_slack(p_img, CHANNEL):
    TOKEN = "xxxxxx" # slackのトークン
    files = {"file": open(p_img, "rb")}
    param = {
        "token": TOKEN,
        "channels": CHANNEL,
        "filename": "filename",
        "initial_comment": "initial comment",
        "title": "title",
    }
    requests.post(url="https://slack.com/api/files.upload", data=param, files=files)
```
pythonからslackに画像を送るコードです。
変数の説明は下記のとおりです。
* `p_img`：送付する画像のパス
* `CHANNEL`：送付先のチャンネル名

`param`内部の文字列は適宜任意のものに変更することができます。