OmniAICreator/Qiita-1.07M huggingface dataset:
ARでアイスブレイクを　in Azure Tech Hackathon

今回は、Azure Tech Hackathonにおいて、自分がチームリーダーを務めた**Team B**の制作物、「FruitsBasket」について紹介いたします!!

# Azure Tech Hackathonについて
顔認証やバーコード読み取りなどの**画像認識**に注目したハッカソンとなっております。IDEACTIVE JAPAN PROJECTの学生アンバサダーチームの運営で開催されました。

https://connpass.com/event/269487/

# FruitsBasketとは
FruitsBasketは、ARを使用したアイスブレイク補助アプリとなります。

![繝上ャ繧ｫ繧ｽ繝ｳ_逋ｺ陦ｨ_繝倥ｚ繝ｼ繧ｷ繧兩10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/a66e8a64-44b5-95f8-6d4c-620b943c7d33.jpeg)
## コンセプト

本アプリのコンセプトは、
「**リアルタイム画像認識で世界を広げる**」です。本アプリによって、より多くの人に**楽しいアイスブレイクの体験**を提供します。

アピールポイントは、下記の図の通りとなっています。
![繝上ャ繧ｫ繧ｽ繝ｳ_逋ｺ陦ｨ_繝倥ｚ繝ｼ繧ｷ繧兩16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/8fa923d4-74e8-1963-d006-e70d34b905d6.jpeg)

## システム概要図
システム概要図です。
![ハッカソン_発表_ページ_23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/55b16a35-3946-8f06-c089-6d94a72bea26.jpeg)
サーバサイドには**node.js**を使用し、物体検知には、**MicrosoftAzure**の**CustomVision**を使用しております。データの収納には、**LINEMessagingAPI**を活用し、簡単な操作でデータの格納を行えるようにしました。


今回使用した**リアルタイムでの画像検知**については、別途記事にしておりますので、こちらをご覧ください。

https://qiita.com/Ishigami100/items/ef74ce0221be44c81272

## アプリの使い方
本アプリは、下記のような流れで使用します。

![繝上ャ繧ｫ繧ｽ繝ｳ_逋ｺ陦ｨ_繝倥ｚ繝ｼ繧ｷ繧兩19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/5ffc2040-8296-cc25-e925-88dde17961a4.jpeg)
![繝上ャ繧ｫ繧ｽ繝ｳ_逋ｺ陦ｨ_繝倥ｚ繝ｼ繧ｷ繧兩20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/8e36d2e9-287a-d4df-f478-1bd0f5cf829d.jpeg)
![繝上ャ繧ｫ繧ｽ繝ｳ_逋ｺ陦ｨ_繝倥ｚ繝ｼ繧ｷ繧兩22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698432/9b0101a8-5ff8-02f3-2a42-69b618136865.jpeg)

本アプリは、インディアンポーカーのように、相手の本当の果物を当てるアイスブレイクとなっています。ARで相手の名札を読み取ることで、名前を記憶に残るように工夫し、スムーズなアイスブレイクを実現しています。

#　結果
今回の作品は、**優秀賞**を受賞いたしました。より多くの人に使ってもらえるように、さらなる改善をしていきます。

# 関係サイト
https://protopedia.net/prototype/3688
StarUMLを使ってPythonのオブジェクトを生成する

## オブジェクト指向のソフトウェアモデラーでPythonのオブジェクトコードを生成する

- UML(Unified Modeling Language/統一モデリング言語)はソフトウェア工学の分野で使われる
- オブジェクト指向の分析・設計・モデリングに用いられる

::: note
__環境__
- python : 3.11.0
- StarUML : v5.1.0
:::


### UMLツール「 [Star UML](https://staruml.io/) 」をインストールする

![スクリーンショット 2023-01-24 22.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/f86fb804-e187-b434-797a-2ef6815baf2b.png)


### オブジェクトを作成

![スクリーンショット 2023-01-24 22.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/d5eb657e-c346-92dc-ef97-ccfa22319d43.png)

::: note
オブジェクトは以下の構造になっている
- class(クラス名)  
- Attribute(属性) 
- Method(関数)
:::

### Extension Toolを使ってPythonコードをジェネレートする

![generate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/3ea7347b-93fa-9514-ea03-b9eadfb2a972.png)

### 生成されたオブジェクト

```Server.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

class Server:
    def __init__(self):
        self.id = None
        self.name = None
        self.port = None
        self.ip_addr = None

    def login(self, ):
        pass

    def ssh(self, ):
        pass

    def ping(self, ):
        pass

    def instance(self, ):
        pass

```
::: note warn
ポイント
- 属性が変数として宣言されている
- 動作がメソッドとして宣言されている
:::

### メソッドの修正とクラスのインスタンス化

```Server.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from ping3 import ping


class Server:
    def __init__(self):
        self.id = None
        self.name = None
        self.port = None
        self.ip_addr = None

    def login(self, ):
        pass

    def ssh(self, ):
        pass

    def ping(self, targetIp):
        ping_rep = ping(targetIp, timeout=0.5, unit='ms', ttl=64)
        if ping_rep is None or ping_rep is False:
            print(f'Host: {targetIp:15} is NOT reachable')
        else:
            print(f'Host: {targetIp:15} is reachable    :{ping_rep:.2f}(ms)')

    def instance(self, name):
        print(name)


if __name__ == ('__main__'):
    svr = Server()
    svr.name = "Edge Server"
    svr.instance(svr.name)

    svr.ping("172.22.0.1")

```

### if_name__ = '__main__' を使って実行してみる

```bash
$ python ./Server.py

Edge Server
Host: 172.22.0.1      is reachable    :6.14(ms)

```

#### オブジェクトの関係を視覚的に確認できて便利！
Azure LogAnalythicsワークスペースのログをCLI経由で削除する

:::note
 Azure LogAnalythicsワークスペースに対してログ削除の要求(AzureRESTAPI)を行う。AzureCLIを使用してcurlコマンドで削除要求を投げる。
:::

### 目次

1. Azure LogAnalythicsワークスペースについて
1. 前提条件
1. 削除リクエスト作成
1. 削除の実行（Azure CLI/curl）



## 1. Azure LogAnalythicsワークスペースについて
一般的にログの確認を行う場合は各APIのApplication Insightから行うが、Application Insightのログは紐付いているLogAnalythicsワークスペースに集約される。
**LogAnalythicsワークスペースから確認が可能なログの削除を行う。**
（ = LogAnalythicsワークスペースに設定されているログ保存期間を過ぎたものはこの手順では削除できない。）

## 2. 前提条件
- Application InsightとLogAnalythicsワークスペースのテーブルの比較参照先が明らかであること
- Application Insightのログ画面で削除対象のログが絞り込めること　→　LogAnalythicsワークスペースでも該当ログが確認できていること



## 3. 削除リクエスト作成

### 削除要求URIの作成
削除要求URIは **「対象LogAnalythicsワークスペースのリソースID」＋「purge?api-version=yyyy-mm-dd」** の形式。
「purge?~」手前までが対象LogAnalythicsワークスペースの情報となるため、リソースIDを参照する。
```:削除URI
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}/purge?api-version=2020-08-01
```


> **リソースIDの確認方法**
　＞対象のLogAnalythicsワークスペースを開く
　＞概要画面の右上、「JSONビュー」をクリック
　＞リソースIDが表示される


### 削除要求JSONの作成

基本的には削除対象を絞り込んだKQLをJSON形式にする。

```json:削除JSON
{
  "table": "Heartbeat",
  "filters": [
    {
      "column": "TimeGenerated",
      "operator": ">",
      "value": "2017-09-01T00:00:00"
    }
  ]
}
```

複数条件の場合は下記のように条件をカンマで区切る。
```json:削除JSON
{
  "table": "Heartbeat",
  "filters": [
    {
      "column": "TimeGenerated",
      "operator": ">",
      "value": "2017-09-01T00:00:00"
    },{
      "column": "Properties",
      "key": "UserId"
      "operator": "==",
      "value": "xxxx-xxxx-xxxx-xxxx-xxxx-xxxx"
    }
  ]
}
```



## 3. 削除の実行（Azure CLI/curl）

:::note warn
削除要求の実行には削除権限(Data Purge Role)が必要
:::

AzureCLIを使用してAzureにサインインする。
```az:Azure CLI
az login
```
トークン情報を取得する。
```az:Azure CLI
az account get-access-token
```

> 設定によっては上記手順での取得が出来ないため、その場合はAzureの認証設定周りの構成を要確認。

上記で取得したトークン、削除要求URI、削除要求JSONを使用する。
※data部分はシングルクォーテーションで囲む

```curl:curl
curl -X POST -i 
-H "Authorization:Bearer <TOKEN>"
-H "Content-Type:application/json"
-d '<JSON>' <URI>
```
ステータスコード202で正常応答、ボディ部は下記形式でオペレーションIDが返ってくる。

```json:レスポンスbody
{
  "operationId": "7d7cf277-9113-4ab3-8359-d0364b74d01d"
}
```

削除処理は削除リクエストを投げてから完了するまでに時間がかかるため、オペレーションIDを使用して状況を確認する。

確認の際は下記形式。
URIは削除要求と同様にリソースIDを参照、オペレーションIDを指定することで該当処理の状態確認を行う形。

