OmniAICreator/Qiita-1.07M huggingface dataset:
rex0220 計算式プラグイン 計算対象の項目を編集

rex0220 計算式プラグインで、計算対象の項目を編集する方法です。
循環参照になりますので、少しコツが必要です。

# 概要

計算式プラグインは、編集画面表示や項目の値変更・レコード保存時などのタイミングで計算処理を実行します。
そのため、計算対象の項目を手入力するには、条件によって入力された値を維持するような計算式にする必要があります。

今回は、下記のような自動計算を行う締切日を手入力可能にします。
・開催日と締切日の項目
・締切日は開催日の２日前を自動セット
・ただし、締切日自動セット後は、手入力による変更可とする
・開催日がクリアされた場合、締切日もクリア

![2023-11-21_21h10_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/1b7a7cd6-1f27-41d4-4535-345af275a056.png)

# 操作例

開催日入力時に、締切日を自動セット。その後、締切日を手入力します。
今回の計算式では、開催日が締切日後に変更されても、締切日は変更されません。

![2023-11-21_21h25_40.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e8f085dd-fe5e-6afa-7b80-d1c80efd7c12.gif)

# フォーム設定
開催日と締切日のみ

![2023-11-21_21h15_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/31c0f76c-1459-49be-cb2d-f0c403e1f538.png)

# 計算式プラグイン設定

「循環参照を許可」をチェックして、締切日の計算式を設定します。

```.js
OPTION: 循環参照を許可

// 締切日 DATE (editable)
IFS(
  // 締切日自動セット (開催日あり,締切日なし)
  AND(開催日,締切日=""), DATE_ADD(開催日, -2, "day"),
  // 締切日維持（手入力・自動セット）
  開催日, 締切日,
  // 締切日クリア（開催日なし）
  ""
)
```

![2023-11-21_21h20_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/231d6400-fb16-4320-0601-76fee78bff91.png)
firewalldを設定する(自サーバのHTTP/HTTPSへのアクセスを可能にする)

firewalld の設定について復習を兼ねて書いていきます。思いつきで書いているので順番バラバラです。内容間違ってたらすいません。
* 常に恒久的な設定として使いたいので、--permanent オプションを使います。一時的に使いたいだけなら --permanent を除去してください。
* 環境は Redhat9系です。AlmaLinux9で設定しています。
* firewalld は起動してください。 systemctl start firewalld
* selinux は切って(disable)ください。分かる人は有効に。


### 今回のパターン
* サーバのNICは ens0p3 という名前 (VirtualBoxだったので)
* このサーバではApacheサーバが動作していて、それをアクセスさせたいのでHTTPとHTTPSを通信許可したい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/785184/42f36e1c-a2b1-8f80-70d0-1a709fc8d162.png)

### 1.ゾーンの選定
どのゾーンを使っても良いのですが(ゾーン設定をいじくり回せばどのゾーンでも好きな動作をさせることができる)、色々いじるのは面倒なので今回はexternalを使用します。externalゾーンは初期では以下のような感じになっています。

基本的な動作：全てを拒否
PING応答： OK(PING応答する)
通信OKのサービス ：ssh

### 2.externalゾーンから不要なサービスを削除する
* ゾーンexternalの通信OKから ssh を削除する
firewall-cmd --permanent --zone=external --remove-service=ssh

### 3.externalゾーンに必要なサービスを追加します
* ゾーンexternalの通信OKにHTTPを追加する
firewall-cmd --permanent --zone=external --add-service=http

### 4.ゾーンexternalを インターフェース enp0s3 に割り当てる
firewall-cmd --permanent --zone=external --change-interface=enp0s3

### 5. 設定を有効化する
firewall-cmd --reload

### 6. externalゾーンの設定を確認する
firewall-cmd --info-zone=external
多分こんな感じ
```
external (avtive)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: http https
  ports:
  protocols:
  forward: yes
  masquerade: yes
  forward-ports:
  source-ports:
  itmp-blocks
  rich rules:
```

以上で http サービスにアクセスができるようになると思います。
laravel existsバリデーションで論理削除もチェックする

# 概要

- existsバリデーションで論理削除されている場合バリデーションエラーにする方法をまとめる。

# 困りごと

- laravelのバリデーションルールにexistsという物がある。リクエストで送られた値がテーブルに存在するかをチェックできる。
- idなどがpostされたときに使うバリデーションルールとして一般的だが、`exists:テーブル名,カラム名`としただけだと論理削除レコードを考慮してくれない。（論理削除されていたとしてもレコードが存在していたらバリデーションで弾かない。）

# 方法

- 下記のようにテーブル名、カラム名に追加してdeleted_atとnullを追加する。

    ```php
    return [
        'id' => ['exists:テーブル名,カラム名,deleted_at,null'],
    ]
    ```
AWS CodeDeploy EC2 appspec.ymlを簡単に解説してみる

## 概要

CodeDeployのデプロイで使うappspec.ymlの項目をちょっとだけ簡単に解説してみる。

## 対象のファイル

```appspec.yml
version: 0.0
os: linux
files:
  - source: ./
    destination: /var/www/html/test
file_exists_behavior: OVERWRITE
hooks:
  ApplicationStop:
    - location: scripts/application_stop.sh
      timeout: 60
      runas: root
  BeforeInstall:
    - location: scripts/before_install.sh
      timeout: 60
      runas: root
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 60
      runas: root
  ApplicationStart:
    - location: scripts/application_start.sh
      timeout: 60
      runas: root
  ValidateService:
    - location: scripts/validate_service.sh
      timeout: 60
      runas: root
```

| キー | 内容の概要 | 備考 |
| :-- | :-- | :-- |
| version | appspec.ymlそのものの内容 | 初めて作ったときは0.0を記載 |
| os | 動作OSを記載 | 今回はAmazonLinux用なのでlinuxと記載 |
| files | デプロイするファイルの設定 |  |
| ┗ - source | デプロイ元となるコードの階層指定 | Githubで管理されているリポジトリのルートがデプロイルートの場合`./`になる |
| ┗ destination | デプロイ先ディレクトリ指定 | EC2インスタンスのどこのディレクトリに`- source`で指定したファイル群を設置するのかを指定する |
| file_exists_behavior | インスタンス内のファイルのふるまい設定 | `OVERWRITE`とすることで上書きしてデプロイが可能 |
| hooks | デプロイ時の詳細な命令郡 |  |
| ┗ ApplicationStop | デプロイの最も最初に実行される処理郡 | サーバー停止処理などを記載 |
| ┗ BeforeInstall | コード取得直前に実行される処理郡 | キャッシュ削除やクリーンアップ処理などを記載 |
| ┗ AfterInstall | コード取得直後に実行される処理郡 | 関連パッケージの取得やサービスの初期化処理などを記載 |
| ┗ ApplicationStart | アプリケーション起動のための処理群 | サーバー起動処理などを記載 |
| ┗ ValidateService | デプロイの最も最後に実行される処理群 | ヘルスチェック処理などを記載 |

上記の各hooks内部の要素を簡単に下記に記載する。

- `location`: スクリプトファイルを指定
- `timeout`: 当該hooksのタイムアウトを指定
- `runas`: スクリプト実行時のユーザー指定


## 参考文献

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file.html

https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-ecs
PowerShellでオートコンプリートを使う

### ■環境
* Windows11 22H2

* PowerShell v7.4.0  

https://github.com/PowerShell/PowerShell
* inshellisense  

https://github.com/microsoft/inshellisense

### ■導入
```
PS C:\Users\masami> node --version
v20.9.0
PS C:\Users\masami> npm install -g @microsoft/inshellisense

added 83 packages in 19s

24 packages are looking for funding
  run `npm fund` for details
npm notice
npm notice New minor version of npm available! 10.1.0 -> 10.2.4
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.4
npm notice Run npm install -g npm@10.2.4 to update!
npm notice
PS C:\Users\masami> inshellisense bind
Select your desired shell for keybinding creation
  bash
  zsh
  fish
  powershell
> pwsh

✓ successfully created new bindings
```

### ■使用方法
```
PS C:\Users\masami> is -s powershell
```
その後はインテリセンスが機能するようになります  
オートコンプリートはこちらのリポジトリを使用している模様  

https://github.com/withfig/autocomplete

[例]

