OmniAICreator/Qiita-1.07M huggingface dataset:
【Bash】ファイルの圧縮・解凍

## はじめに

今回はファイルの圧縮・解凍で用いるコマンドを扱います。



## gzip コマンド

gz 形式でファイルを圧縮・解凍するコマンド

| コマンド | 説明 |
|:-|:-|
| gzip -d(gunzip) | ファイルを解凍する |
| gzip -r | ディレクトリ内のファイルも再帰的に圧縮する |

```text:例（ファイルの圧縮）
[ec2-user@localhost ~]$ gzip file.txt
[ec2-user@localhost ~]$ ls file.txt*
file.txt.gz
```

```text:例（ファイルの解凍）
[ec2-user@localhost ~]$ gzip -d file.txt.gz
[ec2-user@localhost ~]$ ls file.txt*
file.txt
```



## zip、unzip コマンド

zip 形式で圧縮・解凍するコマンド

| コマンド | 説明 |
|:-|:-|
| zip -r | ディレクトリ内のファイルも再帰的に圧縮してディレクトリを圧縮する |

```text:例（zip形式でファイルを圧縮）
[ec2-user@localhost ~]$ zip file.txt.zip file.txt
  adding: file.txt (stored 0%)
[ec2-user@localhost ~]$ ls file.txt.zip
file.txt.zip
```

```text:例（zip形式の圧縮ファイルを解凍）
[ec2-user@localhost ~]$ unzip file.txt.zip
```



## tar コマンド

ファイル・ディレクトリをさまざまな形式で圧縮・解凍するコマンド

| コマンド | 説明 |
|:-|:-|
| tar -c | 圧縮する |
| tar -x | 解凍する |
| tar -f | 対象のファイル・ディレクトリを指定する |
| tar -v | 処理されたファイルの一覧を表示 |
| tar -z | gzip形式で圧縮・解凍（ .tar.gz という拡張子になる ） |
| tar -j | xz形式で圧縮・解凍（ .tar.xz という拡張子になる ） |

```text:例（ディレクトリを tar.xz で圧縮）
[ec2-user@localhost ~]$ tar -cvJf dir1.tar.xz dir1
dir1/
dir1/file1
```

```text:例（ファイルを解凍）
[ec2-user@localhost ~]$ tar -xvJf dir1.tar.xz
dir1/
dir1/file1
```



## おわりに

ファイル転送で大活躍！
え、同じDockerfileなのに動かない。

# はじめに
- Dockerfile を使って環境の共通化をするのは、それぞれの人の環境によって動作する・動作しないという不具合を減らすのも目的の一つだ。
- CPUとOSやCUDAデバイスの状況をそろえて、動作環境の違いをなくそうとしている。
- にもかかわらず、docker build の状況が違ってしまった。
- 自分の経験した範囲の情報に、他の人の記事へのリンクを追記した。

