OmniAICreator/Qiita-1.07M huggingface dataset:
【python】artライブラリを使ってみた

#### 目次
[1.インストール](####-1.インストール)
[2.使い方](####-2.使い方)
[3.フォント](####-3.フォント)
[4.まとめ](####-4.まとめ)
#### 1.インストール
ライブラリをインストールします。
~~~python
pip install art
~~~
#### 2.使い方
以下のコマンドで実行します。
~~~python
from art import *

tprint('python')
~~~
実行結果
~~~
 　            _    _
 _ __   _   _ | |_ | |__    ___   _ __
| '_ \ | | | || __|| '_ \  / _ \ | '_ \
| |_) || |_| || |_ | | | || (_) || | | |
| .__/  \__, | \__||_| |_| \___/ |_| |_|
|_|     |___/
~~~
#### 3.フォント
フォントを色々と使用できます。例えば、
~~~python
from art import *

tprint('python', '3x5')
~~~
実行結果
~~~
         #  #
### # # ### ### ### ##
# # ###  #  # # # # # #
###   #  ## # # ### # #
#   ###
~~~
他にも、
~~~python
from art import *

tprint('python', '3d')
~~~
実行結果
~~~
                    **   **
 ******   **   **  /**  /**
/**///** //** **  ******/**       ******  *******
/**  /**  //***  ///**/ /******  **////**//**///**
/******    /**     /**  /**///**/**   /** /**  /**
/**///     **      /**  /**  /**/**   /** /**  /**
/**       **       //** /**  /**//******  ***  /**
//       //         //  //   //  //////  ///   //
~~~
#### 4.まとめ
クラシックなアスキーアートですね。ではでは。
シェル？bash？ターミナル？

# はじめに

`bash`と「シェル」と「ターミナル」の違いが説明できなかったので調べました。

# 「ターミナル」とは

1. 「『コンピューターと対話するための』物理的なデバイス」
   キーボードを入力・モニターやプリンターを出力とする

2. 「GUI環境内でCLIを提供するソフトウェアアプリケーション（ターミナルエミュレーター）」の略称

簡単に補足します。

まず、コンピューターと人は、そのままでは意思疎通（コンピューターに仕事をさせる）ことができません。
そこで、キーボードやモニターを使用し、コンピューターと意思疎通するわけです。
この端末を「ターミナル」と呼びます。

また、この「ターミナル」のエミュレーター（模倣品）が「ターミナルエミュレーター」です。

「GUI」とは「マウスカーソルを使用してファイルをいじる」ことであり、「CLI」とは「キーボードのみでファイルをいじる」ことです。

# 「シェル」とは

「シェルとは何か」は複雑な問題でした。

1. 「ユーザーからのコマンドを受け取り、OSに伝えるインターフェース」全体の名称。
   ターミナルが画面を提供し、シェル
   例：`bash`も`Windows Powershell`も「シェル」である。

2. かつて多くのUNIX系OSで使用されていた`Bourne shell`のこと。また、そのコマンド名`sh`のこと。
   例：`bash`は`Bourne shell`（=略称：シェル）に影響を受けた「シェル」である。

3. `bash`などの「現在使用されているシェル」への「ハードリンク」「シンボリックリンク」としての`sh`
   例：（設定されていれば）"`docker compose exec web /bin/sh` = `docker compose exec web bash`" である。

4. 例外として、`SSH`（セキュアシェル）の略称。ただし誤解を招く表現で、避けるべきである。

## シェル、一言で何？

「総称としてのシェル」「シェルの中でも、特に`Bourne shell`のこと」「現在使われているシェル（`bash`など）へのリンク」です。
<br>
難しいので、「`shell`や`Powershell`などの総称である」ということだけ覚えればよいでしょう。
# `bash`とは

先ほどから少し触れていますが、`bash`は<font color="Orange">「シェル」の一種</font>であり、
「`Bourne shell`」に大きく影響を受けた後続のシェルです。

`bash`は`Bourne Again SHell`の略称です。もろに`Bourne shell`ですね。

# おわりに

大まかには理解できたと思います。

言葉や理解が足りないところがあればコメントお願いします！
# 参考

https://e-words.jp/w/Bourne%E3%82%B7%E3%82%A7%E3%83%AB.html

## 参考 他

いつか見たツイート

ChatGPT
Elixir: Redix の使い方

## Redis の状態の確認

```bash
sudo systemctl status redis
```

```text
$ sudo systemctl status redis
● redis-server.service - Advanced key-value store
     Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; preset:>
     Active: active (running) since Thu 2024-03-07 08:37:21 JST; 10h ago
```

クライアントでアクセス

```bash
redis-cli
```

```text
$ redis-cli
127.0.0.1:6379> keys *
1) "t1857"
2) "t1852"
3) "t1855"
4) "t1856"
5) "t1854"
6) "t1851"
7) "t1858"
8) "t1853"
9) "t1859"
127.0.0.1:6379> get "t1851"
"{\"name\":\"\xe7\xa6\x8f\xe4\xba\x95\",\"population\":24815,\"date_mod\":\"2001-7-14\"}"
127.0.0.1:6379>
```

## プロジェクトの作成

```bash
mix new redix01 --sup
```

次のフォルダー構造が作成されます

```text
$ tree redix01
redix01
├── README.md
├── lib
│   ├── redix01
│   │   └── application.ex
│   └── redix01.ex
├── mix.exs
└── test
    ├── redix01_test.exs
    └── test_helper.exs
```

```bash
cd redix01
```

mix.exs を修正
>{:redix, "~> 1.1"}, を加えます。

```exs:mix.exs
（省略）
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
	{:redix, "~> 1.1"},
    ]
  end
end
```

```bash
mix deps.get
```

## 対話で Elixir を使う

```bash
iex -S mix
```

```text
Interactive Elixir (1.14.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
```

サーバーに接続

```text
{:ok, conn} = Redix.start_link(host: "localhost", port: 6379)
```

```text
iex(1)> {:ok, conn} = Redix.start_link(host: "localhost", port: 6379)
{:ok, #PID<0.415.0>}
```

Rdis のキーの取得

```text
Redix.command(conn, ["keys", "*"])
```

```text
iex(2)> Redix.command(conn, ["keys", "*"])
{:ok,
 ["t1857", "t1852", "t1855", "t1856", "t1854", "t1851", "t1858", "t1853",
  "t1859"]}
  ```

値の取得

```text
Redix.command(conn, ["GET", "t1851"])
```

  ```text
  iex(3)> Redix.command(conn, ["GET", "t1851"])
{:ok, "{\"name\":\"福井\",\"population\":24815,\"date_mod\":\"2001-7-14\"}"}
```

## プログラムの作成

次のコードを lib/redix01.ex に加えます。

```exs
  def main([]) do
    IO.puts "*** start ***"
{:ok, conn} = Redix.start_link(host: "localhost", port: 6379)
keys = Redix.command(conn, ["keys", "*"])
    IO.inspect(keys)
vv = Redix.command(conn, ["GET", "t1851"])
        IO.inspect(vv)
    IO.puts "*** end ***"
  end
```

```exs:lib/redix01.ex
（省略）
  def main([]) do
    IO.puts "*** start ***"
{:ok, conn} = Redix.start_link(host: "localhost", port: 6379)
keys = Redix.command(conn, ["keys", "*"])
    IO.inspect(keys)
vv = Redix.command(conn, ["GET", "t1851"])
        IO.inspect(vv)
    IO.puts "*** end ***"
  end

end
```

コンパイル

```bash
mix compile
```

実行

```bash
mix run -e "Redix01.main([])"
```

```text
$ mix run -e "Redix01.main([])"
*** start ***
{:ok,
 ["t1852", "t1851", "t1859", "t1856", "t1857", "t1858", "t1854", "t1855",
  "t1853"]}
{:ok, "{\"name\":\"福井\",\"population\":24815,\"date_mod\":\"2001-7-14\"}"}
*** end ***
```
GitHubでリモートリポジトリを作成する

# 初めに

https://qiita.com/Misato0127/items/360de00c71ba031b63e8#:~:text=リモートリポジトリ%201%20GitHubにログインしてください%202%20ログインしたら、GitHubのホームページに移動します%E3%80%82%20...%203%20%22Repositories%22,ページが表示されます%E3%80%82%20...%205%20設定が完了したら、画面下部にある%20%22Create%20repository%22%20ボタンをクリックします%E3%80%82%20

リモートリポジトリについてよく理解できなかったので、
上記のqiita記事を参考に勉強させていただきました。
ありがとうございました。

# リモートリポジトリへpushするまでの流れ




## GitHubでリモートリポジトリを作成

GitHubにログイン後右上にある自分のアカウントアイコンを押してもらって、
![スクリーンショット 2024-03-06 15.14.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/652e9a04-0d79-a85f-f316-300fce95c62e.png)


たくさん項目がある中で、Your repositoriesを選択してください。

![スクリーンショット 2024-03-06 15.16.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/9b87915c-f1a6-9d38-07a5-1d83aeafae29.png)

上の方にあるNewのボタンを押してもらって、


![スクリーンショット 2024-03-06 15.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/40c0b1b6-61b2-126d-2772-6f630203ac7c.png)

リポジトリについての設定をしてください。


![スクリーンショット 2024-03-06 15.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/314fd2ca-6ecd-0b50-db6d-7e75a59a9446.png)


できたらCreate Repositoryで作成してください。

これでリモートリポジトリを作成できました。

## 新しいディレクトリを作る

```
    mkdir ディレクトリ名
```
でディレクトリを作ることができます。
すでにディレクトリがある場合はここをスキップしてください。

## ローカルリポジトリを作成する

作成したディレクトリをローカルリポジトリにするために

```
git init
```
をしてください。

## ローカルリポジトリとリモートリポジトリを結びつける

先ほど作成したリモートリポジトリのURLを入手します。
GitHubにログインします。
アカウントのアイコンを押してもらってYour repositoriesで
リポジトリ一覧を見ます。

先ほど作成したリモートリポジトリのURLがコピーできると思うので、
コピーします。

```
git remote add origin コピーしたURL
```
でローカルリポジトリとリモートリポジトリを結びつけることができました。

これでgit push でローカルリポジトリの内容をリモートリポジトリに反映させることができます。

# 終わりに

ローカルリポジトリとリモートリポジトリの結び付けはgit push を使うために
使うのですが
最初は難しいと感じることやgitに慣れてきても忘れることがあるのでぜひ確認してみてください！
Boost.Coroutine2をwindows/VisualStudioで使う

## 前提
- windows
- Visual Studio 2022
- Boostは現時点での最新バージョン(1.84.0)
- C++11以降

## Boostのダウンロード
https://www.boost.org/

にアクセスし、Latest Releaseから最新のやつをダウンロード(.7zでも.zipでも可)
解凍しておく。

## ビルド
コマンドプロンプトかPSを開いて、

```PS
.\bootstrap.bat
```
を実行。なんかファイルが色々作られる。
次に、
```PS
.\b2.exe install toolset=msvc runtime-link=static,shared asmflags=\safeseh address-model=32,64 -j9 --with-context --prefix=C:\Users\path\to\install
```
とすれば C:\path\to\installにincludeとlibフォルダを含むビルド結果が入れられる。

### オプションについて補足
- toolsetではmsvcだったりgccだったりを指定する。msvcのバージョンまで正確に指定することもできる
- runtime-linkはCランタイムをどうリンクするかで、自分のプロジェクトだとstaticだけでよかったが、一応sharedも指定しておいた。デフォルトではsharedのみなので注意!
- with-hogehogeでそのライブラリのみをビルドする(後述)。複数のwith-hogeをオプションにつけることができる
- asmflags=\safeseh はBoost.Contextでwindowsのx86-32bit上でfcontext_tを使うために必要

他のオプションについては https://boostjp.github.io/howtobuild.html の下部を参照のこと。

### ビルドするライブラリについて補足
Boostはheaderのみでビルドせず使えるモジュールと、ビルドが必要なモジュールがある。
Boost.Coroutine2自体はビルドがいらないが、それが依存しているBoost.Contextにビルドが必要。よって今回は--with-contextとした。
なお、Boost.CoroutineというCoroutine2に置き換えられたライブラリはビルドがいるのですが、2では使わないので--with-coroutineは不要。

ライブラリの一覧は、
```PS
./b2 --show-libraries
```
で見ることができる。

## プロジェクトの設定
VisualStudioで 構成プロパティ→C/C++→全般→追加のインクルードディレクトリ を開き、先ほどビルドした結果のinclude\boost_1_84_0をパスに追加する。

同様に、構成プロパティ→リンカー→全般→追加のライブラリディレクトリ　を開き、先ほどビルドした結果のlibをパスに追加する。

## インストールの確認
```cpp
#include <boost/coroutine2/all.hpp>
```
が動けばとりあえず導入は成功している。が、以下に注意。

## 注意
Coroutine2(Context)ではコンテキストにfcoutext_tかucontext_tを使える。

https://www.boost.org/doc/libs/1_84_0/libs/coroutine2/doc/html/coroutine2/performance.html

を見る限り、fcontext_tを使ったほうがいいだろう。windows環境でこれを使うには罠がいくつかある。

https://www.boost.org/doc/libs/1_84_0/libs/coroutine2/doc/html/coroutine2/overview.html

に書いてあるのだが、** コンパイル時に/GLオプションをoffにして、/EHsオプションを付けないといけない。**
これを忘れると、リリースビルドの時に/GLがついてて壊れたりする。

また、現在自分が使っているContextがfcontext_tかucontext_tかを判定する方法も現在調査中。だれか教えてください。
2024/03/11追記：コンパイル時にどちらの実装を使うか決まる。デフォルトだとfcontext_tなのでそのままでよい。

## 参考文献
BoostJP How To Build https://boostjp.github.io/howtobuild.html
BoostJP Coroutine2 https://boostjp.github.io/tips/coroutine.html
Boost Coroutine2 https://www.boost.org/doc/libs/1_84_0/libs/coroutine2/doc/html/coroutine2/overview.html
MSVC Compiler Option https://learn.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=msvc-170
JavaScriptは省略がお好き【アロー関数】

JavaScriptの関数の書き方を整理してみました。

## 通常の関数
```javascript
function sample (str) {
    return str;
};

console.log(sample("関数sampleにこの文を引数として渡して出力します。"));
```

```javascript
const sample = function (str) {
    return str;
};

console.log(sample("関数sampleにこの文を引数として渡して出力します。"));
```

## アロー関数
```javascript
const sample = (str) => {
    return str;
};

console.log(sample("関数sampleにこの文を引数として渡して出力します。"));
```
### 引数が一つの場合は(str)の部分のカッコを省略できる。

```javascript
const sample = str => {
    return str;
};

console.log(sample("関数sampleにこの文を引数として渡して出力します。"));
```

### 処理が１行で返却されている場合は波カッコとrerutnを省略できる。

```javascript
const sample = str => str;

console.log(sample("関数sampleにこの文を引数として渡して出力します。"));
```

### 右辺をオブジェクトにしたい場合は（）を使う。

```javascript
const sample = (num1, num2) => ({
    bust: num1,
    hip: num2
});

console.log(sample(86, 98));
```

### 省略例

```javascript
const sample = function (num1, num2) {
    return num1 + num2;
};

console.log(sample(86, 98));
```

上述の内容を踏まえ、上記の関数を省略して書くと、以下のようになります。

```javascript
const sample = (num1, num2) => num1 + num2;

console.log(sample(86, 98));
```
JavaScriptでセグメントツリー

## まえがき

前々から身につけたいと思っていたセグメントツリーを学習し
AtCoderでACすることができたのでここに記事として残す
応用範囲が広く解説するのも一苦労なので時間のある時に追記していきたい

## 目次
・[ソースコード](#ソースコード)
・[実際に使ってみた](#実際に使ってみた)
・[あとがき](#あとがき)

# ソースコード

```js
class SegmentTree {
  constructor(n) {
    this.leafSize = 0
    this.data = []
    this.init(n)
  }

  init(n) {
    let leafSize = 1
    while (leafSize < n) {
      leafSize *= 2
    }
    this.leafSize = leafSize
    this.data = Array(2 * leafSize - 1).fill(Number.MAX_SAFE_INTEGER)
  }

  update(k, a) {
    k += this.leafSize - 1
    this.data[k] = a
    while (k > 0) {
      k = Math.floor((k - 1) / 2)
      this.data[k] = Math.min(this.data[k * 2 + 1], this.data[k * 2 + 2])
    }
  }

  get(k) {
    k += this.leafSize - 1
    return this.data[k]
  }

  query(a, b, k, l, r) {
    if (r < a || b < l) return Number.MAX_SAFE_INTEGER
    if (a <= l && r <= b) {
      return this.data[k]
    }
    let vl = this.query(a, b, k * 2 + 1, l, Math.floor((l + r) / 2))
    let vr = this.query(a, b, k * 2 + 2, Math.ceil((l + r) / 2), r)
    return Math.min(vl, vr)
  }

}
```
## 実際に使ってみた
[E - Alternating String](https://atcoder.jp/contests/abc341/tasks/abc341_e)

使い所はすぐにわかる、クエリ問題で列の変更と列の区間を求める問題はセグメントツリーだ
愚直に解くとクエリの数かける列の全体を調査するので計算量はO(Q*N)となり間に合わない
この場合、最大で
5 * 10^5 * 5 * 10^5 
≒ 10^11 でTLEとなる
[提出結果](https://atcoder.jp/contests/abc341/submissions/50925820) TLE 3319ms

だがセグメントツリーを使えば計算量はO(Q*logN)になるので間に合う
この場合、最大でも
5 * 10^5 * log(5 * 10^5) 
= 5 * 10^5 * (log5 + 5log10)
≒ 5 * 10^5 * (2.3 + 5 * 3.3)
≒ 10^6
(２分木なのでlogの底は2、値は計算サイトから算出)
[提出結果](https://atcoder.jp/contests/abc341/submissions/50966908) AC 1751ms

セグメントツリー問題は一目でセグメントツリーを使うとわかるので
問題の本質はセグメントツリーの中にどんなデータを入れるかだ
本問の場合、隣り合う文字の関係を配列にし、文字を反転させても影響があるのは両端のみだと気づく必要がある
初見では分からなかったが次、同様の問題が出た場合は解けるよう精進していきたい


## あとがき

セグメントツリーを身につけたかった
なぜならAtcoderで頻出のデータ構造だからだ
Atcoderの参加回数とレーティングの統計によると
私ぐらいの参加回数だと緑レベルが平均的なようだが
残念ながら私は未だ茶色コーダーだ
私はjsをメインに使っているので
「ライブラリが充実していないので仕方がない」
「C++を使ってたなら今頃もっと上のレートだった、まだ本気を出してないだけ」
という言い訳を作ることもできるが
実力の伴わない現実から目を逸らし自己を向上させることから逃げたくはない
学ぼうと思ってから実際に行動に移すまで想定よりも時間はかかったが
なんとか競プロ中級の入口レベルには到達したように思う

素直にC++使えよって意見についてはもっともだとは思うが
私は他の人がやっていないことをやるのが好きなのだ
レーティングが完全に頭打ちになるまではjsを使い続けようと思う
次に学習したいこととしてよく目にするけど未だ理解していない巡回セールスマン問題あたりを解けるように頑張りたい
[Linux]OS起動時にエラーでフリーズした時やった事

## 初めに

この記事ではOS起動時にエラーが出て正しく起動しないとき、まず初めにやるべきことをお伝えしています。
- ubuntu 22.04.4
## 事の経緯
私は普段サブPCのubuntu OSを、メインPC(win11)からリモートデスクトップを使い操作しているのですが、サブPCにはダミーHDMIプラグというものをさして使用していました。
　＊ubuntuのデフォルトのリモートデスクトップ機能はモニターが接続されていないといけないため

 https://rarak.jp/18469

しかしダミープラグが壊れてしまい、ソフトウェアでダミープラグのようなものを探したところダミーのビデオドライバをインストールするという方法があり早速やってみたのですがOSが起動しなくなってしまいました。。。

https://www.techlife-hacking.com/?p=1720

後に分かったのですが.confファイルを一つ上の階層においてしまっていたようでした。


## 症状

PC起動時に
```
[FAILED] Failed to start Process erautomatic reporting is enabled.
```

が表示され、GUI画面に行きません。
どうにかコマンド打てるようにしたい。。

## やった事

### エラーが出ている画面で　alt + F2　

https://acchi-muite-hoi.hatenablog.com/entry/linuxFreeze

- これでコマンド打てるようになるはずですが、なぜかすぐエラー画面に戻され操作できず、、、
### リカバリーモードで起動
- PCを再起動し、GRUBメニューが表示されるまで「Shift」キー　長押し(連打？)
- 「Advanced options for Ubuntu」を選択し、利用可能な「Recovery mode」オプションを選択
- 「root Drop to root shell prompt」を選択して、ルート権限でシェルにアクセス
```
sudo apt-get update
sudo apt-get remove --purge xserver-xorg-video-dummy
reboot 
```
　　→実行したが、症状変わらず...

もう一度シェルにアクセスし、
```
cd /etc/X11
//xserver-xorg-video-dummyをインストールしたときに自分で作成した設定ファイル
rm xorg.conf 

reboot 
```
　　→解決


  ## おわりに
今回ビデオドライバをインストールする際設定ファイルを置く場所を間違っていたというポンコツをやらかしましたが無事修正できました。
リカバリーモードも初めて触ったのでいろいろ学びがありました。(alt F2でCLIいけない時は焦った)

皆さんもOSに近いファイルいじるときは気を付けよう！！！
Parse Server Java SDKの使い方（Kotlinでのロール操作）

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

ニフクラ mobile backendからの移行先として、お勧めしているのが[Parse Server](https://parseplatform.org/)です。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

Parse ServerではAndroid向けにSDKを提供していますが、言語はJavaのみとなっています。Kotlin向けには、Java SDKの内容を翻訳しながら実装する必要があります。そこで、各機能の使い方を解説します。今回はアクセス権限に関係するロールの操作について解説します。

## Android SDKのインストール

Android SDKのインストールは幾つかの設定が必要です。

### settings.gradleの修正

プロジェクトルートにある `settings.gradle` を修正します。

```groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
				// 以下を追加
        maven {
            url "https://jitpack.io"
        }
    }
}
```

### app/build.gradleの修正

app以下にある `build.gradle` を修正します。

```groovy
dependencies {
	// 以下を追加
	implementation "com.github.parse-community.Parse-SDK-Android:parse:4.2.1"
}
```

バージョンはインストールするタイミングによって異なりますが、現在は以下です。

![](https://jitpack.io/v/parse-community/Parse-SDK-Android.svg)

### AndroidManifest.xmlの修正

開発中で、ローカルのParse Serverを使う場合には、以下の設定が必要です。

```xml
<application
	android:usesCleartextTraffic="true" <!-- 追加 -->
>
```

## 初期化

SDKの初期化は `MainActivity` にて行います。Androidはエミュレーターなので、 `localhost:1337` ではなく、 `192.168.0.2:1337` などがParse ServerのURLになるでしょう。

```kotlin
import com.parse.Parse

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Parse.initialize(
            Parse.Configuration.Builder(this)
                .applicationId("appId")
                .clientKey("clientKey")
                .server("http://your_parse_server/parse/")
                .build()
        )
				// 省略
		}
}
```

## ロールの作成

ロールは子ロールと、ユーザーを持つことができます。以下の例では、 `Administrator` というロールを作成しています。

```kotlin
val roleACL = ParseACL()
roleACL.publicReadAccess = true
val role = ParseRole("Administrator", roleACL)
role.saveInBackground()
```

## ロールにユーザーを追加する

既存のロールに対して、新しいユーザーを追加する場合のコードです。

```kotlin
for (user in usersAddToRole) {
		role.getUsers().add(user)
}
role.saveInBackground()
```

## ロールからユーザーを削除する

ロールからユーザーを消す場合には `remove` を使います。もちろんACLの設定によっては、削除できない場合もあります。

```kotlin
for (user in usersRemoveFromRole) {
		role.getUsers().remove(user)
}
role.saveInBackground()
```

## 既存のロールに新しいロールを追加する

ロールは入れ子の構造にできます。

```kotlin
for (r in rolesAddToRole) {
		role.getRoles().add(r)
}
role.saveInBackground()
```

## 子ロールを削除する

子ロールを削除する場合には `remove` を使います。

```kotlin
for (r in rolesRemoveFromRole) {
		role.getRoles().remove(r)
}
role.saveInBackground()
```

## まとめ

Parse Serverのロールオブジェクトは、NCMBと変わらず利用できます。ユーザーを入れる形もそうですし、ロールを入れ子にできるのもNCMBと変わりません。

ACLの仕組みもParse ServerとNCMBで似ています。他のmBaaSと比べると、全体の修正量はそこまで多くないと思われます。載せ替え先として検討に挙げてください。

[Android Developers Guide \| Parse](https://docs.parseplatform.org/android/guide/)
[Angular][IONIC7]フォーマット付きテキストボックスの作り方

## 数値はカンマ区切りで表示して欲しい！！
Web系のプロジェクトでコレ系の要望をよく言われるけど、
HTMLのinput[type=number]ってそこまで賢くないんだから、

__「うるせー、そんなオンプレでやってるようなことWebで要望すんなや！」__ 

って、めっちゃ言いたい気持ちを笑顔で押し殺して、
サードのライブラリとかはじめからそういったマスク入力が出来るライブラリ（Vueだと[PrimeVue](https://primevue.org/)）を選定するわけですが、毎回使えるわけでもないので。。。

__だったら自分で作ってみたらいいんでね？__

という、車輪の再発明みたいなことをしてみようかと。

## 実装環境
まぁタイトルにありますが、IONICとAngular(Standoalone)で作ってみました。
※多分どのバージョンのIONICでも出来るはず


## 今回の動きとしては
ion-textの表示時・入力時の動きを以下のようにしました。
- 表示：フォーマットしたもの
- 入力：フォーマットを外したものを編集


 ## そんなわけでソース
```html:component.html(抜粋)
<ion-input [formControl]="control" 
  (ionFocus)="focus()" 
  (ionBlur)="blur($event)" 
  (ionChange)="change($event)"></ion-input>
```
ion-textに対してfocus/blur/changeイベントを登録

```typescript:component.ts(抜粋)

export class FormInputNumberComponent implements OnInit {
  // 入力制御用のFormControl
  protected readonly control = new FormControl('');
  private _value: string;
  @Input()
  get value() {
    return this.control.value;
  }
  set value(value: string) {
    // Changeイベントを発生させるかの判定用に値を保持する
    this._value = value;
    
    // {emitEvent: false}　でChangeイベントが発生しないように設定
    this.control.setValue(this.formatNumber(param.value), {
      emitEvent: false,
    });
  }

  @Output() changeEvent: EventEmitter<value?: string> = new EventEmitter();

  constructor() {}

  ngOnInit() {
    console.debug('FormInputNumberComponent ngOnInit');
  }

  focus() {
    // フォーカスが当たったときは、カンマを取り除いて詰め直す
    // {emitEvent: false}　でChangeイベントが発生しないように設定
    this.control.setValue(this._item.value?.replaceAll(',', ''), {
      emitEvent: false,
    });
  }

  blur($event) {
    // フォーカスが外れた時に、入力されてる値を整形して詰め直す
    // {emitEvent: false}　でChangeイベントが発生しないように設定
    this.control.setValue(this.formatNumber($event.detail.target.value), {
      emitEvent: false,
    });
  }


  private formatNumber(val: string): string {
    const num = Number.parseInt(val);
    return isNaN(num)
      ? ''
      : num.toLocaleString('ja-JP');
  }

  change($event) {
    // 値が変わってるときだけイベント発火
    if (this._value !== $event.detail.value){
      // 入力された値を親コンポーネントに返す
      this.changeEvent.emit($event.detail.value);
      // 整形した値を返したい場合は以下
      // this.changeEvent.emit(this.formatNumber($event.detail.value));
    }
  }
}
```

## まとめ
「入力中もフォーマットされた状態でやれや」的なクレームがあるかもしれませんが、
とりあえず表示だけでも出来てりゃええやろということで今回はここまで。

ionBlurじゃなくてionInputとかで入力監視してれば全然出来るんだろうけど、ソレやると整形後のカーソルの位置操作とかも必要になるんじゃないかなと言うめんどくささもあり、とりあえず即席でこんだけ動けばええやろ感覚で作ってみた次第です。
※そこらへんはきっと、もっと賢い人がちゃんと作ってくれるはず！

## 補足
ちなみにですが、Number.parseIntって結構使えない子みたいなので、数値かどうかの確認は
Number.parseInt　したものを　isNaNでチェックするよりも、
きちんと正規表現とかでチェックしたほうが良いかと。
脱VMwareとまらない？代替クラウドへのスムーズな移行ガイド

VMwareの買収によって不安に感じるユーザーが増えてきましたね
[Broadcom配下で「脱VMwareが止まらない」の真相](https://www.itmedia.co.jp/enterprise/articles/2403/05/news081.html "Broadcom配下で「脱VMwareが止まらない」の真相")
早くVMwareを捨てたい気持ちが分かりますが、クラウドの選定基準の理解、計画の正確さ、実装の慎重さが移行の成功には不可欠です。

## クラウドへの選定基準
移行先のクラウドを選定する際は、以下の基準を考慮することが重要です。

- コスト: 移行先のクラウドプロバイダーの料金体系を理解し、隠れたコストがないかを検証します。ライセンスの課金は、CPUコア数か、RAMかそれともストレージベースなのかを確認する必要があります。また、永久ライセンスに対応しているかも確認ポイントです。
- パフォーマンス: アプリケーションのパフォーマンス要件に合致するか、特にパフォーマンス重視のアプリをホストしている場合、要注意です。
- ストレージ：Fibre Channel, iSCSI などサポートしているかを確認する必要があります。多くのVMwareユーザーは外部ストレージを利用しています。NutanixのようなHCI製品は対応できていないケースもあります。
- バックアップ機能：プラットフォーム自身がバックアップ機能付いているか、Snapshotなども利用できるか要確認です。サードパーティーのバックアップソリューションと連携してバックアップ機能を提供しているベンダーも多いです。
- HA：ハードウェア故障時の動き、サーバーやディスクのリプレイス時にダウンタイム発生するかなどを見る必要があります。
- GPUの対応：ライブ配信、ChatGPTによるAIデータ学習などのブームでGPU対応しているプラットフォームがますます重要になってきます。GPU対応一口言っても2種類があります。GPU PassthroughとvGPU。
- 運用と利用のしやすさ：UI、Billing、画面以外のインタフェース（CLI、API）があるか
- 移行支援: クラウドベンダーが移行ツールやサービスを提供しているか、技術サポートの品質を確認する必要があります。
- エコシステムとの互換性: 現在のITインフラとの互換性、特に管理ツール、API、エコシステムの統合性を考慮する必要があります。

## 注意すべき点
移行プロセスは複雑であるため、以下の点に留意する必要があります。

- VMの移行: 大量のデータを安全にかつ効率的に移行するための計画が必要です。
- ダウンタイムの最小化: 移行中のサービス中断を最小限に抑えるための戦略が必要です。
- 従業員のトレーニング: 新しいクラウド環境を効果的に運用するために、従業員のトレーニングと準備を怠らないでください。
- アプリケーションの再構成: すべてのアプリケーションが新しい環境で問題なく動作するわけではないため、適応が必要です。

## 移行のステップ
1. 事前評価: 現在のVMware環境を詳細に評価し、移行によって解決すべき問題を特定します。
2. 計画: 移行計画を策定し、目標、スケジュール、リスク、ロールバックプロセスを明確にします。
3. 移行ツールの選定: 効果的な移行ツールを選択し、テスト環境での検証を行います。
4. データの移行: 必要に応じて、データを段階的にまたは一括で移行します。
5. 環境のテスト: 移行後の環境でアプリケーションが適切に動作するかを確認します。
6. 本番切り替え
AWS CLF入門 - 移行とイノベーション

## はじめに
AWS CLF (AWS Certified Cloud Practitioner) を取得した際の学習記録をアウトプットとして以下に記す。

## リンク
[ネットワーク](https://qiita.com/yashiuri/items/31b2c9c3c49c2584cd01)
[セキュリティ](https://qiita.com/yashiuri01/items/73e5310b09ff41912862)
[コンピューティング](https://qiita.com/yashiuri01/items/9eaf71a1590e7815f9ef)
[コンテナ](https://qiita.com/yashiuri01/items/708b57ee179ae29e72a9)
[スケーリング](https://qiita.com/yashiuri01/items/79050093aff66b0f0665)
[ストレージ](https://qiita.com/yashiuri01/items/6d48d81f5a1651dcc999) 
[データベース](https://qiita.com/yashiuri01/items/159ea63b197f7a836d1c)
[メッセージ](https://qiita.com/yashiuri01/items/d98772b540ef2201c4e2)
[モニタリング](https://qiita.com/yashiuri01/items/64f6dbf38603cdb4828a)
[デプロイ](https://qiita.com/yashiuri01/items/85151311897d6afd429c)
[コストとサポート](https://qiita.com/yashiuri01/items/bac23130a43d62677330)
[移行とイノーベーション](https://qiita.com/yashiuri01/items/6e327034a7c50d56ca88)
[AWS用語集](https://qiita.com/yashiuri01/items/bd36c99623ca596b76e4)


## 移行

### **AWS CAF(Cloud Adoption Framework)**

- AWSへの移行を迅速かつスピーディーに行うためのガイド
- 移行を検討している担当者のロールはそれぞれ違うため、包括的に移行を検討できるようパースペクティブという6つの分野にガイダンスを分類
- ビジネス
    - IT をビジネスのニーズに合わせ、IT への投資が主なビジネスの成果に結び付くようにする
        - ビジネスマネージャー
        - 財務マネージャー
        - 予算担当者
        - 戦略の関係者
- 人員
    - クラウド導入を成功に導く組織全体の変更管理戦略の開発を支援する
        - 人事
        - 人員配置
        - 人材マネージャー
- ガバナンス
    - IT 戦略をビジネス戦略に合わせるためのスキルとプロセスに重点を置く
        - 最高情報責任者 (CIO)
        - プログラムマネージャー
        - エンタープライズアーキテクト
        - ビジネスアナリスト
        - ポートフォリオマネージャー
- プラットフォーム
    - クラウドに新しいソリューションを導入したり、オンプレミスのワークロードをクラウドに移行したりするための原則とパターンが含まれる
        - 最高技術責任者 (CTO)
        - IT マネージャー
        - ソリューションアーキテクト
- セキュリティ
    - 可視性、監査可能性、制御、俊敏性のセキュリティ目標を組織が確実に達成できるようにする
        - 最高情報セキュリティ責任者 (CISO)
        - IT セキュリティマネージャー
        - IT セキュリティアナリスト
- オペレーション
    - ビジネスの関係者の合意を得たレベルで IT ワークロードを実現、実行、使用、運用し、そのレベルに復旧できるようにします
        - IT オペレーションマネージャー
        - IT サポートマネージャー

### **移行の6R**

- APPをクラウドに移行するときに導入できる6つの移行戦略
- Rehosting リホスト
    - lift-and-shift
    - 変更せずにAPPを移行
- Replatforming リプラットフォーム
    - lift-tinker-and-shift
    - クラウドの最適化(アーキテクチャは変更しない)
- Refactoring リファクタリング/アーキテクチャの再設計
    - クラウドネイティブの機能を使用してアプリケーションのアーキテクチャの設計方法や開発方法を作り直す
- Repurchasing 再購入
    - 従来のライセンスから SaaSモデルに移行する
- Retain 保持
    - ソース環境でビジネスに重要なアプリケーションを維持する
- Retire リタイア
    - 不要になったアプリケーションを削除

### **AWS Snowファミリー**

- データをAWSとの間で物理的に転送できる物理デバイス
- AWS Snowcone
    - ストレージ 8TB
    - CPU 2
    - メモリ 4GB
- AWS Snowball
    - Snowball Edge Storage Optimized
        - HDD 80TB (ブロックボリューム, S3用)
        - SSD 1TB (ブロックボリューム)
        - vCPU 40
        - メモリ 80GB
    - Snowball Edge Compute Optimized
        - HDD 42TB (S3, EBS)
        - NVMe SSD 7.68TB (EBS)
        - vCPU 52
        - メモリ 208GB
        - NVIDIA Tesla V100 GPU
- AWS Snowmobile
    - エクサバイト規模のデータ転送サービス
    - 1台あたり最大100ペタバイト

## **イノベーション**

- VMwareのAWSでの稼働
    - VMWare Cloud on AWS
- AI
    - Amazon Transcribe - 音声をテキストに変換
    - Amazon Comprehend - テキストのパターンを検出
    - Amazon Fraud Detector - 不正の可能性があるオンラインアクティビティを特定
    - Amazon Lex - 音声およびテキストチャットボットを構築
- 機械学習
    - Amazon SageMaker
【SwiftUI】push遷移先でタブバーを非表示にした後、前画面に戻った時にタブの表示が遅れる問題の解決法

## 概要
以下のような仕様を実現したいと考え、TabViewとNavigationStackを使用することにしました。
- 複数のタブがある
- タブの中の画面から別画面にpush遷移するが、その際、表示する画面はフルスクリーンで表示したい
- 別のタブでも上記を実現したい
(複数のタブでNavigationStackによる遷移を利用するため、NavigationStackでTabViewをラップすることは出来ない)

この仕様に対して、TabViewでNavigationStackをラップし、`.toolbar(, for:)`にhiddenを設定すれば良いと考えていましたが、以下の問題が発生しました。

**遷移元から別画面にpush遷移後、遷移元に戻るとタブバーの表示にラグが発生する**

この問題に対して、以下で考察と解決法の実装を行います。

## 考察
遷移先の画面(SecondView)に遷移後、前画面 (FirstView)に戻ると問題なくタブは表示されるのですが、上述の通りタブバーの表示にはラグがありました。
`.toolbar(, for:)`を特に設定しなければ、各Viewのツールバー設定はデフォルトでは`.visible`になっているはずなので、Viewが表示されたタイミングでこの設定が適用されており、ここにタブバー表示のラグの原因があると考えました。
そのため、前画面のFirstViewへ戻る**前に**`.hidden`に設定された`.toolbar(, for:)`を`.visible`に設定し直せば良いのでは？と考えました。

この考えをベースに以下で実装します。

## 実装
まずはルートの部分を以下のようにTabViewが親となるようにNavigationStackを配置します。
```SampleApp.swift
@main
struct NavigationSampleProjectApp: App {
    init() {
        UITabBar.appearance().backgroundColor = UIColor.white
    }

    var body: some Scene {
        WindowGroup {
            TabView {
                NavigationStack {
                    FirstView()
                }
                .tabItem {
                    Text("タブ")
                }
            }
        }
    }
}
```
次にSecondViewへの遷移処理を実装したFirstViewを以下のように書きます。
```FirstView.swift
struct FirstView: View {
    var body: some View {
        VStack(spacing: 24) {
            Text("First View")
                .foregroundStyle(.white)

            NavigationLink {
                SecondView()
            } label: {
                Text("to SecondView")
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.red.opacity(0.6))
    }
}

#Preview {
    FirstView()
}
```
最後にSecondViewを実装します。
SecondViewではflagという`.toolbar(, for:)`のvisibilityを変更するためのプロパティを用意します。
このflagを利用して、Backボタンタップ時にvisibilityをFirstViewの表示前にvisibleに変更します。
注意点としては、flagを`@State`で宣言することです。
`@State`で宣言しないと、flagの値が変わってもViewが再描画されないため、前画面に戻った時にタブの表示でラグが発生してしまいます。
```SecondView.swift
public struct SecondView: View {
    @Environment(\.dismiss) var dismiss
    @State var flag: Visibility = .hidden

    public var body: some View {
        Text("Second View")
            .foregroundStyle(.white)
        .navigationBarBackButtonHidden(true)
        .toolbar{
            ToolbarItem(placement: .navigationBarLeading){
                Button {
                    flag = .visible
                    dismiss()
                } label: {
                    Text("Back")
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.blue.opacity(0.6))
        .toolbar(flag, for: .tabBar)
    }
}

#Preview {
    SecondView()
}

```

## 終わりに
TabViewとNavigationStackの両方を使うことはよくあることであり、push遷移後にフルスクリーンで画面を表示したいという要求もまたよくあることだと思います。
一方でこのタブの表示のラグに関する明確な解決策が見つからず、ラグを受け入れる、あるいはフルスクリーンモーダルで実装などの対応を取られていた方もいるかもしれません。
この解決法がTabViewとNavigationStackの実装の一助になると幸いです。
最後までお読み頂き、ありがとうございました。
CORS エラーって・・・？

# CORSエラーって

WEBの技術や知識はとても便利で画期的だと思います。それゆえに、追いつくにはなかなか難しいです。  
私は書籍やネット上から知識を吸収し、日々先輩を追い越すために、上司に追いつくために精進していますが、なかなかすべての知識を身に着けることは難しいです。  
今回はそんな中上司から教えていただいた知識をアウトプットするために本記事を記載します。  

## CORSエラーとは？

表題に「CORSエラーとは？」と記載しましたが、その前に抑えておきたい知識がありましたので、まずはそちらから・・・  

### 同一オリジンポリシーとは？

SORS(Same-Origin Resource shareing)とも呼ばれ、外部のAPIサーバへのHTTPリクエストを制限するための指針です。  
つまり、むやみやたらにAPIを利用されるとサーバへの負荷やセキュリティの観点からよろしくないので、利用できるユーザを制限するということです。  
たとえば、見ず知らずのユーザがAPIを利用してデータを更新できたら(家具の配置を変えられたら)怖いですよね。このような事態を防ぐために、APIキー(鍵)があっているかどうか認証して、入り口を通過できるユーザを制限しています。  

##### 脇道：APIとは？

Application Programming Interfaceの略称で、APIとして公開されたプログラムを外部から手軽に利用できるように提供する仕組みのことです。  
この仕組みにより、外部のユーザはAPIを経由して内部プログラムを呼び出すことができます。  

#### オリジンとは？

オリジンとは下記の3つのことを概念的に指しますが、下記3つが同じことが「同一オリジン」と呼びます。  

* ホスト：ドメインのこと。  
* スキーム：http もしくは https のこと。  
* ポート：通信先となるソフトウェアの識別子のこと。  

### CORS(Cross-origin Resource shareing)とは？

SORSでの制限を一部解除することで異なるオリジンへのアクセスを許可したものです。  

たとえば、下記サーバスクリプト「httpClient」がCROSに該当します。  

https://pleasanter.org/manual/server-script-http-client  

## まとめ：CORSエラーとは？

改めまして、上述の内容からCORSエラーについてまとめようと思います。  
そもそも、CORSとは異なるオリジンへのアクセスを一部許可したものです。このことから、CORSエラーとは異なるオリジンへアクセスした際に発生するエラーであることがわかります。  
また、SSLサーバ証明書が登録されていないためにCORSエラーが発生することもあります。  

## CORSエラーへの対処方法

### Access-Control-Allow-OriginヘッダにURLを追加する

まずは、サーバ側のAccess-Control-Allow-OriginヘッダにURLを追加しましょう。  

### SSLサーバ証明書を追加する

上述した通り、SSLサーバ証明書が登録されていないために発生している可能性があるため、SSLサーバ証明書を登録しましょう。  

# 参考資料

### 同一オリジンポリシーを理解する。CORSエラーの原因と回避方法！

https://ugo.tokyo/same-origin-policy/  

### CORSエラーってなに？どうすれば解決するの？

https://qiita.com/higakin/items/fabe6a23d564b20ad558  

### 用語集｜API（エーピーアイ）

https://www.idcf.jp/words/api.html
vbaで複数のブックのセルデータを一括変更

```
    Dim path As String
    Dim File As String
    Dim wb As Workbook
    
    path = ThisWorkbook.path & "\target\"
    File = Dir(path & "*.xlsx*")
    
    Do While Len(File) > 0
    
        Set wb = Workbooks.Open(path & File)
        
  
        SheetsCnt = wb.Sheets.Count
     
        For i = 1 To SheetsCnt
        
            
            SheetName = Sheets(i).Name
            
                If SheetName = "紙" Or SheetName = "表" Then
            
            Else
                                 
                Worksheets(SheetName).Range("A3") = "画"
            
            End If
            
    
        Next i
        
       
        ActiveWorkbook.Save
        
        Workbooks(wb.Name).Close
        
        Set wb = Nothing
        
        File = Dir()
    
    Loop
私の仕事をする上で大切にしていること

私が仕事をする上で大切にしていることは、

**・長い手戻りは何も価値は生まない**
**・透明性**
**・説明責任**
の３つです。

#### なぜこの３つ？・・・

働き始めた会社の経験、自動車業界での１社目の経験が大きく関係しています。

#### 手戻りの苦い過去

私は、自動車業界に入る前、電源系のアナログ回路エンジニアを短い期間していました。
そこで、仕様折衝、回路設計、パターン設計、試作、信頼性試験の全工程を担当していました。

アナログは本当に素人で、右も左もわからない状態、授業で習う回路図が書けるくらい（抵抗書やコンデンサを置くくらいのレベル）でした。
開発を通して、得た学びは、「**長い手戻りは何も価値を生まない**」です。
ど素人が、回路設計し、パターンを設計しても、うまくいく訳はないですよね。（よくやらせてくれたなと思います、当時の職場に感謝です・・・）
回路図がだめだと、パターンもだめになり、当たり前ですが、性能も信頼性もない製品ができます。
当時すでに回路シミュレータはなどは巷にはありました。小さい会社ではなかなか使うことができないので、実機を使って評価を行うことが多かったと思います。
V字プロセスの、右上に該当するテスト（信頼性試験）で、だめだね（使い物にならないね）というのが分かります。
だめというのがわかって、戻る距離が非常に長いです。
いい設計ができないと、手戻りする距離、量が大きく、その分時間と費用を捨てることになってしまいます。
（試作品の部品の注文や、ポリテクセンターの予約も、自分でやっていたので、どんどん赤字になっていくのが分かり、ごめんなさいといつも思っていました。）
![temodori.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592747/8e65d2dd-0d53-9212-3fe8-3840eebc84d2.png)

だから私は、長い手戻りがとても嫌いです。
早く失敗して、早く直して、お金をあまりかけずに良い製品開発をしたいと常々思っています。
今はソフトウェア開発に携わっているので、小さく作って、小さく失敗して、即修正するを実践しています。

#### ミッションクリティカルに作る

透明性と説明責任は、当時所属していた企業の社是になります。
私は、自動車部品サプライヤ（ブレーキ系）のソフトウェアエンジニアをしていました。
ブレーキと言えば、車に乗る人の命を守る安全部品の一つです。クリティカルセーフティであることが求められる製品です。
ブレーキ開発をする上で、製品開発の透明性が高く求められます。
透明性を担保するために、開発プロセスの順守、トレーサビリティ確立が当たり前の環境で育ちました。
「透明性」は、ユーザー（ドライバーや乗客）の安全を達成するために必要なことであり、また何かが起こったときにエンジニア自身を助けてくれます。
透明性を担保するためには、必然的に説明責任も必要になります。
透明性があることを、プロセスの順守、トレーサビリティの確保、テスト実行により、自分の開発したものが正しい状態・正しく動くことを証明する必要があります。

製品開発を進めながら、この社是は身に染みていきました。
今は、安全部品の開発に携わっていませんが、この三つのことを常に意識しています。
Webアプリケーションのhttps化で躓いた５年目エンジニアの冬

この記事は、私のように知識や技術を曖昧にしか理解していない
ひよこエンジニアにとって、少しでも役に立つ内容になることを
祈って書いていたりいなかったりする。

エンジニアにとってバグやエラーは日常茶飯事で、
常に遭遇する事象であるが、
蓋を開けてみればなんてことない話だったりすることがほとんどだ。

私のように知識ないゆえに、理解が浅いゆえに
苦しんでいるエンジニアのようになりたくなければ、
あなたも基本的な仕組みから理解を深めていくことをお勧めする。

## Webサイトをhttps化する際に躓いたこと

　現在、携わっているクラウド上にWebアプリケーションを
　構築するプロジェクトで、一部のページへのアクセスをhttpsに
　する必要があり、apacheの設定を変更した際の躓きについて紹介したいと思う


## そもそもhttpsとは？

　ブラウザからインターネットを介して、特定のWebサイトにアクセスする際に
　用いられる通信規格は「http」であるが、httpsはhttpによる通信を行う際に、
　情報を暗号化するプロトコルである。

　仕組みとしては、公開鍵暗号化方式によるクライアント-サーバ間の認証と
　認証後の共通鍵暗号化方式による通信により実装できる。

## httpsの具体的な仕組みとは？

　実際に一部のページへのアクセスをhttpsにする場合に、
　apacheの拡張モジュールであるmod_sslを用いて、
　opensslコマンドで秘密鍵と対になる公開鍵を作成し、
　プライベート認証局によるサーバ証明書（.crtファイル）を作成する。

　秘密鍵はサーバ側に保持し、サーバ証明書には公開鍵情報が記載される。
　
　クライアントがサーバにアクセスすると、サーバは
　クライアントに対してサーバ証明書を渡し、
　クライアントは、サーバのルート認証局が正規な認証局であるか、
　サーバ証明書そのものが改ざんされていないか、
　サーバのドメインとSanSが一致しているか、を確認し、
　問題なければクライアントのDH公開鍵をサーバの公開鍵で暗号化してサーバに渡す。

　サーバは暗号化されたクライアントのDH公開鍵を秘密鍵で復号化し、
　認証を行う。

　移行は、共通鍵を生成しサーバとクライアント間の通信を
　共通鍵を用いて暗号化・復号化することで安全な情報通信を確立する。

## どこで躓いたのか？

　今回のWebアプリケーションは、クラウド上で構築しており、
　Linuxサーバ内のファイアウォールシステムと、
　クラウドプラットフォームが提供するWAFの２段階の
　セキュリティが設定されていた。

　systemctlコマンドでapacheのステータスを確認すると、
　httpsとhttpのポート（443，80）がlistenとなっており問題なし。

　systemctlコマンドでfirewallのステータスを確認すると、
　disableとなっており、こちらも問題なし。

　apacheのアクセスログやエラーログを確認しても、
　問題はなし。

　フレームワークのアプリケーションログを確認すると、
　httpsでアクセスしたログの履歴が出力されていない。

　つまり、apacheに対するリクエストが届いていない。

　apacheにリクエストが届く前にブロックされているということは、
　サーバのfirewallではなく、インスタンスに対するFirewall（WAF）によって
　通信が遮断されている可能性がある。

　ここで、クラウドプラットフォームのコンソールから
　セキュリティを確認すると、通信を許可するポートが
　「http：80」と「ssh：22」のみであることが分かった。

　「https：443」ポートが解放されていないために、
　インスタンスレベルで通信が遮断され、apacheまでリクエストが到達
　していないことが分かった。

## まとめ

　正直、このレベルの躓きはよほどクラウドサービスに対する理解が浅い
　初心者エンジニアしか遭遇しないと思われますので、あまり読者の参考には
　ならないかと思いますが、自分への戒めや今後の成長に対する覚悟も込めて
　記録として残しておきたいと思う。
VS vb.net,C#におけるデザイン機能の喪失に対する対処方法

# Visual Studio デザイン不能になる原因と対策

//   **[原因]**　知らないうちにtextオートsizeのpropertyのtext を""空にして消滅させてしまう。その時はデザイナーが生きているのだが。。。
//
**[対策]**
//  Form1.Designer.cs Label3.Size = new Size(0, 0);=>Label3.Size = new Size(13, 20);//(0, 0)　0 要素を無くする
// 　propertyの一番上で部品を選択してtext要素になにか" "入れておく
//  空にしたい時は form_Load イベントで .Text = "";を採用する。

## 以下参考

![スクリーンショット 2024-03-07 151258.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/f28271fe-cda5-2508-8781-2745d9de92ba.png)

![スクリーンショット 2024-03-07 170726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/111700cd-509d-2cea-4deb-29fa28bdbec0.png)

**Size new Size(0, 0);//(x,y)xの要素が0になる**から、**10程に**してやる**とデザイナーが回復する。

![スクリーンショット 2024-03-07 171304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/7dccc893-e134-7912-75ef-ad0871e85f7e.png)

**プロパティの一番上で部品を選ぶ**

念の為　Text 要素に　" "　半角1つくらい入れておく。

![スクリーンショット 2024-03-07 171802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/ee23c92c-aec2-7599-bf21-ef50ebc438fe.png)

Load イベントで処理をしておく。

以上。。。

なに、Form1.Designer.csかない?
![スクリーンショット 2024-03-07 150607.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/d9ecb321-e35f-1aa6-e32c-cd8b27aeb7d8.png) すべてのファイルを表示する。

![スクリーンショット 2024-03-07 145703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/a7941c40-ad5f-7ed9-41e1-1efc181c0aa2.png)
一番下の隠れとるやろ。

![スクリーンショット 2024-03-07 145726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/38cd2d62-83cc-d310-77c3-a2809b2c3893.png)
ここまでスコープ指定する　と　プロジェクトに含める　をクリックする。

![スクリーンショット 2024-03-07 145753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/bfc5d346-8d44-9736-be46-20ddf5e0f9ea.png)
ほら出た。

これで終わりにする。
Pythonのmatplotlibのラベルの文字化け対処コード

Pythonのmatplotlibグラフのラベルやタイトルが文字化けするとき用のコードです。

```
#matplotlibラベル文字化け対応用
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']


```

matplotlibのデフォルト状態では日本語フォントに対応しておらず、日本語をサポートしているフォントを指定する必要があるようです。
7zipで解凍しても文字化けする問題の解決法

# 7zipで解凍しても文字化けする問題の解決法

会社支給のWindows10でzipファイルを解凍する際、ネット上に転がってるどんな方法を試しても文字化けが解消されなかったが、以下の方法であっけなく解消できたので備忘録。
<br><br>

1. 左下スタートボタンより「設定」を開き、「時刻と言語」をクリック
![コメント 2024-03-07 171102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737837/7e9b9ff7-ca8a-acac-c775-96996886395c.png)<br><br>
2. 「言語」をクリック
![コメント 2024-03-07 171304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737837/a70ee937-5da3-6dd9-4225-4fd6c95b25e4.png)<br><br>
  
3. 下の方までスクロールして「管理用の言語の設定」をクリック
![コメント 2024-03-07 171417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737837/8f1ca111-0e17-0d51-eb30-4f7679773a59.png)<br><br>
  
4. 「地域」の「管理」タブの「Unicode対応ではないプログラムの言語」にある「システム ロケールの変更」をクリック
![コメント 2024-03-07 171543.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737837/84f7a695-1018-a623-b5c1-71ae3f7e6236.png)<br><br>
  
5. 資格情報の入力を求められたら入力<br><br>
  
6. 「地域の設定」の「ワールドワイド言語サポートでUnicode UTF-8を使用」のチェックを外す

![コメント 2024-03-07 171753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737837/b19f91be-24fc-f480-b818-e8d89525adc4.png)<br><br>

再起動すれば完了！
Hiltで単体テスト

Androidで、DIで注入した場合にそのメソッドを単体テスト（ユニットテスト）を実施することがあるのですが、情報が正確に記載されてる記事があまりなかったので、記事にしたいと思います。
本来は、Junit5を使いたいのですが、HiltがJunit4を前提にしているため使えませんでした。
そのための制約が色々ありました。

### Gradle

* junit
```@Rule```を使用するために必要

* androidx.junit
AndroidJUnit4::classを使用するために必要

* robolectric
```@Config```を使用するために必要

```gradle
testImplementation("junit:junit:4.13.2")
testImplementation("androidx.test.ext:junit-ktx:1.1.5")
testImplementation("org.robolectric:robolectric:4.11.1")
testImplementation("com.google.dagger:hilt-android-testing:2.50")
kaptTest("com.google.dagger:hilt-android-compiler:2.50")
```

### テストコード

```kotlin
@Singleton
SampleRepository {
    fun checkInteger(value: Int): Boolean {
        if (value > 0) {
            return true
        }
        return false
    }
}
```

```kotlin
@HiltAndroidTest
@Config(application = HiltTestApplication::class)
@RunWith(AndroidJUnit4::class)
class SampleTest {

    @get:Rule
    var hiltRule = HiltAndroidRule(this)

    @Inject
    lateinit var sampleRepository: SampleRepository

    @Before
    fun setUp() {
        hiltRule.inject()
    }

    @Test
    fun `整数テスト001`() {
        val result = sampleRepository.checkInteger(100)
        assertTrue(result)
    }
    
    @Test
    fun `整数テスト002`() {
        val result = sampleRepository.checkInteger(-1)
        assertFalse(result)
    }
}
```

ポイントとしては、下記を定義することなのですが、上記のtestImplementationとの繋がりが分かりづらいです。

```kotlin
@HiltAndroidTest
@Config(application = HiltTestApplication::class)
@RunWith(AndroidJUnit4::class)

@get:Rule
```

* ```@HiltAndroidTest```
hilt-android-testing

* ```@Config```
robolectric

* ```@RunWith(AndroidJUnit4::class)```
androidx.junit

* ```@get:Rule```
junit

それぞれ、別々のライブラリーを必要としているのとどのライブラリーが何を提供しているか分かりづらいのでまとめてみました。


### まとめ

Junit5を使いたいのですが、Googleが全く興味を示していないため絶望的だと思います。
なので、今回のJunit4を使っていきましょう。
画像の白黒を反転させる【道具としての OpenCV 画像認識】

# 本記事でできること
元画像
![binary_sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/98abec86-38d8-a586-cfce-28bd0b26a13a.jpeg)


白黒反転した画像
![Screenshot from 2024-03-06 21-00-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/81692ed2-c87c-fc5d-afb2-4eeb32c5bc0f.png)


# 想定シーン
## ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。

## 画像の白黒を反転させる
ロボット制御用のカメラ画像に対して画像処理フィルターをかける際に、背景を抽出してマスクとして除去したり、膨張縮小させた2枚の画像を比較して境界領域を抽出したり、２値化画像の白黒を逆転させたいというシーンが多くあります。本記事では、白黒を逆転させるプログラムを掲載します。


# 実行環境
- OS：Ubuntu 22.04 LTS
- 言語：C++
- クルーボ：v5.1.0

## クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。

- クルーボの製品サイト：https://chitose-robotics.com/

## プログラム抜粋
```c++
cv::Mat invert_image(const cv::Mat& image) {
    cv::Mat gray_image = convert_grayscale(image);
    cv::Mat inverted_image;
    cv::bitwise_not(gray_image, inverted_image);
    return inverted_image;
}
```

## 全体プログラム
```c++
#include <iostream>
#include <opencv2/opencv.hpp>

cv::Mat load_image(const std::string file_path) {
    cv::Mat loaded_image = cv::imread(file_path, 1);
    if (loaded_image.empty()) {
        throw std::runtime_error("画像を正常に読み込めませんでした。");
    }
    return loaded_image;
}

cv::Mat convert_grayscale(const cv::Mat& image) {
    const int grayscale_channel_num = 1;
    if (image.channels() == grayscale_channel_num) {
        return image.clone();
    }
    cv::Mat gray_image;
    cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    return gray_image;
}

cv::Mat invert_image(const cv::Mat& image) {
    cv::Mat gray_image = convert_grayscale(image);
    cv::Mat inverted_image;
    cv::bitwise_not(gray_image, inverted_image);
    return inverted_image;
}

int main(void) {
    std::string file_path = "../data/binary_sample.jpg";
    const cv::Mat loaded_image = load_image(file_path);

    const cv::Mat inverted_image = invert_image(loaded_image);

    cv::imshow("window", inverted_image);
    cv::waitKey(0);
}
```

## おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御＝ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。
M5stack Core2のSPIFFSに保存したmp3を再生する

# 背景
* そこまで大きくないmp3ファイルを用いて音を鳴らしたい
* データの書き換えにSDカードを抜き差しするのが面倒だった
* M5stack Core2にはSPIFFSがあり、内蔵フラッシュにデータを置けるので、そこから読み出せるかやってみた

# 環境・データ
* Windows11
* mp3ファイル(yaho.mp3)
    * VOICEVOXでやっほー等の短いワードのwavデータを出力し、ffmpegで変換して作成
* vscode、platformio
* ライブラリは、ESP8266Audio、M5Unifiedを使用

# 手順
## SPIFFへの書き込み
1. プロジェクトを作成
2. プロジェクトの直下にdataフォルダを作成し、その下にmp3を置く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324101/f438b8f2-37fb-3355-ff1b-ee69d4556b99.png)
3. M5stack Core2をつなぎ、蟻のマーク > PROJECT TASKS > Platform > Upload Filesystem Imageをダブルクリックしてmp3を書き込みます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324101/7f01e6c5-156e-967e-58c3-e52d1e285811.png)


## 再生ファームウェアの用意
SPIFFSにアクセス可能かと、データの存在を確認してから、音声の再生を行う
I2SのdefineはM5stackCORE2に合わせて変更
M5Unifiedで自動設定できそうな気もする

```c++:main.cpp
#include <M5Unified.h>
#include "FS.h"
#include "SPIFFS.h"

#include "AudioFileSourceID3.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2S *audioOut;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;
float volume = 100;

#define BCLK_PIN 12
#define LRCK_PIN 0
#define SADTA_PIN 2
#define EXTERNAL_I2S 0

void soundInit(void) {
    audioOut = new AudioOutputI2S(I2S_NUM_0, EXTERNAL_I2S);
    audioOut->SetPinout(BCLK_PIN, LRCK_PIN, SADTA_PIN);
    audioOut->SetGain(volume / 100.0);
    audioOut->SetOutputModeMono(false);
}

void setup() {
    auto cfg = M5.config();
    cfg.internal_spk = true; 
    M5.begin(cfg);    
    M5.Speaker.begin();
    M5.Lcd.setTextFont(2);

    //SPIFFS 
    if(!SPIFFS.begin(true)){
      M5.Lcd.printf("can not accessed\n");
      return;
    }

    //check data
    File fileTest= SPIFFS.open("/yaho.mp3", "a");
    if(!fileTest){
        M5.Lcd.println("- failed to open file for appending");
        return;
    }
    M5.Lcd.println("OK");
    fileTest.close();

    soundInit();

    delay(500);
    
    M5.Lcd.printf("test start\n");

    file = new AudioFileSourceSPIFFS("/yaho.mp3");
    id3  = new AudioFileSourceID3(file);
    mp3 = new AudioGeneratorMP3();
    mp3->begin(id3, audioOut);
}

void loop() {
    if (mp3->isRunning()) {
        if (!mp3->loop()) mp3->stop();
    } else {
        M5.Lcd.printf("MP3 done\n");
       delay(1000);
    }
}
```
【Rails】メソッドの中でメソッドを定義したらRuboCopに怒られたゾ

どうもこんにちは。

今回は、Railsでメソッドの中にメソッドを記述してコードを書いた時に、Rubocopに怒られたのでその対処法を紹介します。

Rubocopの導入方法は以下の記事で紹介しています。

https://qiita.com/PDC-Kurashinak/items/1de32b66d95c705f5b82

# 実際に書いたコード

※ こんな感じで書いたという感じで書きます。

```ruby
def display_calculate_result(x, y, z)
    # 足し算メソッドを定義
    def add_calculate(a, b)
        result = a + b
        result
    end

    # 掛け算メソッドを定義
    def multiplication(add_result, c)
        result = add_result * c
        result
    end

    # 足し算メソッドを呼び出し
    add_result = add_calculate(x, y)

    # 掛け算メソッドを呼び出し
    calculate_result = multiplication(add_result, z)

    # display_calculate_resultメソッドが呼ばれた時に返す値
    calculate_result
end
```

# Rubocop実行時のエラー

```sh
app/helpers/samples_helper.rb:105:5: W: Lint/NestedMethodDefinition: Method definitions must not be nested. Use lambda instead.
    def add_calculate(a, b) ...
    ^^^^^^^^^^^^^^^^^^^^^^^
app/helpers/samples_helper.rb:120:5: W: Lint/NestedMethodDefinition: Method definitions must not be nested. Use lambda instead.
    def multiplication(add_result, c) ...
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

`lambda`使えやって怒られましたね...

では言われた通りにしましょう。

# Lambda関数使ってみよう

メソッドをlambda関数に直してみました。

```ruby
def display_calculate_result(x, y, z)
    # 足し算メソッドを定義
    add_calculate = lambda do |a, b|
        result = a + b
        result
    end

    # 掛け算メソッドを定義
    multiplication = lambda do |add_result, c|
        result = add_result * c
        result
    end

    # 足し算メソッドを呼び出し
    add_result = add_calculate.call(x, y)

    # 掛け算メソッドを呼び出し
    calculate_result = multiplication.call(add_result, z)

    # display_calculate_resultメソッドが呼ばれた時に返す値
    calculate_result
end
```

これでRubocopからは何も言われなくなりました！
EC2でUbuntuにRDPしたが、ターミナルしか出てこない

# はじめに
こんにちは、ユーゴです。
今回は、AWSのEC2で起動したインスタンスに、Microsoft Remote Desktopでアクセスしようとした時に、うまく接続できたもののターミナル以外のGUIが出てこない現象が起きたので、それについて

# 課題
AWSのEC2で起動したインスタンスに、Microsoft Remote Desktopでアクセスしようとした時に、うまく接続できたもののターミナル以外のGUIが出てこない。

# 原因
UbuntuにGNOMEが構築されていない

# 解決策
### 1. GNOMEの環境構築をする

```bash
sudo apt update
sudo apt install ubuntu-desktop
```

### 2. 再起動する
コマンドから行うなら、以下の通り
```bash
sudo reboot
```

AWSのEC2コンソールからでもいいです。

【**注意**】
再起動のやり方によっては、**パブリックIPが変わります**。接続できない時は、IPアドレスを確認し、必要に応じてRDPのIPアドレス設定を変えてください。(Elastic IPを指定している方はもちろん大丈夫です)

### 3. 接続
RDP接続を行います。
最初は真っ暗な画面ですが、待ちます。しばらく待つと、Ubuntuのクラゲが表示されます。(ログインが必要かも)

![スクリーンショット 2024-03-07 16.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/bb4577b1-5ce4-3bb8-2fb4-840126ae678e.png)

![スクリーンショット 2024-03-07 16.34.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/29edf411-e123-009b-74ce-605e609aea75.png)


# 補足
EC2でインスタンスを起動した時、DebianへのRDPでも同じ現象が起きます。Debianの場合は、ubuntu-desktopではなく「gnome-core」をインストールすれば良いかと思われます。

ちなみにAmazon Linux 2では、デフォルトでデスクトップGUIの環境が構築されています。

# まとめ
いかがだったでしょうか。今回は、EC2で構築したUbuntuへのRDPで、デスクトップが表示されない問題を紹介しました。
手軽に、まずは無料で、クラウドで仮想サーバーを起動できるなんて、いい時代に生まれたと思います。
今回のように、AWSに関する知見から、UnityやPythonなど様々なエンジニアリングに関する知見を共有していきます。お役に立てましたら、いいね, LGTM, フォロー等よろしくお願いします！
grepを使用した文字、ファイル、ディレクトリの検索方法

# 概要
ログファイルから何らかの調査を行う事が多々あると思います。
ログに関しては、ファイルやログが膨大にある為、必要な情報を何らかの方法で検索しないと目的の情報が探し出せないと思います。エンジニアであれば良く使用しているであろう`grep`コマンドについて、ログ調査で良く使用する方法を学んだので、備忘録も兼ねて手順をまとめます。


# コマンドの事前知識
:::note info
`cat`：ファイルの内容を表示する為に使用する
`tail`：ファイルの末尾部分を表示する為に使用する。デフォルトでは、ファイルの最後の10行が表示される。`-n`オプションを使用する事で、表示する行数も指定する事が可能
```sh
tail -n 20 ファイル名  # ファイルの最後の20行を表示
```
:::


# 特定のファイル、ディレクトリを検索する方法
```sh
# 構文
ls | grep ファイル名 or ディレクトリ名

# 入力例
ls | grep test.log
```

# 特定の文字を検索する方法
- 検索文字には、正規表現を使用して検索する事も可能
```sh
# 構文
cat ファイル名 | grep '検索文字(検索したいパターン)'
tail ファイル名 | grep '検索文字(検索したいパターン)'

# 入力例
cat test_access.log | grep 'test'
tail test_access.log | grep 'test'
```


# 特定の文字を複数検索する方法
```sh
# 構文
cat ファイル名 | grep -e '検索文字1' -e '検索文字2' -e '検索文字3' etc
tail　ファイル名 | grep -e '検索文字1' -e '検索文字2' -e '検索文字3' etc


# 入力例
cat test_access.log | grep -e 'test' -e 'aiueo'
tail test_access.log | grep 'test'
```

# 複数あるファイルの中から特定の文字が含まれたファイルのみを抽出する
```sh
# 構文
grep -rl '検索文字' .

# 入力例
grep -rl 'test' .
```
`-r` : 指定したディレクトリとそのすべてのサブディレクトリ内のファイルが検索対象とする
`-l` : 検索パターンにマッチした行を含むファイルの名前だけを抽出する。具体的なマッチした行の内容ではなく、どのファイルにマッチがあったかを知りたい場合に便利
`.` : 現在のディレクトリを表す。状況に応じてパスを指定する

# まとめ
今回`grep`コマンドについて学んだので、業務の中で多様していきたいと思います。また、オプションも豊富にあるので、必要に応じで使用し、より`grep`コマンドについて理解を深めていきたいと思います。