![1](https://github.com/pea-sys/Til/assets/49807271/da377e02-692c-4157-ad5e-7de0cd6061ed)

![1](https://github.com/pea-sys/Til/assets/49807271/de4ed437-16a9-44a5-9852-605149a7fd0f)

![1](https://github.com/pea-sys/Til/assets/49807271/72d1b8b3-ac47-4750-9d9d-e42e3d66fcf6)
Dockerを使ったrails apiモードの環境構築

## はじめに
Dockerを使ってrails apiモードの環境構築を行います。

## 環境
`ruby 3.2.2`
`rails 6.1.0`

## 作業ディレクトリ作成
はじめに作業ディレクトリを作成して`Dockerfile`と`docker-compose.yml`を作成します。

```terminal
mkdier app
```

railsコンテナはAPIとして運用するのでapi、データベースのコンテナ名はdbとしました。

```docker-compose.yml
version: '3'
services:
  db:
  api:
```

## rubyインストール
いきなりrailsをインストールするのではなくapiコンテナにrubyをインストールします。

```Dockerfile:Dockerfile
FROM ruby:3.2.2

RUN apt-get update -qq && apt-get install -y vim

WORKDIR /app
```

docker-composeも編集しましょう。

```docker-compose.yml
version: '3'
services:
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - mysql_daa:/var/lib/mysql
  api:
    build: .
    command: bash -bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
    tty: true
    stdin_open: true
volumes:
  mysql_daa:
```

.envファイルに`MYSQL_ROOT_PASSWORD=XXX`という記述をすればdocker-compose.ymlで読み込んでくれます。

一度ビルドします。

```terminal
docker-compose build
```

## railsインストール
次はapiコンテナに入りrailsをインストールします。
今回は`6.1.0`でバージョンを固定してみます。

まずapiコンテナに入ります。

```terminal
docker-compose run --rm api bash
```

コンテナ内でrailsをインストールします。

```terminal
gem install rails -v '6.1.0'
```

インストールできたら、コンテナ内でrailsプロジェクトを作成しましょう。

```terminal
rails _6.1.0_ new . --api -d=mysql
```

### Dockerfile
あとは`Dockerfile`を編集します。
`dockr-compose up`実行ときに`bunlde install`が実行されるようにします。

```Dockerfile
FROM ruby:3.2.2

RUN apt-get update -qq && apt-get install -y vim

WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

RUN bundle install

EXPOSE 3000
```

## database接続
`database.yml`を編集してmysqlへ接続できるようにします。

まずDBに接続するためのusernameとpasswordをrailsの`credentials`を使って保存しましょう。

```terminal
docker-compose exec -e EDITOR=vim rails credentials:edit
```

私の環境では`database.yml`の設定は以下のようになりました。

```yml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= Rails.application.credentials.db[:development][:username] %>
  password: <%= Rails.application.credentials.db[:development][:password] %>
  host: db
```

これでDBに接続できるはずです。
下記のコマンドでデータベースを作成します。

```terminal
docker-compose exec api rails db:create
```

最後に`docker-compose build`, `docker-compose up`してlocalhost:3000にアクセスすればrailsの画面を確認できます。
laravel ✕ Stripe （Laravel Cashier） 登録されている顧客情報を取得

## 概要

- Laravel Cashier（Stripe）にて登録されている顧客情報を取得する方法を簡単にまとめる。

## 前提

- 下記の内容を参考に疎通が確認されているものとする。

https://qiita.com/miriwo/items/01cac1cab4133ebd0d9a

- 顧客がStripeに登録されているものとする。

## 方法

- tinkerを起動し、下記を実行する。

    ```php
    use Laravel\Cashier\Cashier;

    Cashier::findBillable('stripeId');
    ```

- `stripeId`はusersテーブルにLaravel Cashier導入時に追加された`stripeId`カラムを見るか、Stripeにブラウザからログインし、顧客の詳細直下を確認する。
laravel ✕ Stripe （Laravel Cashier） 登録されている顧客情報をモデルクラスから取得

## 概要

- 今回はStripeに登録されている顧客情報をモデルクラスから取得する方法をまとめる。

## 前提

- 下記の内容を参考に疎通が確認されているものとする。

https://qiita.com/miriwo/items/01cac1cab4133ebd0d9a

- Userモデルに紐づく顧客がStripeに登録されているものとする。

## 結論

- `モデルクラスインスタンス->asStripeCustomer()`とすることで取得可能である。

## 方法

- tinkerを起動し、下記を実行する。（usersテーブルのfirstでヒットするレコードが顧客としてStripeにすでに登録されていることが前提）

    ```php
    use App\Models\User as UserModel;
    $user = UserModel::first();

    $stripeCustomer = $user->asStripeCustomer();
    ```

## おまけ

- `App\Models\User`でBillableトレイトが正常にuseされていない場合、下記の様なエラーが出る。

    ```
    Call to undefined method App\Models\User::asStripeCustomer().
    ```
laravel ✕ Stripe （Laravel Cashier）ユーザーの決済方法を登録する流れ（実装コード無し）

## 概要

usersに登録されているユーザーの決済方法を登録するまでの流れを簡単にまとめる。
※実際の実装コードは本記事には記載しない。

## ドキュメントの内容

下記ドキュメントを参照し、ちょっと調べた内容を本記事に記載する。

https://readouble.com/laravel/10.x/ja/billing.html#creating-customers

https://readouble.com/laravel/10.x/ja/billing.html#payment-methods-for-subscriptions

## 用語まとめ

- `顧客`: Stripe内での支払いをするユーザーのこと。

## 処理の流れ

下記のような流れで処理が行われる。

```mermaid
sequenceDiagram
		actor user as ユーザー
		participant front as FrontEnd
		participant back as BackEnd
		participant stripe as Stripe
		user->>front: クレカ情報入力<br>登録実行
		front->>back: client secret<br>取得API実行
		back->>stripe: 顧客情報取得命令
		stripe->>stripe: 顧客未登録の場合登録
		stripe->>back: 顧客情報
		back->>stripe: 支払い情報<br>設定開始依頼
		stripe->>back: 支払い情報<br>オブジェクト
		back->>front: 支払い情報<br>オブジェクト<br>クライアント<br>シークレット返却
		front->>stripe: クレカ情報送信（Stripe.js使用）
		stripe->>front: 支払い方法ID
		front->>back: 支払い方法<br>ユーザー紐づけ<br>API実行
		back->>stripe: 支払い方法<br>ユーザー紐づけ<br>リクエスト
		stripe->>back: 成功可否
		back->>front: 200 ok
		front->>user: 正常登録表示
```
Docker laravel APP_ENVをtestingに指定しているのにdevelopmentでPHPUnitのテストコードが実行される

## 概要

- Dockerでローカル開発環境を作成したlaravel環境にてPHPUnitを使ってFeatureテストを実行したところ何故か`APP_ENV`が`development`で実行されてしまう問題が発生し詰まったので簡単に原因をまとめる。

## 状況

- .env.testingを用意して記載を行った。
- 下記コマンドを実行しUnit、Featureそれぞれのテストを実行した。

    ```
    php artisan test --env=testing
    ```

- 実行されているテストコードの中に`dd(app()->environment());`のコードを仕込んでテストを実行したところ`development`という文字列が出力された。（本当は`testing`）と出力されてほしい。
- `APP_ENV`が`testing`になっていないと.env.testingが読み込まれずテスト用の設定でテストコードが実行されない場合がある。（ただし、`--env=testing`のように設定しているため、`.env.testing`は一応読み込まれているようだった。しかし.envに合って.env.testingに存在しない定数設定は.envのものが残ってしまうようだ。おそらくコンテナはdevelopmentという環境で起動しているから先に.envが読まれ、テスト実行時に`--env=testing`が指定されているから.envの設定項目を.env.testingの内容で上書きしてからテストを実行していた模様。今回.envにはstripeのapiキーが設定され.env.exampleにはキーの記載すら行っていなかったためテストコードを実行し.envに記載されたstripeのキー設定が生きた状態でテストコードが実行されていることに気が付き発覚した。）

## 原因と解決

- ローカル開発環境のdocker-compose.ymlを確認したところapiサービスで下記のような定数を設定していた。

    ```
    environment:
        - APP_ENV=development
    ```

- コンテナ起動時にAPP_ENVをdevelopmentとして起動してしまっているため、このようなことが起きている模様。
- 取り急ぎ当該のdocker_compose.ymlの内容を削除し、再び同様のコマンドでテストを実行したところ`APP_ENV`は`testing`として出力された。
laravel 現在のAPP_ENVの値を確認する方法

## 概要

- APP_ENVに設定されている環境を示す文字列を確認するコードをメモ的にまとめる。

## 内容

- 下記を実行されるコードに忍ばせるとAPP_ENVに設定されている値を確認する事ができる。

    ```PHP
    dd(app()->environment());
    ```
Git 未マージのブランチを除いて、マージ済みのローカルブランチを削除するコマンド

## 概要

- mainブランチにマージ済みのローカルブランチを一括削除するコマンドを簡単にまとめる。

## 方法

- mainブランチに移動する。
- 下記を実行してmainにマージ済みローカルブランチを一括削除する。（`-D`にしてしまうと未マージのブランチも削除されるので注意）

    ```shell
    git branch | xargs git branch -d
    ```
application/jsonとmultipart/form-dataについて

## 概要

`application/json`と`multipart/form-data`についてざっくりとした違いを初めてちゃんと認識したので簡単にまとめる。

## Content-Typeって？

本題に入る前に`application/json`と`multipart/form-data`を包括している存在のContent-Typeについて簡単にまとめる。
Content-Typeはリクエストヘッダに設定された、そのリクエストのボディの種類や形式を指定しているもの。
すべてのContent-Typeを見たい方は下記を参照

https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa

## `application/json`について

APIで最もよく見られると言っても過言ではないContent-Typeの一つで、「一つのJSONの文字列」で情報をやり取りする。

## `multipart/form-data`について

ファイルアップロードを伴うAPI等で使われるContent-Typeの一つで、「トップのキーごとに**パート**と言われる単位で区切られる」

## 比較

細かい部分は若干異なるかもしれないがイメージは下記に近い

| application/json | multipart/form-data |
| --- | --- |
| {"name":"miriwo", "age": "27"} | 「nameパートにmiriwoという文字列」<br>「ageパートに27という文字列」 |


## 参考文献

https://e-words.jp/w/Content-Type.html

https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa
AWS OpsWorks AutoHealingのON/OFF設定の場所

## 概要

- OpsWorksの各StacksのAutoHealingの現在の設定値の確認方法を簡単にまとめる。

## 方法

1. AWSのコンソールにログインし、OpsWorksを開く。
1. 「OpsWorks Stacks」を開く。
1. 任意のStack名を開く。
1. 「Layers」のレイヤー名をクリックする。
1. 「General Settings」のタブの「Auto healing enabled」を確認し、`YES`ならAuto HealingがONで、`NO`ならAuto HealingがOFFとなる。
EC2 GitHubのコードをCloneできるようにする

## 概要

- EC2のAmazonLinux2インスタンスにてGitHubのコードをCloneできるようにする方法をまとめる。

## 前提

- 筆者が作業するEC2インスタンスは下記と下記の記事に紐づく一連の作業で構築したEC2インスタンスである。

https://qiita.com/miriwo/items/b39d1ac6289c54cc2cfd

## 方法

1. 素の状態だとAmazonLinux2はGitが入ってないはずである。下記を実行してGitを入れる。

    ```
    sudo yum install git
    ```

1. 下記のように出たら`y`キーを押下し、Enterを押下する。

    ![version__0_0_•_Untitled-2_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/09f0e4f7-b629-4b68-f068-6bae50189c01.png)

1. 下記コマンドを実行して比較的新しいバージョンのGitがインストールされたことを確認する。（[Gitの最新バージョン確認](https://git-scm.com/downloads)）

    ```
    git -v
    ```

1. 下記コマンドを実行して、sshキーを生成する。（下記コマンドを実行するとパスフレーズの登録などが始まるが、設定しないならEnter連打でOK）

    ```
    ssh-keygen -t rsa -b 4096 -C "ご自身のGitHubのアカウントのメールアドレス"
    ```

1. 上記を実行すると`~/.ssh/`に`id_rsa`と`id_rsa.pub`が生成されるはずである。下記を実行して公開鍵の方を画面に表示する。

    ```
    cat ~/.ssh/id_rsa.pub
    ```

1. 表示されたキーの`ssh-rsa`から末尾のメールアドレス部分までをすべて選択し、コピーする。
1. GitHubを開き、右上のご自身のアイコンをクリック → Settingsをクリック → 左側のメニューの「SSH and GPG keys」をクリックと進む。
1. 右上の「New SSH key」をクリックする。
1. 「Title」にこれから登録するsshキーが認識し易い任意の名前の記入する。
1. 「Key」に先程コピーしたid_rsa.pubの内容を貼り付ける。

    ![Add_new_SSH_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/cd60e6e5-4d36-8b26-69ad-e51f2f5c4d54.png)

1. EC2内部で下記を実行して`~/.ssh/config`のファイルを作成して開く。

    ```
    vi ~/.ssh/config
    ```

1. 開いたファイルに下記の内容を記載する。

    ```~/.ssh/config
    Host github
        HostName github.com
        User git
        IdentityFile ~/.ssh/id_rsa.pub
        IdentitiesOnly yes
    ```

1. 下記を実行して`~/.ssh/id_rsa.pub`のファイルオーナーと権限を変更する。

    ```
    chmod 600 ~/.ssh/config
    sudo chown ec2-user:ec2-user ~/.ssh/config
    ```

1. 下記を実行してEC2インスタンスからGitHubへのsshの疎通確認を行う。（`Are you sure you want to continue connecting (yes/no)?`を聞かれたら`yes`と入力してEnterを押下する。）

    ```
    ssh -T git@github.com
    ```

1. 下記の様に出力されたらEC2インスタンスとGitHubの疎通確認が完了している。

    ```
    Hi GitHubのユーザー名! You've successfully authenticated, but GitHub does not provide shell access.
    ```

1. 疎通が完了したためこれでGitHubからEC2のコードをクローンする事ができるようになった。

## 参考文献

https://qiita.com/eyener/items/3fde597feda105eb61e6
AWS CodeDeploy  EC2「No such file or directory」というエラーが出てデプロイが失敗する

## 概要

CodeDeployでデプロイ中に`No such file or directory - /opt/codedeploy-agent/deployment-root/[ID]/[デプロイグループ名]/deployment-archive/test`というエラーが`/var/log/aws/codedeploy-agent/codedeploy-agent.log`に出てデプロイが失敗した。
筆者の場合の原因を簡単にまとめる

## 原因究明までの道のり

1. EC2インスタンスにssh接続し、下記コマンドを実行した。

    ```
    less /var/log/aws/codedeploy-agent/codedeploy-agent.log
    ```

1. エラー内容は下記だった。

    ```
    No such file or directory - /opt/codedeploy-agent/deployment-root/[ID]/[デプロイグループ名]/deployment-archive/test
    ```

1. 本当に当該のディレクトリ内部にtestディレクトリが存在していないか確認する。

    ```
    ll /opt/codedeploy-agent/deployment-root/[ID]/[デプロイグループ名]/deployment-archive/
    ```

1. deployment-archiveディレクトリ内部にはデプロイ対象のGithubのルートディレクトリと同じファイル郡が存在していたが確かにtestディレクトリは存在しなかった。

## 原因

appspec.ymlのsourceの記載に誤りがあった。

- 誤

    ```appspec.yml
    version: 0.0
    os: linux
    files:
      - source: test
        destination: /var/www/html/test
    hooks:
      ApplicationStop:
        - location: scripts/application_stop.sh
          timeout: 60
          runas: root
      BeforeInstall:
        - location: scripts/before_install.sh
          timeout: 60
          runas: root
      AfterInstall:
        - location: scripts/after_install.sh
          timeout: 60
          runas: root
      ApplicationStart:
        - location: scripts/application_start.sh
          timeout: 60
          runas: root
      ValidateService:
        - location: scripts/validate_service.sh
          timeout: 60
          runas: root
    ```

- 正

    ```appspec.yml
    version: 0.0
    os: linux
    files:
      - source: ./
        destination: /var/www/html/test
    hooks:
      ApplicationStop:
        - location: scripts/application_stop.sh
          timeout: 60
          runas: root
      BeforeInstall:
        - location: scripts/before_install.sh
          timeout: 60
          runas: root
      AfterInstall:
        - location: scripts/after_install.sh
          timeout: 60
          runas: root
      ApplicationStart:
        - location: scripts/application_start.sh
          timeout: 60
          runas: root
      ValidateService:
        - location: scripts/validate_service.sh
          timeout: 60
          runas: root
    ```
AWS CodeDepoly デプロイ時にエラーになった場合のログの確認方法（EC2）

## 

- CodeDeployにてエラーになった場合にログを見る方法を簡単にまとめる。

## 方法

複数の方法があるようだが、今回はEC2インスタンスにログインし、デプロイ時のログファイルを実際に確認する。

1. EC2インスタンスにssh接続する。
1. 下記を実行してサーバー内のログファイルを確認する。

    ```
    less /var/log/aws/codedeploy-agent/codedeploy-agent.log
    ```
青い空を見上げればいつもそこに白い猫

<!--
2023/11/17
-->
[picoCTF][Forensics][St3g0]

## Writeup
* 画像解析系の問題は、とりあえずこれ。
ファイルを開いて、ステガノグラフィー解析。
![screenshot 49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/ec83300a-c604-77c1-9573-a27ceeaa6ced.png)
<br>

* とりあえずビット抽出
`LSBを`選択、`テキストのみ表示`をチェックで。
![screenshot 50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/c9819e19-9d69-1ee2-fcdd-7c6fd57a9f29.png)
<br>

* 以上です。

## 参考サイト

https://digitaltravesia.jp/CTF/picoCTF2022/picoCTF_2022_Writeup.html
Wireshark

<!--
2023/11/15
-->
[picoCTF][Forensics][Eavesdrop]

## Writeup
* pcapファイルなので、とりあえず`Wireshak`で開く。
`HTTP`を見ても気になる通信がなかったので、TCPで接続しようとしているパケットを確認。
~~~
(http.request or tls.handshake.type eq 1 or (tcp.flags.syn eq 1 and tcp.flags.ack eq 0)) and !(ssdp)
~~~
<br>

* `9001`番ポートの通信から、`Follow` `TCP Stream`で内容を確認。
![screenshot 33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/e18f1ed0-d882-8a48-a26a-22fab1fa3793.png)
* 内容をDeepLで確認。
![screenshot 29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/f9adae55-9047-7e59-5de4-ffc03249b4a7.png)
以下のコマンドで、9002番ポートの通信を復号でするのかな。
~~~
openssl des3 -d -salt -in file.des3 -out file.txt -k supersecretpassword123
~~~
<br>

* `9002`番ポートの通信から、`Follow` `TCP Stream`で内容を確認。
`Salted`とあり、ソルトが入っているのかな。
![screenshot 34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/7061827e-3434-5b38-bffb-4d88d9297763.png)
* Rawにして、ファイルとして出力
![screenshot 36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/59fc3c83-4f2d-8141-9bb6-b73fd688a0fb.png)
<br>

* 出力したファイルの名前を変更して、指定のコマンドを実行。
![screenshot 32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/6c52e9ab-839f-8099-9c57-ab6703b0efc2.png)
<br>

* 以上です。
ubuntu 22.04にDocker構築手順

## 参考サイト
Dockerについて
 
 https://knowledge.sakura.ad.jp/13265/
 
 構築手順
 
 https://kinsta.com/jp/blog/install-docker-ubuntu/

## 作業内容
### 1.aptレポジトリを使ってDockerをインストールする
　DockerのGPGの鍵をaptに登録する為、下記を実行。
　これで、aptによるインストールしたDockerパッケージの検証が可能になります。
```
$ sudo mkdir -p /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 sudo chmod a+r /etc/apt/keyrings/docker.gpg
```
### 2.dockerの公式リポジトリを追加する
これで、Dockerパッケージのソースをシステムに追加出来る。下記を実行。
```
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullecho "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
### 3.パッケージ情報を再度更新する
　更新を行わないとaptがDockerパッケージの検出が不可となる為、下記を実行。
　これで、apt installコマンドで、Dockerのイメージをシステムに追加することが出来る。
```
$  sudo apt update sudo apt update
```
### 4.以下の3つの最新版のDocker Community Edition（CE）をインストール
- docker-ce：Docker Engineのデーモン
- docker-ce-cli：操作することになるDocker CLI「CLIとはコマンドラインインターフェースの略称」
- containerd.io：コンテナの起動と実行に利用する

下記を実行。
```
$ sudo apt install docker-ce docker-ce-cli containerd.io
Reading package lists... 0%Reading package lists... 100%Reading package lists... Done
Building dependency tree... 0%Building dependency tree... 0%Building dependency tree... 50%Building dependency tree... 50%Building dependency tree... Done
Reading state information... 0% Reading state information... 0%Reading state information... Done
containerd.io is already the newest version (1.6.21-1).
docker-ce-cli is already the newest version (5:24.0.2-1~ubuntu.22.04~jammy).
docker-ce is already the newest version (5:24.0.2-1~ubuntu.22.04~jammy).
0 upgraded, 0 newly installed, 0 to remove and 60 not upgraded.
```
### 5.バージョン確認を行う
出力がされれば問題なくインストールに成功となる。下記を実行。
```
root@nizeki-ubuntu:~# docker -v
Docker version 24.0.2, build cb74dfc
ORACLE MASTER Silver DBA 2019(1Z0-082-JPN)に合格しました

# はじめに
Oracle Database Administration I (1Z0-082-JPN)の試験を受け、
ORACLE MASTER Silver DBA 2019の認定資格を取得できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368839/9da0168b-6dbc-7b74-89b4-956022b22883.png)


# 私のスキルレベル
業務でOracleを6,7年使用していました。

所持資格は以下のとおりです。
・ORACLE MASTER Bronze Oracle Database 11g
・ORACLE MASTER Silver SQL 2019

# 勉強方法・時間
1. 黒本を1章分読む（章末問題も解く）
1. Notionに黒本1章分の内容をまとめる
1. １と２を繰り返して黒本を読破する
1. 黒本の模擬試験を解く
1. 模擬試験の反省をNotionにまとめる


黒本は翔泳社の公式通販サイトでPDF版を購入しました。
Notionにまとめる際、電子書籍だと図のスクショを撮って
そのままNotionに貼り付けられるので便利でした。

平日１～２時間、週末４～５時間という日々を１ヶ月ほど続けました。
まったく勉強しなかった日もありましたが、
１ヶ月間、それなりに勉強したかなという印象です。

黒本は800ページ以上もありますが、半分はSQLの内容なので
Silver SQLに合格したばかりの自分はほとんど読まずに済みました。

# 受験した感想
模擬試験などは完璧にして臨んだつもりですが、
自信を持って解答を選べない問題が結構ありました。
かなりの問題数を消去法で解答したと思います。

ちなみに消去法でも絞りきれない問題が2,3問ありました。
日本語の言い回しなど少しでも可能性が高そうなものを選びました（笑）。
（スコアレポートを見ると奇跡的にどれも正解できていたようです）

Silver SQLと同様、黒本から「同じような問題」は出ないにせよ、
「同じような知識」を問う問題は出てきました。

黒本1冊を念入りに勉強すれば問題なく合格できると思います。

# おまけ
「実機でコマンドを打ったりして演習した方が良いか」という話になったりますが、
黒本を使って勉強するのであれば不要かと思います。

記載されているコマンドの多くはちゃんと実行結果がずらずらと書いてあります。
親切な参考書だなーとしみじみと思いました。
シェル芸オンラインジャッジを作りました

# はじめに
シェル芸で問題を解いて遊ぶウェブサイトを作成しました。ユーザが入力したシェル芸に対して実行結果を返して、自動で正誤判定も行ってくれます。2023年11月19日時点で38問あります。ぜひ遊んでいただけますと幸いです。

# シェル芸オンラインジャッジへのアクセス方法
リンクはこちら↓です。また「シェル芸オンラインジャッジ」と検索すれば一番上に出てくると思います。もちろん無料です。

https://shellgei-online-judge.com/

# 遊び方
シェル芸オンラインジャッジの遊び方です。パソコンでもスマホでも遊べます。

## 1. 問題を選択
問題を選んで「決定」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/a31dc17b-9b99-89c1-e8d2-751390c26290.png)

## 2. 問題を確認
問題文と与えられる入力、想定出力を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/12a588dc-a86d-d01b-251c-3dd5a652b5d8.png)

## 3. シェル芸を入力
想定出力を得るためのシェル芸を記述して「実行」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/e376ee8d-6b98-0f0b-48e0-d10981116fe6.png)