## 動作が違ってしまう状況
1. 環境変数の参照結果の違い
1. ホスト環境でのディレクトリ構成の違い
1. RUN　コマンドで指定したコマンドがホスト環境のものである場合に、ホスト環境にそれが入っているかどうか
1. ライブラリのバージョンを明示的に指定していない場合だと、apt やpip　の中で選択されるライブラリのバージョンが人によって違ってきてしまって、docker build 自体で異なったり、docker環境内での動作結果が違ってしまう。
1. 

 ## 実行時の不具合になりうる項目
 1. Dockerの中でキャッシュしているディスク領域が十分にあるかどうか
 1. `torch2trt` をDocker環境の中で構築するような場合
 1. [Dockerfile 中でtorch2trtを実行する方法](https://qiita.com/nonbiri15/items/d840db806790c51928c8)
1. qiita [メモリ容量が異なる](https://qiita.com/kaityo256/items/ac10649debc10898f903)
1. note [Docker Desktop for Mac は相対パス指定を消している](https://note.milldea.com/posts/docker-for-mac-remove-relative-path)
1. qiita [DockerfileでCOPYのファイルパスが正しいのに動かないのはおかしい！](https://qiita.com/Sicut_study/items/8e0fd9ba1339ef9856cf)
1. `/etc/apt/sources.list` の内容の違い　aptでのダウンロードに影響する。
1. `apt install` する際のPGPエラー
venvを使ったPythonの仮想環境構築(windows)

# venvについて
　[venv](https://docs.python.org/ja/3/library/venv.html#module-venv)はPythonで軽量な仮想環境を作成するための標準ライブラリである。
 
 ### 仮想環境をとは
　ソフトウェア開発において、プロジェクトごとに異なる依存関係やパッケージを隔離して管理するための仕組みである。
##### <メリット>
・依存関係の管理..プロジェクトごとに異なるバージョンのパッケージを使用でき、パソコンのPython環境を汚染せずにパッケージをインストールできる。
・再現性の確保..."requirements.txt"ファイルを使用して、特定のバージョンのパッケージを簡単に再インストールできる。
・開発の効率化...複数のプロジェクトを並行して開発する際に、環境設定をプロジェクトごとにカスタマイズできる。また、新しいプロジェクトを始める際にクリーンな環境を素早く作成できる。
##### <デメリット>
・容量の消費...各仮想環境は独自のPythonインタープリンタ(Pythonプログラムを実行するためのソフトウェア)とパッケージを持つため、各仮想環境ごとに容量を消費する。
・管理の手間...各環境を有効化/無効化する手間や依存関係を最新の状態に保つ環境管理の作業が増える。
# 環境
```cmd.
python -version
python [USER_VERSION]  >= python 3.3
```
Python 3.3以降のバージョンで使用できる。
# 利用手順(windows)
### 仮想環境の作成
```cmd.
cd [PROJECT_DIR]
python -m venv [venv_NAME]
```
[PROJECT_DIR]には仮想環境を作成するディレクトリを指定する。
[venv_NAME]には仮想環境の名前を指定する。
※仮想環境を作成したディレクトリ以外のプロジェクトでも仮想環境を使用することが可能である。
### 仮想環境の有効化
```cmd.
cd [USER_PROJECT]
[venv_NAME]\Scripts\activate
```
環境が有効になるとコマンドラインプロンプトに仮想環境名が表示される。
```cmd.
[PROJECT_DIR]
↓(仮想環境有効化)
([venv_NAME])[USER_DIR]
```
### 仮想環境の無効化
以下のコマンドを使用すると仮想環境を無効にする。
```cmd.
([venv_NAME])$ deactivate
```
### パッケージのインストール
仮想環境内でパッケージをインストールする場合、通常の pip コマンドを使用する。
```cmd.
pip install [package_name]
```
### 依存関係の管理
プロジェクトの依存関係を記録するには、以下のコマンドで"requirements.txt"を作成する。
```cmd.
pip freeze > requirements.txt
```
別の環境で同じ依存関係をインストールするには、以下のコマンドを使用する。
```cmd.
pip install -r requirements.txt
```
"-r"は"--requirement"の短縮形であり、指定されたファイルを読み込み、その内容に基づいてパッケージをインストールする。
# 参考
・[venv --- Creation of virtual environments](https://docs.python.org/ja/3.12/library/venv.html)
・[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)
備忘-プロパティ & コンストラクタ

## プロパティとは
呼び出す側は直接フィールドを変更しているように見えますが、実際はgetterやsetterを通して行われる仕組みを指します。

```java
public class Product{
    private String name;
    private String id;
    private int price;

    public String getName(){
    return this.name;
    }

    public void setName(String name){
    this.name = name;
    }
}
```
上記の仕組みにより、フィールドを自由にいじることができ、修正が発生しても簡単に実行できるようになります。

## インスタンスとは
コンストラクタを説明する前にインスタンスについて整理することにより、コンストラクタとの違いがわかり、理解しやすいと考えインスタンスをまず書いていきたいです。

インスタンスとは、データを格納できる箱のような存在です。名前や価格を箱に詰めていくことで、独自の箱になることができます。

下記にコードで書いてみました。
```java
public class Product{
    String name;
    String id;
    int price;
    }
}
```
productクラスを呼び出し、製品名を設定していきます。
```java
Product product1 = new Product();
product1.name = "冷蔵庫";
product1.id = "1234";
product1.price = 300000;
```
上記のやり方でインスタンスという箱に様々なデータを与えていきます。
しかし、いくつかの課題があるように感じます。
①毎回、インスタンス生成時にフィールド初期値を設定しないといけない。
②フィールド初期値を設定するのを忘れてしまう

①②の課題を解決する方法がコンストラクタというメソッドになります。

## コンストラクタとは
インスタンス生成時に自動実行されるメソッドです。

```java
public class Product{
    private String name;
    String id;
    int price;
    }

    public Product(){
    this.price = 300000;
}
```
Productインスタンスが生成時に価格が自動的に設定されます。

## 余談　インスタンスについて
クラス型を宣言した際、メモリにインスタンスのための領域①が確保されます。その後、newを使ってインスタンスを生成されたとき、メモリにインスタンスのフィールドを設定するための領域②が確保されます。フィールドに値が設定されると、領域①が領域②のフィールドを見にいく仕組みになっています。

ここで私が注目したのは、ムダにnewをしてインスタンスを生成してしまうとパフォーマンスが落ちることです。仮に下記のようなやり方だとパフォーマンスがおちないのではないかと考えています。

```java
Product p1; 
p1 = SQLxxx01.sqlxxx01();
```

上記のやり方では、newをせずにp1へ情報を渡しているのでメモリ領域をムダに取らずに処理を実行できるのではないかと思っています。
JavaScriptフレームワーク,ライブラリについて調べてみた









## Vue.js

Vue.jsは、シングルページアプリケーション開発に使われていることが非常に多い。

シングルページアプリケーションで開発すると、ページ遷移をする時はJavaScriptを使用することによりHTMLの一部を差し替えて切り替えることができる。従来のWebページではページ遷移の時に全体を切り替える必要があったので、シングルページアプリケーションによって新しいUIの実現やスピードの向上を実現することが可能となった。

このようなパフォーマンスの高さから今では多くの企業でWebサイトやアプリケーションの開発にシングルページアプリケーションを採用しており、シングルページアプリケーション開発に使われるVue.jsの人気も高まっている。

## React

React.jsはWebサイトよりもアプリケーション開発に使われることのほうが多い。何かに特化したWebサイトやアプリケーションの開発がしたい方に最適である。

他にもReact.jsではVR開発も行える。VRと聞けば、Unityを利用したゲーム開発が主に一般的なのですが、Reac.jsでtはWebベースのVR開発を行うことができる。





## Next.js

「Next.js」は、Reactをベースに開発されたフレームワークである。そのため、Reactと同様に機能的な共通点は多く、性能面もそれほど大きな差はない。

ただし、Next.jsは海外で高い人気があるものの、日本語の参考情報はVue.jsと比べて少ない傾向がある。そのため、プログラミング初心者にとっての学びやすさでいえば、Vue.jsに軍配が上がる。



## AngularJS

AngularJSでは、マスターメンテナンスなどのような「CRUD系アプリ」「業務系アプリ」といった、各機能が独立した画面として成り立って存在しており、フォームを使ってデータなどの送受信を行うようなアプリの開発に向いているとされている。

ですが逆に、ゲームなどのように変化するデータの量が多くて速度重視となるアプリの開発や、シングルページアプリケーションと呼ばれる、AjaxやWebSocket通信を使い、画面が遷移しないWebアプリなどの開発にはあまり向いていない。

## jQuery

jQueryはとても多くのWebサイトで使われている。主に商用のホームページやECサイトなどで使われることが多く、Webアプリケーションでも小中規模のものはだいたい使われている。

jQueryではプラグインを利用することで、機能追加も簡単にでき、ブラウザ間の違いを気にすることもないところも特徴の１つである。



参考情報：https://www.sejuku.net/blog/70110?utm_source=blog&utm_medium=blog&utm_campaign=blog_Low_10766
【Bash】systemd と systemctl

## はじめに

今回は systemd と systemctl の学習備忘録です。



## OS の起動プロセス

OS は起動時に以下のフローでプロセスが起動されていきます。

最後に init プロセスが起動されますが、systemd はこの init プロセスの種類の内の一つに該当します。

1. 電源ON
1. BIOS の起動
    - ハードウェアの初期化・設定
    - メモリ状態のチェック
    - 起動するデバイス（ OS、ディスク等 ）の設定・チェック
    - bootloader の実行
1. bootloader の起動
    - カーネルをメモリにロードする
1. カーネルの起動
    - メモリを初期化し、initプロセスを起動するための一時的な（ initramfs ）をマウントする
1. init プロセスの起動
    - /etc/init.d に格納されているプロセスを起動する



## init プロセスとは

プロセスはメモリを利用して動くプログラムである。
一方で、**initプロセス** はシステム起動時において最初に起動される、他のプロセスを起動する役目を持ったプロセスを指す。

init プロセスは複数種類があるが、よく使われるのは systemd である。

| initプロセスの種類 | 説明 |
|:-|:-|
| SysVinit | 並列起動できずに起動するのに時間がかかる init プロセス |
| Upstart | サービスの起動準備が整ったらイベントを受け取り、並列にサービスを起動する |
| systemd | 細かい制御が可能で、必要なサービスのみ並列に高速に起動することができる |



## systemctl コマンド

systemd で制御しているサービスを管理するコマンド

`systemctl オプション サービス名` のように利用する。

| オプション | 説明 |
|:-|:-|
| start | サービスを起動 |
| stop | サービスを停止 |
| restart | サービスを再起動 |
| reload | サービスに新しい設定を読み込む |
| status | サービスの状態を確認する |
| enable | OS 起動時にサービスが起動されるようにする |
| disable | OS 起動時にサービスが起動しないようにする |
| daemon-reload | 新たにサービスを作成した場合に設定を読み込み直す |



## 設定ファイルを格納したディレクトリ

##### /usr/lib/systemd/system

主に各サービスの設定を記述したファイルを格納

##### /etc/systemd/system

主に `/usr/lib/systemd/system` に格納したファイルのリンクを格納

##### Unit とは

systemd が立ち上げるプログラムの単位


### 設定内容一覧

##### Unit セクション : 各ユニットの説明や、依存関係を設定

- **Description:** Unit の説明文
- **Requires:** この Unit が必要とする別の Unit
- **Before:** この Unit より後に起動すべき Unit

##### Service セクション : 実行する処理内容や作業ディレクトリなど詳細な設定

- **User:** 実行ユーザ
- **ExecStart:** サービスの起動コマンド
- **WorkingDirectory:** サービスが実行されるときのカレントディレクトリ

##### Install セクション : enable / disable 時の挙動の設定

- **WantedBy:** 動作モード



## おわりに

systemctl と systemd を使いこなして、自分好みの環境を作りましょう。
thisについて

# はじめに
jsでthisのことをよくわかっていなかったので、

# 試してみた
```.js
const movie = {
    name: 'コナン',
    kind: 'アニメ',
    genre: 'ミステリー',
    location: '日本',
    introduction() {
        console.log(`${name}}です`);
    }
}
```

コンソールでintroductionメソッドを呼び出すと以下のようにnameが表示されない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516005/fe19bd70-c35e-ab1c-caad-9a2d76d6f5fa.png)


thisを使って呼び出す
```.js
const movie = {
    name: 'コナン',
    kind: 'アニメ',
    genre: 'ミステリー',
    introduction() {
        console.log(`${this.name}です`);
    }
}
```

名前が表示された！
this.nameとすることでオブジェクトに入っている変数が使える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516005/06a96775-3399-a74b-6ead-7a0bac91c180.png)


thisの値は、thisを使っている関数がどのように呼ばれたかで決まる

```.js
// introdutionを別の変数に入れてみた
const movie2 = movie.introduction;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516005/99933071-347e-b573-4c3d-7707fbfd5adc.png)

何が入っているのかわからないので、ログを入れてみた
movieのthisにはオブジェクト
movie2のthisにはwindowが入っている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516005/1f0826b0-0f43-35d4-08ad-564c405149ec.png)

windowが何者なのか・・・？
windowというのはjavascriptに必ず存在しており、
あらゆるものがwindowに存在している
ということだけはわかったので今のところ深入りはしない
https://developer.mozilla.org/ja/docs/Web/API/Window

# まとめ
thisはどこで呼ばれるかどうかで入ってくる値が変わる
this.movieの場合はそのオブジェクトがthisになる
.xxxxとかの場合は、windowが入ってくる
mathematica で独立な積分を並列に計算したい: Do parallel Integrate on mathematica

# 並列な処理の命令: Parallel process order

`` ParallelTable``は``Table``と同様の処理を並列に行うとのこと．
例えば，4つの異なる積分を並列に評価させたいなら，以下のように書けば良い：

`` ParallelTable`` returns the same process as `` Table``, but with parallel. 
If we would like to do parallel integration independently, we should write the following order.

```
(* 
4成分配列を定義し，各成分に被積分関数を記述 
Define a list having four elements
*)
f = Range[4]
f[[1]] = x;
f[[2]] = Exp[x];
f[[3]] = Cos[x];
f[[4]] = 1;

Result = ParallelTable[
    Integrate[ f[[i]],x ],
{i,1,4}] (*i=1~4 の場合をそれぞれ並列に評価*)
```
この処理の結果は，以下のようになる：
The above process returns the following result:
```
{x^2/2,Exp[x],Sin[x],x}
```
この配列の2番目の結果を取り出したい場合は，
If one wants to take the second element of the result, write:
```
Result[[2]]
```
と書く．
Access-Control-Allow-Credentials: trueにしないとsessionをCookieに保存できない

卒研でWebアプリを開発しており、ログインセッションの実現をしようとしていたところ思いのほか躓いたので記事書くことにしました。

:::note warn
ここではExpressでのsession構築、Redis構築の話は一切行いません。予めご了承ください。
説明は致しませんが、この記事の最下部にて私が参考にしたURLを貼っております。
:::

## Cookieがセットされない…
[express-session](https://www.npmjs.com/package/express-session)というライブラリを使って、Redisにセッション情報を保存しつつログインセッションを実現しようと思い環境構築を行っていました。
いろんな方のブログや公式リファレンスを参考にして、いざやってみるとなぜかブラウザにCookieがセットされない。
ブラウザの検証ツールで確認してみると、**通信は正常**に行われており、**Set-Cookieもレスポンスヘッダーに存在**し、ますます路頭に迷う羽目となっておりました。

## ざっくり環境
- **Front**: SvelteKit & Svelte
    - **Library**: Axios
- **Back**: Node.js（Express）
- **DBMS**: Redis
- **Middle**: Docker・Docker Compose・Ubuntu（limaというアプリで仮装環境構築）


## 結論
```javascript:api/index.js
import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'http://localhost:3000',
  headers: {
    'Content-Type': 'application/json',
    'X-Request_With': 'XMLHttpRequest',
  },
  responseType: 'json',
  withCredentials: true, // AjaxでCookieを使用するのに必須
});
```
フロント側では、Ajaxを行う際にAxiosを使用。
今まで`withCredentials`というオプションはつけていなかったのですが、**AjaxでCookieを使用する場合は必要みたい**ですので、付け加えます。
...が、フロント側で`withCredentials`をつけても、サーバー側で許可してない場合、**CORS Policy違反**となりフロントとサーバーのやりとりが拒絶されます。
なので、サーバー側で**CORS Policy**の設定を行います

```diff_javascript:src/index.ts
// 上記の方で色々importやインスタンス化を行っているが結構あるため省略
app.set('trust proxy', 1);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
// express-sessionというライブラリでsessionを実現
// そのためのconfig
  expressSession({
    secret: 's3Cur3',
    name: 'session',
    resave: false,
    saveUninitialized: true,
    store,
  })
);
// CORS系設定
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', ['http://localhost:5000']);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, x-request_with, XMLHttpRequest')
  // ↓がwithCredentialsを許可する設定
  res.header('Access-Control-Allow-Credentials', 'true')
  next();
});
```

上記では、`withCredentials`について、「AjaxでCookieを使用する場合は必要」と記述したのですが、正確には以下のようです
> Access-Control-Allow-Credentials レスポンスヘッダーは、リクエストの資格情報モード (Request.credentials) が include である場合に、レスポンスをフロントエンドの JavaScript コードに公開するかどうかをブラウザーに指示します。
証明書の資格情報モード (Request.credentials) が include である場合、レスポンスがフロントエンドの JavaScript コードに公開されるのは Access-Control-Allow-Credentials の値が true である場合のみです。
資格情報は **Cookie、認証ヘッダー、または TLS クライアント証明書**です。
>
> *Access-Control-Allow-Credentials - HTTP - MDN Web Docs*

AjaxはJavaScriptを用いて非同期的に通信を行うもので、その際に**Cookie、認証ヘッダー、TLSクライアント証明書**を使用するにはwithCredentialsのCORSをtrueにする必要があるみたいです。


### 参考先
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

https://qiita.com/yuta-katayama-23/items/4ea30b13e8002853402b

https://qiita.com/wind-up-bird/items/f2d41d08e86789322c71

https://kazuhira-r.hatenablog.com/entry/2021/12/29/023347

https://www.npmjs.com/package/express-session

https://www.npmjs.com/package/connect-redis
【いもす法の練習問題】練習問題 その 2 (paizaランク B 相当)

#### 問題

https://paiza.jp/works/mondai/prefix_sum_problems_advanced/prefix_sum_problems_advanced__imos_practice_step2?language_uid=vb

#### 解答

入場者を計算する方法で悩みました。
しかし、今までの問題でしていた出入り口に置いていた数字の`1`や`-1`を入場者数に変えるだけでした。はあ、すっきり！！:punch::v_tone2::cow:

```php
<?php
    list($q, $m) = explode(" ", trim(fgets(STDIN)));

    // 配列の範囲が与えられなかったので、取りうる可能性がある値の範囲分初期化
    $a = array_fill(0, 2001, 0);
    
    for($i = 0; $i < $q; $i++) {
        list($left, $right, $p) = explode(" ", trim(fgets(STDIN)));
        
        // 入場者数を更新
        $a[$left] += $p;
        
        // 退場者数を更新（退場自国の次の時間から人数が減る） 
        if($right + 1 <= 2000) {
            $a[$right+1] -= $p;
        }
    }

    // indexが0の時を無視する
    // 0の時には前の要素が存在しないから
    for($i = 1; $i <= 2000; $i++) {
        $a[$i] += $a[$i - 1];
    }
    
    if($m > max($a)) {
        echo "Yes";
    } else {
        echo "No";
    }
    