```curl:curl
curl -H
"Authorization:Bearer <TOKEN>"
"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}/operations/<OPERATIONID>?api-version-2020-08-01"
```
レスポンスは"completed"または"pending"のどちらかのみ。
削除にはかなり時間がかかる模様。

```json:消去中
{
  "status": "completed"
}
```
```json:完了時
{
  "status": "completed"
}
```

ステータスがcompletedになっていることを確認し、念のためブラウザからもログが消えていることを確認して削除完了。




 リンク
---
https://learn.microsoft.com/ja-jp/rest/api/loganalytics/workspace-purge/purge?tabs=HTTP
Expoの使い方

# Expoのインストール
講義で使用した環境ツールは2020年ものなので，今時2022年ものに変更しようかと思いましたが，Expo側が対応していなかった・・・

1. Expoのアンインストール
```sudo npm un -g expo-cli```
1. [node jsのアンインストール](https://blog.proglus.jp/5518/#i)
1. [今度はHomebreでインストール](https://brew.sh/index_ja)
1. [Homebreで最新のLTS Nodejsをインストールする](https://tech-blog.s-yoshiki.com/entry/254#nodejs%E3%81%AE%E6%A4%9C%E7%B4%A2)
1. expo-cliをインストールしようとするるもNodejsが新しすぎるということでエラー
```required: { node: '>=12 <=16' },```
1. Nodejsをアンインストールしてnodejsのバージョン１６の安定板をダウンロード


# プロジェクトの作成

以下コマンドを実行する
```
npx create-expo-app {プロジェクト名} --template
```
テンプレートを選択する
選択するテンプレートは特にこだわりがなかったらNavigationでいいんじゃないかな．全部入ってるし
[テンプレートのGithubページ](https://github.com/expo/expo/tree/main/templates)
テンプレートの名前見るとexpo initのテンプレートっぽい？

# パッケージのインストール
expo installや npm installなどありますが，
Expo SDK 46以降は下のコマンドらしい．
どこかで見た記事が見当たらないので信憑性薄です．
```
npx expo install {パッケージ名}
```

# そのた
[expo initとcreate-react-native-appの違い](https://qiita.com/mikanbaco/items/0789ea9648d6fcd02df1)
SelectボックスのOptionの型が異なる時のコンポーネント側の対応

Select Optionの中身の方が以下のように異なっている場合の分岐のやり方

```typescript

type Options = {
  id: number | string;
  name: string;
  key?: string;
  order?: string;
}

type Props = {
  options?: SelectOptions[] | readonly string[] | readonly number[];
};

```
のようになっている場合の話です。
(そもそもの設計がだめという話は置いておいて)



```jsx
const FormSelect = forwardRef<HTMLSelectElement, FormSelectProps>((props, ref) => {
  const {
    placeholder,
    disabled,
    value,
    onChange,
    errors = '',
    size,
    textSize = 'md',
    options,
    isLoading,
    isProcessing,
    className,
    ...rest
  } = props;

  const { t } = useTranslation('ui');

  return (
    <>
      <div className={classNames('w-auto')}>
        {isLoading || isProcessing ? (
          <div className='absolute inset-0 flex h-full w-full items-center justify-center'>
            <Oval
              color='#ffffff'
              secondaryColor='#444444'
              height={25}
              width={25}
              strokeWidth={2}
              strokeWidthSecondary={3}
            />
          </div>
        ) : (
          <select
            {...rest}
            ref={ref}
            disabled={disabled || isLoading || isProcessing}
            placeholder={placeholder}
            className={classNames(
              className,
              disabled ? 'bg-gray-300' : 'bg-white',
              'boxsizing-border inline-block w-full rounded-none border-gray-300 py-[0.5em] pl-[0.5em] pr-[3em] shadow-sm',
              getSize(size),
              getTextSize(textSize),
            )}
            value={value}
            onChange={onChange}
          >
            <option value=''>{t('form.select')}</option>
            {options?.map((option) => (
              <Options option={option} />
            ))}
          </select>
        )}
        {errors && (
          <p
            className={classNames(
              getTextSize(textSize),
              getSize(size),
              '-bottom-6 left-0 flex items-center justify-start text-attention-900',
            )}
          >
            {errors}
          </p>
        )}
      </div>
    </>
  );
});


```


JSX内で分岐するのは気に食わないのでいずれ書き直します。
【Oracle】パスワードポリシーの種類

仕事でパスワードポリシーの設定をした。
あんまり触ったことなかったので、こんなものもあるのかとメモ。

パスワードポリシーを設定することで、定期的にパスワード変更を促したり、
パスワード設定のルールなどを決めたりすることができる。

以下はその種類。
ユーザー作成時など、パスワードポリシーを省略するとDEFAULT値が設定される。
※DEFAULT値はOracle 11g 以降のもの。11g以前のDEFAULT値はすべて「規定なし(UNLIMITED)」となっている。


|  パラメータ名  |  内容  |  DEFAULT値  |
| ---- | ---- | :----: |
|  PASSWORD_LIFE_TIME  |  パスワードが有効な日数  |180日  |
|  PASSWORD_GRACE_TIME　|パスワードの有効期間終了後、パスワードが変更可能な日数    |7日  |
|  PASSWORD_REUSE_MAX　|現在のパスワードを再利用するまでに必要なパスワードの変更回数<BR>※PASSWORD_REUSE_TIMEと組み合わせて設定する。    |規定なし  |
|  PASSWORD_REUSE_TIME　|現在のパスワードを再利用できない日数<BR>※PASSWORD_REUSE_MAXと組み合わせて設定する   |規定なし  |
|  PASSWORD_VERIFY_FUNCTION  |パスワード設定のルールが記載されているSQL関数を指定。<BR>パスワードの文字数などが指定できるようになる。|規定なし  |
| FAILED_LOGIN_ATTEMPTS  |指定した回数連続してログインに失敗するとアカウントがロックされる  |10回  |
| PASSWORD_LOCK_TIME  |FAILED_LOGIN_ATTEMPTSによって、アカウントがロックされる日数|1日  |

デフォルトでも有効日数が設定されていたり、ログイン失敗でアカウントロックされることが意外だった。
ハッシュの基礎

# hash = { キー: 値 }

- ハッシュのキーを取得する→keysメソッド
- 値を取得する→valuesメソッド
を使用します。

（例）
```ruby
hash = {one: 1, two: 2, three: 3}
puts hash.keys
puts hash.values
```
```:ターミナル
one
two
three
1
2
3
```
このように返ってきます。
【Flutter】TextFieldのキーボード管理で苦戦した話

## きっかけ
参画させていただいているプロジェクトで、
「前の画面に戻ったときにキーボードが出ている状態にしたい」
とのことで、思いの外悩んだので備忘録も兼ねて。
(TextFieldも、CupertinoTextFieldも解決済み)

## あまりいい記事がかけなかったので結論
インスタンスの生成タイミングの見直しをすべき:frowning2:

## 悩んだ理由
### 1. 入力後すぐ初期化されてしまう
### 2. 初期値を設定時も入力後すぐ初期化されてしまう
### 3. キーボードが閉じなくなった
### 4. キーボードが開かなくなった
## 結論：何が悪いのか
### インスタンスを生成する場所が悪かった
ただこれに尽きる。
基本的なサイトでは**全て画面を描画するところで説明している**為、インスタンスの生成タイミングについては触れられていないので苦戦してしまったということ。
じゃあどうすればいいのかというと**親クラス**でインスタンスを生成すればいい。
``` dart
class _MyHomePageState extends State<MyHomePage> {
  // 基本的に全てここでインスタンスを生成すれば良い。
  var focusNode = FocusNode();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          TextField(
            focusNode: focusNode,
          ),
          ElevatedButton(
            onPressed: () {
              FocusScope.of(context).unfocus();
            },
            child: Text('down Keyboard'),
          ),
        ],
      ),
    );
  }
}
```
例えば、appBarを別の独自クラスで作っている場合も
``` dart:appbar_custom.dart
class AppBarCustom extends StatefulWidget  {
  AppBarCustom(this.title);

  final FocusNode focusNode;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: focusNode,
        ),
        ElevatedButton(
          onPressed: () {
            FocusScope.of(context).unfocus();
          },
          child: Text('down Keyboard'),
        ),
      ],
    ),
  }
}
```

``` dart:main.dart
class _MyHomePageState extends State<MyHomePage> {
  // 基本的に全てここでインスタンスを生成すれば良い。
  var focusNode = FocusNode();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ここでインスタンスを別クラスに送っている
      body: AppBarCustom(focusNode: focusNode),
    );
  }
}
```

これと同じようにTextEditingControllerも実装できる(が、今日はここまで。)

## 最後に
iOSアプリ開発をしています。
主にSwiftですが、最近は熱が入ってきてFlutterも🦾
色々やってます。もし良かったら見てってください。

https://sogablog.net/
だれでもわかるGitの使い方

# はじめに
こんにちは。初めまして。ここではGitの使い方を書いていく感じです。
ミス等ありましたらコメントをしていただけるとありがたいです。

# まずそもそもGitってなに？？？
Gitっていうのは、バージョン管理が楽になるやつです。
大規模から小規模のプロジェクトまで、幅広い場面で活躍します。

....筆者はGitHubにアップロードしたいがために使ってますが、まぁ正しい使い方でしょう。(たぶん)

# つかってみよう
大変お待たせしました。使ってみようのコーナーです。

## Git　を　インストール　しよう！

※既にインストールしている方はここは飛ばして結構です。

まずは[公式サイト](https://git-scm.com)からインストールを始めましょう。

インストールをして実行するとこんな感じの規約画面が出てきます。
よいこはよんでおきましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/771da462-61e3-c7ca-dafd-f4f230566e0a.png)

うえの規約をよんだあと、Nextを押すとこんな感じの画面が出てきます。

難しいことはやりたくないので、何もしないでおきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/9a5ee7e8-a8a9-8f22-35bb-256a05455649.png)

～終了～

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/204d0e73-1a92-b4da-fce3-5aa9d6e2fec9.png)


これでGitのインストールは終了！
つぎは実際に使ってみましょう！

## Git って どうやって つかうの？

ためしにGithubでこんな感じのリポジトリをつくってみましょう
（名前まで同じじゃなくて結構です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/28acf15e-bc9d-719e-c626-73d8e42af220.png)

つくったら、PCの適当なところにファイルを作って、なんかのテキストファイルを作ってみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/54f25cd5-3164-5ea7-3e72-a83aea812a69.png)

これはすばらしいですね！

これを保存して、早速アップロードしてみましょう！

## Githubに飛ばす - 準備

おまたせ。早速やってみましょう。

まずはその上の章で保存したファイル、もしくは自分がいまアップロードしたいファイルへと行き、
パス（住所的なやつをもらいます。）

![スクリーンショット 2023-01-24 221706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/48903393-ed40-3bcb-a7b0-4bcc378c42e0.png)

Windows11の人はこんな感じにコピーできます。（10もそうかも）

そしたら、Windowsマークを右クリックして、すごいメニューを出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/1d65f879-938f-e5c3-bfa1-8b3a46231c5c.png)