## 4. 正誤判定の結果を確認
最後に正誤判定の結果を確認します。出力が正しい場合は「正解」、間違っている場合は「不正解」と表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/dcf5ed72-dc02-ab8d-9033-8518ffa4a1b3.png)

以上がシェル芸オンラインジャッジの基本的な遊び方です。

# シェル芸オンラインジャッジの仕組み
シェル芸オンラインジャッジの中身は次の画像のような構成になっています。ユーザが記述したシェル芸をシェル芸サーバに送って、返ってきた実行結果を表示しています。シェル芸を実行するたびにDockerのコンテナを作成&削除しています（実行環境に影響を残さないためです）。また、ShellgeiBotのイメージを拝借しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/b588ce9a-df25-ab25-a0d8-83708de7c788.png)

# その他の話とシェル芸オンラインジャッジを作った感想
- 名前は AIZU ONLINE JUDGE を参考にしています
- 危険シェル芸はまだ試していません（怖いので危険シェル芸は禁止です）
- 初めてPHPのコードを書きました
- Dockerのコンテナを使い捨てにするアイデアは websh を参考にさせていただきました
- HTMLとCSSを直書きしているのでデザインはお察しくださいませ
- 以上

# おわりに
シェル芸オンラインジャッジ、ぜひ遊んでみてくださいませ。