?>
```
Javaで「拡張for文(for-each文)を使って要素を順に取得する」の動作を確認してみた

# 概要

Javaで「拡張for文(for-each文)を使って要素を順に取得する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/for/index8.html

# 実装

以下のファイルを作成しました。
```JSample8_1.java
class JSample8_1{
  public static void main(String[] args){
    String pref[] = {"北海道", "東京都", "神奈川県"};
    
    for (String str: pref){
      System.out.println(str);
    }
  }
}
```

以下のコマンドを実行しました。

```
$ javac JSample8_1.java 
$ java JSample8_1 
北海道
東京都
神奈川県
```

# まとめ

何かの役に立てばと。
僕なりの Git 備忘録



# fetch

リモートのコピーをローカルにダウンロードするコマンド、ローカルのリモート追跡ブランチにコピーしてくるだけでワーキングツリーには影響しない

1. リモートのコピーちょうだいー
2. ローカルとの差分を確認し、リモートリポジトリが変更や新規ブランチをリモート追跡ブランチにあげる
3. リモート追跡ブランチが更新される



# merge

```bash
$ git checkout aaa
$ git merge bbb
```

ローカルでは今いるブランチにほかのブランチを合体させる



```bash
$ git fetch
$ git merge origin/aaa
```

リモートリポジトリのブランチをマージする場合、先にリモートの状態をリモート追跡ブランチにコピーしてからマージする



# rebase

```bash
$ git checkout master
$ git rebase aaa
```

マージと同じ、今いるブランチに他のブランチの変更を取り込むものだがちょっと違う。マージは合体で一つになった！という感じだが、rebaseは上にコミットを積むというイメージ。だから、今いるブランチの未来ができているという感じで、master headとaaa headは異なる。



# pull

```bash
$ git pull
=
$ git fetch
$ git merge
```

一回でまとめてやってくれるから便利よね



```bash
$ git pull --rebase
=
$ git fetch
$ git rebase
```

まとめてやるののrebaseバージョン

--rebaseオプション付ける

メリット：マージコミットが残らないから履歴がきれいになる 



# reset

`git reset --hard <ブランチ名>` ... commitもaddも吹き飛ばす

`git reset --soft <ブランチ名>` ... commit吹き飛ばしてadd後(ステージングにある状態)まで戻す

`(HEAD, master)` ... HEADが名のないブランチを指しており、それとmasterっていう２つのブランチがあるよ→下の状況にするには `git checkout master `を叩く

`(HEAD → master)` ... HEADがmasterブランチを指している＝HEADとmasterが同じ



全ファイル取り消し

```bash
$ git reset HEAD
```

特定ファイル取り消し

```bash
$ git reset HEAD file_name
```





# branch

自分なりの命名方法

- f/xxxxx 機能追加/変更
- ref/xxxxx リファクタリング
- fix/xxxxx バグ修正
- hotfix/xxxxx  masterから派生させる緊急性の高い修正



# stash

メッセージを付ける

```bash
$ git stash save "message"
```

特定のファイルのみstashする

```bash
$ git stash push -m "メッセージ" ファイルパス
```



# merge commit in local

リモートリポジトリがない時に履歴を残したい時に使う

```bash
$ git merge --no-ff <targetBranch>
```



# commit

```bash
$ git commit -m "message"
$ git commit -m "message" -m "detail message"
```



## empty commit

> https://qiita.com/miriwo/items/dbf82ca73723026d96f2

```bash
$ git commit --allow-empty -m ""
```



### modify commit message

1つ前

```bash
$ git commit --amend -m ""
```

2つ以上前

```bash
$ git rebase -i HEAD~3
# 変更したいcommitをe(edit)に
$ git commit --amend -m ""
$ git rebase --continue
```

最初のコミットメッセージが対処の場合

```bash
$ git ch <最初のコミットID>
$ git commit --amend
$ git rebase --onto HEAD <新しくできた最初のコミットID> master
```



# checkout

作業ツリーの特定のファイルを戻す

```bash
$ git checkout HEAD <fileName>
```

作業ツリー全体を戻す

```bash
$ git checkout HEAD .
```



# rm

```bash
$ git rm <dirName>
$ git rm -r <dirName>
$ git rm -r --cached <dirName>
```



# diff 

```bash
$ git diff <branchName> --name-only
```



# remote

> https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%81%A7%E3%81%AE%E4%BD%9C%E6%A5%AD

```bash
$ git remote -v
```

```bash
$ git remote add origin <remoteUrl>
```

```bash
$ git remote set-url origin <newRemoteUrl>
```

```bash
$ git remote <shortname> <url>
```



# SSH connect

```bash
# 鍵作成
$ ssh-keygen -t rsa -f github_rsa

