OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript 基本知識

# JavaScriptとは
Webページに動的な機能を追加するためのプログラミング言語．初めは「<font color="Blue">LiveScript</font>」という名称で開発されたが，当時から人気があった「Java」に影響されて，「<font color="Green">JavaScript</font>」に名称を変更した．

JavaScriptはHTMLとCSSと組み合わせることで，**見た目や振る舞いを制御**し，**Webページに動き**を加えることができる．例えば，ユーザの入力に応じてコンテンツを動的に変更したり，フォームのバリデーションチェックやアニメーションの作成，サーバとのデータ通信もJavaScriptを利用することで可能になる．

**役割の整理**
HTML：Webコンテンツの構造を定義するマークアップ言語
CSS：Webコンテンツのデザインやスタイルを定義するスタイルシート言語
JavaScript：<ins>Webページに動的な機能やインタラクティブな振る舞いを提供するプログラミング言語</ins>

# JavaScriptの特徴
JavaScriptには以下のような特徴を持つ．

**１．Webコンテンツに動的な機能を追加できる**
静的なWebページに動的な要素やインタラクティブな動作を追加することができる．
**２．非同期通信**
Ajaxと呼ばれる機能を使うことで，ページの更新なしでデータの取得などの非同期通信を実現する．
**３．ブラウザがあれば実行できる**
ユーザが特別な環境を用意する必要がなく，ブラウザさえあれば利用できる．
**４．ライブラリやフレームワークが豊富**
JavaScriptには開発効率を向上させるライブラリやフレームワークがたくさんある．
**５．動的型付け言語**
変数の型を明示的に宣言する必要がなく，実行時に変数の型が自動的に付与される．

# JavaScriptのフレームワーク・ライブラリ
JavaScriptのフレームワークとライブラリは非常に多く存在する．以下にいくつか主要なものをリストアップする．

**○フレームワーク**
* Angular
データバインディング，コンポーネントベースのアーキテクチャなどの機能を提供し，SPAの構築を支援するフレームワーク．
* Vue.js
コンポーネントベースのアーキテクチャ，仮想DOMなどの特徴を持つ，UIを構築するためのフレームワーク．
* Next.js
Reactをベースにしたサーバーサイドレンダリング(SSR)および静的サイトジェネレーター機能を提供するフレームワーク．
* Nuxt.js
Vue.jsをベースにしたサーバーサイドレンダリング(SSR)および静的サイトジェネレーター機能を提供するフレームワーク．

**○ライブラリ**
* jQuery
HTMLドキュメントの操作やイベント処理を簡単に行えるJavaScriptライブラリ．
* React.js
ユーザーインターフェースの構築に特化した，柔軟で高性能なJavaScriptライブラリ．
* D3.js
データを元にグラフや可視化コンポーネントを生成するためのデータ駆動型JavaScriptライブラリ．
* Underscore.js
JavaScriptのユーティリティ関数を拡張し，効率的なデータ操作をサポートするライブラリ．
* Moment.js
日付と時刻の処理を容易に行えるJavaScriptライブラリ．
* Axios
JavaScriptから簡単にHTTPリクエストを行えるHTTPクライアントライブラリ．

これらのフレームワークとライブラリをうまく活用することによって，効率と質の高いWebコンテンツを開発することができる．
せんせー、ディープテックってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/b1f5182f-e34e-7353-d5ef-fa746e95605d.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7b3ab395-76ce-d410-8fd5-3a1200c87156.png)

せんせー、ディープテックってなに？

# ディープテックとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/4f79fea0-c46b-acbc-57db-856da60cd3ca.png)

ディープテック、難しそうな言葉ですね

でも
これをすごくすごくシンプルに説明すると
ディープテックは「すごい科学や技術を使って世界をもっと良くするためのアイデア」のことを指します

例えば
お絵描きをするときに、色鉛筆だけでなく、マジックやパステル、スパンコールなど
たくさんのツールを使って、一つの絵を描くようなイメージです

でも
このディープテックの場合
そのツールは「科学」や「新しい技術」です

そして
その絵がただキレイなだけではなく人々が困っていることを解決しあたり
世界をもっと良くしたりするための絵なんです

例えば
病気の人を元気にする絵や
地球をきれいにする絵などです

つまり
ディープテックとは
科学や新しい技術を使って
みんなのために何かステキなことをするアイデアのことなんですね

# まとめ

ディープテックとは科学や新しい技術を使って
みんなのために何かステキなことをするアイデアのこと
Safariではoption要素をhiddenできない