https://shellgei-online-judge.com/
【GitHub Actions】 self-hosted runner実行後にnodeの依存関係・リポジトリデータをクリーンアップする

## 概要
GitHub ActionsでNode.jsのプロジェクトを色々動かしていたら、self-hosted runnerとして使用していたEC2インスタンスがディスクフルになってしまったので、備忘録として残しておきます




## リポジトリファイル・依存関係のクリーンアップ
```yml
jobs:
  workflow:
    runs-on:
      labels: [self-hosted, ec2-runner]
    steps:
      - name: checkout
        uses: actions/checkout@v3
      - name: Node Setup
        uses: actions/setup-node@v3.1.1
        with:
          node-version-file: ".node-version"
      - name: npm install -g yarn
        run: npm install -g yarn
      - name: yarn install # パッケージインストール
        run: yarn install
        
      - name: "リポジトリのデータをクリーンアップ"
        run: |
          ls -la ./
          rm -rf ./*
      - name: "yarnのキャッシュをクリアする"
        run: yarn cache clean
```

## クリーンアップを実行しない場合・する場合の比較

#### クリーンアップを実行しない場合

```bash
$ cd actions-runner/_Work

$ du -d 1 -h
~~~
1.2G    ./github-repository
```

```bash
$ cd

$ du -d 1 -h
~~~
3.1G    ./.yarn
```