# config作成
$ vim config
>>
Host github
  HostName  github.com
  User  git
  Port  22
  IdentityFile ~/.ssh/github_rsa

ServerAliveInterval 15
<<

# GitHubやGitLabに公開鍵を設置

# 接続確認
$ ssh -T github
```
Amazon Bedrockを活用した社内検索システムの事例

## はじめに
本記事では、AWSおよび生成AI初学者が、Amazon Bedrockを活用した社内検索システムの事例を紹介します。

## なぜ書いたか
個人的にAWSの生成AI技術で社内検索システムをどう実現するのか気になっていたため、調査しました。

## 対象読者
- AWSの生成AI技術で何ができるのか知りたい方
- 生成AIを利用した社内検索システムの事例を知りたい方

## Amazon Bedrockとは
Amazonが提供するAIの基盤モデル（Fundation models、FM）を利用可能なサービスです。様々なモデルの中から、自分たちが利用したいケースに応じたものを選択し利用できます。

（ご参考）

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/what-is-bedrock.html

https://aws.amazon.com/jp/bedrock/

https://aws.amazon.com/jp/what-is/foundation-models/

## Amazon Bedrockを利用した社内検索システムの事例紹介
- 高度な質問検索機能の早期開発
まずご紹介するのは、Amazon BedrockとAmazon OpenSearch Serviceという機能を活用して質問検索機能を開発した事例です。
本事例では、既に導入済のOpenSearchの検索システムに、クエリと文書の意味的な類似性に基づく検索を可能とするベクトル検索技術を取り入れることで、利用者の検索体験の向上を目指しています。
また、1ヶ月という短い期間で検証を行っています。

    （詳細は以下をご参照ください）

https://aws.amazon.com/jp/blogs/news/genai-case-study-connehito/

（ご参考）

※ベクトル検索とは
与えられたデータ（テキスト、画像など）を数値化し、その中から類似するデータを見つける技術です。

https://aws.amazon.com/jp/blogs/aws/vector-search-for-amazon-documentdb-with-mongodb-compatibility-is-now-generally-available/

- 社内業務をアシストするAI環境の構築
続いてご紹介するのは、Amazon BedrockとAmazon Kendraという機能を活用してチャットボットを構築した事例です。
構築したチャットボットは、ユーザーからの質問に対して、社内に点在する複数のドキュメントをふまえて回答を作成するものです。
本事例では、生成AIと社内データの連携により、社内問い合わせに対して70％超のヘルプデスク回答満足度を実現しています。

    （詳細は以下をご参照ください）

https://classmethod.jp/news/20231003-gen-ai-helpdesk/

## 事例で活用されていたサービスについて
- Amazon OpenSearch Service
コミュニティ主導・Apache 2.0 ライセンスのオープンソース検索・分析スイートです。
データストア、検索エンジンの OpenSearch、可視化、UIツールの OpenSearch Dashboardsから構成されています。
本サービスを活用することで、例えば社内データの中から最適な製品、サービス、ドキュメント、回答を素早く発見する全文検索が可能になります。

    （ご参考）

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_Amazon-OpenSearch-Service-Basic_0131_v1.pdf

- Amazon Kendra
こちらも全文検索などが可能な機能です。AWS内外のデータソースのドキュメントを取り込むことができます。他にも、ドキュメントの権限管理なども可能です。

    （ご参考）

https://aws.amazon.com/jp/kendra/

https://aws.amazon.com/jp/kendra/features/

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2024_AWS-Language-AI-Services_0425_v1.pdf

## おわりに
今回はAmazon Bedrockを使用した社内検索システムの事例を紹介しました。

社内検索システムの導入を検討中の皆様の参考になれば幸いです。

個人的な感想として、検索に利用できるサービスが複数あると知れたため、ケースに応じて最適な構成を考えられるようになりたいと思います。
誰でも簡単に使える！シンプルなQRコードジェネレーターを作ってみた

今回は、私が個人的な用途で素早く作成したQRコードジェネレーターを紹介します。このツールは非常にシンプルで、誰でも自分のプロジェクトに簡単に統合することができます。また、最終結果を見ることができるオンラインデモも用意しています。コードの各部分を解説しながら、どのように動作するかを詳しく説明します。

[QR] (https://qr.tehito.com)

QRコードジェネレーターのスクリーンショットです。テキストやURLからQRコードを簡単に生成できるシンプルなツールの画面です
![Screenshot 735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801337/67f2bb04-adc8-99de-194a-174d7b31dd6f.png)


## QRコードジェネレーターの紹介

このQRコードジェネレーターは、ユーザーが入力したテキストやURLからQRコードを生成します。生成されたQRコードは、その場で表示され、ダウンロードも可能です。

### 必要なHTMLタグ

まず、以下のHTMLタグを使用します。必要な部分だけを抜粋して説明します。

#### ユーザー入力セクション

```
<div class="user-input-section">
  <section class="user-input">
    <input type="text" placeholder="何かを入力してください..." name="input_text" id="input_text" autocomplete="off">
    <button class="button" type="submit">生成する<i class="fa-solid fa-rotate"></i></button>
  </section>
</div> 
```

#### QRコード表示エリア

```
<div class="qr-code-container">
  <div class="qr-code"></div>
</div>
```

### コードの解説

まず、ボタンとQRコード表示エリアを取得します。

```
let btn = document.querySelector(".button");
let qr_code_element = document.querySelector(".qr-code");
```

次に、ボタンがクリックされたときの処理を定義します。

```
btn.addEventListener("click", () => {
  let user_input = document.querySelector("#input_text");
  if (user_input.value != "") {
    if (qr_code_element.childElementCount == 0) {
      generate(user_input);
    } else {
      qr_code_element.innerHTML = "";
      generate(user_input);
    }
  } else {
    console.log("not valid input");
    qr_code_element.style = "display: none";
  }
});
```
ユーザーの入力が空でない場合、QRコードを生成します。既にQRコードが生成されている場合は、表示エリアをクリアしてから再生成します。

### QRコード生成の関数

ここで、QRコードを生成する関数を説明します。この関数はQRコードを生成し、ダウンロード用のボタンを作成します。

```
function generate(user_input) {
  qr_code_element.style = "";

  var qrcode = new QRCode(qr_code_element, {
    text: `${user_input.value}`,
    width: 180, //128
    height: 180,
    colorDark: "#000000",
    colorLight: "#ffffff",
    correctLevel: QRCode.CorrectLevel.H
  });

  let download = document.createElement("button");
  qr_code_element.appendChild(download);

  let download_link = document.createElement("a");
  download_link.setAttribute("download", "qr_code.png");
  download_link.innerHTML = `Download <i class="fa-solid fa-download"></i>`;

  download.appendChild(download_link);

  let qr_code_img = document.querySelector(".qr-code img");
  let qr_code_canvas = document.querySelector("canvas");

  if (qr_code_img.getAttribute("src") == null) {
    setTimeout(() => {
      download_link.setAttribute("href", `${qr_code_canvas.toDataURL()}`);
    }, 300);
  } else {
    setTimeout(() => {
      download_link.setAttribute("href", `${qr_code_img.getAttribute("src")}`);
    }, 300);
  }
}
```

この関数のポイントは、`QRCode`ライブラリを使用してQRコードを生成するところです。このライブラリがQRコードのデータエンコード、パターン生成、エラー修正などの複雑な処理をすべて行います。私たちのスクリプトは、そのライブラリを呼び出し、適切なパラメータを渡しているだけです。

以上が、私が作成したQRコードジェネレーターのコードとその解説です。このツールが皆さんのお役に立てれば幸いです。興味がある方は、ぜひご自身のプロジェクトでも試してみてください！

ご質問やフィードバックがあれば、ぜひコメントでお知らせください。

それでは、楽しいコーディングライフを！
謎のエラー　curl: (56) Recv failure: Connection reset by peer

# docker-compose.yml

version: "3"
services:
  python:
    container_name: backend_dev
    build: ./backend
    ports:
      - "5000:5000"
    volumes:
      - ./backend:/var/www/backend
      - ../backend/logs:/var/www/backend/logs
      - ./backend/output_txt_files://backend/output_txt_files
      - /home/sudouser/project/ALBT/backend/input_audio_files:/input_audio_files
      - /var/run/docker.sock:/var/run/docker.sock



# dockerfile

FROM python:3.11.0-slim
WORKDIR /var/www/backend
RUN apt update && \
    apt -y upgrade &&\
    apt install -y gcc
COPY requirements.txt .
RUN pip install --upgrade pip && \
    pip install -r requirements.txt \
    pip install requests
COPY . .
CMD ["python", "`app.py"]