## 問題
optionにhiddenをつけた場合、Chromeでは期待通りに動きますが、Safari(やiPhoneのwebview）では選択肢としてでてきてしまいます。。

```html
<select name="choice">
  <option hidden>choose...</option>
  <option>First</option>
  <option>Second</option>
  <option>Third</option>
</select>
```

[Sampleコード](https://syncfiddle.net/fiddle/-NaA9SkC93fMnzWSqZX1)

|Chrome|Safari|
|--|--|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6149/8c07c381-6ebf-9c41-8fb0-de1007b79466.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6149/2f75c562-5bab-c8bf-0cb8-09a6379cd8d9.png)|

## 原因
Safariのバグのようでhiddenやdisplay:noneが効かないようでした。
https://bugs.webkit.org/show_bug.cgi?id=8351
https://stackoverflow.com/questions/9234830/how-to-hide-a-option-in-a-select-menu-with-css

## 対策
hiddenではなくdisabledのほうを使いましょう
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option
ABC311復習

# ABC311復習
https://atcoder.jp/contests/abc311
## ■結果  
* ABC3完
* C/Dとも再帰で進めましたが、DのBFS実装中に時間切れ。Dの実装は難しかった。

## ■Ａ問題（First ABC）
３文字全部を見つけたことの判定がポイント。
解く速さを優先して出現文字種類が３文字になったことで判定。
```python
n = int(input())
s = input()

chars=set()
for ii in range(n):
    chars.add(s[ii])
    if len(chars) >=3:
        print(ii+1)
        break
```
## ■Ｂ問題（Vacation Together）
* 15分AC。まあOK。
* 最大値を記録する部分は`ans=max(ans, count)`とかでもよい。
ただ変数名をmaxにするとハマった。pythonで関数名と同じ変数名を使わない方がよい例。

```python
n,d = map(int, input().split())

schedule = []
for ii in range(n):
    schedule.append(input())

ans  = 0
count = 0
for day in range(d):
    free = True
    for ii in range(n):
        if schedule[ii][day] == 'x':
            free = False
            break
    if free:
        count +=1
        ans =max(ans, count)
    else:
        count=0
print(ans)
```
## ■Ｃ問題（C - Find it!）
面白い問題。
まずループを探索する処理は再帰がよさそう。ひたすら辿る列を伸ばして過去に同じノードが存在したかをチェックすればよい。気になる単連結ではない点だけれど、どの連結にも必ずループが有る点に気づき、任意の始点から辿ってよいと割り切る。実装時に、過去に同じノードが存在したか O(1)で確認するためsetを使った。45分でAC（やや長い）
```python
import sys
sys.setrecursionlimit(10000000)

n = int(input())
route = list(map(int, input().split()))

l = []
s = set()

def go_next(node):
    if node in s:
        pos = l.index(node)
        print(len(s)-pos)
        print(*l[pos:])
        return
    l.append(node)
    s.add(node) 
    next = route[node-1]
    go_next(next)

go_next(1)
```
面白かった別解。

https://qiita.com/Konini64/items/2999b55e65b7e079414b

なるほどUnionFind。ノード順に処理で平均処理量速そう。

https://qiita.com/mae-commits/items/6452da2d4563f50dfaf3

こちらは、ループ検出をコンパクトにwhile文で関数化。非再帰。

強コーダの方によると、C問題は強連結成分(SCC)を検出する問題と捉えることもできるそう。言語によっては強連結成分分解ライブラリも有るらしい。

## ■D問題（Grid Ice Floor ）
難しかった。
頭の整理と実装に時間が要りそうな感覚が有り、案の定という感じで提出に間に合わず。
startから上下左右に向かう。壁の手前で停止する。停止点をnext_nodeとする。next_nodeが過去辿った経路上なら終点になる、を移動ルールと解釈しよう。
過去通った点の管理には単純にvisited用gridを使う。（後で二重カウントせずに訪れた点を数えるにも都合がよい。）探索はbfsかdfsが良い。bfsにしよう。これで作戦が出来たが、実装に慣れがなくて時間かかる。
数回推敲し下記コードでコンテスト後AC。現状の精一杯かも。

```python
from collections import deque

# up, down, left, right
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]

n, m = map(int, input().split())

grid = []
for ii in range(n):
    s = input()
    grid.append(s)

v = [[0] * m for _ in range(n)]

def go_next_node(node, dir):
    x, y = node[0], node[1]
    v[x][y] = 1
    while True:
        cur = v[x][y]
        v[x][y] = 1
        xx = x + dx[dir]
        yy = y + dy[dir]
        if grid[xx][yy] == "#":
            break
        x, y = xx, yy
    if cur == 1:
        return (0, 0)
    return (x, y)

def bfs(start):
    queue = deque([start])
    while queue:
        node = queue.popleft()
        for dir in range(4):
            next_node = go_next_node(node, dir)
            if next_node != (0, 0):
                queue.append(next_node)
    return

#for line in grid:
#    print(*line)

bfs((1, 1))

#for line in v:
#    print(*line)

ans = 0
for line in v:
    ans += sum(line)
print(ans)
```
macOSのシステム言語設定を日本語にしたままアプリの言語設定を英語にする

macOSでは、アプリケーションごとに言語を変更できます。これによって、システム言語設定と異なる言語でアプリケーションを使うことができます。

たとえば、システム言語設定を日本語にしたまま、特定のアプリだけ言語を英語に設定できます。特定のアプリで日本語での表示がおかしい場合などに便利です。

# 設定方法

- アップルメニューから「システム設定」を開いて、「一般」→「言語と地域」を選択します。
- 「アプリケーション」で「＋」ボタンを押し、設定したいアプリケーションと言語を選択します。

これは「[Macの言語を変更する - Apple サポート (日本)](https://support.apple.com/ja-jp/guide/mac-help/mh26684/mac)」に書いてあります。
PowerBIサービスからDr.Sumに接続する【On-premises data gateway】

# 目次
- [はじめに](#はじめに)
- [On-premises data gatewayのインストール](#On-premises-data-gatewayのインストール)
- [On-premises data gatewayの設定](#On-premises-data-gatewayの設定)
- [PoserBIService画面からのゲートウェイの事前設定](#PoserBIService画面からのゲートウェイの事前設定)
- [PoserBIServiceからDr.Sumへ接続](#PoserBIServiceからDr.Sumへ接続)
- 最後に



# はじめに 
Dr.Sum Ver.5.6のアップデートモジュールの提供でPower BIとの連携ができるようになりました。
PowerBI DeskTopとの接続方法については、以下の記事を参照ください。
　　[Power BI でDr.Sumにつないでみた](https://qiita.com/ilovehome/items/02891b875c56acaea0a1)

PowerBI DeskTopと接続する場合は、上記のサイトの手順で接続できますが、
PowerBIServiceと接続する場合、**On-premises data gateway**の設定が必須になります。

今回は、PowerBIServiceからDr.Sumに接続する場合の手順についてご紹介します！


# On-premises data gatewayのインストール

まずは以下のURLより、On-premises data gatewayをダウンロードしていきます。
[On-premises data gateway](https://go.microsoft.com/fwlink/?LinkId=2116849&clcid=0x409)

インストーラーがダウンロードされるので、実行してインストールしていきます。
基本的に「次へ、次へ」でインストールできます。

# On-premises data gatewayの設定

Power BI Serviceがアクセスできるように、フォルダに「<font color="Red">**NT Service\PBIEgwService**</font>」ユーザーのアクセス権限を設定します。
フォルダは、Dr.SumとPowerBIの接続設定をした際に作成しているフォルダです。
場所：C:\Users\＜ユーザー名＞\Documents\Power BI Desktop\Custom Connectors

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/28f5bb5f-e57f-4c17-2300-0d5548872a87.png)


インストールしたOn-premises data gatewayを開き
カスタムデータコネクタのフォルダパスをPowerBIのカスタムコネクタフォルダに変更します。
変更適用後、「Dr.Sum」の名前が表示されればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/390415fe-ce32-e8b4-dbe1-25f9e4492ce5.png)

ここまででローカル環境でのOn-premises data gatewayの設定は以上になります！
実際にPowerBIServiceからDr.Sumに繋げてみよう！といきたいですが、
その前に、もう一つ設定が必要です。

# PoserBIService画面からのゲートウェイの事前設定

PowerBIServiceのホーム画面からゲートウェイ管理画面を開き、
「ユーザーのカスタム データ コネクタに、このゲートウェイ クラスターを介して更新することを許可します (プレビュー)。」
にチェックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/e285570e-221b-409c-f883-0a568b28d5dc.png)

# PoserBIServiceからDr.Sumへ接続

まずは、PowerBI DeskTopでダッシュボードを作成し、PowerBI Serviceに発行していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/3e3d6d37-79b0-f587-a7c5-9cd2e067d25e.png)


発行後、PowerBIService画面で確認します。
最初はエラーが発生しているので、下記手順でゲートウェイを手動で追加していきます。
接続情報を入力する際は、パスワードも<font color="Red">**必須入力**</font>となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/5b8ed1ba-8e88-e402-18d7-1cf38327cffc.png)


ゲートウェイ接続で、一つ上の手順で作成した接続情報が選択できるようになります。
プルダウンから接続情報を選択すると、レポートが表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/b8032296-baf1-ac69-9de3-2cd8c1e7c781.png)

PowerBI ServiceからもDr.Sumに接続できました！
手動で追加するゲートウェイ毎にユーザーIDを設定するので、Dr.Sum側で設定した権限管理もそのまま活用いただけます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/645202ca-34b7-1cb6-b27a-c7fc2f506de8.png)

# 最後に
Dr.Sumは高速に集計できる事と、柔軟な権限設定が強みのデータベース製品です。
Dr.Sumに接続することで、より一層PowerBIを使いこなせそうですね！
python subprocess cannot use a string pattern on a bytes-like object

### encoding='utf8'を追加する

```python
 proc_result = subprocess.Popen(cmdargs,
                                        stdin=subprocess.PIPE,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE,
                                        startupinfo=_no_window,
                                        encoding='utf8').communicate()[0]

            # No tx update required
            if rx_maketx_noupdate.search(proc_result):
                message = 'No update required: %s (%s)' % (out_tile_tx, tile)
                logger.info(message)
                results.append({'info': message, 'src': tile, 'tx': out_tile_tx, 'status': 'no_update_required'})
                continue
```
Lambdaで特定のサブネットのインスタンスを自動停止する方法

## はじめに
当チームではテスト環境等の社内利用用途を目的としたEC2インスタンスは業務時間内しか利用しないことが多いため、深夜帯や休日に稼働し続け無駄なコストがかかってしまうことがあります。
そういった不要なコストを抑えるためにテスト環境専用のサブネットを用意し、定時でサブネット内のすべてのインスタンスを停止する機能があると便利だなと思っていました。
件数が少ない時期はAmazon EventBridgeでルールを作成し個別で自動停止の設定をしていましたが、件数が増えるにつれ一括の設定が必要になり構築することにしました。

今回はLambdaを使って構築をしましたので設定方法を記述します。

## 構築イメージ
AWSサービス全体の構築イメージは以下の図の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/a8870731-8076-9f68-664c-ea007861c001.png)
今回設定方法を記述するのは以下の工程です。
* AWS EventBridgeで毎日PM10:00に指定のLambdaを実行するルールを設定する
* Lambdaで対象のサブネット配下にあるEC2インスタンスすべてを停止する関数を設定する
* IAM RoleでLambdaがEC2インスタンスを操作する権限を付与する

## やってみる
#### AWS EventBridgeの設定
ルールを新規作成します。
UIに従って設定していくので特に難しい点はないと思います。
Cronが日本時間と9時間差があるので注意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/0f13ea44-b3a3-8740-8602-dd869eb0526c.png)


ターゲットは作成するLambdaを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/b44b67f1-b855-a9c5-59d8-57055a149b13.png)

#### Lambdaの設定
停止対象のサブネットIDにあるインスタンスを配列で取得し、すべて停止する処理をpythonで記述します。
IAMRoleが正しく設定されていないとインスタンスの情報を取得できないのでお気を付けください。


``` python
import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    subnet_id = 'subnet-xxxxxxxxxxx'  # 停止対象のサブネットIDを指定
    
    response = ec2.describe_instances(
        Filters=[
            {'Name': 'subnet-id', 'Values': [subnet_id]},
            {'Name': 'instance-state-name', 'Values': ['running']}
        ]
    )
    
    instance_ids = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            print(instance)
            instance_ids.append(instance['InstanceId'])

    if instance_ids:
        stop_response = ec2.stop_instances(InstanceIds=instance_ids)
        print(stop_response)
        return stop_response
    
    else:
        return null
```
トリガーの設定をします。
EventBridgeで作成したルールを設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124412/8204dbf5-e1f0-6c97-64f3-9d43e5fd5c0a.png)



#### IAM Roleの設定
インスタンスの表示・停止権限を付与します。
以下のコードを設定したIAMポリシーをIAM Roleに紐づけます。
``` json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2DescribeInstances",
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        },
        {
            "Sid": "EC2StopInstances",
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        }
        ]
}
```

:::note info
以上の設定をすることで毎日PM22:00に対象サブネット内のインスタンスが自動停止されます。
:::


## おわりに
今までインスタンスを個別で管理していたので工数がかかっていたのですが、サブネット単位で管理できると大分工数削減につながるなと感じました。
また、野良インスタンスがずっと起動しっぱなしで不要なコストがかかってしまうことも回避できるので有用だと思いました。
本稿の内容だけで運用・管理できるわけではないので明確なオペレーションを策定していきたいと思います。
【備忘録】Azure DevOps で Pipelines からデプロイとかするためにService Connectionを確立する方法

再構築しようと思ったら初回作業時の記録が無くて困ったのでメモ
**完全にメモなので画像は略**

1. Azure AD でアプリの登録 -> DEVOPS接続用のアプリケーションを登録（登録済みなら流用できるので省略）

2. デプロイ先が所属するリソースグループの共同管理者に 1. で作成したアプリを登録（もっと適切なロールがあるかも）

3. アプリのクライアントシークレットを新規作成し、シークレットの値をメモ