#### クリーンアップを実行した場合

```bash
$ cd actions-runner/_work

$ du -d 1 -h
~~~
900K    ./github-repository
```

```bash
$ cd ~

$ du -d 1 -h
~~~
0    ./.yarn
```

クリーンアップを実行することによって、ワークフロー実行時にクローンしたリポジトリのファイルデータやパッケージインストール時のキャッシュを削除できていることが確認できます。
【Reactアプリ100本ノック】06 Profile

![bandicam 2023-11-12 17-57-27-287.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/2d8a18c1-3e89-036a-6791-bbc313cd0886.jpeg)

# はじめに

<h3>こんにちは！！@Sicut_studyです！</h3>

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

こちらの記事が嬉しいことに多くの方に見ていただきました。
そこで**React**が多くの初心者の方に注目されているんだなということを実感させられました。

私の記事では何度も言っている通り

<font color="red"><h4>最速で学ぶならとにかく何か作る</h4></font>

というのが大事になってきます。そこで **「Reactアプリ100本ノック」** というのに挑戦していこうかと思います。徐々に難易度を挙げていってどこまでお題を作りきれるかの腕試しでやっていただければと思います。

今回は簡易的なプロフィールカードを作ってみたいと思います！

# 前回のお題

https://qiita.com/Sicut_study/items/c38b51907d18131b31f6

# Reactアプリ100本ノックルール

- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する
- 要件をみたせばデザインなどは自由

# 06. Profile

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/bdc24898-4852-67ce-b814-c77a1f34126e.png)

## 問題

プロフィールカードを生成できるサービスを作成します

## 目的

入力フィールドの管理を行い、状態の更新と状態を使ったUIの更新を学びます

## 達成条件

機能的なプロフィールカード:

- ユーザーが名前、誕生日、電話番号を入力し、プロフィール写真をアップロードできる
- アップロードされた画像がプレビューとして表示される。
- ユーザーが生成したプロフィールカードをPNG形式でダウンロードできる

## 実際に解いてみた

### 利用技術

- React
- TypeScript
- Vite
- Emotion
- html2canvas

解答時間 : 1時間

プロフィールカードだけだと簡単に感じる方が多いかなと思いましたので、ダウンロード機能も条件にいれてみました
ライブラリが簡単に利用できたのですぐに実装できました

昔流行ったプロフィール帳をオンラインで作るサービスにして画像をSNSにシェアできるみたいなサービスにすればもしかしたらバズって使ってもらえるかもしれません
画像出力ができると応用が効きますね

(ちなみに画像は出力できたのですが私の環境では背景が灰色になってました。本質ではないのでこのままにしています)

# 次のお題

https://qiita.com/Sicut_study/items/0fb7e80bc0a973000ae9

# おわりに

React100本ノックの記事を地道に上げていこうと思いますので、一緒に挑戦したい方は @Sicut_study をフォローいただけるととてもうれしく思います。
ここまで読んでいただけた方はぜひ**いいね**と**ストック**よろしくお願いします。

<h5>少し宣伝します🔥🔥🔥🔥🔥</h5>

これからエンジニアになろうとしている人を本気でコーチングして3か月の期間で立派なエンジニアにするようなチャレンジをしてみたいなと考えております。