実行したら、以下のエラーが出ました...
swiftリテラル一覧

Xcode（正確にはSwift）では、以下のような特殊なリテラルが利用可能です：

#file：現在のソースファイルの名前を表す文字列リテラルです。Swift 5.3以降では、完全なファイルパスを返しますが、これはセキュリティ上の問題を引き起こす可能性があるため、非推奨となりました。

#filePath：現在のソースファイルの完全なファイルパスを表す文字列リテラルです。Swift 5.3以降で導入されました。

#line：現在のソースコードの行番号を表す整数リテラルです。

#column：現在のソースコードの列番号を表す整数リテラルです。

#function：現在の関数名を表す文字列リテラルです。

#dsohandle：現在のダイナミック共有オブジェクト（DSO）のハンドルを表すリテラルです。これは、主にライブラリのコードがどのバイナリにリンクされているかを特定するために使用されます。

これらのリテラルは、主にデバッグ情報を提供するために使用されます。たとえば、テストケースで失敗した場所を特定するために使用することができます。

参考：https://developer.apple.com/documentation/swift/initialization-with-literals
保守の現場について

#### はじめに
入社して3年目の小林です。
入社してから保守業務をやっています。
保守という仕事は性に合っている気がするので、
自分的に楽しい事、大変な事とか書いてみます。
保守業務を経験した事がない方へすこしでも興味を持ってもらえたらと思います。

## 保守業務について
一口に「保守」と言っても、会社によって指すものは変わってきます。
自分自身の業務は、プログラムを一切書かない保守業務です。
保守業務にはプログラムを書いたり、設計とか仕様決めるとか、自社開発でなければ他社との営業的なお仕事もあるみたいです。

##  保守業務で大変な事
お客様からのご質問に対してヒヤリングする事です。
対応するお客様の全員がIT関係に詳しい訳ではありません。
その為どんな作業をしてこうなったのか、最終的にどのようになっていればいいのかなどヒヤリングする必要があります。
ヒヤリングする上で特に大変な事は原因の切り分けだと思います。
伝えられている内容だけで判断すると解決までに時間を要する事が多々あります。
目の前の事だけをやっていても暫定対応にしかなりません。

## 保守業務のやりがい
「保守のおかげで昨日と同じ事ができる」
当たり前の事ができ、ストレスなく業務出来ている事を確認できた時です。

## まとめ
まだまだわからないことだらけで勉強の日々です。
今後は業務に少しでも役に立つ資格を勉強しようと思っています。

次回の記事にはシステムの不具合などが発生した場合の対応についてお話しようと思います。

以上、小林でした。
PostgreSQLのINTERVAL型を、ISO 8601形式（`P2Y3M`みたいなの）に変換する

# やりたいこと
「2年3ヶ月」を、ISO 8601の`P2Y3M`のような形式にしたい。

# 結論
```sql
postgres=# select to_char(interval '2 year 3 month', 'PYY"Y"MM"M"');
 to_char 
---------
 P02Y03M
(1 行)
```

Java側ではこうします。 `02`や`03`になってても大丈夫みたいです。

```java
java.sql.ResultSet rs = ...;
String value = rs.getString("列名");  // "P02Y03M"のような文字列
java.time.Period period = Period.parse(value);
```
WSL上でのROS2開発環境構築メモ

### wslの設定
https://learn.microsoft.com/ja-jp/windows/wsl/install
失敗した時
    wsl --unresister Ubuntu-22.04
    wsl --uninstall Ubuntu-22.04
    wsl --install -d Ubuntu-22.04
### vscode
### cuda
https://developer.nvidia.com/cuda-12-1-0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=WSL-Ubuntu&target_version=2.0&target_type=deb_local
### ros2
https://docs.ros.org/en/iron/Installation/Ubuntu-Install-Debians.html
### desktop
https://qiita.com/Akaaku/items/31428b3478a1b58196a6

https://zenn.dev/melos/articles/56cecf17f24372

https://qiita.com/bluesDD/items/eaf14408d635ffd55a18

https://learn.microsoft.com/ja-jp/windows/wsl/systemd?source=recommendations

https://qiita.com/shigeokamoto/items/ca2211567771cf40a90d
1 << 31と2 ** 31は同じ値ですか?いいえ違います。JavaScriptではね

# TL;DR;
JavaScriptにおいて乗算のかわりにbit shiftをつかってもは同じにならないことがある
これはJavaScriptの数値が64bit doubleであることに起因している
計算するときにbit shiftのことを理解していないのであれば、これを使用してはいけない


# bit shiftとか計算とかのおさらい
計算機では内部的には電気信号を操作して、数値や計算を実装しています
回路の話とかCPUだとかの話とかはおいておいて内部的に2進数で処理しています
これを操作するためにbit shiftという演算があります
```
0b00000001 << 1
2 (0b00000010)
0b00000001 << 2
4 (0b00000100)
```
となります

# bit shiftではどこまで保証されているのか、答は31bit
bit shiftはだいたい2の指数計算と一緒です
ただしそれは桁が保証されている範囲となります
計算の結果は以下のとおりとなります
```
2 ** 0 -> 1
2 ** 1 -> 2
2 ** 2 -> 4
2 ** 3 -> 8
2 ** 4 -> 16
```
これくらいの計算であればbit shiftでも同様にできます
```
1 << 0 -> 1
1 << 1 -> 2
1 << 2 -> 4
1 << 3 -> 8
1 << 4 -> 16
```
よくわからない人はたとえば
0b0001を左に3つ移動したら0b1000になりますが、これは8です、というのを理解しておいてください

そしてこれはどこまで確実でしょうか?
答えは31bit分までです
```
2 ** 30
> 1073741824
1 << 30
> 1073741824
2 ** 31
> 2147483648
1 << 31
> -2147483648 
```
bit shift演算では32bit(符号あり)整数として処理されます
JavaScriptのNumberの精度は仮数部で52bitあるのもあって、乗算では普通に計算してくれます
おそらくは仮数部分が52bitなので、bit shift演算が有効なのは32bitまでで64bitではないのだな、と思いました(実際、52bitで演算するのも変な話?ですし、64bitだと52bit以降はよくわからない結果になることはわかる)
32bitでbit shiftを扱うのがIEEE 754の規定なのかどうかは知らないので、ご存知の方はおしえてください


# じゃあ32桁分shiftしたらどうなるの?
```
1 << 31
> -2147483648
1 << 32
> 1
```
一見rotateしてますが、以下でおかしなことがおこります
```
2 << 30
> -2147483648
2 << 31
> 0
2 << 32
> 2
2 << 33
> 4
```
おい、ちょっと待て。
普通にbit rotateしてたら2 << 31は0ではなく1なのではないか?
つまりbit rotateしてるのではなく、31までは普通にbit shiftしてあふれた分はおとしてるけど、32のときはbit shift 0と同様にあつかっているのではないか?

# どうしてもbit shiftしたい人むけ
bigintつかってください
```
2n << 31n
4294967296n
2n << 32n
8589934592n
```

# 乗算する分には大丈夫だよね?
Number.MAX_SAFE_INTEGER以下の数値ならね
ちなみにこれは(2^53 - 1)です
64bit doubleの仮数の限界です
これを越えて正しく計算したい場合はBigintを使用してください
```
≈
Number.MAX_SAFE_INTEGER
9007199254740991

2 ** 53
9007199254740992
2n ** 53n
9007199254740992n
2 ** 54
18014398509481984
2n ** 54n
18014398509481984n
2 ** 55
36028797018963970
2n ** 55n
36028797018963968n //ずれた
```
# まとめ
Numberを安易にbit shiftしてはいけない
bit shiftが32bitで行われていることや32桁以上のshiftが循環するのはchromeだけの仕様かもしれないので、ちがっていたらなんか書いてください
(調べるのがそろそろ苦痛なので、<del>やり過ぎると上司におこられるので</del>)

# 感想
なんでこんな記事が誕生したかというとBigEndienなUint8ArrayをNumberに変換しようとしてbit shiftつかっておしゃれなコード書こうとしたら数値がおかしくなったのが原因です
ことと次第を調べていたら、こんなことになっていました
linux よく使うfindコマンド

一番よく使うfindコマンド
```find ディレクトリ -type f -exec rm -f {} \;```　（古い人）
以下の方が良いみたい
```find ディレクトリ -type f -exec rm -f {} +```　（推奨）
指定したディレクトリ配下のファイルタイプのファイルを削除する
事前に対象ファイルをログするなら
```find ディレクトリ -type f -ls```
AppSheetを使って簡単な業務報告アプリを作成！

こんにちは、
地方のスーパーで製造部門の教育や指導をしているkuwaharaです。

最近、同じ教育をしている部門の先輩と世間話をしている中、
前回の記事や前々回の記事について話すことがありました。
すると、意外にも反応が良く褒めていただき、**自分も学んでみたいけど、学ぶ機会とか無いんだよね**と返事が返ってきました。