ターミナル、もしくはPowerShellをクリックして開きます。

![スクリーンショット 2023-01-24 221935.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/cc2d9cb4-c34b-58c0-6d17-cb9279d6a3cb.png)

わぁすごい！これでハッキング出来る！（ごめんなさい）

はい、それでさっきコピーしたパスを
```
cd コピーしたパス
```
って感じにします。
これでEnterを押して実行すると、指定したファイルと同じ位置に来ています！まぁびっくり！

変わってない人は、ドライブが違うのかもしれません。

```
cd /D さっきのぱす
```
でやってみてください。できます。（たぶん）

## Githubに飛ばす - メイン

まずは最初に、

```
git init 
```
をしてうけいれる準備をしましょう。
そして、

```
git add .
```
を押して、全ファイルを指定します。
（指定したいファイルを選ぶときは、 . の部分をファイル名に変えてください。)

そして、
```
git commit -m "Super Yours COmment"
```
でコミット変更を発言して、

push...と言いたいところですが、まだあります。

さきほと作成したリポジトリのURLをもってきて、末尾に.gitを付けます。
```
git remote add origin https://sakkinourl.github.com.example/yoursname/reponame.git
```

そして、ブランチ（場所）の名前を付けます。
ここでは `main` の部分です。
```
git branch -M main
```

これで準備おｋ！

```
git push origin ブランチの名前
```

をしてみましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/2b0eb6c6-dc9b-ac50-3a32-84e71d2edc86.png)

やったぁ！すごい！

# おわりに

結構簡単に言ってましたが、大丈夫でしたかね？
みなさんもぜひやってみてくださいね！
設定ファイルを参照するシェルスクリプト（CSH）

# 概要
PHPプログラムで利用している特定設定ファイルに定義した変数をシェルスクリプトで参照するため、
シェルスクリプトからPHPファイルをパーシング処理を作成してみます。

# 事前準備
cshをインストールとPHP設定ファイルを用意します。

・cshインストールコマンド
sudo apt-get install csh

・PHP用設定ファイル
~~~PHP
<?
$GLOBAL_BASE_DATE = "20230124"; // TEST : YYYYMMDD, TODAY : date("Ymd");
?>
~~~

# シェルスクリプト
以下のスクリプトからconf.phpファイルに定義されている内容を取得するコードです。

■ソース
~~~bash
#!/bin/csh -f
set BASE_DATE = `cat conf.php|grep GLOBAL_BASE_DATE`
set DATE = `echo $BASE_DATE | awk 'BEGIN{FS=";"}{print $1}'|awk 'BEGIN{FS="="}{print $2}' | sed 's/\"//g'`
echo $DATE
~~~

■実行結果
~~~bash
# PHP設定ファイルの内容
pi@raspberrypi:~/work/php $ cat conf.php
<?
$GLOBAL_BASE_DATE = "20230124"; // TEST : YYYYMMDD, TODAY : date("Ymd");
?>

# シェルスクリプトの実行結果
pi@raspberrypi:~/work/php $ csh print.sh
20230124
~~~

■ソースコードの説明

~~~csh
①set BASE_DATE = `cat conf.php|grep GLOBAL_BASE_DATE`
→conf.phpファイルから指定した文字列をgrepした結果が取得されます。
取得結果：$GLOBAL_BASE_DATE = "20230124"; // TEST : YYYYMMDD, TODAY : date("Ymd");

②set DATE = `echo $BASE_DATE | awk 'BEGIN{FS=";"}{print $1}'`
→ここまで書いたソースの場合は、「;」区切り文字の前部分が取得されます。
取得結果：$GLOBAL_BASE_DATE = "20230124"

③awk 'BEGIN{FS="="}{print $2}
→②番の結果から「=」区切り文字の後の部分が取得されます。
取得結果："20230124"

④sed 's/\"//g'`
→③番の結果から「"」文字列を削除した結果が取得されます。
取得結果：20230124
~~~

■参照サイト
sedでダブルクォーテーション・シングルクォーテーションの置換・削除を行う
https://orebibou.com/ja/home/201607/20160712_003/

# 終わりに
PHP設定ファイルに定義されている変数内容をシェル側で取得する方法を工夫してみました。
もっと楽な方法があるかもしれないですが、私の中ではこの処理で取得できました。
作成することになった理由としてはPHP側で定義した内容をシェル側にまた定義するのが、
問題でしたので、作成しました。
PHP言語だけではなくテキストファイルであればこの方法で出来ると思います。
s3にアップロードしたファイルをaws cliを用いて更新する方法

はじめに
--
自分が作成したポートフォリオでは、cloudfrontとs3を使用してフロントエンドのファイルを表示しています。
デプロイ後にフロントエンドのファイルを修正したいという場面があり、方法を調べたので備忘録として残そうと思います。

##### ※下記が作成したポートフォリオなのでよかったら覗いてみてください！

https://qiita.com/shuhei_m/items/292699e76dbd206a2462

修正方法
--
今回は、aws cliを用いてターミナルからコマンドを叩くことでs3のファイルを更新します。

ローカルで修正した内容をs3上へ同期させたい場合には、下記の`sync`コマンドを使用します。

そうすることでローカルで追加・修正したファイルをs3へ同期することができます。
~~~
//構文
aws s3 sync <source> <target> [--options]

// 例
aws s3 sync {フォルダパス} s3://{バケット名}/{パス} 

// IAMユーザーを指定する場合
aws s3 sync {フォルダパス} s3://{バケット名}/{パス} --profile {IAMユーザー名}
~~~

デフォルトでは追加・修正した内容のみの同期のため、削除したファイルなどは反映はされません。
もしローカルで削除したファイルについてもs3へ反映したい場合は、`--delete`オプションを使用します。

~~~
aws s3 sync {フォルダパス} s3://{バケット名}/{パス} --delete
~~~ 

参考リンク
--
https://qiita.com/uhooi/items/48ef6ef2b34162988295

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html
草莽Erlang ── 36. lists:nthtail


口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:nthtail/1

[lists:nthtail/1](https://www.erlang.org/doc/man/lists.html#nthtail-1)はリストのN+1番目から始まりリストの末尾まで続くサブリストを返します。

要素の数え方は「１、２、３ぁっダー！」です。例えば最初の要素のインデックスは`1`となります。

https://youtu.be/AWxwmqzbOaw

https://youtu.be/FSz7N5hCltw

https://note.com/awesomey/n/n4d8c355bc8f7

```erlang
> lists:nthtail(3, [a, b, c, d, e]).
[d,e]
```

[lists:nthtail/1](https://www.erlang.org/doc/man/lists.html#nthtail-1)は`tl`をN回実行するものという考え方もできそうです。

```erlang
> tl(tl(tl([a, b, c, d, e]))).
[d,e]
```

パターンマッチでも同じ答えを求めることが可能です。

```erlang
> [_, _, _ | Tail] = [a, b, c, d, e].
[a,b,c,d,e]

> Tail.
[d,e]
```

[listsモジュール](https://www.erlang.org/doc/man/lists.html)には他にもリスト処理のための関数がたくさんあります。

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
e.printStackTrace()とSystem.out.println(e)とSystem.out.println(e.getMessage())の違い

e.printStackTrace()
と
System.out.println(e)
と
System.out.println(e.getMessage())
の違い。

```java
public class App {
    public static void main(String[] args) throws Exception {

        String aaa = "aaa";

        try{
            aaa.substring(1000);
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e);
            System.out.println(e.getMessage());
        }
    }
}