もし、本気でエンジニアを目指してコーチングを受けてみたいという方がいれば、[Twitter](https://twitter.com/Sicut_study)に「プログラミング教えてほしいです」みたいなリプライ送っていただけたらなと思います！！

以上です。
今週もプログラミング頑張りましょう！

![bandicam 2023-10-04 20-58-54-525.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f41a0065-b23e-1895-da22-66bf0e48c5fb.jpeg)
Bottle勉強

 Bottleがどういうコードなのか、どういった表示ができるのかわかりやすい。
 APIキーを使って株価を取得してくるコードも書いているのでAPIの使い方の参考にもなった
 [[Python初心者向け]Bottleの使い方](https://blog.codecamp.jp/programming-python-bottle)

##### 公式チュートリアル
 https://bottl-translate-ja.readthedocs.io/en/latest/01_1_tutorial.html
画像を中央に配置して余白にぼかしを入れるコマンド

先日、以下のようなAR作品を作りました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">名古屋の栄を散策していたら「小便小僧」を発見しました！<br>しかし、どうやら噴水機能は備わっていないようです…<br><br>というわけでAR噴水つくってみました！<br><br>現地行ける方は、こちらからAR体験できます！<br>👉 <a href="https://t.co/A24c9oMKBa">https://t.co/A24c9oMKBa</a><br><br>場所は名古屋三越のライオン口付近です！<a href="https://twitter.com/hashtag/STYLY?src=hash&amp;ref_src=twsrc%5Etfw">#STYLY</a> <a href="https://twitter.com/hashtag/AR?src=hash&amp;ref_src=twsrc%5Etfw">#AR</a> <a href="https://twitter.com/hashtag/%E5%90%8D%E5%8F%A4%E5%B1%8B?src=hash&amp;ref_src=twsrc%5Etfw">#名古屋</a> <a href="https://twitter.com/hashtag/%E6%A0%84?src=hash&amp;ref_src=twsrc%5Etfw">#栄</a>… <a href="https://t.co/HQBhbxZTTC">pic.twitter.com/HQBhbxZTTC</a></p>&mdash; segur(せぎゅ)@都市ARエンジニア (@segur_vita) <a href="https://twitter.com/segur_vita/status/1726125135739117766?ref_src=twsrc%5Etfw">November 19, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この作品のサムネイルを作るときに、以下のような画像変換をしました！

|| 画像 |
|---|:---:|
|入力| <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/3e327215-73c7-54a9-3d21-e1cc8e33099e.jpeg" /> |
|出力| <img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/3fd4846e-e34f-9704-58f4-b3add3a3fc3d.jpeg" /> |

つまり、縦長画像を1920x1080にリサイズするときに、入力画像をぼかして拡大したもので余白を埋めたいという状況です！

# 処理内容

上記の画像変換の処理手順を書き出すとこんな感じです！

1. 入力画像のwidthを1920にリサイズして、ぼかし処理をかけたものを `background.jpg` として出力する。
1. 入力画像のheightを1080にリサイズしたものを `foreground.jpg` として出力する。
1. `background.jpg` を背景として、 `foreground.jpg` を中央に合成して出力する。


# コマンド

完成したコマンドがこちらです！ImageMagickを使ってみました！

```bat
magick convert input.jpg -resize 1920x -blur 0x8 -gravity north -extent 1920x1080 background.jpg
magick convert input.jpg -resize x1080 foreground.jpg
magick convert background.jpg foreground.jpg -gravity center -composite output.jpg
```

なお、ImageMagickのバージョンは7.1です。

WindowsでもmacOSでも無事に画像変換できました！

# さいごに

本記事作成にあたり、以下のページを参考にしました。ありがとうございました。

- https://qiita.com/yoya/items/b6926f01b7cb90217e07
TruthyとFalthy JavaScriptとPHPの違い

## Truthyとは
動的型付け言語において、真偽値型に変換されたらTrueになる値のこと

## JSとPHPで異なる例
#### '0'（文字列の0）
JSではtrue、PHPではfalse
```test.js
'0' == true // true
```
```test.php
'0' == true // false
```
#### []（空配列）
JSではtrue、PHPではfalse
```test.js
[] == true // true
```
```test.php
[] == true // false
```
ちなみに、JSでは{}（空オブジェクト）もtrue
```test.js
{} == true // true
```
#### 公式
https://developer.mozilla.org/ja/docs/Glossary/Truthy

https://developer.mozilla.org/ja/docs/Glossary/Falsy

https://www.php.net/manual/ja/types.comparisons.php
@cosmeのプロモーションキャラクターをCSSで描いてみた

# はじめに
この記事は アイスタイル [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/istyle) 4日目の記事です。

こんにちは、アイスタイルではフロントエンド周りをちまちま触っているsakaguchiiと申します。

この記事では弊社のサービス「@cosme」のプロモーションキャラクターである「ミカエル」をCSSで描いてみようと思います。

# ミカエルとは
https://www.cosme.net/html/spc/about-micael/

>3月6日生まれの男の子。
@cosmeでみなさんとマイコスメとの出会いをお手伝いする、カエルの姿をした妖精。
名前の語源は「美に変える(change)」「美が買える(buy)」。
キラキラの目がトレードマーク！ お風呂のときにはおなかの@cosmeをとるらしい…！？

トレードマークであるキラキラの目は[@cosme](https://www.cosme.net/)のアイデンティティである「Dot&Space」のSpaceから来ており、[こちらの記事](https://qiita.com/sakaguchii/items/0db0b7bc0e0b8d82f95c)で「Dot&Space」をCSSで表現することは出来たのでこの部分が描けたならミカエルもCSSで描けるのでは…！と思いついたため、ミカエルのお顔を描いてみました。

# さっそく
<p class="codepen" data-height="300" data-slug-hash="RwvMgva" data-user="sakaguchii" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sakaguchii/pen/RwvMgva">
  micael</a> by sakaguchii (<a href="https://codepen.io/sakaguchii">@sakaguchii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# こだわりポイント
### キラキラの目
「ベースの塗りつぶし部分」「トレードマークのキラキラ部分」で構成しました。
キラキラ部分はCSSの`radial-gradient`を使って下記のようなドット模様の背景を作り出来たスペースの部分を利用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417065/a632bbd6-4b03-abbb-1c81-81899b6d8ba2.png)


ただし、これだと使いたいところ以外の余白も見えてしまうため、`clip-path: circle()`を使って丸くクリッピング領域を作り、あとは`position`で良い感じの場所に配置して描画しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417065/328f345f-b425-d3a5-cd5e-eb702da96697.png)

### くち
楕円の線の部分を使ってくちの弧を作り、キラキラ目と同様`clip-path: circle()`で必要な部分だけを残すことでにっこりとしたくちを表現しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417065/a8f61125-824e-fce5-e1a4-68ef7278755d.png)


### ふちどり
かなり力業ですが、塗りつぶされた顔のベースの要素を複製し`border`を付けた要素を作成。この要素の後に塗りつぶされた顔の要素を記述することで、見せたくない部分の線を上書きしてふちどったように見せています。



# 最後に
意外と難しかった…CSSお絵描き……。キラキラ目の余白を良い感じにするために`clip-path`を使えば良いのか！と思いつくまで少し時間がかかりました😅CSSの自分の引き出しを試されることになり、面白い機会になりました。
初心者ということもありお顔のみのチャレンジになりましたが、来年は全身か、アドカレらしくサンタなど描いてみるのも楽しそうだなと思いました。

ここまで読んでくださりありがとうございました😊
RDRAについて調べてみた


RDRAについて調べたので、まとめます。

*** 

### RDRAについての概要

RDRAとは、ウォーターフォールおよびアジャイル開発手法の両方で遭遇する要件定義の課題に対応するために開発された手法です。このアプローチは、要件定義のプロセスをシステマティックに構築することを目的としています。

### RDRAの主要な特徴

* 視覚的なアプローチ：
        RDRAは、絵や図を活用して、システムに必要な要素や機能を視覚的に捉えます。このプロセスは、単なる話し合いを超え、要件を明確にするのに役立ちます。

* ステークホルダーの意見の統合：
        この手法では、システムの利用者や関係者の視点を積極的に取り入れ、全体的なアプリの使い勝手を高めます。

* 段階的な精密化：
        RDRAは、初期の大まかな概念から始め、徐々に要件を詳細化していきます。このアプローチにより、システムの構築中に見落としが少なくなります。

* 関連要素の分析：
        この手法は、システム内の異なる要素がどのように連携するかを検討します。これにより、システム全体の効果的な設計に貢献します。

* 変更への対応性：
        システム開発中に要件の変更が生じた際、RDRAは柔軟に対応できる構造を持っています。

### RDRAによるアプリ開発プロセス

アプリ開発におけるRDRAの応用は、以下のようなステップで進行します。

1. 要件の特定：
        開発者は最初に、アプリで実現したい機能や目標を特定します。

2. 図解による概念化：
        次に、必要な機能やデータフローを図解し、視覚的な表現を作成します。

3. 関係者のフィードバック収集：
        アプリのエンドユーザーや開発チームからの意見を収集し、要件を調整します。

4. 図解を用いた議論：
        図解を参照しながら、アプリの改善点や新たなアイデアについて話し合います。

5. 要件の更新と共有：
        要件に変更がある場合、図解を更新し、関係者全員と共有します。

### RDRAの利点

RDRAの使用には、以下のような多くの利点があります。

* 共通理解の促進：
        図解により、関係者間での共通理解が促進されます。

* エンドユーザー中心の設計：
        ユーザーの視点を反映した使いやすいアプリが開発されます。

* 見落としの低減：
        段階的な要件定義により、重要な要素の見落としが減少します。

* 変更への適応性：
        図解の活用により、要件変更への対応が容易になります。

### RDRAのデメリット

* 時間と労力の要求：
        RDRAは時間がかかるプロセスであり、詳細な図や文書を作成するために多くの時間と労力を要します。

* 専門知識の必要性：
        図を正確に作成し、解釈するためには、特定の専門知識や技術が必要です。これは、チーム内でこの知識を持つメンバーが限られている場合、問題となることがあります。

* 過剰な文書化：
        RDRAは詳細な文書化を伴うため、過剰な文書化によってプロジェクトが遅延するリスクがあります。

* 柔軟性の欠如：
        一部のアジャイルな開発環境では、RDRAのような徹底した前もっての計画が柔軟性を制限すると見なされることがあります。

* 全員の参加が必要：
        RDRAはプロジェクトに関わる全員の積極的な参加を要求します。関係者が十分に関与しない場合、プロセスの効果が低下する可能性があります。

### RDRAに向いているシステム開発のケース

* 複雑なシステム：
        RDRAは、多くの機能や相互依存する要素がある複雑なシステムに適しています。図を使って要件を視覚化することで、複雑さを管理しやすくなります。

* 多様なステークホルダーが関わるプロジェクト：
        異なる背景を持つステークホルダーが関与するプロジェクトでは、RDRAを用いて彼らのニーズと期待を明確にすることができます。

* 要件が頻繁に変更されるプロジェクト：
        RDRAは、要件の変更が頻繁に起こるプロジェクトにも適しています。変更があった場合に、既存の図やドキュメントを迅速に更新し、全員が最新の情報にアクセスできるようにします。

* 大規模な開発プロジェクト：
        多数の開発者やチームが関わる大規模プロジェクトでは、RDRAによる要件の視覚化がコミュニケーションを助け、誤解を防ぎます。

*** 

以上です。ここまで読んでくださりありがとうございます！
Chromeブラウザーでローカル時間帯を変更

こんばんは。Dynatrace井上です。

私も仕事で必要上使うことのあるブラウザーの機能を紹介します。
Dynatrace UI では常に日付時刻情報はブラウザーのローカル時間で表示されます。
ですので別の時間帯で働く同僚に画面ショットを共有する場合少々紛らわしいです。

Chromeでは以前から以下の画面ショットのように`Developer Tool` からの `Sensors` で設定できました。もしかすると今はもっと簡単な設定方法や、extensionがあるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109054/bc3ceb7b-a2e9-9f81-0a2f-0d2b81f9bcf9.png)