さて、今回は私の仕事の中でちょっと面倒な報告作業について業務改善出来ないか挑戦してみました。
![Brown Work From Home Instagram Post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/6d40d869-160b-3bd4-e141-b3d18735cd92.png)

## 現状の報告作業
店舗
写真撮影⇒PCに取り込み⇒Excelに落とすかそのまま送付

確認者
メールから画像をダウンロード⇒Excelやメールに添付⇒店舗ごとまとめる⇒上司へ報告

## アプリで報告作業

店舗
スマホやタブレットのアプリから写真撮影⇒アプリで項目入力

確認者
アプリで確認⇒リンクを上司へ報告

〇メリット
手軽に写真を確認することが出来る
確認者はリンクやアプリを開き確認
現場とのメールのやり取りが不要
他店舗の状況確認が簡単
　
〇デメリット
報告内容が変わるとアプリの作り直し
初回マニュアルは必要

大きな業務改善では無いですが、細かなPC作業が無くなります。
今まで大体15分以上かかっていた作業がアプリ登録していれば5分ほどで終わります。

## AppSheetの紹介と使用方法
Appsheet ⇒ https://about.appsheet.com/home/

:::note info

AppSheetは、Googleが提供するノーコード開発プラットフォームです。プログラミング知識がなくても、スプレッドシートやクラウドストレージのデータを活用して、モバイルアプリやウェブアプリを簡単に作成できます。豊富なテンプレートと直感的なインターフェースにより、ビジネスプロセスの自動化やデータの可視化が迅速に行えます。リアルタイムでのデータ同期や多様なデバイス対応も特徴で、効率的な業務運営をサポートします。

:::

## アプリ作成手順
①Appsheetにログインします。
GoogleのアカウントでログインするとGoogleスプレッドシートも使用出来るので良いと思います。(個人だと使用出来る範囲は限られます。)
②+create⇒APP⇒Start with existing dataで作成します。
アプリ名とカテゴリー(Field Service)を設定し、「Next step:choose your data」をクリックします。

![課題用40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/a859ea16-d74d-5449-c842-d6a812f0cc86.jpeg)
![課題用48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/fc7b80ed-b043-e479-a357-15b255314e14.jpeg)


③同時に報告項目をGoogleスプレッドシートに入力しておきます。
![課題用47.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/2822d655-15f5-6da8-a452-caf6c32ed257.jpeg)

④Googleドライブ上のファイル選択画面から、用意したスプレッドシートを選択します。

⑤仮のアプリが出来ました！右側に携帯の画面が出ていると思います。
![課題用42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/bc7fcd1d-d098-96c1-7a81-ca8f0099a600.jpeg)

:::note warn
今回は、撮った写真を報告したいので、写真のTYPEをIMAGEにします。
報告タイミングの時間を表示するように日付のTYPEをDATEにしています。
報告内容を選択式にしたい為、左メニューのDATE⇒Columns⇒依頼内容の左の鉛筆をクリック⇒TYPEをEnum1listに⇒Valuesを選択してもらいたい内容にします。
:::

![課題用49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/60230d0e-b328-e211-5f5f-0b9077974e45.jpeg)

UXのLocalizeから英語表示項目を手動で日本語に直すことが出来ます。
![課題用50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/cb481613-0374-fe82-b052-ca404e38daaa.jpeg)

## 完成したもの

https://x.com/216JLYNEUf3696/status/1798612693022363686

Googleスプレッドシートで内容の確認、フィルターをかけて調べることも出来ます。
![課題用51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/705b5749-c6d4-5a52-eca5-48f708994b5e.jpeg)

アプリ、ブラウザ版でもフィルターをかけて調べることも出来ます。
![課題用52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763115/694a4612-96db-8916-be2e-d23b4af32dd3.jpeg)

## 出来たものを上司や同僚に試してもらいました

上司　Nマネージャー
デジタルのことに挑戦していることは知ってもらっていましたが、
実際に作成したものを見せてみると...「早く完成させてよ！」と言ってくれました。店舗にはipadがあるので、それで店舗の人が簡単に使用出来るといいね！とコメントもいただきました。

同僚　
スマートフォンの画面で見ると分かりやすいね！
所々英語になっているので、日本語に！
店舗の年齢層は高いので、マニュアルも必要だね！

マニュアルや、所々の項目の修正はしていき、実際に現場で使用してみようと思います。

店舗はタブレット端末やスマートフォンの整備はされるようにはなってきていますが、実際の業務には少ししか活用されていません。
私たちと店舗の業務を削減するために中身を詰めていき、実際に店舗で活用出来るものを作っていきます！

今回は以上になります。
ご覧いただきありがとうございました。
NextjsでCookieを設定&ロードをする


# なぜライブラリを使わないといけないのか?

NextjsはSSR(サーバーサイドレンダリング)ベースなので、基本的にサーバーでHTMLを生成してからそれをブラウザに転送します。そういった使用上、cookieはもちろんwindowやdocumentオブジェクトも通常では使用できません。