```

## e.printStackTrace()の場合

```
java.lang.StringIndexOutOfBoundsException: begin 1000, end 3, length 3
        at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4604)
        at java.base/java.lang.String.substring(String.java:2707)
        at java.base/java.lang.String.substring(String.java:2680)
        at App.main(App.java:8)
```

## System.out.println(e)の場合

```
java.lang.StringIndexOutOfBoundsException: begin 1000, end 3, length 3
```

※System.out.println(e.fillInStackTrace())も同じ結果になる。

## System.out.println(e.getMessage())の場合

```
begin 1000, end 3, length 3
```
.gitignoreの記載ファイルが反映されない

.gitignoreでファイルを指定すると、gitへアップしたくないファイルをが追跡されなくなります。  

ローカルでのみ必要なファイル（自動生成ファイル、セキュリティ上gitへ上げ内容はいいファイルなど）がある場合に非常に便利です。

# 原因
gitへ一度アップしたファイルは、キャッシュにインデックスが残っているため反映されていなかった。  

# 解決手順
1\.対象ファイルのcache削除
2\..gitignore編集
3\.commit
4\.push


## 1.対象ファイルのcache削除
<pre>git rm -r --cached . ←ファイル全体キャッシュ削除
git rm -r --cached [ファイル名]  ←ファイル指定してキャッシュ削除</pre>


## 2..gitignore編集
<pre>hogehoge.html ←ファイルで指定
/root.html ←ルートディレクトリで指定
dir/ ←指定ディレクトリ以下を指定</pre>


## 3.commit
<pre>git commit</pre>


## 4.push
<pre>git push -u origin master</pre>


# 補足
Gitでの開発をする際に詰まるポイントかなと思います。  
全ファイルのcacheを削除すると膨大な量のコミットが発生するため、ファイルごとにcacheを削除することをオススメします。
かっこいいやり方が優れたやり方とは限らない

職場のスクリプトでローカルに生成したファイルの改行コードが CrLf になってしまって本質的な変更があるのかどうかもよくわからなかったので nkf を入れたんです。
参考にさせて頂いたページだとちょっと手順が足りなかったのと、ひとつ気になった事があったのでメモ


# まず手順
まずは手順のほうを簡素に

```
$ mkdir -p ~/abs/nkf
$ cd ~/abs/nkf
$ wget https://ja.osdn.net/projects/nkf/downloads/70406/nkf-2.1.5.tar.gz
$ sha256sum ./nkf-2.1.5.tar.gz
d1a7df435847a79f2f33a92388bca1d90d1b837b1b56523dcafc4695165bad44 *./nkf-2.1.5.tar.gz