上のスクショでハイライトした部分は以下です。

1. 左下でWindows OSの時間が 18:53 と表示されてます。日本時間です。もうすぐ夕飯ですね。
1. Chrome Browser の下半分が`developer tool` です。`Sensors` で`Singapore`を選択してます。シンガポールは日本より１時間遅れなので 17:53 です。
1. Chrome上半分が Dynatrace Dashboard です。観測データの直近のデータがダイナミックに表示されます。2つのチャートで日本の18時台のデータが表示されるので横軸は `06 PM` と表示されるはずなのですが`Sensors`設定により1時間ずれて `05 PM` となってます。

なお、`Location`はカスタムで追加できて以下のように緯度経度省略して設定しても動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109054/9c523cad-3950-77cb-155c-9b1106d5975c.png)

参考になれば！
Pythonで「ビット演算に関する演算子」の動作を確認してみた

# 概要

Pythonで「ビット演算に関する演算子」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/num/index4.html

# 実装

以下のファイルを作成しました。
```sample.py
print("10 | 12 = " + str(10 | 12))
print("10 & 12 = " + str(10 & 12))
print("10 ^ 12 = " + str(10 ^ 12))
print("~10 = " + str(~10))
print("11 << 2 = " + str(11 << 2))
print("11 >> 1 = " + str(11 >> 1))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
10 | 12 = 14
10 & 12 = 8
10 ^ 12 = 6
~10 = -11
11 << 2 = 44
11 >> 1 = 5
```

# まとめ

何かの役に立てばと。
【備忘録】git stash

| 説明                                       | コマンド                        |
|--------------------------------------------|---------------------------------|
| 変更しているファイルを退避                     | `git stash push`                    |
| 特定の変更しているファイルを退避                   | `git stash push -- <filepath>` |
| 退避しているファイルを確認                     | `git stash list`               |
| 退避したファイルを戻す（最新のもの）           | `git stash pop stash@{0}`      |
| 退避したファイルを削除（最新のもの）           | `git stash drop stash@{0}`     |
| 退避したファイルを全て削除                   | `git stash clear`              |



### git stash と git stash push の違いは？
git stash: 追加のオプションなしでするコマンド。オプションなしのgit stash pushと同じ。
git stash push: 追加のオプションや引数を使用するためのコマンド。


### 参考
https://git-scm.com/docs/git-stash
二重木アルゴリズム(Double Tree Algorithm)をPythonで実装する

# この記事で得られるもの
- Double Treeアルゴリズムの手順
- Pythonでの実装例

# 環境
- Google Colaboratory

# 二重木アルゴリズムの概要
二重木アルゴリズム(Double Tree Algorithm)は[巡回セールスマン問題（TSP）](https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E3%82%BB%E3%83%BC%E3%83%AB%E3%82%B9%E3%83%9E%E3%83%B3%E5%95%8F%E9%A1%8C)の近似解を求めるためのアルゴリズムです。
巡回セールスマン問題はNP困難であり、多項式時間で最適解を求めることは困難であるので、最適解に近い近似解を求めるアルゴリズムが用いられます。


# Double Tree アルゴリズムの手順
1. 最小全域木を作成する
2. 最小全域木を二重化する
3. 得られた経路からオイラー閉路を作成する
4. オイラー閉路を用いてハミルトン閉路を作る

ただし、最小全域木の作成にはKruskalのアルゴリズムを用いました。

# 実装例
~~~python
import itertools
import networkx as nx

def get_double_tree_tour(n, T):
    checked = [False] * n  # 各ノードが訪問されたかどうかを追跡するためのリスト
    tour = []  # ツアーを保存するリスト
    g = nx.MultiGraph()  # グラフの作成
    g.add_edges_from(T + T)  # 最小全域木を2倍にしてグラフに追加する
    # オイラーサーキット（各エッジを一度だけ通る閉路）を見つける
    for u, v in nx.eulerian_circuit(g):
        if not checked[u]:  # まだ訪問していないノードに出会った場合
            tour.append(u)  # ツアーにノードを追加
            checked[u] = True  # ノードを訪問済みとしてマーク
    tour.append(tour[0])  # ツアーの開始点に戻る
    return tour

# ツアーを取得するためのメイン関数
def get_tour(P, distances, start):
    G = get_complete_graph(P, distances)  # 完全グラフを作成
    # 最小全域木を見つける
    T = [(u, v) for u, v, w in nx.minimum_spanning_edges(G, algorithm='kruskal')]
    tour = shift_tour_start(get_double_tree_tour(len(P), T), start)
    return tour

# ツアーの開始点をシフトする関数
def shift_tour_start(tour, start_node):
    if start_node not in tour:
        raise ValueError("Start node not in tour")
    start_index = tour.index(start_node)  # 開始ノードのインデックスを見つける
    return tour[start_index:] + tour[1:start_index+1]  # ツアーの開始点をシフト

# 完全グラフを生成する関数
def get_complete_graph(P, distances):
    g = nx.Graph()
    edges = []
    for i, j in itertools.combinations(range(len(P)), 2):  # 全てのノードの組み合わせに対して
        edges.append((i, j, distances[i][j]))  # エッジと距離を追加
    g.add_weighted_edges_from(edges)  # グラフに加重エッジを追加
    return g
~~~


### 使用例
~~~python
def get_tour_cost(tour, distances):
    return sum(distances[tour[i]][tour[i + 1]] for i in range(len(tour) - 1))

if __name__ == '__main__':
    # 2x3のグリッドの座標を定義
    coordinates = np.array([
        [1, 1], [2, 1], [3, 1],
        [1, 2], [2, 2], [3, 2]
    ])

    # 2x3グリッドのダミーの距離行列を定義
    distances = [
        [0, 1, 2, 1, 2, 3],
        [1, 0, 1, 2, 1, 2],
        [2, 1, 0, 3, 2, 1],
        [1, 2, 3, 0, 1, 2],
        [2, 1, 2, 1, 0, 1],
        [3, 2, 1, 2, 1, 0]
    ]

    # ツアーを計算する
    start_index = 0
    d_tour = get_tour(coordinates, distances, start_index)

    # ツアーとそのコストを出力する
    print("Route:", " -> ".join(map(str, d_tour)))
    print("Cost:", get_tour_cost(d_tour, distances))
~~~

### 結果
~~~
Route: 0 -> 3 -> 1 -> 4 -> 2 -> 5 -> 0
Cost: 10
~~~
点と三角形の当たり判定（内外判定）

# 外積の使い道
大学で習うベクトルの外積。これを何に使えるかの一つの答えとして持ち出す話。


三角形ポリゴンでできた地面の上にキャラクターが立ってるとする。そのとき、どのポリゴンの上にいるのかを知りたいとする。三角形の重心との距離が一番近い、でもいいが、外積でもできる。

　以下のプログラムのように、三角形の3頂点とマウス座標の4点から、3つの外積を計算する。その3つ外積のz座標が正正正もしくは負負負なら、マウス座標は三角形の内側にある。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/32acc6b2-d7ff-0555-c434-98073f284345.png)