4. Azure DevOps側の設定からPipelinesのService Connectionを開く

5. 新規追加で Azure Resouce Manager(manual)を選択

6. Environment は Azure Cloud を選択

7. Scope Level は Subscription

8. Subscription IdとNameにサブスクリプションのID/Nameを入力

9. Service Principal Id には1.で作成したアプリの アプリケーション (クライアント) IDを使用する

10. Service Principal Key には 3. でメモしたシークレットの値を入力

11. Tenant ID には 1.で作成したアプリの ディレクトリ (テナント) IDを使用する

12. Verify で認証。失敗した場合はどこかが違う（手順2.が抜けているなど）

13. 名前を付けて保存
Chromebook で Docker インストールコマンド

<h2>Chromebook に Docker をインストールするコマンド一覧</h2>

<h4>入力するターミナル</h4>
1. Chrome OS の設定<br>
2. 詳細設定<br>
3. デベロッパー Linux 開発環境(ベータ版)<br>
4. オンにする<br>
5. ランチャーのLinux アプリ<br>
6. ターミナル起動<br>
<br>

<h4>パッケージのインストール</h4>

```console
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
```
| パッケージ | 詳細 |
|:-|:-|
|apt-transport-https|AHTTPSプロトコルでパッケージを取得するトランスポートメソッド |
| ca-certificates  | SSL/TLS通信時に使用される証明書を管理  |
| curl |  コマンドラインからデータを転送 |
| gnupg-agent  | GNU Privacy Guard エージェント  |
| software-properties-common  | ソフトウェアリポジトリ管理ツール  |

<h4>GPG公開鍵を登録</h4>
※GPGとは？: Docker のデジタル署名技術. パッケージが正当なものか確認するために必要.

```console
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```
| コマンド | 詳細 |
|:-|:-|
|  https://download.docker.com/linux/ubuntu/gpg | GPG公開鍵URL  |
| sudo apt-key add -  | 公開鍵をシステムに登録  |

<h4>フィンガープリント表示</h4>
※フィンガープリントとは？:、GPG公開鍵の識別子.デジタル署名を検証するために必要.

```console
$ sudo apt-key fingerprint 0EBFCD88
```
| コマンド | 詳細 |
|:-|:-|
|  fingerprint  | フィンガープリント表示  |
| 0EBFCD88  | Dockerの公式GPG公開鍵識別子  |

<h4>リポジトリを追加</h4>

```console
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
```
| コマンド | 詳細 |
|:-|:-|
|  add-apt-repository  | APT を使用してソフトウェアリポジトリを追加  |
| https://download.docker.com/linux/debian<br>https://download.docker.com/linux/ubuntu | Docker公式リポジトリURL  |
| [arch=amd64] | アーキテクチャを指定 |
| $(lsb_release -cs) | Debianリリースのコードネームを動的に取得 |
| stable | Docker 安定版リリース |

<h4>リポジトリ更新</h4>

```console
$ sudo apt-get update
```

<h4>Docker インストール</h4>

```console
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
```

| パッケージ | 詳細 |
|:-|:-|
| docker-ce | Dockerコアコンポーネントとツール |
| docker-ce-cli  | Dockerコマンドラインインターフェースパッケージ |
| containerd.io | containerdパッケージ(コンテナ実行に必要) |

<h4>インストールできたかバージョン確認</h4>

```console
$ docker --version
Docker version 24.0.5, build ced0996
```

無事インストール完了

<h4>Ex: コマンド入力した際に何かメッセージが・・・</h4>

```console
$ docker ps
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
```

Dockerコマンドを実行するには,Dockerグループに所属している必要あり.
Dockerデーモンは, DockerグループのメンバーのみがDockerコマンドを実行できるように制限されている.

```console
$ sudo usermod -aG docker <ユーザー名>
```
※ユーザー名は現在ログインしているユーザー名に変更 ubuntu@ip-0-0-0-0 = ubuntu

<h3>コードを実行したら一度ログアウトして再度ログイン (1敗)</h3>

```console
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

コマンド成功
面倒でなければ sudo をつけても実行可能
上司の心得　6訓

# はじめに
つい最近まで新人、若手ということで教えてもらう側だったのに、後輩が増えてきてそんなことも言えなくなってきた今日この頃。
というわけで、「リーダーの立ち振る舞い」や「上司、先輩としての接し方」などを題材とした書籍を読み漁っている中で**上司の心得**なるものがとても参考になったので、記事にして共有したいと思います。

今回引用する書籍は以下です。

**自分の頭で考えて動く部下の育て方 上司１年生の教科書/篠原信**

https://bunkyosha.com/books/9784905073611

# 上司の心得
### **1.部下ができたら楽になると思うなかれ**
>**「部下ができたら自分の仕事を振ろう」「部下ができたら、大変だった自分の仕事も楽になるだろう」と甘い期待を抱いている人は多いだろう。しかし、そう考えている人の多くが足元をすくわれることになるので注意が必要だ。**

こんな甘い期待をされている人ってそんなにいないと思いますが、大事なことですね。
上司の仕事は「**部下に働いてもらうこと**」であって、「**上司の仕事を部下にやってもらうこと**」ではないです。

書籍では上司と部下の関係を身体で例えていて、上司は神経、部下は筋肉と言っています。
運動のために伸縮するのが、筋肉。いつ伸び、いつ縮むかを決定するのが神経。
つまり、実作業を行うのが部下であり、意思決定や計画を行うのが上司というそもそもの役割が違うわけですね。
(プレイングマネージャーのように実務もこなすような上司もいますが、それでも意思決定の部分は上司の役割であり、部下に任せることができない領域です。)

### **2.上司は部下より無能で構わない**
>**部下にしっかりした見本を見せなければ…。率先垂範というくらいだから自分が模範となるくらいに働かなければ…。そう思って頑張りすぎると、かえって部下が働かなくなってしまう恐れがある。**

部下だったころは自分のやってきたことをアピールして評価してもらうことは重要ですが、上司が部下に自身のパフォーマンスを見せてしまうと悪影響を及ぼす可能性が高いそうです。
例えば、人はお手本を見たときに2通りの反応を示すそうです。
1.「**このお手本通りに、上手にできるようになりたい**」**と願って努力する**
2.「**まあ、なんて素晴らしいお手本でしょう。素晴らしすぎて自分にできるとは思えません…**」**と自信を無くす**

優秀な上司による部下への「**俺は仕事ができる**」アピールは多くの場合、後者になるため、模範となるどころか部下の意欲を削ぐ結果を招いてしまうのです。
そもそも前述した通り、上司と部下では役割が違うので、同じ土俵に立つ必要はなく、如何に部下を上手に動かすかが重要です。

### **3.威厳はなくて構わない**
>**初めて上司になる人の中には、「部下に尊敬されなければ」「部下がビシッと言うことを聞く厳格な上司でなければ」と気負っている人もいるだろう。しかしそういう人が部下を指示待ち人間にしてしまいがちなようだ。**

これはいわゆる**軍隊式**と言われるような教育法に近く、恐怖で支配することで従順な人間を作り出すものです。
軍隊式は兵隊のような命令が絶対な組織には必要な教育かもしれませんが、一般企業の上司であれば、「**自ら考えて動く部下が欲しい**」と思うはずです。
軍隊式では全く逆の人間を育ててしまうので、恐怖で支配するような教育は改めたほうがよいでしょう。

### **4.部下に答えを教えるなかれ**
>**上司は部下に懇切丁寧に仕事を教えなければいけないと考えている人がいる。あまりに丁寧に教えすぎると、仕事への情熱を奪い、「指示待ち人間」を生んでしまう。**

前述したように上司の仕事は「**部下に働いてもらうこと**」であり、そのためには「**部下の意欲を引き出す**」必要があります。
そこで大事なのが、「**何を教えないか**」です。
部下は上司が丁寧に教えてくれると自分で考えることをしなくなります。「**おばあちゃん子は三文やすい**」ってやつに近いですね。

意欲というのは「**できない**」が「**できる**」に変わったときに得られるので、思考をアウトソーシングしている部下に意欲は生まれない…達成感も得られない。
だから、「**何を教えないか**」を徹底し、部下に自分で考えるの習慣をつけさせましょう。

### **5.部下のモチベーションを上げようとするなかれ**
>**マネジメントとは、部下のモチベーションを上げ続けることだと考えている人がいるかもしれない。しかし部下のモチベーションを上げようとする上司の働きかけは往々にして失敗に終わってしまう。**

先ほどの「**何を教えないか**」によって「**できるようになった快感**」を強めることを意欲を高めると言いましたが、では具体的にどうすれば…？

それは「**一利を起こすは一害を除くに如かず**」がポイント。
意欲を高めるために仕事の仕方を教えるなどの**手助け**をするのではなく、いかに余計なことを省くかが重要。つまり、モチベーションが下がるようなことを取り除けばいいわけです。

そして、部下に行ってもらう業務は解決不能な難問ではなく、**ぎりぎり上手くいきそうな、でも簡単には達成できなさそうなレベル**のものを振ることも重要です。



### **6.部下を指示なしで動かす**
>**部下には、手っ取り早く「次はこうするんだ」と指示をどんどん出したほうが仕事が早く済むと考えている上司は多いだろう。しかし、早そうに見えるその指示が、結果、指示待ちになっていつまでもあなたの手を離れない部下になる原因になる。**

上司が何もかも細かく指示を出してしまうと「**やらされている感**」が強くなります。
**受動的**に行った行為は**能動的**に行った行為に比べて、達成感も面白さも半減します。
なので、上司は**如何に能動的に部下に動いてもらうか**を考える必要があります。

具体的には、タスクの進め方に指示を出すのではなく、**逆に質問をする**ことで部下にどうしたらいいか考えてもらうことが有効です。
自身で考えたことであれば、納得感も理解度も格段に違うのでスキルアップもしやすくなります。


# おわりに
いかがだったでしょうか？
今回は上司心得の紹介でしたが、他にも書籍にはシチュエーション別の教育方法も書かれていますので、かなり参考になります。
後輩育成などに悩んでいる方にぴったりの書籍ですので、ぜひご一読ください。
React Native: ベースのコンポーネントに任意のPropsを追加する方法


React Nativeの開発では、特定の機能を持った基底コンポーネントを作成し、それを再利用することがよくあります。ここでは、既存のベースコンポーネントに新たにPropsを追加する方法について説明します。

## 元となるコンポーネント

まず、出発点となるコンポーネントを見てみましょう。以下は一例となる`Card`コンポーネントです。

```tsx
import React, { FC } from 'react';
import { View, ViewProps } from 'react-native';