$ tar xzvf ./nkf-2.1.5.tar.gz
$ cd nkf-2.1.5
$ make nkf
$ make install
```
参考にさせて頂いたページだと make nkf が足りてなくて makefile を参照して付け足しました。


# 参考にしたページとの差
元々のページでは mkdir の最後のパラメーターを $_ として使って cd して (ここは特に問題ないというかむしろいい)、
curl の出力を標準出力に向けて、それをパイプで tar に渡していました。

かっこいいやり方だとは思う。
何度も同じ表現が出てこないし、ローカルに余分な物も残さないしね?

でも自分なら、特段の事情がないのであれば普通にローカルに保存してハッシュを確認して、それを tar で展開するやり方をお勧めします。

ネットワーク上から取得したリソースは本来ならどれだけ疑っても足りないくらい慎重になるべきで、提供側がハッシュ値も一緒に提供してくれてるのに、それを確認しないのは残念なやり方だと思います。
特にソースコードという形だと一般的なセキュリティ対策ソフトの目を潜り抜けてしまう可能性が高いと思うし、いざという時に情報は多く残っていた方がいい。
失敗した時こそ、まずかった理由が有耶無耶になるより明確に残っていたほうがありがたいはずです。

かっこよくやる事を意識したばかりに足元がお留守になってしまっては元も子もないですよね。
かっこいいやり方が優れたやり方とは限らないというお話でした。
001_デザイン素人が団体のロゴを考えてみる話（進行中）

# ロゴデザインを考えよう

## 0. はじめに（経緯）
こんにちは。Nagaseと申します。
私は農業農村工学を専攻しており、大学で学んだ土壌物理学、水文学などに魅力を感じたため、卒業研究および修士研究で扱う領域（用水計画）と近い分野に強みを持つ会社に就職しました。

農業農村工学会には「サマーセミナー実行委員会」という学生＆若手社会人による団体があり、私はそこに所属しています。

https://sites.google.com/view/n-n-summer-seminar/%E3%83%9B%E3%83%BC%E3%83%A0?authuser=0

##### Q. なんで「サマーセミナー」って名前なの？
##### A. 農業農村工学会大会講演会が毎年夏に行われて、同時に学生自主企画を行うから。
参考までに、過去に私が参加した企画タイトルおよび実施形式を示します。
2019/8 サマーセミナー2019 ＠東京（リアル）
2020/8 サマーセミナー2020 ＠Zoom（オンライン）
2021/9 サマーセミナー2021 ＠Zoom（オンライン）
2022/9 サマーセミナー2022 ＠石川＆Zoom（ハイブリッド形式）
2023/1 NNオンライン交流会 ＠Zoom＆Gather（オンライン）

今月行った「NNオンライン交流会」に関するイベントレポートは、来週を目途に投稿予定です。

サマーセミナー2022では、「サマーセミナーのロゴデザインを考えてみよう」というグループディスカッションが行われました。残念ながら私はその企画当日には参加できなかったのですが、いいアイデアが出たと思うので、誠に勝手ながら、ラフデザインにとどまらず、きちんとしたロゴを完成させたい（サマーセミナーは限られた時間の中で「NN分野の若手交流」を第一目標として実施するため、あまりにも時間が足りないのが実情です。毎回「楽しかった」という意見を多数いただくオススメイベントなのですが、このロゴ作成については最後まで（ほかの人に自信を持って見せることのできるロゴを作り上げるまで）引き続き取り組みたい、と思いました。

ということで、「全くのデザイン初心者が、自分の所属する団体のロゴを考えてみる」チャレンジ企画を実行します。どうぞよろしくお願いいたします。

時は大インターネット時代、便利なものでGoogle先生に尋ねれば大抵の知識を得ることができます。
（正しく検索できているか、得た知識を自分のものにできるかどうかは別問題）
ネット検索により「だいたいわかった」状態になりました。
ダニングクルーガー効果がきちんと観測されましたね。
「デザインわからない」→「デザインちょっとわかる」→「デザインかなりわかる」
（ダニングクルーガー効果：自分の能力を過大評価してしまう。何かを学び始めてしばらくしたころに陥りがち。）

https://motifyhr.jp/blog/training/dunning-kruger_effect/

## 1. イメージを固める
自分が作成したいロゴで、何を表現したいのかをまとめる
私の場合は「NN分野の魅力を伝えたい」
→何がNN分野の魅力なのか？（哲学、サマーセミナー2019のディスカッションテーマ）
・理論と実践が組み合わさる（実学）
・農業土木とは世界最古の学問である（要出展）
・ロマンがある（『ファウスト』一番美しいのは農民が灌漑用水を引くために土木作業を行う音だ（by主人公）：まあ盲目の主人公は気づいていないだけで、実は主人公と契約した悪魔の手下が主人公の魂を奪う気満々で墓穴を掘っている音なんですけど）

https://www.aozora.gr.jp/cards/001025/card50909.html

・日本の歴史＝農業土木の歴史と言っても過言ではない。いやマジで。

https://www.youtube.com/watch?v=22mPOpkfBWM

https://www.youtube.com/watch?v=lUFPqk_aP70

#### 「1.ロゴで表現したいこと」のまとめ
農業土木（農業農村工学、NN）は捨てたもんじゃないぜ
「自然、農業、農村、人、河川」などなど、都市に住んでいると意識しづらいけど大事な対象を扱う
「食料自給、インフラ整備、治水などの災害防止」など様々な分野において私たちの生活に直結する学問なのだ
「Think Globally, Act Localy.」

http://www.jsidre.or.jp/aboutus_for-univ/

https://www.jstage.jst.go.jp/article/jjsidre/85/5/85_431/_article/-char/ja/

https://jagree-ikusei.jp/

http://soil.en.a.u-tokyo.ac.jp/jsidre/search/PDFs/15/S7-1.pdf

## 2. 先人の知恵を借りる
早い話が「（丸パクリにならない程度に）参考にさせていただく」
世の中にはプロのデザイナーが作成した素晴らしいロゴデザインに溢れているので、色々見て参考にする。1.で確認した自分のイメージを表現できそうなモチーフをピックアップする。
（参考資料は省略、世の中のありとあらゆるものが対象になってしまうので…）

## 3. いざ実践
今回はここまでとなります。Nagase先生の次回作にご期待ください！
通し番号を3ケタに設定したことからも分かる通り、私はこの企画を（たとえ誰にも見てもらえなくても）どれだけ時間がかかろうと続けるつもりでいます。まあ本業をおろそかにしない程度にぼちぼち頑張ります。
もしよろしければ、いいね！やコメントなどをいただければ幸いです。
### 参考資料

https://goodpatch.com/blog/logo-design-inspiration

https://worldvectorlogo.com/
Rails7を使ったシンプルなCRUD。Turbo Rails Tutorial をやってみた（1章）

本記事は、🔽「Turbo Rails Tutorial」の学習を進めていく際の個人メモです！

https://www.hotrails.dev/turbo-rails

🔽 0章で行った環境構築はこちら

https://qiita.com/yuppymam/items/0c26b65bd6a7a624e982

# 1章 [A simple CRUD controller with Rails](https://www.hotrails.dev/turbo-rails/crud-controller-ruby-on-rails)

このチュートリアルでは以下のような成果物を作成していきます。基本的なCRUDをページ移動せずSPAのような操作性で実現していきます！

https://www.hotrails.dev/quotes

## テスト作成
Rails 標準のシステムテスト（Minitest）を作成します。システムテストでは実際のブラウザを使用するため JavaScript を使った操作も簡単にテストすることができるのですね。
以下のコマンドでシステムテストが走ります🏃🏼‍♀️
```terminal
$ bin/rails test:system
```

## モデル作成
`name`カラムを持った`Quote`モデルを作成します。空のデータを防ぐため、`name`カラムに`presence: true`と`null: false`制約を追加します。

## ルーティングとコントローラー作成
`Quote`リソースに`resources`を追加します。また、それぞれ対応する7つのアクションもコントローラに追加します。Turbo Rails Tutorialではこの辺の詳しい説明はなく、「ここでつまづいている人はRuby on Rails ドキュメントの入門ガイドを読んで戻ってきてね！」と書いてありましたので、この辺はRailsチュートリアルでじっくり学んでからやると良さそうですね。

## ビューの追加
`simple_form`を使ってフォームを作成していきます。

https://github.com/heartcombo/simple_form

私は以下の記事を参考に日本語対応してみました！

https://qiita.com/sibakenY/items/951244811404b8e4d38b

🔽 GitHubに残しているので参考に置いておきます

https://github.com/Yuppymam/quote-editor/commit/aa2d16a02d9d3460b0c32cfecce4b61a0f62252f

まだCSS当たってないので見た目は寂しいですが、現時点こんな感じです。
![スクリーンショット 2023-01-23 22.00.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293962/e586ea65-a250-ea18-2259-58a9674b4134.png)

特別なことはしていませんが、すでにこの時点でSPAチックになっています。見積もりの作成や編集、削除にページのリロードが発生しません。（その理由は3章で教えてくれそうです。）

ここで、空のフォームを送信した際にエラーメッセージが表示されないことを確認します。これは Rails7からの「重大な変更」であるとチュートリアルで述べられています。`status: :unprocessable_entity`を追加することで正常になります。（こちらも詳しくは第3章で学ぶようなので、楽しみにしておきましょう。）

そして、フラッシュメッセージが機能していないことにも気づきました。チュートリアルの目次を見ると7章で対応しそうな気配があったので、今はそのままにします。

## seed を追加する
`test/fixtures/quote.yml`のデータをそのまま開発データとして利用します。`db/seeds.rb`に`bin/rails db:fixtures:load`を行うよう記載します。

`test/fixtures/*`は minitest を実行する際に使用されるデータですが、それをそのまま開発データとしても再利用しちゃおうって訳ですね！

https://techblog.kayac.com/2016/12/01/000000

🔼 読んで`bin/rails db:fixtures:load`について、勉強しました。

以上、1章でした👍
🔽 次は2章をやっていきます！CSS書いていくっぽいですね✌️

https://qiita.com/yuppymam/items/ba18149d2a1afcc64556
JavaScript, TypeScript｜大文字小文字判定

JavaScript, TypeScriptで大文字小文字を判定する方法です。
言語によっては大文字小文字を判定する関数が備わっているものもありますが、JS, TSにはないので下記の方法を取ります。
（例えばPythonには、islower(), isupper()があります）

##### 大文字かどうか確かめる場合
1. 文字を大文字に変換します
1. 変換前の文字と変換後の文字を比較します
1. trueなら大文字、falseなら小文字です

```typescript:sample.ts
const letter: string = "a";

if (letter === letter.toUpperCase()) {
    // trueの場合
    console.log("これは大文字です");
} else {
    // falseの場合
    console.log("これは小文字です");
}
```
XcodeでTabBarを遷移先にも表示させる方法

# XcodeでTabBarを遷移先にも表示させる方法


まず、UITabBarを設置します。
参考
https://ios-docs.dev/uitabbar/

つぎに、Tab Ber Controllerの遷移先に、Navigation Controllerを配置します。

Navigation Controllerの遷移先に画像では黄色のViewControllerを配置します。

#### 【ビルド！】すると、Tab Berを継承して黄色のViewControllerに表示することができます〜！👏👏

![2023-01-24 21.42のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690272/8cf8e997-c589-88f1-f6f2-d15ec3ee7cf6.jpeg)

ちなみに、右下からもNavigation Controllerを選択できます。

![2023-01-24 21.45のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690272/166306e0-49f4-4729-9cbe-e63e8790494c.jpeg)

#### 【おまけ】
buttonが出てこない場合は、制約(コンストレイント)をつけましょう
![スクリーンショット 2023-01-24 21.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1690272/f11945ed-8cde-ec46-b111-ddfe7259aa93.png)
【Python】3DモデルのIoUを計算した

# 概要
3D分野の研究では、生成したモデルの精度を評価するために、ターゲットオブジェクトとのIoUを測ることがあります。
今回はボクセル表現の３次元モデルにおけるIoUをPythonで実装しました。

# IoUとは
IoUはIntersection over Unionの事で、「２つの物体の領域がどれだけ重なっているか」を評価する指標です。
２D画像では物体検出などに用いられます。

例えば、物体Aと物体BのIoUを測る際は以下のように求めることができます。

```math
IoU(A, B) = \frac{A \;\cap \; B}{A \; \cup \; B}
```
したがって、物体のAND領域をOR領域で割ることで、どれだけ重なっているかを求めることができるのです。

では3DモデルにおけるIoUとは、どのように求めるのでしょうか？
最もシンプルな方法は、3Dモデルを**ボクセル表現**に変換し、その重なりを調べる事です。

ボクセル表現とは、2D画像を構成するピクセルの３次元版にあたります。この表現を用いれば、単純なAND, OR領域の算出でIoU計算ができます。

# Pythonでの実装
まずはボクセル表現の3Dモデルを用意します。
もし3Dモデルがボクセル表現以外（メッシュや点群）の場合、Pythonの3D操作などで用いられるライブラリを用いる方法があります。

例）
* Trimesh... https://github.com/mikedh/trimesh
* Open3D... https://github.com/isl-org/Open3D

もし上記のライブラリでボクセル表現を取得した場合は、そこからnumpy配列を取得しましょう。
…といいつつ、ここら辺のライブラリの仕様が理解しきれていないため、具体的な方法はわかっていません。おそらくライブラリ内のget系関数やプロパティを活用すれば取得できるはず。

以下は実装になります。

```python
def calculate_volume_IoU(preds, gt, thresh=0.4):
	"""3次元IoU評価指標

	Args:
		preds (np.array): 推論ボクセル
		gt (np,array): GTボクセル
		thresh (float, optional): ボクセルの閾値. Defaults to 0.4.

	Returns:
		float: IoU値
	"""
    # 推論numpy配列の値が0,1(True, False)でない場合の処理
	preds_occupy = preds >= thresh
	# ボリュームの積集合を計算
	intersection = np.logical_and(preds_occupy, gt[0, :, :, :, 0])
	# 2つのボリュームの和集合を計算
	union = np.logical_or(preds_occupy, gt[0, :, :, :, 0])
	# IoU計算
	volume_IoU = np.sum(intersection) / np.sum(union)
	return volume_IoU
```

# まとめ
3D表現の変換まわりについて分かったことがあれば、別途まとめたいです。

# 参考サイト

https://towardsdatascience.com/how-to-voxelize-meshes-and-point-clouds-in-python-ca94d403f81d

https://qiita.com/shoku-pan/items/35eae224c59989957623
Linuxが起動しない！！

# Linuxが起動しない！！

とあるコマンドを実行したら、sudoができなくなり、強制再起動したらcentosも起動しなくなりました。
画面には Kernel panic! の表示が

# 対応

[CentOS7でシングルユーザーモードで起動する方法](https://trios.pro/centos7-single-user-mode/)
シングルユーザーモードとは、windowsのセーフモードみたいなやつです。

```shell:bash
cd /lib64
ln -s libz.so.1.27 libz.so.1
```

# 顛末書

## 原因

/lib64/libz.so.1 を削除した
```shell:bash
cd /lib64
sudo rm libz.so.1 # ここでsudoができなくなる
sudo ln -s libz.so.1.29 libz.so.1 # sudoができないのでエラー
```

## 経緯

### 1. ZLIB_1.2.9 がないと怒られた

[YOLO8](https://github.com/ultralytics/ultralytics#python)を実行したら、ZLIB_1.2.9 がないって

```shell:bash
ImportError: /lib64/libz.so.1: version `ZLIB_1.2.9' not found (required by /home/s.ando/.pyenv/versions/3.9.16/lib/python3.9/site-packages/cv2/../opencv_python.libs/libpng16-186fce2e.so.16.37.0)
```

### 2. zlibはyumで更新できないようなので、ダウンロードしてmake

[stackoverflow: `ZLIB_1.2.9' not found](https://stackoverflow.com/questions/48306849/lib-x86-64-linux-gnu-libz-so-1-version-zlib-1-2-9-not-found)

### 3. シンボリックリンクを削除して追加しようとした

更新できないと思っていたので、削除して追加しようとした

## 再発防止策

シンボリックリンクの更新オプションを使用する
```shell:bash
ln -nfs [target] [link]
```

## 環境

Let's note LIGHT R7 CF-R7CW5AJR
CentOS7 


# 編集後記

winodwsじゃあるまいし、linuxが起動しなくなるとは思いもよりませんでした。
本番環境でいきなり実行することはないですが、テスト環境なら実行していたと思います。
自宅にあるマシンなので直接操作できましたが、EC2ならどうなっていたか分かりません:scream:
何か方法はあると思います（[たぶん](https://ctrlzr.sakura.ne.jp/img/ameblo/tabun2.gif)）
expo initとcreate-react-native-appの違い

# 結論

```
npx create-expo-app {プロジェクト名} --template
```
でプロジェクトを作成しましょうね．

# 本文

expoの講座を一通り見たので自分で調べて最初からやってみようと思ったら，プロジェクト作成の時点でわからんことが
プロジェクト作成の方法は２通りあるみたいで

```
# 洗濯するプロジェクトタイプはブランク
expo init {プロジェクト名}

npx create-expo-app {プロジェクト名}
```
はほぼ同じでした．
マージツールで比較すると以下画面のように名前が違うくらいですかね．
create-expo-appで作成した方にはyrnのロックファイルがありますが，どこかの設定ですかね．
![マージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118687/bb88de3b-6f0a-c0fa-4adf-9ae3016cd574.png)

## で，どっち使うべきなの？

```
expo init expo-blank

Migrate to using:
› npx create-expo-app --template
```
expo initを使用すると上のような推奨パターンが出てきます．
ってことはcreate-expo-appを使用するのが正解なんでしょうね．

expo initではコマンド実行直後にテンプレートを選択できますが，
create-expo-appではテンプレートを聞かれずに素の状態のプロジェクト（blank）が作成されてしまいます．

なので，テンプレートを使用したい場合は，オプションに--templateを入れましょうね．
```
npx create-expo-app {プロジェクト名} --template
```

選択できるテンプレートも変わってるみたいです．
中身的には同じそうですが
TypeScript｜コールバックの型注釈

TypeScriptでコールバックの型注釈の方法。

下記のコードだと型指定は以下の通り。
- 1つ目の引数は、numberを受け取ってnumberを返す関数
- 2つ目の引数は、string

```typescript
function sampleFunction(f: (n: number) => number, country: string): void {
    // 処理
}
```

より詳細な型注釈のお作法を知りたい方は[こちら（公式Docs）](https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#callback-types)
新人SEが効率的に成長するために必要なこと

# 新人SEが効率的に成長するために必要なこと

**軽く挨拶**
記事を閲覧していただきありがとうございます。当記事は、SIerで働く新人SEの葛藤と日々のアウトプットを行うための記事です。技術的な話もしますが今回は「新人がいち早く戦力になる」ためにどういうステップを踏めばいいのかという観点で話していこうと思います。



1. [結局アプトプットを出せるかだと思う](#anchor1)
1. [エンジニアとして成長するために必要なこと](#anchor3)
1. [まとめ](#anchor4)



<!-- リンク先(目次部分のリンクの飛び先) -->
<a id="anchor1"></a>

## 結局アプトプットを出せるかだと思う

1. エンジニアにおけるvalueとは
   いきなりですが、私の思う価値のあるエンジニアとは、「生産性の向上にに貢献できる」エンジニアだと思います。これはベテランであっても新人であっても共通にしてチームに貢献することが大切だと思います。
「生産性」という言葉が抽象的なので一つ階層を下げてみましょう。例えば以下のようなものがありますね
- プロダクトの品質を高める
- チーム内、さらには外部にナレッジの共有ができる
- プロジェクトを進めるうえでの戦力になる
あげたらきりがないですが....

よく、エンジニアは技術だ!!　という言葉を巷で小耳にはさみますがそれは、プログラミング力やインフラの知識といった狭義の技術力ではなく、「**チーム、さらには組織のアウトプット力の向上に貢献する技術**」私はそう考えます。

では、そのアウトプット力はどうやって身に着けていけばいいのでしょうか。純粋な技術力、コンサル力、そして業務知識。それらは、ベテランエンジニアが我々新人の数十倍と、保有しています。上司が私たち新人に求めることは爆速でプログラミングできることでしょうか? クッソ複雑なインフラ設計ができることでしょうか? 

1. 優秀な新人SE
個人の主観になりますが、新人SEにいち早く求められているのは「早く戦力になってほしい」純粋にこれに尽きると思います。そのために我々は**成長**することを求められているのです。
どのような点を伸ばすべきか、今現在自分の課題も踏まえて簡潔に考えると

- ITの基礎知識をいち早く入れる(IPアドレスとかサーバーとかbuild deplyとか....)
    - 自分の業務に関係する技術領域の基礎知識はとっとと入れましょう。というか勉強すればいいだけなので土日も勉強すべき
- 今かかわっているプロジェクトの全体像を把握する
    - 用語シランと会議の内容わからないし仕様ミスなど致命的なミスにつながります
- 仕事を可視化する
    - 今何をやっていて進めるうえでどのような課題があって~というものを割り振られた小タスク内で作業履歴を残す
    - これを行うことで自分の思考の整理にもなるし、先輩や上司と連携するときにも何をやっていてどこに課題を抱えているとかが分かりやすい
- 常に言語化することで分かりやすい文章を書けるようにする
    - 自分が何を理解していて何がわからないの可視化か? もやもやわかりません。
    例えば新しい技術を学んだら、まったくその知識がない人も理解できるくらい説明できるか。結局物事を伝えるのには言語で伝えるしかないので技術的な質問をするときとかもいかにわかりやすく伝えられるかが、キーになっていると思います。


<a id="anchor3"></a>
## エンジニアとして成長するために必要なこと
技術力というとPCの前での作業に終点が当たりがちですが、仕事ということで生産性の向上に貢献するのが目的なわけです。わかりやすい文章を書くだとか、凡ミスを減らすだとか割かし基本的なことが重要な気がします。
あとは、日々の気づきを振り返ることだと思います。結局良いアウトプットを出すにはは、経験値の蓄積が物を言うと考えています。なのでいかにして、「経験を積むか」だと思っています。有効な経験値を積むために、起きた事象や気づきを言語化してナレッジとして蓄積しておくことが重要な気がします。そしてそれを仕事の中で活用して理論を肌で感じて身に着けていく。結局これの繰り返しな気がします。仕事の優先順位のつけ方とか、上司に注意されたこと、うまくいったこと、すべて言語化して蓄積する習慣をつける。　世界が変わって見える気がします。
<a id="anchor4"></a>
## まとめ 

とはいいつつ。このような思考になったのもつい最近の話です。未経験入社の頃の配属当時は、目の前の作業で頭がいっぱいでした。でも結局、わからないことが多すぎると馬鹿みたいにワーキングメモリ食うし、結果ミスも増えるしそれで委縮するし、負の連鎖になっちゃうのは仕方ない気がします。「いち早く基礎を頭にぶち込むか」そのカギは、学んだことの言語化、そしてタスクの可視化(ある意味では言語化)にあると思います。

次はもっと技術的な話がしたい.....
【SwiftUI】アクセシビリティ設定によって透明度が変化する

# はじめに
https://qiita.com/SNQ-2001/items/d94c39ed765889b46869

https://qiita.com/SNQ-2001/items/25e8602ab341c7ec2cb5

アクセシビリティ設定によって実機で試してみるなんてことはなかなかないので気づきにくいです。
今回もたまたま発見したので紹介します。
(今回はMacOS限定です)
(しかも、メニューバーアプリの`window`スタイルで発生した)
(しかも、私がアクセシビリティをオンにしてた)

ということでかなり限定的な記事ですが、記録しておきます。

# 該当コード
```swift:App
import SwiftUI

@main
struct accessibility_sampleApp: App {
    var body: some Scene {
        MenuBarExtra {
            ContentView()
        } label: {
            Image(systemName: "paperplane.fill")
        }
        .menuBarExtraStyle(.window)
    }
}
```
```swift:ContentView
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello, world!")
        }
        .frame(width: 200, height: 300)
    }
}
```

# 該当のアクセシビリティ
![スクリーンショット 2023-01-24 21.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/13ea44a8-5b70-f49b-cf99-15b3954933ab.png)

# どうなるか
透過されすぎっしょ！！！
|OFF|ON|
|-|-|
|![スクリーンショット 2023-01-24 21.12.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/84c982de-3d36-4def-a8b9-6b9ac2d2ccb1.png)|![スクリーンショット 2023-01-24 21.12.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9063c952-3c19-ceec-c6e6-e862ce34db71.png)|

もし背景が明るい色でダークモードなどであれば文字が見えなくなる可能性があります。

# 対策
こちらの環境変数でON / OFFの取得ができます。

https://developer.apple.com/documentation/swiftui/environmentvalues/accessibilityreducetransparency

もしくは、最初から背景色を追加しておく、などが考えられます。

アクセシビリティを無効にすることはできないっぽいです。

# おわり
たまたまMacのアカウントを切り替えたところ、発見しました笑
アクセシビリティは頻繁に切り替えることがないので気づきにくいです。。
VscodeのRemote-SSHの調子が悪い時の対処

# VscodeのRemote-SSHの調子が悪い時の対処

こんにちは、九州大学修士２年の浅海です。
VscodeのRemote-SSHの調子が悪くなり、つまづいたのでここにメモします。

こちらの記事は、VscodeのRemote-SSHの障害に関する以下のセッションの内容をまとめたいと思います。

## 結論
**リモート接続先の`~/.vscode-server`フォルダを消すことで解決！**

`~/.vscode-server`フォルダはVSCodeでRemote-SSH接続した時に、リモート先に作成されるフォルダであり、このフォルダを消すと設定をリセットできます。

**Remote-SSHが重くなった際やエラーが出た際は以下のコマンドで消してみてください。**
```
# フォルダの削除コマンド
rm -rf ~/.vscode-server/
```

[この記事](https://qiita.com/keyhole0/items/88c20d05933ebea5b9ed)を参考にしました。


## `~/.vscode-server`フォルダには何が保存されてるのか
色々とサイトを調べましたが、分かりませんでした。おそらくlog等が保存されているのではないかと...
分かり次第追記します。

## まとめ
以上が、VscodeのRemote-SSHの調子が悪い時の対処方法です。
これからも気になった点をまとめていこうと思います！
VRMをFBXに変換

# はじめに
Unityを使ってVRMをFBXに変換するためのメモです。

# 環境
Unity 2021.3.12f1
uniVRM 1.08 (VRM-0.108.0_e16d.unitypackage)
FBX Exporter 4.1.3
適当に作ったVRMファイル

# 手順
Unityのプロジェクトを作成する。
uniVRMアセットをダウンロードし、インストールする。
Package ManagerからUnity Registry内で「FBX」で検索し、FBX Exporterを探し、インストールする。
VRMファイルをAssetsにD&Dする。
（できない場合は、元ファイルのフォルダ場所が悪い）
D&Dしたファイルを選択し、ModelタブのMigrate To VrmをApplyする。
同様に、Materialsタブでextractする。
同様に、Vrmタブでextractする。
これらをしないと、FBXファイルのマテリアル書き出しでバグる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/184828da-137b-25c1-9fb4-986a0edd5538.png)

モデルをシーンに配置し、右クリックし、Export to FBXを選択。保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/bcc59b55-44ce-78de-e1c1-76749268371f.png)
他の３DCGソフトで読み込み、確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/e7f82051-edf4-5eed-2df0-51241919ba9a.png)


顔色が悪い。
【vim】　検索

```
/検索文字-- 順方向にパターンを検索
?検索文字-- 逆方向にパターンを検索
n                -- 前回と同じ方向に再検索
N                -- 前回と逆の方向に再検索
/        -- 順方向に再検索
?        -- 逆方向に再検索
```
【Rails】ログイン認証用gemのdevise_token_auth動作確認時にNoMethodError: undefined method `downcase' for nil:NilClassエラー


## 1. 問題
ログイン機能の実装のため、ログイン認証用のgemであるdevise_token_authを導入した。
前提としてDocker上でフロントをVue.js、バックエンドはRails APIで実装している。

一通りdevise_token_authの設定が終わったので、Postmanから新規登録のAPIを叩いてみる


urlは、``http://localhost:8000/v1/auth``
paramsは、``name``, ``email``, ``password``, ``password_confirmation``を設定した



下記のエラーが発生した

```:Postman
{
    "status": 500,
    "error": "Internal Server Error",
    "exception": "#<NoMethodError: undefined method `downcase' for nil:NilClass>",
    "traces": {
        "Application Trace": [],
        "Framework Trace": [
            {
                "exception_object_id": 20620,
                "id": 0,
                "trace": "rack (2.2.5) lib/rack/utils.rb:464:in `[]='"
            },
            ...
        ]
    }
}
```

```console:console
backend_1   | NoMethodError (undefined method `downcase' for nil:NilClass):
backend_1   |   
backend_1   | rack (2.2.5) lib/rack/utils.rb:464:in `[]='
backend_1   | rack (2.2.5) lib/rack/utils.rb:432:in `block in initialize'
backend_1   | rack (2.2.5) lib/rack/utils.rb:432:in `each'
backend_1   | rack (2.2.5) lib/rack/utils.rb:432:in `initialize'
backend_1   | rack (2.2.5) lib/rack/utils.rb:425:in `new'
backend_1   | rack (2.2.5) lib/rack/utils.rb:425:in `[]'
backend_1   | rack (2.2.5) lib/rack/etag.rb:29:in `call'
backend_1   | rack (2.2.5) lib/rack/conditional_get.rb:40:in `call'
backend_1   | rack (2.2.5) lib/rack/head.rb:12:in `call'
```


## 2. 解決策
下記のGitHubに解決策が載っていた
https://github.com/lynndylanhurley/devise_token_auth/issues/1540

config/initializers/devise_token_auth.rbに``:'authorization' => 'authorization'``を追加する

```ruby:config/initializers/devise_token_auth.rb
# Makes it possible to change the headers names
  config.headers_names = {:'access-token' => 'access-token',
                         :'client' => 'client',
                         :'expiry' => 'expiry',
                         :'uid' => 'uid',
                         :'token-type' => 'token-type',
                         # ↓ここを追加！！！
                         :'authorization' => 'authorization'}

```

修正後、再度``docker-compose build``、``docker-compose up``

```console:conosole
docker-compose build --no-cache

docker-compose up
```

もう一度APIを叩いてみたら、新規登録できた！

```:Postman
{
    "status": "success",
    "data": {
        "id": 20,
        "provider": "email",
        "uid": "ginger-yell@example.com",
        "name": "ginger-yell",
        "email": "ginger-yell000@example.com",
        "created_at": "2023-01-17T11:27:37.803Z",
        "updated_at": "2023-01-17T11:27:37.867Z"
    }
}
```

```console:console
backend_1   |   User Create (2.1ms)  INSERT INTO `users` (`uid`, `encrypted_password`, `name`, `email`, `created_at`, `updated_at`) VALUES ('ginger-yell@example.com', '$1a$14$KhKsTVkilNgLofubgXGOdu32UsLF9W.BUCayj7w28oVeNNONDijy6', 'ginger-yell', 'ginger-yell@example.com', '2023-01-17 11:27:37.803531', '2023-01-17 11:27:37.803531')
```


## 参考
https://github.com/lynndylanhurley/devise_token_auth/issues/1540

https://github.com/m-kawahigashi/todo-app/pull/5
相対論に関するLaTeXのコードをまとめました


## アインシュタイン方程式
```LaTeX
\begin{equation}
G_{\mu\nu}=
\frac{8\pi G}{c^4} T_{\mu\nu}
\end{equation}
```
```math
G_{\mu\nu}=
\frac{8\pi G}{c^4} T_{\mu\nu}
```
\begin{equation}　と　\end{equation}　は数式の始まりと終わりを表します。
これがないとエラーが出るので注意。
以下省略します。
## アインシュタインテンソル

```LaTeX
G_{\mu\nu}\equiv R_{\mu\nu} - \frac{1}{2} g_{\mu\nu} R^{\alpha}{}_{\alpha}
```
```math
G_{\mu\nu}\equiv R_{\mu\nu} - \frac{1}{2} g_{\mu\nu} R^{\alpha}{}_{\alpha}
```
## リッチテンソル
```LaTeX
R_{\mu\nu}\equiv \partial_{\alpha} \Gamma^{\alpha}{}_{\mu\nu} - \partial_{\mu} \Gamma^{\alpha}{}_{\nu\alpha} + \Gamma^{\alpha}{}_{\mu\nu} \Gamma^{\beta}{}_{\beta\alpha} - \Gamma^{\alpha}{}_{\mu\beta} \Gamma^{\beta}{}_{\nu\alpha} 
```
```math
R_{\mu\nu}\equiv \partial_{\alpha} \Gamma^{\alpha}{}_{\mu\nu} - \partial_{\mu} \Gamma^{\alpha}{}_{\nu\alpha} + \Gamma^{\alpha}{}_{\mu\nu} \Gamma^{\beta}{}_{\beta\alpha} - \Gamma^{\alpha}{}_{\mu\beta} \Gamma^{\beta}{}_{\nu\alpha} 
```
## クリストッフェル記号
```LaTeX
\Gamma^{\alpha}{}_{\mu\nu}　= \frac{1}{2} g^{\mu\nu} (\partial_{\mu} g_{\nu\beta} + \partial_{\nu} g_{\mu\beta} - \partial_{\beta} g_{\mu\nu})
```

```math
\Gamma^{\alpha}{}_{\mu\nu}　= \frac{1}{2} g^{\mu\nu} (\partial_{\mu} g_{\nu\beta} + \partial_{\nu} g_{\mu\beta} - \partial_{\beta} g_{\mu\nu})
```
## ビアンキの恒等式
```LaTeX
\nabla_{\lambda} R^{\mu}{}_{\nu\rho\sigma} + \nabla_{\rho} R^{\mu}{}_{\nu\sigma\lambda} + \nabla_{\sigma} R^{\mu}{}_{\nu\lambda\rho} = 0
```

```math
\nabla_{\lambda} R^{\mu}{}_{\nu\rho\sigma} + \nabla_{\rho} R^{\mu}{}_{\nu\sigma\lambda} + \nabla_{\sigma} R^{\mu}{}_{\nu\lambda\rho} = 0
```

## リーマンテンソル
```LaTeX
R_{\alpha\beta\gamma\sigma} = \frac{1}{2}(\partial_{\alpha}\partial_{\sigma}h_{\beta\gamma} + \partial_{\beta}\partial_{\gamma}h_{\alpha\sigma} - \partial_{\beta}\partial_{\sigma}h_{\alpha\gamma} - \partial_{\alpha}\partial_{\gamma}h_{\beta\sigma})
```
```math
\begin{equation}
R_{\alpha\beta\gamma\sigma} = \frac{1}{2}(\partial_{\alpha}\partial_{\sigma}h_{\beta\gamma} + \partial_{\beta}\partial_{\gamma}h_{\alpha\sigma} - \partial_{\beta}\partial_{\sigma}h_{\alpha\gamma} - \partial_{\alpha}\partial_{\gamma}h_{\beta\sigma})
\end{equation}
```


## 線形化されたアインシュタインテンソル
```LaTeX
G_{\mu\nu} = \frac{1}{2}(-\Box\psi_{\mu\nu} + \partial_{\alpha}\partial_{\mu}\psi^{\alpha}{}{\nu} + \partial_{\alpha}\partial_{\nu}\psi^{\alpha}{}{\mu} - \eta_{\mu\nu}\partial_{\alpha}\partial_{\beta}\psi^{\alpha\beta})
```
```math
G_{\mu\nu} = \frac{1}{2}(-\Box\psi_{\mu\nu} + \partial_{\alpha}\partial_{\mu}\psi^{\alpha}{}{\nu} + \partial_{\alpha}\partial_{\nu}\psi^{\alpha}{}{\mu} - \eta_{\mu\nu}\partial_{\alpha}\partial_{\beta}\psi^{\alpha\beta})
```

## 線形化されたアインシュタイン方程式
```LaTeX
\Box\psi_{\mu\nu} = -\frac{16\pi G}{c^4} T_{\mu\nu}
```
```math
\begin{equation}
\Box\psi_{\mu\nu} = -\frac{16\pi G}{c^4} T_{\mu\nu}
\end{equation}
```






## 参考文献
Bernard Schutz.江里口良治・二間瀬敏史　共訳
『シュッツ相対論入門』丸善株式会社　第２版,2010

奥村/晴彦,黒木裕介
[改訂第7版]LaTeX2ε美文書作成入門　技術評論社，2017
C++入門 AtCoder Programming Guide for beginners (APG4b)のEX6 - 電卓をつくろう

# 読んで欲しい人
・未来の私。（実は2回目）
・電卓を作りたい人
・プログラミングを詳しい方。
# 注意
 ・C++入門 AtCoder Programming Guide for beginners (APG4b)のEX6 - 電卓をつくろう
のネタバレがあります。

# 問題文
[EX6 - 電卓をつくろう](https://atcoder.jp/contests/apg4b/tasks/APG4b_cq)
# ACしたコード
```C++
#include <bits/stdc++.h>
using namespace std;

int main() {
	int A, B;
	string op;
	cin >> A >> op >> B;

	if (op == "+") {
	cout << A + B << endl;
	} else if (op == "-") {
	cout << A - B << endl;
	} else if (op == "*") {
	cout << A * B << endl;
	} else if (op == "/" && B != 0) {
	cout << A / B << endl;
	} else {
	cout << "error" << endl;
	}
}
```

# 理解できなかったところ1
・電卓で0で割るとエラーになる事を認識してなかった。[0で割り算すると、、、の記事](https://club.informatix.co.jp/?p=8895#:~:text=a%C3%B7%EF%BC%90%E3%81%A8%E3%81%84%E3%81%86%E8%A8%88%E7%AE%97,%E6%AD%A3%E4%BD%93%E3%81%A0%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82)

```C++
//初手のコード(部分)
      else if (op == "/") {
          cout << A / B << endl;
    } else if (op == "/" && B == 0) {
          cout << "error" << endl;
	}
```
この書き方だとテストケースで　100 / 0　が与えられた場合
```C++
Floating point exception (core dumped)
```
このようなエラーになる。
(このエラー文を詳しく知りたいけど調べてみたら沼になったので後回しにする。)
(多分、[浮動小数点例外](https://www.ibm.com/docs/ja/aix/7.2?topic=concepts-floating-point-exceptions)だと思うけど自信がない)
# 理解できなかったところ2
・条件分岐の判定の順番
初手のコード(部分)で判定されているのは最初の else だけでは？
と思ったので else の順番を入れ替えたらACできた 笑
```C++
#include <bits/stdc++.h>
using namespace std;

int main() {
	int A, B;
	string op;
	cin >> A >> op >> B;

	if (op == "+") {
    	cout << A + B << endl;
	} else if (op == "-") {
    	cout << A - B << endl;
	} else if (op == "*") {
    	cout << A * B << endl; 
	} else if (op == "/" && B == 0) { //ここと
        cout << "error" << endl;
    } else if (op == "/") {           //ここの順番を入れ替えた
        cout << A / B << endl;
    } else {
    	cout << "error" << endl;
	}
}
```
順番を入れ替えると判定される順番も変更されるから
解説と異なるコードだけどACになる。

```C++
#include <bits/stdc++.h>
#include <iostream>
```
# ↑の使い分けがわからないので調べ中
# 参考にした記事まとめ
・[0で割り算すると、、、の記事](https://club.informatix.co.jp/?p=8895#:~:text=a%C3%B7%EF%BC%90%E3%81%A8%E3%81%84%E3%81%86%E8%A8%88%E7%AE%97,%E6%AD%A3%E4%BD%93%E3%81%A0%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82)
特定の文字列のフォントカラーを赤色に変更する（VBA）

特定の文字列のフォントカラーを赤色に変更する

	Option Explicit

	Sub TextColorChange()

	    '■概要
	    '開いているシートの特定文字列の色を赤色に変更する
	    '色を変更したいシートでマクロを実行する
	    
	    Call StartProcess
	    
	    '変数宣言
	    Dim TargetSheet As Worksheet: Set TargetSheet = ActiveWorkbook.ActiveSheet
	    Dim SerchText   As String: SerchText = ""
	    Dim TextLength  As Integer: TextLength = 0
	    Dim TextPoint   As Integer: TextPoint = 0
	    Dim LastColumn  As Long: LastColumn = 0
	    Dim LastRow     As Long: LastRow = 0
	    Dim SerchObj    As Object: Set SerchObj = Nothing
	    Dim TmpObj      As Object: Set TmpObj = Nothing
	    
	    '赤色に変更する文字列を取得するダイアログを表示
	    SerchText = InputBox("Plz enter text to be change red", "InputBox", "")
	    
	    '文字列が未入力もしくはダイアログを閉じた場合は、実行終了
	    If SerchText = "" Then
	        Call EndProcess
	        Exit Sub
	    End If
	    
	    '文字列の長さを取得
	    TextLength = Len(SerchText)
	    
	    '最終列、行を取得
	    LastColumn = TargetSheet.Cells.SpecialCells(xlLastCell).Column
	    LastRow = TargetSheet.Cells.SpecialCells(xlLastCell).Row
	    
	    '文字列を検索
	    Set SerchObj = TargetSheet.Range(Cells(1, 1), Cells(LastRow, LastColumn)).Find(SerchText, LookAt:=xlPart)
	    Set TmpObj = SerchObj '検索結果を一時保存
	    
	    '検索結果が存在しない場合は、実行終了
	    If SerchObj Is Nothing Then
	        Call EndProcess
	        Exit Sub
	    End If
	    
	    '最初の検索結果と同じになるまでループ
	    Do
	        '2つ目の文字列を検索
	        Set SerchObj = TargetSheet.Range(Cells(1, 1), Cells(LastRow, LastColumn)).FindNext(SerchObj)
	        
	        '文字列の位置を取得
	        TextPoint = InStr(SerchObj.Value, SerchText)
	        
	        '文字列を赤色に変更
	        SerchObj.Characters(Start:=TextPoint, Length:=TextLength).Font.Color = RGB(255, 0, 0)
	        
	        '文字列の位置が取得できなくなるまでループ
	        Do
	            '2つ目の文字列の位置を取得
	            TextPoint = InStr(TextPoint + 1, SerchObj.Value, SerchText)
	            
	            '文字列の位置を取得できた場合は実行
	            If TextPoint <> 0 Then
	                '文字列を赤色に変更
	                SerchObj.Characters(Start:=TextPoint, Length:=TextLength).Font.Color = RGB(255, 0, 0)
	            End If
	            
	        Loop While TextPoint <> 0
	        
	    Loop While TmpObj.Column <> SerchObj.Column Or TmpObj.Row <> SerchObj.Row
	    
	    Call EndProcess
	    
	End Sub

	'開始処理
	Function StartProcess()
	    Application.DisplayAlerts = False
	    Application.ScreenUpdating = False
	End Function

	'終了処理
	Function EndProcess()
	    Application.DisplayAlerts = True
	    Application.ScreenUpdating = True
	End Function