```java
PVector a, b, c;    //3頂点
PVector AB, BC, CA; //頂点間のベクトル

color c1 = color(0, 0, 255);
color c2 = color(255, 0, 0);

void setup() {
  size(512, 512);
  noFill();
  a = new PVector(256, 128, 0);
  b = new PVector(128, 384, 0);
  c = new PVector(384, 256, 0);
  AB = sub(b, a);
  BC = sub(c, b);
  CA = sub(a, c);
}

void draw() {
  background(255);

  PVector p = new PVector(mouseX, mouseY, 0);

  PVector AP = sub(p, a);
  PVector BP = sub(p, b);
  PVector CP = sub(p, c);
  float z1 = cross(AB, BP).z;
  float z2 = cross(BC, CP).z;
  float z3 = cross(CA, AP).z;
  if ((z1<0 && z2<0 && z3<0)||
      (z1>0 && z2>0 && z3>0)) {
    println("in");
  }else{
    println("out");
  }

  fill(z1<0 ? c1 : c2, 105);
  triangle(a.x, a.y, b.x, b.y, mouseX, mouseY);
  fill(z2<0 ? c1 : c2, 85);
  triangle(b.x, b.y, c.x, c.y, mouseX, mouseY);
  fill(z3<0 ? c1 : c2, 64);
  triangle(c.x, c.y, a.x, a.y, mouseX, mouseY);
}

PVector sub(PVector p, PVector q) {
  PVector t = new PVector(0, 0, 0);
  t.set(p);
  return t.sub(q);
}

PVector cross(PVector p, PVector q) {
  PVector t = new PVector(0, 0, 0);
  t.set(p);
  return t.cross(q);
}
```

:::note warn
PVectorは、基本型(int,float等)ではないので、参照渡しになる。数学に近い書き方にしたく、PVectorクラスのsubは、値が変わるので使わずに、自分で関数を作った。
:::

```java
  fill(z<0 ? c1 : c2);
```
このコードは、以下のコードを三項演算子を用いて書いたもので、同等です。
```java
if (z<0) {
  fill(c1);
} else {
  fill(c2);
}
```
始めようかデータカタログ。カタログ利用者目線でどんなことが出来るのかをハンズオンで体験。

# 概要
[IBM TechXchange Conference Japan](https://www.ibm.com/jp-ja/events/techxchange)
- 日時：2023年10月31日 (火) - 2023年11月1日 (水)
- 会場：ベルサール東京日本橋

にて開催された、セッションDS-06 の資料（DS-05も同じ内容）です。

- セッション時間は90分、資料は180ページ弱あります。

https://speakerdeck.com/shumpei3/shal-we-start-data-catalog-with-ibm-knowledge-catalog

# 注意事項
- 当該資料にはハンズオン用環境へのアクセス情報は含まれていません。
- 当該資料は2023年11月1日時点での最新情報を記載していますが、確認するタイミングによっては内容は最新のものでなくなってしまいますので、ご留意下さい。

# セッション情報
![スクリーンショット 2023-11-21 16.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295123/edcc388c-dcac-8b5b-1233-44e17fafb8e8.png)
rex0220 計算式プラグインの使い方をGPTsに学習させてみる（その１７）GPTsを公開

「[rex0220 計算式プラグインの使い方](https://chat.openai.com/g/g-wvbi2Ah1R-rex0220-ji-suan-shi-puraguinnoshi-ifang)」の GPTs を公開してみました。
よろしければ、いじって遊んでみてください。

[rex0220 計算式プラグインの使い方をGPTsに学習させてみる（その１６）学習の再現性](https://qiita.com/rex0220/items/697275614c24f7691881)の続きです。

# 概要

ChatGPT の有料会員限定になりますが、下記からrex0220 計算式プラグインの使い方を利用できると思います。
まだまだおかしなところが沢山ありますが、いじって遊んでみてください。
よろしければ、ご感想・不具合報告などをいただければと思います。

「[rex0220 計算式プラグインの使い方](https://chat.openai.com/g/g-wvbi2Ah1R-rex0220-ji-suan-shi-puraguinnoshi-ifang)」

![2023-11-21_18h23_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/bd15d692-cd6f-51b4-6e07-6ceca0df9218.png)

# 公開方法

Update で、「Public」にしました。
これだけで、いいはず？

![2023-11-21_18h22_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e7247c13-f8d1-f9df-7dfd-d631400614c5.png)
数値の出現率 Python3編

https://paiza.jp/works/mondai/data_structure/data_structure__dict_step1

> 0 以上 9 以下の整数が N 個与えられます。各数値の出現回数を求め、「0」の出現回数、「1」の出現回数、...「9」の出現回数、をこの順に半角スペース区切りで1行に出力してください。

前回と比べたら難しくはないかな。。。

```py
N = int(input())
A = list(map(int,input().split()))
counts =[]
for i in range(10):
    count = 0
    for j in A:
        if i == j:
            count += 1
    counts.append(count)
print(*counts)

```

答えだと、
countを配列にして、それぞれのインデックス（0~9）ごとに
数値を加算する方法だった。
ちょっと一瞬わかりづらいかも？

`print(*counts)`もよいが、
`print(" ".join(map(str, count)))`
展開のやり方も覚えておこう


```py
N = int(input())
A = [int(x) for x in input().split()]

count = [0] * 10
for num in A:
    count[num] += 1

print(" ".join(map(str, count)))

```
APIについて学習

こちらのサイトを自分で簡単にまとめてみた。詳細についてはHPへ
[REST（レスト）とは何か？わかりやすくまとめました【WEBの勉強】](https://myantora.com/web/136/)
![スクリーンショット 2023-11-21 13.12.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627182/fa5072d6-bcd1-f257-4a7d-7e77562ed02a.png)


つまりRESTful APIとはRESTの６つのアーキテクチャスタイルを考慮した設計思想のもと構築されたAPIのことであり、web全体でよりよいものになるというAPIのこと


##### APIレスポンス
帰ってくるデータ形式はJSONやXMLが多い
こちらがわかりやすかった
[「JSON」とは？非エンジニアでもよくわかる解説](https://cloudapi.kddi-web.com/magazine/json-javascript-object-notation)
VBA シートが存在するか

# シートが存在するか

仕事で初めてVBAを使ってます。

ある文字「WorksheetName」のシートが存在するかどうか
判定するコードを書きたかったのだけど、
調べて出てくるのは ブックの全体のシートをとって
for文でぐるぐる回すコード。

それでもいいちゃいいのだけど、
ある文字「WorksheetName」を何個か検証したい場合に、
何度もfor文が回るのが、主義に反する（笑）なぁと

ということで、
こんなコードを書いてみました。

```
Function existsWorkSheet(WorksheetName As String) As Boolean
    existsWorkSheet = True
    On Error Resume Next ' Ignore errors for now
    Dim Worksheet As Worksheet
    Set Worksheet = ThisWorkbook.Worksheets(WorksheetName)
    On Error GoTo 0 ' Stop ignoring errors
    If Worksheet Is Nothing Then
        existsWorkSheet = False
    End If
End Function
```
`On Error Resume Next`
…VBA書いて行ったら慣れるのかな。

for文で書く方が処理速度が早くなるとか、
あるかもしれないけど、ベンチマークとる時間はなかった。
主義ということで。
時間ある時に詳しくみてみます。

返り値、boolにしたけど、
WorkSheetをあとで使うならWorkSheetを返す
Functionにしても良いかな。
[Linux] 正規表現メモ

# 正規表現とは
「正規表現」とは、文字列のパターンを記述するための一種の言語である。
これはテキスト処理において非常に重要で、様々なプログラミング言語やツールで広く利用されている。
正規表現を使用することで、複雑なテキスト検索や置換を簡単かつ効率的に行うことが可能となる。

# 正規表現集

## 改行以外の任意の１文字
.(ピリオド) で表現

## 指定の候補文字にマッチ
\[]で囲んだ任意の文字
- \[_=]: _(アンダーバー)と=(イコール)のいずれかにマッチ
    - python_/python=など
- \[aio]: a,i,oのいずれかにマッチ
    - D\[aio]mの場合、Dim/Domなど。Daimはマッチしない。

## 特定の文字範囲にマッチ
- \[0-9]
- \[a-z]
など。{a-z}としないように注意。

## 先頭と最後にマッチ
- ^ 行の先頭
- $ 行の末尾

## OR
- () 正規表現のパターンをグループにまとめる
- | 複数の正規表現のどちらかにマッチ

grepに「-E」を付けるか、「egrep」コマンドを使う。

## 繰り返し回数
直前の項目の繰り返し回数を指定する

- ∗ 直前の項目が、0回以上マッチする
- ? 直前の項目が、0回か1回マッチする
- \+ 直前の項目が、1回以上マッチする
- {n} 直前の項目が、n回マッチする
- {n,} 直前の項目が、n回以上マッチする
- {,m} 直前の項目が、m回以下でマッチする
- {n,m} 直前の項目が、n回以上m回以下でマッチする

「?」「+」(プラス)、波カッコを使う場合、grepに「-E」を付けるか、「egrep」コマンドを使う