type CardProps = ViewProps;

export const Card: FC<CardProps> = ({ children, ...rest }) => {
  return (
    <View {...rest}>
      {children}
    </View>
  );
};
```
この`Card`コンポーネントは、子要素として任意のコンテンツを受け取ることができます。

この`CardProps`の型は、`ViewProps`として定義されています。`ViewProps`はReact Nativeが提供する型で、`View`コンポーネントが受け取ることができる全てのプロップスの型定義を含んでいます。これにより、この`Card`コンポーネントも`View`と同じプロップを受け取ることができます。

## 新しいPropsの追加

次に、この`Card`コンポーネントに、新たなプロップとして`onClose`を追加しましょう。これは、ユーザーが閉じるアクションを行ったときにトリガーされるイベントハンドラを想定します。

新たなプロップを追加するには、まず、新たなプロップの型を定義します。ここでは、`onClose`関数の型は`() => void`とします。

そして、この新たなプロップを`CardProps`に追加します。

```tsx
interface CardProps extends ViewProps {
  onClose: () => void;
}
```

## コンポーネントへの適用

最後に、新たに追加した`onClose`プロップを`Card`コンポーネントに適用します。

```tsx
import React, { FC } from 'react';
import { View, ViewProps, TouchableOpacity } from 'react-native';
import { CloseIcon } from '../icons/CloseIcon';

interface CardProps extends ViewProps {
  onClose: () => void;
}

export const Card: FC<CardProps> = ({ onClose, children, ...rest }) => {
  return (
    <View {...rest}>
      <TouchableOpacity onPress={onClose}>
        <CloseIcon />
      </TouchableOpacity>
      {children}
    </View>
  );
};
```
新たな`onClose`プロップは`CardProps`インターフェースに追加され、`Card`コンポーネントの引数にも追加されました。これにより、親コンポーネントからこの関数がプロップとして渡されるようになり、ユーザーが`CloseIcon`をタップしたときにこれがトリガーされるようになります。

ここで注目したいのは、`...rest`という記述です。これはJavaScriptの「残余パラメータ（rest parameter）」と呼ばれる構文で、いくつかのアイテムを一つの配列にまとめることができます。この場合、`Card`コンポーネントが受け取る全てのプロップを`rest`オブジェクトにまとめ、それを`View`コンポーネントに渡しています。つまり、`Card`コンポーネントが受け取る全てのプロップ（`onClose`と`children`を除く）は、そのまま`View`コンポーネントに渡されます。

## まとめ

React Nativeで汎用的なコンポーネントを作成し、それを再利用する際には、新たなプロップを追加してコンポーネントをカスタマイズすることがよくあります。この記事ではその方法を具体的に説明しました。また、React Nativeの`ViewProps`とJavaScriptの「残余パラメータ」についても解説しました。これらを理解し活用することで、コンポーネントの再利用性と可読性が向上します。
世界のトップ 13 産業は今後 5 年間で急成長見込みます


進化し続ける世界経済では、技術の進歩、消費者行動の変化、市場の需要によって、特定の業界がリーダーとして浮上します。今後 5 年間に目を向けると、いくつかのセクターが大きな成長と革新を遂げる準備が整っています。この記事では、市場データと洞察力に富んだ分析に基づいて、今後 5 年間で大幅な成長が見込まれる世界のトップ 13 業界を探ります。これらの業界は、投資家、起業家、求職者にとって同様に有望な見通しを提供します。

1. 再生可能エネルギー
2. 電気自動車（EV）
3. 人工知能 (AI) と機械学習 (ML)
4.電子商取引
5. ヘルスケア技術と遠隔医療
6. 通信と5G
7. サイバーセキュリティ
8. バイオテクノロジーと医薬品
9. 拡張現実 (AR) と仮想現実 (VR)
10. リモートワークとコラボレーション道具
11. スマートホーム技術
12. 浄水技術
13. 持続可能な建設


詳しくはこちら：https://www.sdki.jp/blog/global-industries-that-will-boom-in-the-next-5-years/25
クロージャについてゆるくまとめてみる。

#目次
[1.はじめに](#1はじめに)
[2.関数内関数を理解する](#2関数内関数を理解する)
[3.クロージャを理解する](#3クロージャを理解する)
[4.まとめ](#4まとめ)


# 1.はじめに
pythonを勉強していくと関数に苦手に感じるのではないでしょうか。（本人初学者）個人的に関数を理解していく上で、特にややこしく感じた「クロージャ」についてまとめたいと思います。

# 2.関数内関数を理解する
関数について勉強していくと、必ず目にする「関数内関数」を少しまとめてみる。
```
def outer():
  a = 1
  def inner():
   return a + 1
  return inner()

print(outer())
<<< 2
```

outer()で定義された引数に、inner()で追加で新しい機能（処理）を定義し、returnでその機能をouter()に返している。

# 3.クロージャを理解する
上記とは少し異なるコードを書いてみました。
```
def outer():
  a = 1
  def inner():
   return a + 1
  return inner

print(outer())
```
違う点は、outer関数の戻り値がinner()ではなく、innerであること。つまり、括弧が外れた状態でouter関数に返している点です。この場合の出力結果は以下になります。
```
<<<  <function outer.<locals>.inner at 0x7c6dc7b79e10>
```
これが意味するのはinner関数の実行結果ではなく、inner関数そのものを返しているという事です。つまりinner関数は実行されていない状態です。
aはローカル変数といい、outer関数内でのみ使用できる変数で、その範囲（スコープ）外では使えないです。しかし、inner関数内でaを呼び新しくa+1と定義しています。

つまり、クロージャとは外側の変数を記憶する関数といえます。
```
def outer(a):
  def inner():
   return a + 1
  return inner

c = outer(4)
d = outer(7)
print(c())
print(d())
<<< 5
<<< 8
```
また、関数を変数に代入することによりその変数が関数の処理機能を持ちます。
上記のコードでは、c,dはそれぞれouter関数の機能を持っていることが出力結果から確認できます。

クロージャの使い方としては、デコレータなど使い方があるようです。
機械学習モデルなどの処理時間を計測するデコレータは便利だなと思いました。
[Pythonのデコレータを理解するための12Step](https://qiita.com/_rdtr/items/d3bc1a8d4b7eb375c368)

# 4.まとめ
以上python初学者がクロージャについてゆるくまとめてみました。クロージャについて勉強したことにより、関数の理解度は以前よりも上がったと思っております。これからも頑張っていこうと思います。
√(9x-18)<=√(-x^2+6x)「17年 芝浦工大 工・シス理工・デザ工・建 1(1)」をChatGPTとMathematicaとWolframAlphaとsympyでやってみたい。

グラフがでます。

**パイソニスタの方へ
???同値変形の方法を教えて下さい。???**

オリジナル

https://kamelink.com/blog/2023/07/24/1-3-17-sibaurakoudai-kou-sisurikou-dezakou-kenn-1-1/

上と同じです。大学入試数学問題集成＞テキスト
未登録

# xxxx ChatGPT で(できませんでした。) xxx
入力文
```
不等式√(9x-18)<=√(-x^2+6x)をみたすxの範囲
```
XXXXX  したがって、不等式の解は 1.315 ≤ x ≤ 13.685 です。

# Mathematicaで
調子が悪いですね？(2023/07/28)
```
In
Reduce[{\[Sqrt](9 x - 18) <= \[Sqrt](-x^2 + 6 x)}, x]