Nextjsのレンダリングについて
[Rendering - nextjs.org](https://nextjs.org/docs/pages/building-your-application/rendering)

# 今回使用するライブラリ

https://www.npmjs.com/package/cookies-next

## 基本的な使い方
今回はTypescript版のNextjsを使います  
```tsx
import { setCookie } from 'cookies-next';

setCookie('key', 'value', options);
```

setCookieという関数でセット、getCookieで取得します。optionsはCookieの使用可能時間などを設定します。

## 実装方法

これだけだとエラーになってしまうのでいろいろ追加して実装してみました。

```tsx
import { setCookie,getCookie } from 'cookies-next';
import { useEffect, useState } from "react";

export default function Cookie () {
    const [loginedData, setLoginedData] = useState<string>()
    useEffect(() => {
      // セット
      setCookie('key', 'value', {maxAge: 30 * 24 * 60 * 60});
      //　取得
      setLoginedData(getCookie('userids'));
  }, [])
  return (
    <>
      <p>{loginedData}</p>
    </>
  )
}
```

こんな感じで開発者コンソールでも見れます。
![スクリーンショット 2024-06-06 161442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081812/73338053-ffb6-c739-3512-d123c45ed700.png)

以上でーす。

# まとめ
こんな感じでツールを使わないとCookieが取れないのはNextjsのデメリットの一つですね💦

あとそのほかのSNSもよろしく(宣伝)

https://nknighta.github.io/
CUIでの基本的なCRUD操作

## 1. ファイルとディレクトリの作成（Create）

### ファイルの作成

新しいファイルを作成するには、`touch` コマンドを使用します。以下は、`example.txt` という名前のファイルを作成する例です。

```sh
touch example.txt
```

### ディレクトリの作成

新しいディレクトリを作成するには、`mkdir` コマンドを使用します。以下は、`example_dir` という名前のディレクトリを作成する例です。

```sh
mkdir example_dir
```

## 2. ファイルとディレクトリの読み取り（Read）

### ファイルの内容を表示

ファイルの内容を表示するには、`cat` コマンドを使用します。以下は、`example.txt` の内容を表示する例です。

```sh
cat example.txt
```

より詳細にファイルの内容を確認するには、`less` コマンドも便利です。

```sh
less example.txt
```

### ディレクトリの内容を表示

ディレクトリの内容を表示するには、`ls` コマンドを使用します。以下は、現在のディレクトリの内容を表示する例です。

```sh
ls
```

詳細な情報を表示するには、`-l` オプションを使用します。

```sh
ls -l
```

### ディレクトリの移動

ディレクトリを移動するには、`cd` コマンドを使用します。以下は、`example_dir` というディレクトリに移動する例です。

```sh
cd example_dir
```

上のディレクトリに戻るには、`cd ..` を使用します。

```sh
cd ..
```

## 3. ファイルの更新（Update）

### ファイルへの書き込み

既存のファイルにテキストを追加するには、`echo` コマンドとリダイレクトを使用します。以下は、`example.txt` にテキストを追加する例です。

```sh
echo "追加するテキスト" >> example.txt
```

### ファイルの名前変更または移動

ファイルの名前を変更するには、`mv` コマンドを使用します。以下は、`example.txt` を `new_example.txt` に名前を変更する例です。

```sh
mv example.txt new_example.txt
```

ディレクトリを移動する場合も同じコマンドを使用します。以下は、`example_dir` を `new_example_dir` に名前を変更する例です。

```sh
mv example_dir new_example_dir
```

## 4. ファイルとディレクトリの削除（Delete）

### ファイルの削除

ファイルを削除するには、`rm` コマンドを使用します。以下は、`new_example.txt` を削除する例です。

```sh
rm new_example.txt
```

### ディレクトリの削除

空のディレクトリを削除するには、`rmdir` コマンドを使用します。以下は、`new_example_dir` を削除する例です。

```sh
rmdir new_example_dir
```

空でないディレクトリを削除するには、`rm -r` コマンドを使用します。以下は、`example_dir` を削除する例です。

```sh
rm -r example_dir
```

## 例: 一連のCRUD操作

ここでは、一連のCRUD操作を通じて具体的な例を示します。

### 1. ファイルとディレクトリの作成

まず、新しいファイルとディレクトリを作成します。

```sh
touch myfile.txt
mkdir mydir
```

### 2. ファイルの内容を読み取り

次に、ファイルにテキストを書き込み、その内容を読み取ります。

```sh
echo "Hello, World!" > myfile.txt
cat myfile.txt
```

### 3. ファイルの更新

ファイルに追加のテキストを書き込み、その内容を再度読み取ります。

```sh
echo "This is additional text." >> myfile.txt
cat myfile.txt
```

### 4. ファイルとディレクトリの削除

最後に、ファイルとディレクトリを削除します。

```sh
rm myfile.txt
rmdir mydir
```

## まとめ

以下にまとめた基本的なCUI操作コマンドを使いこなすことで、ターミナル上でファイルやディレクトリを効率的に管理できます。

- **作成**:
    - ファイル: `touch filename.txt`
    - ディレクトリ: `mkdir dirname`
- **読み取り**:
    - ファイル内容表示: `cat filename.txt`
    - ディレクトリ内容表示: `ls`
- **更新**:
    - ファイルへの書き込み: `echo "text" >> filename.txt`
    - ファイル/ディレクトリの名前変更/移動: `mv oldname newname`
- **削除**:
    - ファイル削除: `rm filename.txt`
    - ディレクトリ削除: `rmdir emptydir` または `rm -r nonemptydir`
- **ディレクトリ移動**:
    - ディレクトリに移動: `cd dirname`
    - 上のディレクトリに戻る: `cd ..`
Flutterでよく使うテンプレ（View関係）

# 右上のDEBUGを消す
```dart
MaterialApp(
      debugShowCheckedModeBanner: false,
      ...
```

# AppBarの設定

```dart
 AppBar(
    backgroundColor: Color.fromARGB(246, 228, 228, 228), //背景色
    elevation: 0, //影
    leading: IconButton(onPressed: (){}, icon: const Icon(Icons.menu)),
),
```

# 全体の背景色
```dart
Scaffold(
      backgroundColor: const Color.fromARGB(246, 228, 228, 228),
      ...
```

# FloatingActionButtonの設定
```dart
floatingActionButton: FloatingActionButton(
    onPressed: (){},
    backgroundColor: Colors.white, //背景色
    child: const Icon(Icons.add, color: Colors.black,), 
),
```

# ページ遷移
```dart
Navigator.push(context, MaterialPageRoute(builder: (context)=> NewPage()));
```

# riverpod関係

main.dart
```dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shelf/view/home_page.dart';

void main() {
  runApp(
    ProviderScope(child: MyApp())
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: HomePage(), //最初に表示されるページ
    );
  }
}

```


```dart
final hogesProvider = StateProvider<List<hoge>>((ref)=> []);
```

```dart
class Hoge extends StateNotifier{
  Ref ref;

  Hoge({required this.ref}) : super(null);

}
```
※自分はよくこの形で使ってるけど、実際どういう使い方が多いのだろうか？
一人で始めるアジャイル開発

# 一人で始めるアジャイル開発

## 見える化する

- アジャイル開発はインクリメンタル（少しずつ）かつイテレーティブ（反復的）に作り進める
- 現在どんな問題を抱えているのか、またどのような状況にいるのかわからなければ、次の一歩を打てない
- まずは、タスクと状況を見える化する
- 朝会で日常を見える化し、日々発生する課題と向き合う
- スプリントの終わりにはそのスプリントにやったことを振り返る

## タスクの見える化（スプリントバックログ、プロダクトバックログ）

### スプリントバックログ（スプリント期間内のタスクリスト）を作成する

- やるべきタスクをすべて洗い出し、優先順位をつける、同じ順位は付けない
- 見えていないタスクを見えるようにする（見落としていたものや難しさを見誤ったものは更新する）

### スプリントバックログを更新する

- 一番下にあるタスクよりも優先順位が低いものはプロダクトバックログ（製品に必要な全てのタスクリスト）に置いておく

### プロダクトバックログには「わかったこと」を追加していく

- 新しく実施が必要だと「わかったこと」についてはプロダクトバックログに追加する
- 計画と実際の行動にはどれくらい差があったのか、遅れが生じた原因は何か、どのような対策が考えられるか
- 見える化することで、次に打つべき一手が明らかになる

## 状況の見える化（タスクボード）

### タスクボードを作る

- やること（TODO）、やっていること（DOING）、やったこと（DONE）の3つのレーンを作成し、タスクは左から右に流れるように設計する
- TODOのレーンにはスプリントバックログをすべて貼り出し、優先順位で並べる
- 物理的にタスクの量が表現されているため、タスクの量が多い、半分くらい終わった、TODOに置きっぱなしのタスクがある、などが一目でわかる
- 必要であればWAITなども作成して、カスタマイズする
- 初めて実施する場合は、ホワイトボードなど簡単に変更を行えるツールを使用する
- タスクは付箋紙に書き、必要であればタスクの種類（内部か外部か、追加されたタスクか、など）によって色分けする

### タスク簡潔にわかりやすく

- タスクは「いつまで、誰が、何をするか」が明確にし、簡潔にする
- 1枚につき1つのタスク、1タスクは1日以内で終わる量にする
- 見積もりが難しい場合は、大きな粒度から初めて、徐々に細かくする
- 期限、担当者、対象、完了条件を書く

## 日常の見える化（朝会）

### 毎日軌道修正する

- 朝会の3つの問い
  - 昨日やったこと・・・進捗の遅れを検知し対策する
  - 今日やること・・・優先順位が合っているか
  - 困っていること・・・問題が大きくなる前に対策する

### 朝会のグランドルール

- 決まった場所と時間
- 15分以内
- 立ったまま
- タスクボード前にタスクを指さしながら

## やったことの見える化（ふりかえり）

### KPT（Keep, Problem, Try）

- Keep・・・よかったこと、成功したこと、続けていきたいこと
- Problem・・・悪かったこと、失敗したこと、問題だと思ったこと
- Try・・・Keepをさらに良くする、Problemを解決する対策としてやってみること

## プラクティスの習慣化

1．スプリント開始、計画作りでタスクと状況を見える化し、見積もりを行う
2. 朝会で日々アップデート、課題と向き合う
3. スプリント終了時点で、成果物レビュー
4. ふりかえりを行い、次のスプリントをより良いものにする→1に戻る

## まとめ

- 継続していくことで、大きな成果を発揮する
- 一度効果が出なかったからといってあきらめず、継続してプラクティスに取り組む
- システム開発だけではなく、日常の家事や趣味、学習などにも活用できそう

## 参考文献

[いちばんやさしいアジャイル開発の教本 人気講師が教えるDXを支える開発手法](https://book.impress.co.jp/books/1119101090)
SlowFast（行動認識・検出）

動画ファイルに対して、認識、検出をします。
次の環境で行っています。
ubuntu 22.04 
cuda 12.4 
cudNN 9.1.1
Docker 26.1.3

## SlowFast　の動かし方

githubよりダウンロードし、ディレクトリを移動しておきます。
```
git clone https://github.com/eijwat/SlowFast_with_GradCam
cd SlowFast_with_GradCam
```
### データの準備
`DA_dataset`フォルダを`SlowFast_with_GradCam`のディレクトリ直下に作成
```
mkdir DA_dataset
```
次の画像を参考に.mp4データを配置
（ここではフォルダ名をnega、posiで作成しています。変更する場合は`make_dataset_csv.py`内のフォルダ名も併せて変更してください）
ex
![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/53a1c5c1-89c0-f2eb-a185-70f0bc338b68.png)


データセットの作成(配置したmp4を元にcsvを作成）
```
python3 make_dataset_csv.py
```
`DA_dataset`フォルダ内にcsvファイルが作成されます

### dockerのビルド

```
docker compose up -d
docker compose exec slowfast /bin/bash
```
trainの実行

```
python3 tools/run_net.py --cfg configs/DA_dataset/da_dataset.yaml
```
結果は　results.csv　になります。
segment-and-track-anything(物体のセグメンテーションと追跡)


物体のセグメンテーションと追跡をおこないます。
ex.　cars
|<iframe width="560" height="315" src="https://www.youtube.com/embed/DDMiO_trV3g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>|
|:---|


<iframe src="https://drive.google.com/file/d/1SGT1-Vx5rzgMQlfruRVC06psf6Prnp70/preview" width="640" height="480" allow="autoplay">動画</iframe>



次の環境で行っています。
ubuntu 22.04 
cuda 12.4 
cudNN 9.1.1
Docker 26.1.3

### segment-and-track-anything　の動かし方
githubよりダウンロードし、ディレクトリを移動しておきます。
```
git clone https://github.com/eijwat/Segment_and_Track_Anything_with_Minor_Modification
cd Segment_and_Track_Anything_with_Minor_Modification
```
コンテナの作成と起動
```
docker compose up -d
docker compose exec segment-and-track-anything /bin/bash
```
pythonパッケージのインストール
```
bash ./script/install.sh
```
モデルのダウンロード
```
mkdir ckpt
bash script/download_ckpt.sh
```
プログラムの実行
サンプルとして入っているcar.mp4を使い、cars　でセグメント＆追跡をします
```
python3 demo.py car.mp4 --prompt cars
```
ビルド済のイメージを使う場合は、こちらを続いて行ってみてください。
```
exit
docker compose -f docker-compose.prebuild.yml up -d
docker compose -f docker-compose.prebuild.yml exec segment-and-track-anything /bin/bash
python3 demo.py car.mp4 --prompt cars
```

保存されるデータ

`assets/cars_pos/<frame-no>.json` 　# 各フレームでの検出したオブジェクトのIDと中心位置
`assets/cars_masks/<frame-no>.png ` 　# 各フレームでのマスク画像
`assets/cars_seg.mp4`  　# マスク結果を描画した動画
lang-segment-anything（テキスト入力による画像認識）


テキスト入力による画像認識
ex.　「All yellow tailed fish」
![img4_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/eae0733c-8611-369f-524e-462984df4af8.png)　![img5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/31d2f4a3-b77f-40a0-d32d-8682a3b1be5e.png)

ここではDockerをインストールして仮想領域を作り
lang-segment-anythingを使用する方法をご紹介しています。
(ubuntu22.04.4  cuda12.4.1 cudNN9.1.1)の環境で行っています。

### Dockerのインストール
```
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
```
リポジトリをaptソースに追加する
```
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
```
Docker のパッケージをインストールします
```
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
うまくインストール出来たら試しに、次を実行してみてください。
```
sudo docker run hello-world
```
きちんとインストールされていると次が表示されます
```
Hello from Docker!
This message shows that your installation appears to be working correctly.

```

### Docker composeのインストール
```
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
```
バージョンを表示して、きちんとインストール出来ているのを確認してみてください。
```
docker compose version
```
### dockerグループに追加
sudoを使わないで実行できるようにユーザー名を登録しておく
（dockerグループが既に作成されている場合は`sudo groupadd docker`をする必要はありません）
```
sudo groupadd docker
sudo usermod -aG docker あなたのPCのユーザー名
```
再起動しないと反映されないので
```
sudo reboot
```
### dockerのビルド
lang_segment_anythingのファイルをgithubより入手し、ディレクトリを変更する
```
git clone https://github.com/eijwat/lang_segment_anything_with_minor-modification
cd lang_segment_anything_with_minor-modification
```
NVIDIA Docker Toolkitのインストールのためbashファイルを作る
以下をコピーし、`nvidia-container-runtime-script.sh`で保存
```:nvidia-container-runtime-script.sh
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
```
作成した.shファイルを実行
```
sh nvidia-container-runtime-script.sh
```
コンテナの作成と起動
```
docker compose -f docker-compose.prebuild.yml up -d
docker compose -f docker-compose.prebuild.yml exec lang-segment-anything /bin/bash
```
GroundingDINO　をインストール
```
pip install git+https://github.com/IDEA-Research/GroundingDINO.git
```
プログラムを実行します。
ダウンロードしたフォルダ内にある`fish.jpg`を使い、
demo.py内の　text_prompt = "All yellow tailed fish"について画像分類します。
```
python3 demo.py
```
結果は　fish_result.png　になります。
pytorch-image-models(画像分類)


画像分類をします。
cat、dogの画像を用意して、分類をしました。
ex.　dog5.jpgの分類結果　pngファイルと　csvファイル
![img7_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/0e4cf4d7-64c6-b47d-4532-2c4a00d3736c.png)　![img7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/1d4eb4dc-820f-fd9d-437f-388af8daf7ce.png)

![img7_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/a2654590-356f-c955-d695-63488330fafe.png)
画像のどの部分をみてdogと判断したのかがわかります

ここではpytorch-image-modelsの使い方をご紹介しています。
（ubuntu22.04　cuda12.4　cudNN12×(9.1.1)の環境で行いました）

## インストール方法
pytorch-image-modelsフォルダをgithubよりダウンロードする
```
git clone https://github.com/NIBB-Neurophysiology-Lab/pytorch-image-models
```
動かすのに必要なライブラリをインストールしておく
```
pip3 install huggingface_hub
pip3 install pandas
pip3 install torchcam
pip3 install torchvision
```
ダウンロードした`pytorch-image-models`フォルダにディレクトリを変える
```
cd pytorch-image-models
```
## 動かし方
### 事前準備
フォルダ作成とデータを用意します
```
mkdir data_cd
```
作成した`data_cd`フォルダ内にテスト用、学習用、評価用の画像を入れておきます。
data_cdフォルダの中の構成は以下を参考にしてください
ex.　catとdogの画像分類
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/8c2b9cf5-a41d-2cac-c786-885003413fa9.png)

class_map_cd.txt を作成し、train.pyと同じディレクトリに保存してください。
ex.　catとdogフォルダを作成した場合のclass_map_cd.txt
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/1224207b-c545-1263-db35-360160cf6d6f.png)


学習をします
```
python3 train.py data_cd/train --pretrained --model tf_efficientnetv2_s_in21ft1k -b 16 --epochs 30 --num-classes 2 --class-map class_map_cd.txt
```
学習をした結果はoutput/train/に保存されます。

保存された学習結果をもとにテストをします。
output/train/に保存されたファイル名をコピーします(日付等の数字は異なります）
![Screenshot from 2024-05-24 10-51-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2666944/0de74f09-7d9f-c770-10fd-ba62d7cf6ee1.png)
次のpythonコードの `20240522-155044-tf_efficientnetv2_s_in21ft1k-300`の部分をコピーしたファイル名に置き換えて実行してください。
```
python3 inference.py data_cd/test --model tf_efficientnetv2_s_in21ft1k --checkpoint output/train/20240522-155044-tf_efficientnetv2_s_in21ft1k-300/model_best.pth.tar --topk 0 -b 16 --num-classes 2 --class-map class_map_cd.txt
```
分類結果を保存するため、フォルダを作成します（cat,dogの場合）
```
mkdir torchcam
mkdir torchcam/cat torchcam/dog
```
実行(先ほどと同様に学習したファイル名に置き換えてください）
```
python3 torch_cam.py data_cd/test --model tf_efficientnetv2_s_in21ft1k --checkpoint output/train/20240522-155044-tf_efficientnetv2_s_in21ft1k-300/model_best.pth.tar --num-classes 2 --layer-names conv_head blocks
```
torchcamフォルダに結果（pngファイル）が保存されます。
CSVファイルは`pytorch-image-models`フォルダ内の`tf_efficientnetv2_s_in21ft1k-300.csv`です。

--補足--
今回使用したmodelは　`tf_efficientnetv2_s_in21ft1k`　になります。
modelを変更すると結果が変わってきますよ。ちなみにmodelの種類はこちらを参考にしました。

https://zenn.dev/piment/articles/e46bffb3f64975

また、layer-names　を変更しても結果がかわります。組み合わせを変更してみてください。
layer-namesの一覧　は　torch_cam.py　を実行した際に　ターミナルに表示されます。
八百屋システムを考える（なぜDXの内製化）

# なぜ内製化がいいの？
ちょっとここで、ひと呼吸置きたいと思います。
今までの記事は以下の２つ

[八百屋システムを考える（DX内製化の手順１）](https://qiita.com/kawamo55/items/b801875ca9494eb89d7a)
ここではスプレッドシートで管理システムの一部を作ってみます。

[八百屋システムを考える（DX内製化の手順２）](https://qiita.com/kawamo55/items/2ef97b4873b1a56f6906)
ここではスプレッドシートの内容から見えてくるからVBA化とPython化するにあったって考慮すべきこと（システム構成）について触れています。

今回は具体例を上げる前に、なぜDXの内製化がいいのか？なぜ２つの言語がいいのか？について解説します。

内製化することは、以下の理由から非常にメリットが大きいと言えます。
１．システム構築時に起きる制作者側とクライアント間の食い違いがない。
２．システム拡張も改修も自由にできる。
３．メンテナンスも自社で完結できる
などなどがありますが・・・
最も大きなメリットはシステムにかけるコストが安くなるので大きな利益につながるということです。

# 内製化できる社員の資質と選定言語について
とは言うもののプログラミングは難しいと思ってませんか？
それは考え方の問題でDX化の手順１をスプレッドシートで作って計算式を作れる技量があれば可能な気がしませんか？
これが自作できる資質を持っている社員がいれば内製化は可能です。
なので１つ目の言語としてExcel VBAを使います。

もう一つは、以前に書いた記事で
[スプレッドシートで考えるプログラム](https://qiita.com/kawamo55/items/38c538b1350c8790b65a)
という記事がございます。

実はスプレッドシートの内容はPythonプログラムに置き換えやすいんだよと言ってます。
なので２つ目の言語としてPythonを選んでいます。

ただし、担当する社員さんは、必ず２名必要です。
属人化を避けるため作ったシステム内容を理解している人は２名必要になります。

この記事に関するお問い合わせは、こちらまで m_kawase@embed-ai.com まで！