Out
x == -6 || 2 <= x <= 3
```
グラフ作成
```
Plot[{\[Sqrt](9 x - 18), \[Sqrt](-x^2 + 6 x)}, {x, -10, 10}]
```
![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/27e771bd-3668-17ec-074e-dacbf9edb21c.png)

# WolframAlpha で
グラフがでます。

https://ja.wolframalpha.com/input?i=%E2%88%9A%289x-18%29%3C%3D%E2%88%9A%28-x%5E2%2B6x%29

解 2<=x<=3
　？？？？？　x = -6　？？？

# sympyで(数学入試問題 様のやり方で)同値変形しましょう．
①？？？sympyの同値変形はどのようにしたらいいですか？？？
②＞sympyのsolve関数で求めた複数の不等式の解の共通範囲を求めたい．
https://teratail.com/questions/227429
```python
from sympy import *
x=symbols('x',real=True)
my0  =Eq( sqrt(9*x-18),sqrt(-x**2+6*x)      )
my1_U=Eq( my0.lhs**2  ,my0.rhs**2           )
my1_S=Eq( my1_U.lhs           ,0            )
my2_U=Eq( my1_U.lhs-my1_U.rhs,0             )
my2_S=Eq( x           ,solve(my1_S.lhs,x)[0]) 
my3_U=Eq( factor(my1_U.lhs-my1_U.rhs),0     )
my3_S=Eq( x           ,solve(my1_S.lhs,x)[0]) 
my4_U=solve(my3_U.lhs-my3_U.rhs,x         ) 
my4_S=solve(my3_S.lhs-my3_S.rhs,x         ) 
print("#0",my0  )
print("#1",my1_U)
print("#1",my1_S)
print("#2",my2_U)
print("#2",my2_S)
print("#3",my3_U)
print("#3",my3_S)
print("#4",Intersection(Interval(my4_U[0],my4_U[1]),
                        Interval(my4_S[0],oo)))
#0 Eq(sqrt(9*x - 18), sqrt(-x**2 + 6*x))
#1 Eq(9*x - 18, -x**2 + 6*x)
#1 Eq(9*x - 18, 0)
#2 Eq(x**2 + 3*x - 18, 0)
#2 Eq(x, 2)
#3 Eq((x - 3)*(x + 6), 0)
#3 Eq(x, 2)
#4 Interval(2, 3)
```

# sympyで(solveで)
```python
from sympy import *
x=symbols('x',real=True)
myEq=Eq(sqrt(9*x-18),sqrt(-x**2+6*x))
print("#",solve(myEq.rhs- myEq.lhs >=0))
# (2 <= x) & (x <= 3)
```


![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/a209c2a0-ace5-ec56-3155-c0c021d9c0a3.png)
# sympyの実行環境
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# 参考

https://docs.sympy.org/latest/modules/solvers/inequalities.html

以下、いつもの?おすすめです。

https://qiita.com/mrrclb48z/items/75904cdc6e84ecef4d03#%E5%8F%82%E8%80%83wolframalpha-%E9%96%8B%E7%99%BA%E7%89%A9%E8%AA%9E
４月に専門学校に入学した22歳

こんにちは。
高校を卒業し、３年間社会人として働いていましたが、ずっと勉強したいと思っていたIT関係を学び、ITにかかわる仕事を就くため、専門学校に入学しました。
4月にITの情報専門学校に入学した今年22歳です。
プログラミングを勉強し始めてまだ数か月ですが、勉強の履歴として調べたこと、
エラーが起きた時の対処法、質問したことなどを少しずつまとめていけたらいいなと思っています。
たくさん知識をつけれるように頑張っていきます。
よろしくお願いします！
java アウトプット　変数


こんにちは。yukaです。
javaを勉強し始めました。自分の備忘録用として投稿しています。
今回はjavaの変数について簡単に要点だけを書いていきます。

# 基本データ型の種類
Javaの基本データ型は以下の8種類あります。

| データ型 | bit数 | 値 |
|:-----------|------------:|:------------:|
| boolean    | 1bit       | true あるいは false |
| char    | 16bit      | 文字     |
| byte       | 8bit      |整数（扱える範囲は -128～127）  |
| short   | 16bit      | 整数（扱える範囲は-32,768～32,767）|
| int      | 32bit     | 整数（扱える範囲は-2,147,483,648～2,147,483,647）    |
| long    | 64bit     |整数（扱える範囲は-9223372036854775808～9223372036854775807） |
| float    | 32bit     | 小数（精度低） |
| double    | 64bit     | 小数（精度高） |

# 変数の宣言
変数を宣言するには、以下のように型名に続けた変数名を記述する。
```
型名　変数名;
```
行末に「;（セミコロン）」を必ずつけます。
Javaでは、命令の終わりにセミコロンが必要で、書き忘れるとエラーになります。


# 変数を使う
エディタを使用して、以下のコードを記述します。
このコードはJavaでは必ず書かなくてはいけないコードです。
下記の「//ここに処理を記述する」と書かれた箇所にコードを記述していきます。
```java
class Main {
  public static void main(String[] args) {
    //ここに処理を記述する
  }
}
```
「//ここに処理を記述する」のところに以下のコードを入れて実行してみよう。
すると計算結果が「78.5」と表示されます。
```java
int radius;
radius = 5;
System.out.println(radius * radius * 3.14);
```
このコードの意味は
① int radius;によって、int型の変数radiusを宣言する
② radius = 5;によって、変数radiusに整数の5を代入する
③ printlnを実行して、計算結果を出力する。

このように、Javaで変数を使用する際には、まず型の宣言が必要です。

# 型推論
まず型推論を利用した変数の宣言方法について見てみましょう。
```java
var 変数名 = 値
```


「var」を使って宣言を行い、初期値を代入すると、先ほどの①・②をまとめることができる。
```java
int radius;
radius = 5;
System.out.println(radius * radius * 3.14);
```
　　　↓↓
```java
var radius = 5;
System.out.println(radius * radius * 3.14);
```
varに変えて実行してみよう。同じ結果になることが分かる。
このようにvarを使用すると、代入する値（今回の例では5）からデータ型を推論してくれるため、int型であるという宣言が不要になります。

__データ型の種類を確認する__
以下のようにコードを追加し、実行しよう。
```java
class Main {
  public static void main(String[] args) {
    var radius = 5;
    System.out.println(radius * radius * 3.14);

→   System.out.println(((Object)radius).getClass().getSimpleName());
  }
}
```

実行すると「Integer」と表示され、変数radiusが整数型で宣言されていることがわかります。
Pythin 3.10 の pip にアップグレード & request ライブラリの Lambda レイヤーを作成する方法



Lambda で requests を使いたかったので、Lambda レイヤーを作成する時に Pything 3.10 の pip に切り替えて requests の zip ファイルパッケージを作ったときのメモ書き

MacOS の Homebrew での作業です。

```
$ brew install python@3.10
# python3.10 -m pip install --upgrade pip
```

```
$ pip --version
pip 23.2.1 from /usr/local/lib/python3.10/site-packages/pip (python 3.10)
```

```
$ mkdir python
$ pip install -t python requests==2.28.2
$ zip -r9 layer.zip python
```

- Lambda Layer を追加
- Lambda 関数に Layer を紐付け



参考
https://stackoverflow.com/questions/54409696/upgrading-pip-for-different-versions-of-python
https://sebenkyo.com/2021/05/21/post-1979/
なんか

    Dim AcrobatApp As Object ' Acrobat.Application
    Dim PDFDoc As Object ' Acrobat.Document
    Dim FilePath As String
    Dim OldPassword As String
    Dim NewPassword As String
    
    ' パスワードを設定したい既存のPDFファイルのパスを指定
    FilePath = "C:\フォルダ\既存のPDFファイル.pdf"
    
    ' 既存のPDFファイルのパスワード（設定されている場合）と新しいパスワードを指定
    OldPassword = "" ' 既存のパスワードがない場合は空文字列を指定
    NewPassword = "新しいパスワード"
    
    ' Acrobatアプリケーションを起動
    Set AcrobatApp = CreateObject("AcroExch.App")
    AcrobatApp.Show ' Acrobatのウィンドウを表示（不要な場合はコメントアウト）
    
    ' PDFを開く
    Set PDFDoc = CreateObject("AcroExch.PDDoc")
    If PDFDoc.Open(FilePath, OldPassword) Then
        ' パスワードを設定
        If PDFDoc.SetSecurity(1, "", NewPassword, 0, "", "") Then ' 1: パスワード保護, 0: 印刷の制限なし
            ' パスワード付きで上書き保存
            If PDFDoc.Save(1, FilePath) = False Then
                MsgBox "PDFの保存に失敗しました。", vbExclamation
            End If
            ' PDFを閉じる
            PDFDoc.Close
        Else
            MsgBox "パスワードの設定に失敗しました。", vbExclamation
        End If
    Else
        MsgBox "PDFファイルのオープンに失敗しました。", vbExclamation
    End If
    
    ' Acrobatを終了
    AcrobatApp.Exit
    Set AcrobatApp = Nothing
    
    MsgBox "PDFファイルにパスワードを付与しました。", vbInformation
【Rails7】Javascriptがリロードしないと動かないとき

## 結論から
　data:{turbo: false}　を加えてください。


  ```ruby:例
   <%= link_to "リンク", some_path, data: { turbo: false } %>
   <%= form_with model: @model, data: { turbo: false } do |form| %>
  ```
　

## 原因
Rails7ではTurbo（以前はHotwireとも呼ばれていました）がデフォルトで有効になっており、これが悪さをしています。

とはいえ、基本はTurboを否定する必要はないので、javascriptが関わる部分だけ上記の記述をしましょう。

## 別の方法
アプリ全体でTurboを無効にする

```diff_javascript:application.js
- import "@hotwired/turbo-rails"
+ import { Turbo } from "@hotwired/turbo-rails"
+ Turbo.session.drive = false
```


## ちなみに意味がない方法
■　document.addEventListener("turbo:load", function() {})
　　⇒　"turbo:load"を"load"にしてみる

　turboの記述は、あってもなくてもデフォルトで有効になります。
[備忘録シリーズ] gitで過去のcommitを修正する方法

# 直前のcommitの場合
1. `git commit --amend -m “修正コメント”`
2. `git rebase --continue`
3. `push -f origin <target_branch>`

# 2個以上前のcommitの場合
1. `git rebase -i HEAD~n` （nは戻りたいcommitが直前のcommitから見て何番目かを入れる）
2. 変更したいcommitを全て`pick`から`edit`へ変更し、保存
3. `git commit --amend -m “修正コメント”`
4. `git rebase --continue`
5. HEADが`edit`したcommitを古い順に移動するので、#3→#4を繰り返す
5. `git push origin <target_branch>`(差分で問題があれば`-f`オプションを使う。気をつける）

# ログの確認
1. `git log --oneline`でHEADやcommit idの確認ができる
WSL + C/C++でのデバッグで変数のウォッチができない問題の対処法

# はじめに
最近になってAtCoderを触りはじめました。AtCoderにはコードテストがあるためわざわざ環境構築をする必要はありませんが、やはり使い慣れたエディタ上で作成をしたいものです。
Visual Studio 2022を使うことも考えましたが、ソースコードの管理の点で使いにくいと感じたため、Visual Studio Codeを使用しています。
言語は既に環境構築をしているPythonを使用していましたが、C/C++を使おうとして環境構築で躓いたため備忘録として本記事を書きます。

# 環境構築
環境構築は以下の記事を参照しました。この記事の通りにやれば一通りできると思います。
私は Windows10 + VSCode + WSLの環境で構築しました。

https://note.com/syntax_error_/n/ndded92400e46


# 問題発生
テストコードも動かせることだし実際にコードを作成してみようと思いデバッグを始めた所で問題に気がつきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519793/c338e45f-3992-2108-ebb6-56a3b47b6264.png)
ブレイクポイントが設定されている時点で既にNや配列への入力は済んでいるため、画面左側の`変数>Locals `に表示されているはずです。しかし、何も表示されておらず、これでは Visual Studio 2022 の代わりとしてのエディタにはなれません。
なんとかして問題を解決する必要が出てきました。

# 解決策
色々と弄ってみた結果、問題はtask.jsonにありました。環境構築の手順に従って作成した時点で以下のようになっていました。
```task.json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "/usr/bin/g++",
            "args": [
                "-std=gnu++17",
                "-Wall",
                "-Wextra",
                "-O2",
                "-g",
                "-fsanitize=address,undefined",
                "-I${workspaceFolder}/ac-library",
                "-o",
                "${workspaceFolder}/program",
                "'${file}'",
            ],
			"options": {
				"cwd": "${fileDirname}"
			},
			"problemMatcher": [
				"$gcc"
			],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "echo": true,
                "reveal": "silent",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false,
                "clear": true
            },
        }
    ]
}
```
問題は、"arg"で渡している最適化オプション("-O2")にありました。最適化は高速化を図ることが出来ますが、その反面として今回のような意図しない結果を産んだと思われます。
なのでこのオプションを最適化を行わない"-O0"に書き換えます。
```diff_json
"args": [
    "-std=gnu++17",
    "-Wall",
    "-Wextra",
-    "-O2",
+    "-O0",
    "-g",
    "-fsanitize=address,undefined",
    "-I${workspaceFolder}/ac-library",
    "-o",
    "${workspaceFolder}/program",
    "'${file}'",
],
```
これで無事想定通りに動きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519793/7c465e1d-bfe4-ff14-8c17-895455236345.png)

# おわりに
Visual StudioでC/C++を使っていた時は、最適化がデバッグ時に問題を引き起こすということがなかったので、今までいい感じにエディタがやっていてくれていたのかなと思いました。
また余談ですが、ネットで調べてもデバッグのやり方を書いた記事が多く出てきたものの、解決方法を見つけることは難しかったです。この記事が今後誰かの役に立てばいいなと思います。

本記事について誤字脱字や語弊などがありましたら、指摘して頂けると幸いです。
JSON.parse()

## JSON.parse()

:::note
JavaScriptの組み込み関数
**JSON(JavaScript Object Notation)の文字列をJavaScriptオブジェクトに変換する**
:::

**JSON** : データのシリアル化やデータ交換などで使われる軽量なデータ形式

- **シリアル化**
 JavaScriptオブジェクトをJSON形式の文字列に変換すること

- **デシリアル化**
JSON形式の文字列をJavaScriptオブジェクトに変換すること


### JSON.parse()
:::note
**JSON形式の文字列を受け取る
↓
解析
↓
対応するJavaScriptオブジェクトに変換**
:::

### JSON

- **文字列** : キーと値をダブルクォートで囲む
- **オブジェクト** : 中括弧 {} で囲む
- **配列** : 角括弧 [] で囲む

## JSON.parse()の使用例

```javascript
const jsonString = '{"name": "John", "age": 30, "isMarried": false}';
const parsedObject = JSON.parse(jsonString);
console.log(parsedObject.name); // "John"
console.log(parsedObject.age); // 30
console.log(parsedObject.isMarried); // false
```

### 注意

**JSON.parse()は有効なJSON形式の文字列を受け取る必要がある
→ダブルクォートを使用**

- シングルクォートで囲まれた文字列はJSON形式とは見なされない
- JSON形式の文字列にはコメントが含まれない
- トリリオンのようなBigIntをサポートしていない

***
##### JSON.parse()がよく使用される例
- APIから取得したJSONデータをJavaScriptで扱う場合
- LocalStorageやSessionStorageに保存されたJSONデータを取得する場合
[MR Dev Tips #1] UnityEngine.Application.StreamingAssetsPath のフォルダパスについて

Unity で HoloLens 2 のアプリケーションを開発する際に、``Application.StreamingAssetsPath`` を用いて、ファイルを保存すると、以下ファイルパスに保存される。

| 変数名 | パス |
| --- | --- |
| Application.StreamingAssetsPath | ``C:/Data/User/<UserName>/AppData/Local/DevelopmentFiles/<ApplicationName>/Data/StreamingAssets`` |


Application.streamingAssetsPath で取得できる StreamingAssets フォルダのパスは読み取り専用です。プラットフォームごとに、配置されるフォルダのパスは異なるので注意。


# Refs
- [Application.streamingAssetsPath](https://docs.unity3d.com/ja/2020.1/ScriptReference/Application-streamingAssetsPath.html)
チーム開発をして感じたこと

# まず初めに
この記事はまだまだ何も知らないただのペーペーである筆者が自分の考えていたことを後から見直せるように、考えていることを言語化して整理するために書いているものです。なにか勉強になる記事を求めている方は別の記事を読むことを推奨します。

# 前提
Connect開発プロジェクトは僕がPMをしていたアプリ開発プロジェクトです。僕はPMとしてアプリのコンセプト、そしてどうユーザにリーチして使ってもらうか考える事、計画どおりに開発を進める事などに責任をもって行いました。また、この開発プロジェクトにおける一番の目的はアプリを開発し公開してユーザに使ってもらうという一通りのプロセスを行いアプリ開発を勉強するという事でした。そのため、お金の動きは一切発生しないプロジェクトでした。

# マネジメント的視点で学んだこと

今回のプロジェクトにおいて、マネジメントをする中で１番自分に求められた能力は適切にタスクを振り分けて、スケジュールを完遂することでした。それを実現するために必要な３つの事が「やることの明確化」、「責任を渡す」、「期限を決める」でした。<br>またやることの明確化では、どれくらいの粒度でタスクを渡すかが非常に重要でした。粒度を極限まで小さくして、誰がやっても同じになるようにしてから渡してしまうと、その人の見える範囲が狭くなってしまします。また、粒度が大きすぎても適切にやりたいことが伝わらないこともあります。よって、開発メンバーに見てもらう範囲をタスクの粒度を通して適切に調整することはマネジメントとして、とても大きな意味を持つと学びました。

# 思い切って大きな単位でタスクを振った話
ある時、一緒に開発してくれている人に、管理者側の機能の設計から実装まで大きく任せてみました。これの理由は、正直自分のキャパ的に余裕がなくなっていたからでした。しかし、結果的に上述の事を学べたためこれは成功でした。実際、その人も見える範囲と責任を大きく持ったことで、自分で調べて自分で課題を考えて実行することをしてくれていました。本来これが人と共にやることの大きな意義であり、この経験はその後のマネジメントにおいて大きな糧となっています。

# PMよりもやりたいことがある 
元も子もないことですが、今回のプロジェクトを通して自分の本当にしたいことはPMの仕事ではないと感じました。PMとしての仕事は、最終的なプロジェクトの成功に対して責任を持つことです。そのため、アプリをどう宣伝するか、ポスターの作成依頼、ポスターを掲載させてもらう大学との調整、プロジェクトメンバーのモチベーション管理など、開発ではないところの仕事が非常に多く、PMをしているうちに自分が本当にやりたいことはこれではなく、もっと技術に特化してバリバリ開発することにあると気づきました。もちろん、自分の見る視点を絞ってPM的な視点を完全に捨てるのは間違っていますが、一番トップの立場は違うなと感じたのです。

# お金が動かないことによる限界
今回の開発プロジェクトはアプリ自体収益化しておらず、開発メンバーに対しても開発経験が出来るということをメリットとしていたので、お金は発生していませんでした。しかし、実際開発をしようとするとお金が発生していないわけで責任も発生しないので、メンバーのコミット量はメンバーのモチベーションに依存することになります。もちろん、こちらから話したりしている中で実装するアプリに対して興味を持ってもらってモチベーションを高めることなど工夫したりもしましたが、これは根本的な解決でなく効果は一時的であったり、コストのかかるものでした。結果としてはメンバーの入れ替えなどあったりして、なんとかスケジュールに合わせて公開するとこまでたどり着くことができました。そのため、実際にアプリ開発をして公開をすることで、勉強をするというプロジェクトの一番の目的は達成でき、プロジェクトも一区切りとなりました。そんな時、別のアプリ開発プロジェクトで技術リーダ的なポジションで参加してくれないかと誘ってもらいました。そちらは、アプリを収益化して開発者で利益分配をすることも目的の一つでしたので、是非参加させて欲しいという事でその誘いを受けることにしました。

# まとめ
Connect開発プロジェクトはPMなんてやってましたが僕自身初めてのアプリ開発であり、非常に多くの学びがありました。プロジェクトの第一目標自体、勉強に置いていたので成功として捉えることが出来ると思います。しかし、さらに次のステップに進むためにも、上述のお金の限界などもあったので参加することになったプロジェクトで技術に特化しアプリの質を向上させることで、収益化に対して取り組んでいきたいです。
エクセルVBAで、「パスで指定したディレクトリに含まれているファイル名」が格納された配列を取得する関数

# 結論
`Dir`関数を使用してタイトルにある関数を作成できます。

# Dir関数
`Dir`関数は、「引数に指定したファイルパスに一致したファイル」のうちの1ファイルのファイル名を取得する関数です。
また、引数を指定しない場合、「最後に指定したファイルパスに一致したファイル」のうち、まだ取り出していない1ファイルのファイル名を取得します。
引数の有無にかかわらず、該当するものがない場合は空文字が返ってきます。
この関数を利用してタイトルにある関数を作成します。

# 前提
このVBA記述されたエクセルファイルと同階層に「test」というディレクトリがあるとします。
また、そのディレクトリのファイル構成は以下です。
```
エクセル1.xlsx
エクセル2.xlsx
エクセル3.xlsx
エクセル4.xlsx
エクセル5.xlsx
テキスト1.txt
テキスト2.txt
テキスト3.txt
テキスト4.txt
テキスト5.txt
```

# サンプルコード
```vb
Sub 検証()
    Dim DirectoryName As String: DirectoryName = "test"
    Dim FileNames() As String
    'ThisWorkbook.Pathは、開いているエクセルファイルのファイルパス
    FileNames = GetFileNamesInDirectory(ThisWorkbook.Path & "\" & DirectoryName)

    '空配列チェック
    If (Not FileNames) = -1 Then
        Exit Sub
    End If
    For i = LBound(FileNames) To UBound(FileNames)
        Debug.Print (FileNames(i))
    Next
End Sub

Private Function GetFileNamesInDirectory(ByRef DirectoryPath As String) As String()
    Dim tmp() As String
    Dim i As Long: i = 1

    '指定したファイルパスに一致したもののうち、1ファイルのファイル名を取り出す
    Filename = Dir(DirectoryPath & "\")
    While Filename <> ""
        ReDim Preserve tmp(1 To i)
        tmp(i) = Filename
        i = i + 1
        '最後に指定したファイルパスに一致したもののうち、まだ取り出していない1ファイルのファイル名を取り出す
        Filename = Dir
    Wend

    GetFileNamesInDirectory = tmp
End Function
```

### 結果
```
エクセル1.xlsx
エクセル2.xlsx
エクセル3.xlsx
エクセル4.xlsx
エクセル5.xlsx
テキスト1.txt
テキスト2.txt
テキスト3.txt
テキスト4.txt
テキスト5.txt
```

無事、ディレクトリ内のファイルを取得できました。

# 補足
1. 上記の関数では指定パスのディレクトリに含まれているファイルだけが取得できます。「指定パスのディレクトリに含まれているディレクトリ」は取得できません。
1. `Dir`関数で指定するパスはディレクトリでなく、ファイルパスも指定できます。そしてワイルドカードも使用できます。これを応用すると、エクセルファイルに絞り込んで配列に格納することもできます。
```vb
Sub 検証2()
    Dim DirectoryName As String: DirectoryName = "test"
    Dim FileNames() As String
    'ThisWorkbook.Pathは、開いているエクセルファイルのファイルパス
    FileNames = GetExcelFileNamesInDirectory(ThisWorkbook.Path & "\" & DirectoryName)

    '空配列チェック
    If (Not FileNames) = -1 Then
        Exit Sub
    End If
    For i = LBound(FileNames) To UBound(FileNames)
        Debug.Print (FileNames(i))
    Next
End Sub

Private Function GetExcelFileNamesInDirectory(ByRef DirectoryPath As String) As String()
    Dim tmp() As String
    Dim i As Long: i = 1

    '指定パスのファイルを検索して、1ファイルのファイル名を取り出す
    Filename = Dir(DirectoryPath & "\" & "*.xls*")
    While Filename <> ""
        ReDim Preserve tmp(1 To i)
        tmp(i) = Filename
        i = i + 1
        '最後にパスを指定したフォルダの中から、まだ取り出していない1ファイルのファイル名を取り出す
        Filename = Dir
    Wend

    GetExcelFileNamesInDirectory = tmp
End Function
```
```
エクセル1.xlsx
エクセル2.xlsx
エクセル3.xlsx
エクセル4.xlsx
エクセル5.xlsx
```

以上です。

# 参考

https://www.helpforest.com/excel/emv_sample/ex100012.htm

https://happy-tenshoku.com/post-2347/
単体テスト内容

![単体テスト_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519994/bcb6df51-ba4d-bd62-892b-c6bca40e7f9a.jpeg)
![単体テスト_page-0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519994/1930d580-479f-6240-7ab3-ed0362c12cfb.jpeg)
【nodenv】インストールできるバージョンの最新化

## はじめに

今日 Node.jsのLTSバージョンを調べたところ`18.17.0`だったので、`nodenv`を利用してインストールを試みたところ、バージョン一覧に表示されませんでした。  
そこで`nodenv`でインストールできるバージョンを最新化します。

### 環境

- Intel Mac 13.4.1(c)

### 前提

- `nodenv`が利用できること

## 手順
### 対応前の状態

対応前に`v18`でインストール可能なバージョンは以下のようになってました。(`18.17.0`が無い)

```sh
# nodenvのバージョン
$ nodenv --version
nodenv 1.4.1

# node-buildのバージョン
$ node-build --version
node-build 4.9.117

# 18系でインストール可能な一覧
$ nodenv install --list | grep -e "^18"
--- 省略 ---
18.16.0
18.16.1
```

### 最新化

#### `nodenv`を`Homebrew`でインストールしている場合

Homebrewで`nodenv`および`node-build`を最新化すればOKでした。

```sh
$ brew upgrade nodenv node-build
```

- [参考: オフィシャルサイト](https://github.com/nodenv/nodenv#using-package-managers)


### 対応後

```sh
# nodenvのバージョン
$ nodenv --version
nodenv 1.4.1    <- 変更なし

# node-buildのバージョン
$ node-build --version
node-build 4.9.119    <- 更新された！

# 18系でインストール可能な一覧
$ nodenv install --list | grep -e "^18"
--- 省略 ---
18.16.0
18.16.1
18.17.0    <- 追加された！
```

---

備忘録として残します。
github備忘録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/33df0817-0188-97cb-b0a9-386cbe314d73.png)
リポジトリ作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/fbb16e46-18c5-b621-e9e1-c811ac3a0f9b.png)
public repositori name のみを入力し作成


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/835615c4-757a-f329-f876-3d59fa24de0f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/d2fc53ef-94f3-5fd4-1e33-d52c57840e44.png)
何も出てないのを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/572e1c9c-bf09-9112-11e2-810342b5079d.png)
一連の流れ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/9b1b5dd1-76f9-6e12-b4c3-c73e20fec37b.png)

txtファイルが追加されている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/a0c65853-6af4-88bc-ac79-26dda0b6d332.png)

sourcetreeにフォルダ追加

共同作業用にコラボレーターの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/a7d122f9-b23f-deca-e693-6e0086c4e260.png)
settingsを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/cda43306-13a7-19af-8d7c-69e7e0ecd1ad.png)
collaboratorsからadd peopleで共同作業者のinviteを行う

spring boot用設定


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/caf1f619-f6a5-7f2b-f70e-d5fef07825b9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/35120b97-cb9b-6b72-f1a7-318d373bb360.png)

eclipsで作成しとく（パッケージ名も変える）

repositoryをshop99で作成する
discordのチャンネルに特定のワードが投稿されたときにDMで教えてくれるbot

chatGPTに教えてもらいながら作りました
動機はゲーム関係です

FF14というゲームで、レアモンスターが出現したことを通知してくれるdisco鯖があるのですが、あまりに通知が多いので、botを使って特定のモンスターの時だけアナウンスできるようにしたいと思い立った次第です
※結局サーバーにbotを追加する権限がないので使うことができませんでした泣

何かに役立つかもしれないので書き記しておこうと思います

~~~python
import discord

# Discordボットのトークンをここに入力します
TOKEN = 'hoge'
# 監視したい特定のワードをここに入力します
TARGET_WORD = 'hogehoge'

# 必要なIntentsを指定してClientを初期化
intents = discord.Intents.default()
intents.messages = True  # メッセージイベントを監視
intents.guilds = True    # サーバー参加・退出イベントを監視

# Discord Clientを作成
client = discord.Client(intents=discord.Intents.all())

@client.event
async def on_ready():
    print(f'We have logged in as {client.user}')

@client.event
async def on_message(message):
    # bot自身のメッセージは無視
    if message.author == client.user:
        return
    
    content = message.content.strip()

    if TARGET_WORD.lower() in content.lower():
        # DMを送信したいユーザーのID（DiscordユーザーID）を指定
        target_user_id = hogehogehoge  # ここにユーザーIDを入力

        # 特定のユーザーにDMを送信
        target_user = await client.fetch_user(target_user_id)
        if target_user:
            dm_channel = await target_user.create_dm()
            await dm_channel.send('特定のキーワードが検出されました！')

# ボットをDiscordに接続
client.run(TOKEN)
~~~

bot作成やユーザーIDの取得など面倒でしたが、ちゃんと動く用になったので嬉しかったです
私の環境ではprompt上で実行しないとエラーが出て動きませんでした
mtoa5 make tx

```
D:/tool/runtime/MtoA5/versions/002.002.001/Maya2022/windows/x64/bin/maketx -v -u --unpremult --oiio --colorengine ocio --colorconfig D:/tool/settings/ocio/v5/config.ocio --colorconvert srgb ACEScg D:/asset/character/Char/all/-/-/rig/anim/default/Char_all_default.v005/sourceimages/v020/leonTeeth_baseCol_srgb_mid.tif -o D:/asset/character/Char/all/-/-/rig/mid/default/Char_all_default.v002/sourceimages/v020/leonTeeth_baseCol_srgb_mid.tx
```
Python　辞書型の配列を定義する方法

※忘れないようにするためのメモ

## Pythonで辞書型の配列を定義する方法
```Python
array = []
array.append({
    'name': '鈴木', 
    'age': 20,
    'address': '北海道'
})
array.append({
    'name': '佐藤', 
    'age': 30,
    'address': '沖縄'
})
```

## print()で出力した場合
```Python
[{'name': '鈴木', 'age': 20, 'address': '北海道'}, {'name': '佐藤', 'age': 30, 'address': '沖縄'}]
```
ゼロ位相フィルタに関する備忘録

# はじめに
業務の中で，ローパスフィルタ(LPF)を検証する場面があり，その中でゼロ位相フィルタを実装しようとしたことがありました．しかし，私の勉強不足故に，いくつか学ばされることがあったため，備忘録としてゼロ位相フィルタについてまとめさせて頂きます．(間違いがございましたら，ご指摘いただけると幸いです．)
# ゼロ位相フィルタを導入するに至った背景
本業の中で，遅れが最小で，かつ振動抑制効果が高いLPFを設計することが求められていました．この問題に関して，解決方法を調査したところ，mathworks様のウェブサイトでゼロ位相フィルタの項目を見つけました．

https://jp.mathworks.com/help/signal/ref/filtfilt.html

「遅れもないし，抑制効果も高く，これを使ってみよう！」と私は，安易に考えてしまいました．しかし，ゼロ位相フィルタを適用する上での前提条件を見落としていました．

# ゼロ位相フィルタの数理と前提条件
ここでは，ゼロ位相フィルタの数理を説明することで，適用する際の前提条件を記します．実装をMatlab/Simulinkのコマンド「filtfilt」により行うため，Signal Processing Toolboxのユーザガイドを参照し，コマンドの内部の計算を確認しました．

https://jp.mathworks.com/help/pdf_doc/signal/signal_ja_JP.pdf

上記のファイルから，filtfiltの計算フローは下記の図になります．

![zero_phase_filter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629986/854382cc-f0d0-1cf2-bbbd-caec1cfc5977.png)


したがって，filtfiltは下記の計算が行われていることになります．

全データを用いて，z変換$X(z)$を計算する．
```math
\begin{align} 
X(z) &= \sum_{k=0}^{n} x[k]z^{-k} 
\end{align}
```
次に，LPFを施します．LPFは次式で表されるとします．
```math
\begin{align} 
H(s)  &= \frac{K}{1+T_cs}\tag{1}
\end{align}
```
上の式は連続時間系ですので，離散時間系に変換します．
```math
\begin{align} 
    z &= e^{T_ds}\\
      &= 1 + T_ds + \frac{(T_ds)^2}{2!}+\cdots\\
      &\approxeq 1 + T_ds
~~~~~~~~\because \text{$\|T_{d} s\|\ll1$とし，二次以上の項を無視しました．}\tag{2}
\end{align}
```
式(1)，(2)より，離散時間LPFの伝達関数は，式(3)となります．
```math
\begin{align} 
    H(z) &= \frac{K}{1+T_c(\frac{z-1}{T_d})}\\
         &= \frac{KT_d}{T_d+T_c(z-1)}\tag{3}
\end{align}
```
上記の式(1)，(3)を用いて，filtfiltの計算フローに従って，
ゼロ位相フィルタを施すことになります．

ただし，z変換の計算に開始時刻から現時点までのデータが必要になります．したがって，ゼロ位相フィルタを適用するには，全データが必要になります．実際に，mathworks様の例も心電図のノイズ除去であり，この例においても全データが分かっている前提で，コマンドが実行しております．このことから，リアルタイム演算と相性が悪いです．

# ゼロ位相フィルタをリアルタイム実装するための修正
上記の内容を踏まえて，リアルタイム実装するには修正を加える必要があります．サンプリング時間$T_s$の間，データをサンプリングし，サンプリングしたデータに対してゼロ位相フィルタを施す仕様に修正します．そのために現時刻から，$T_s$前の時刻までのデータをすべて用いて，ゼロ位相フィルタを施すような，ゼロ位相フィルタっぽいものを実装し，検証します．

# Simulinkモデル作成とシミュレーション検証
シミュレーションはSimulinkで行いました．シミュレーションモデルは下記の写真を用いました．

![スクリーンショット 2023-07-25 114634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629986/13cbf66d-c199-cf8c-2c9c-d5f4c1876df6.png)

入力$u(t)$は私の方で勝手に以下の式で定め，用意しました．$\mathrm{rand}$は一様乱数です．
```math
\begin{align}
 u(t) = &\frac{100}{1+e^{-2\times 10^{-2}t}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0\le t\le 2.5)\\
 u(t) = &u(2.5)+ 4\sin(\pi t/25)+\mathrm{rand}~~~~~~~~(2.5< t\le 15)\\
 u(t) = &u(15)-\frac{u(15)(t-15)}{5} + \mathrm{rand}~~~~~(15< t\le 20)
\end{align}
```
シミュレーション結果は次の通りになりました．
![data2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629986/e4f584a8-5fcb-c496-2e3f-bb909be7e217.png)


やはり，データをサンプリングする過程の影響で，遅れが出てしまいました．特にステップ入力になると遅れの影響が大きく表れてしまいそうです．一方で，この例においては，振動している区間($t\in[2.5,~ 15]$)においては，遅れの影響も小さく，振幅も抑制できてそうです．また，LPFの種類(bessel型，butterworth型，etc...)を変えてみたらもっといい結果が得られるかもしれません．



# おわりに
最後まで読んで頂きありがとうございます。ゼロ位相フィルタを安易に適用して，イマイチなフィルターを設計してしまった反省として記事を書かせていただきました．何かの参考になれば幸いです．
このバッチは、ダブルクリックで起動されたか、コンソールから起動されたか、分かるよ！＝＞うそでした！

## バッチがどうやって起動されたか知りたくないですか？
:::note warn
2023/7/28環境変数SESSIONNAMEが分からなくなりました。

バッチをファイルサーバに置いて、ダブルクリックするとSESSIONNAMEはブランクにならずにConsoleになることが分かりました。
ローカルドライブや、one driveにあるバッチのダブルクリック起動の場合は、ブランクです。
いったい、どんな基準で、この変数に値が入るのかわからないので、この書き込みは信じないでください。
とはいえ、ローカルでテストしている時は便利なんですが・・・。
:::

（2023/7/26タイトルと内容を少し変更しました。）

それが分かるだけです。(^^ゞ
たまたま、環境変数SESSIONNAMEってなんだ？と思って調べてみました。

バッチの魅力って、
１．何もインストールせずに動く。
２．ダブルクリックでも起動できる。
と思ってます。

ダブルクリックでバッチを起動したら、画面を残したいからpause入れることないですか？
でも、コンソールからコマンド起動したときはpauseが邪魔。
そんな時、起動方法を判定してpauseを入れることができます。

終了の手前に、以下を入れるだけ。
```bat:
if "%SESSIONNAME%"=="" pause
```

リモート起動は出来なかったので、その部分はテストしてませんが、こんな感じでした。

```bat:
@echo off
if "%SESSIONNAME%"=="" (
    echo バッチファイルをダブルクリックして起動しました。
    pause
) else if "%SESSIONNAME%"=="Console" (
    echo コマンドコンソールから起動しました。
) else if "%SESSIONNAME:~0,4%"=="RDP-" (
    echo リモートで、起動しました。
) else (
    echo SESSIONNAMEが「%SESSIONNAME%」です。
    echo どうやって起動ましたか？
)
```