OmniAICreator/Qiita-1.07M huggingface dataset:
この書き方何だっけな系まとめ（PHP）

〇〇演算子とか〇〇関数とかの名前や通称が付いてるショートハンドやシンタックスシュガー系のまとめ。（名前を知っておかないと調べにくいやつ）

# エルビス演算子（?:）

三項演算子の省略系の通称。PHP≥5.3から使用可。

https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary

```php
echo $a ?: $b;
```

```php
//これと同じ
echo $a ? $a : $b;

//これと同じ
if ($a) {
	echo $a;
} else {
	echo $b;
}
```

# Null合体演算子（??）

エルビス演算子のisset版。PHP≥7.0から使用可。

https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.coalesce

```php
echo $a ?? $b;
```

```php
//これと同じ
if (isset($a)) {
	echo $a;
} else {
	echo $b;
}
```

# Null合体代入演算子（??=）

null合体演算子の代入版。PHP≥7.4から使用可。

https://www.php.net/manual/ja/migration74.new-features.php#migration74.new-features.core.null-coalescing-assignment-operator

```php
$a ??= $b;
```

```php
//これと同じ
$a = $a ?? $b;

//これと同じ
if (isset($a)) {
	$a = $a;
} else {
	$a = $b;
}
```

# Nullセーフ演算子（?->）

オブジェクトのプロパティ・メソッド参照時のnullチェックを省略。PHP≥8.0から使用可。

https://www.php.net/manual/ja/language.oop5.basic.php#language.oop5.basic.nullsafe

```php
$foo = $a?->b?->c();
```

```php
//これと同じ
if ($a !== null && $a->b !== null && $a->b->c() !== null)) {
	$foo = $a->b->c();
} else {
	$foo = null;
}
```

# 宇宙船演算子（<=>）

二項の大小比較。PHP≥7.0から使用可。

https://www.php.net/manual/ja/migration70.new-features.php#migration70.new-features.spaceship-op

```php
echo $a <=> $b;
```

```php
//これと同じ
if ($a < $b) {
	echo -1;
} elseif($a > $b) {
	echo 1;
} else {
	echo 0;
}
```

# アロー関数（=>）

無名関数のショートハンド。PHP≥7.4から使用可。

https://www.php.net/manual/ja/functions.arrow.php

```php
$foo = fn($a, $b) => $a + $b;
echo $foo(1, 2);
```

```php
//これと同じ
$foo = functino($a, $b) {
	return $a + $b;
}
echo $foo(1, 2);
```

# 可変長引数と配列のアンパック（…）

PHP≥5.6から使用可。

https://www.php.net/manual/ja/functions.arguments.php#functions.variable-arg-list

https://www.php.net/manual/ja/language.types.array.php#language.types.array.unpacking

```php
function foo(...$args) {
	foreach($args as $v) {
		echo $v;
	}
}

$a = [1, 2, 3];
foo(...$a);
$b = [1, 2, 3, 4, 5];
foo(...$b);
```

```php
//これと同じ
function foo() {
	$args = func_get_args();
	foreach($args as $v) {
		echo $v;
	}
}

$a = [1, 2, 3];
foo($a[0], $a[1], $a[2]);
$b = [1, 2, 3, 4, 5];
foo($b[0], $b[1], $b[2], $b[3], $b[4]);
```
実際に新しいブランチに既存ブランチで作成していたファイルをStashを使って反映させてみた

## はじめに
本日実際にgitのStash機能を使って、新しいブランチに既存ブランチで作成したファイルを取り込んだのでその備忘録を書いていく。

## Stashの基本的な使い方
https://qiita.com/yastinbieber/items/c405f5ce31af3f1835fd

## 実際の使用までの流れ
今回やった流れがベストかはわからないが、なんとかうまくいったので1つの方法として考えてほしい。

### 既存ブランチでStashを作成しておく
```
# Stashを作成
git stash save "WIP 受講者詳細API作成中"
```

そうするとStashが作成されるので、リストを見てみる
```terminal
git stash list

// こんな感じでリストが確認できる(今は1件のみ)
// stash@{0}: On 28-be-webtest-userapi: WIP 受講者詳細API作成中
```

### リモートリポジトリ上の最新のmainをローカルでも反映させる
```
# mainブランチへ移動
git checkout main
```

```
# git pullでmainを最新に
git pull origin main
```

### ローカルでのmainが最新になったところで新しいブランチを作成する
```
# 新しいブランチを作成
git branch be-webtest
```

```
# 新しいブランチへ移動
git checkout be-webtest
```

### 今回の開発ブランチへ移動したのでStashを開いていく
```
# 念の為現在のブランチを確認
git branch
```

```
# Stashを開く
git stash pop
```

これでコンフリクトが起こらない限りうまくいくはず。
コンフリクトが起きた場合は差分をチェックして1つずつ修正していく。

以上。
【Wordpress】テーマFAKEでグローバルナビゲーションメニューの表示速度を速くする方法

# 概要
* Wordpressテーマの`FAKE`を利用していて、デフォルトでのグローバルナビゲーションメニューの表示速度が遅く感じました。どのように修正するのか、備忘も兼ねて記します。

# Wordpressテーマ`FAKE`とは
* `FAKE`はコーポレートサイト向けWordPress有料テーマです。とてもシンプルで使いやすいので人気です。
* 「コンテンツビルダー」というTCDオリジナルのトップページ専用の編集ツールがあるので、直感的な操作で構築できて便利です。
* 3種類の固定ページテンプレートがあるので、円滑に企業サイトを作成できるなどの魅力があります。
* 比較的シンプルでコンテンツもそう多くない企業の方がマッチしている印象ですね。
* TCDワードプレステーマの公式ページはこちら：
    * [FAKE（TCD074）](https://tcd-theme.com/tcd074)

# 修正方法
* Wordpress管理画面→テーマファイルエディター→style.cssを選択します。
    * ちなみにファイルは、以下にあります。こちらから直接編集してあげても良いです。

```
/var/www/html/xxxxxxx/wp-content/themes/fake_tcd074/style.css
```

* `style.css`で`header.animate`と検索すると、以下のような記載が見つかります。

```css
/* アニメーションの設定 */
.pc #header { opacity:0; }
.pc #header.no_animate { opacity:1; }
.pc #header.animate {
  -webkit-animation: opacityAnimation 1.4s cubic-bezier(0.165, 0.84, 0.44, 1) forwards 2.0s;
  animation: opacityAnimation 1.4s cubic-bezier(0.165, 0.84, 0.44, 1) forwards 2.0s;
}
```

* `forwards`の`2.0s`を低くすれば、表示速度を早めることができます。元々FAKEのテーマはふわっと浮かび上がるような仕様なので、あまり低くしすぎると違和感あるかもしれません。お好みで決めてください。デフォルトの2.0sはちょっと人によってストレス感じる速度かなぁと思いました。
dockerとdocker composeでwebアプリをdocker化する方法

### dockerとdocker-composeでwebアプリをdocker化
今回構築したいDocker環境
- docker-compose upでrailsプロセスとdbが起動し、http://localhost:3000 でアクセスできるようにすること
- nodejs,yarnはマルチステージビルドでインストールすること(apt-getは使用しない)
  ※マルチステージビルド
  - 1つのDockerfileに複数のイメージを作る
  - 複数のFROMが存在する

#### 手順
- 今回は`rails new`はしてある
- 必要なファイルを準備する
`touch [Dockerfile docker-compose.yml]`
  - Dockerfileに以下を記述
  ```Dockerfile
  # FROMが2つあり、nodeとrubyの2つのイメージ
  FROM node:14.17.6 as node
  FROM ruby:3.0.2

  # railsのセットアップ
  WORKDIR /rails-docker
  # 複数コピーする場合はtargetのディレクトリの最後にスラッシュ(/)を追加しないとエラーになるらしい
  COPY Gemfile Gemfile.lock /rails-docker/
  RUN bundle install

  
  # nodeのイメージからyarnを取得、hostのパッケージを持ってくる
  COPY --from=node /opt/yarn-* /opt/yarn
  COPY --from=node /usr/local/bin/node /usr/local/bin/
  COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
  
  # npmが入っているファイルに扱いやすい名前でシンボリックリンクを作成
  # -sでシンボリックリンク、デフォはハードリンク
  # -fでリンクファイルと同じ名前のファイルがあっても強制的に上書きする、ビルド時にファイル重複でエラーを吐かせないため
  RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
    && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
    && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
    && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

  # docker-compose up時にrailsサーバーを立ち上げる
  CMD [ "rails", "s", "-b", "0.0.0.0" ]
  ```
  - docker-compose.ymlに以下を記述
  ```docker-compose.yml
  version: '3.9'

  volumes:
    # dbのデータを入れておくためのdocker volume
    db-data:

  services:
    web:
      build: .
      ports:
        - "3000:3000"
      volumes:
        - '.:/rails-docker'
      environment:
        - 'DATABASE_PASSWORD=postgres'
      tty: true
      stdin_open: true
      depends_on:
        - db

    
    db:
      # DBをpostgresqlに
      image: postgres
      volumes:
        - 'db-data:/var/lib/postgresql/data'
  ```


- /config/database.ymlの変更
default: &defaultに以下を追記
host, user, port, paswordを追加
```database.yml
host: db
user: postgres
port: 5432
password: <%= ENV.fetch("DATABASE_PASSWORD") %>
```

- `docker-compose up`して、http://localhost:3000/ にアクセスしてrailsの画面が表示されていれば成功


自分はvolumes先のパスの指定をWORKDIRで指定したものと違うものによくなっているのでチェックを忘れないようにしたい。コンテナが立ち上がったあとコンテナに入って`ls`でちゃんとビルドコンテキストがマウントできているか確認するのが良さそう。
ETL/ジョブのツール整理


■SAPとのジョブ連携
・JP1(日立)で、SAPのプログラムとバリアントを設定して、スケジュール起動
　- 実行ファイル(.exe,.bat)の起動も可能
　- PwCなどのETLツールの連携も可能
・SystemWalker(富士通)
・Tivoli(IBM)

■Hostとのジョブスケジュール連携
・A-Auto(ユニリタ)

■ジョブの全体監視
・Zabbix(Zabbix)

補足)ETLツール
・Waha!Transformer(ユニリタ)
・Talend(Talend)
・PowerCenter(Informatica)
【Solidity】(tips)大きい数字を見やすくする方法

大きい数字を見やすくする方法に関して下記します。
1 etherが10の18乗weiということもあり、solidity内でwei表記で大きい数字を扱うことがあります。
そんな"_"をつけると見やすくなリます。

RemixIDEで確認するとnumber2も"1000000000000000000"と表記されます。
"_"は数字に影響することなく、見やすくなります。
```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Sample{
    uint public number1 = 1000000000000000000;
    uint public number2 = 1_000_000_000_000_000_000;
}

```
※RemixIDEにより動作確認
DartSDKの1系をインストールしたいのに3系が入ってしまう

# はじめに

AngularDartを実行するのにDartSDK3を入れてしまい、動かなかったので、1系を入れ直す必要があり調べてもなかなかうまく行かなかったのでまとめます

# 問題

```
$ sudo apt-get install dart=1.24.3
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
E: 'dart' のバージョン '1.24.3' が見つかりませんでした
```

```
$ sudo apt-get install dart 1.24.3
$ dart --version
```

なぜかDartのDevの最新版がインストールされてしまいました
以前に最新版をインストールしているのでそれが影響しているのか、バージョン指定が効いていないのかよくわからなかったです

# 解決方法

https://dart.dev/get-dart/archive

ここからZIPをダウンロードしました
そして以下のコマンドでパスを通しました

```
$ unzip dartsdk-linux-x64-release.zip
$ mv dart-sdk ~/bin/dart-sdk
$ vi ~/.bashrc

// 以下を末尾に追加
export PATH="$PATH:~/bin/dart-sdk/bin"
```

これで読み込めるようになりました

# おわりに
なんとかDartが入ったので動かせるようになりました 

# 参考

https://dart.dev/get-dart/archive
標本標準偏差と母標準偏差、pandas/Numpyでの計算時注意

# 標本と母集団
統計学の話としてまず以下を振り返る。

+ 母集団
対象となる事象やデータの「すべて」の集団。
観測できていないものであっても、該当し得る対象がある場合は
それらも含んだ集団のことを指す。
　　例）国内の小学生を対象にした算数の成績
　　　　：ただ一人も欠けることなく全小学生を対象に算数テストを行って集計した場合
　　　　　母集団である。

+ 標本
対象となる事象やデータのうち、抜き出した（観測、計測した）集団。
母集団の部分集合となる。
　　例）国内の小学生を対象にした算数の成績
　　　　：各県から、代表となる小学校を選び、そこで算数テストを行って集計した場合
　　　　　標本である。

# 標本標準偏差と母標準偏差
母集団の標準偏差を本当は知りたい。
（前述の例だと、国内全員の小学生を対象にした際の標準偏差を本当は知りたい）

一方、実際観測できるのはその一部である。
標本から導出する標準偏差は、母集団の標準偏差よりも若干小さくなってしまう。
→数学的な導出を知りたい場合は以下のサイト等を参照
[統計学 : 標準偏差や分散はなぜnで割ったりn-1で割ったりするのか](https://walkintheforest.net/variance/)

よって、Python等（Pyhtonに限らずだが）で標準偏差を求める場合、以下を留意する。

+ 対象データは母集団といえるか、標本といえるか
+ そのライブラリの標準偏差導出メソッドは、標本標準偏差と母標準偏差のどちらを求めてくれるのか

# Python/pandasにおける標準偏差
例
```python:Python
import pandas as pd

df = pd.DataFrame({
    'Name': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

# pandasのstd()で標準偏差を計算→母標準偏差
df['value'].std()
```
結果
```css:css
1.2909944487358056
```

例
```python:Python
import pandas as pd

df = pd.DataFrame({
    'Name': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

# pandasのstd(ddof=0)で標準偏差を計算→標本標準偏差
df['value'].std(ddof=0)
```
結果
```css:css
1.118033988749895
```

このように、pandasのstdでは、
デフォルトは母標準偏差となる。



# Python/Numpyにおける標準偏差
例
```python:Python
import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Name': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

# npのstd()で標準偏差を計算→標本標準偏差
np.std(df['value'])
```
結果
```css:css
1.118033988749895
```


例
```python:Python
import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Name': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

# npのstd(ddof=1)で標準偏差を計算→母標準偏差
np.std(df['value'], ddof=1)
```
結果
```css:css
1.2909944487358056
```
このように、numpyのstdでは、
デフォルトは標本標準偏差となる。
paizaラーニング レベルアップ問題集 新・Bランクレベルアップメニュー JavaScript【全探索 1】高い寿司を食いたい！

【全探索 1】高い寿司を食いたい！ (paizaランク B 相当)

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_richer_sushi

# 解答例
K枚の寿司の合計を全探索します。
Pの配列、先頭のインデックスをiとして、K枚の合計を求めます。
Pの最後の要素を先頭とするまで、求めていきます。
合計を求めるのに、一回ごとに全て合計していると計算量が増えるので、前の合計金額から、先頭を引いて、末尾を加えれば、計算量が少なくて済みます。
P_1 の寿司と P_N の寿司は隣接しているので、Pの最後の要素を超えたら、最初の要素に戻ります。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);
const P = lines.slice(1).map(Number);

//現在の連続する K 枚の寿司の合計金額
let now_price = P.slice(0, K).reduce((a, b) => a + b);//先頭がi=0
//連続する K 枚の寿司の合計金額の最大値
let max_price = now_price;

if (K < N) { //NとKが同じなら必要ない
 //連続するK枚の寿司の先頭のインデックスi
  for (let i = 1; i < N; i++) {
    //前の合計金額から先頭を引く
    now_price -= P[i - 1];
    //前の合計金額に最後尾を足す
    now_price += P[(i + K - 1) % N];//P_1 の寿司と P_N の寿司は隣接
    //最大更新
    max_price = Math.max(max_price, now_price);
  } 
}
console.log(max_price);
```
Nuxt3 + javascript d3 ライブラリで散布図を描く ( Compotision API ) ( script setup )

# インストール

```
npm install d3 --save
```

typescript型管理用

```
npm i --save-dev @types/d3
```

とくにnuxt configに何も設定しなくても動く様子

# コード例


script直下でd3を利用しようとするとエラーが発生したが onMounted の中に書くことにより動いた

d3のコード部分はほぼ以下参考サイトのまま
https://wizardace.com/d3-scatterplot/

```vue
<template>
  <div id="foo">
  </div>
</template>

<script setup lang="ts">
import * as d3 from 'd3'

onMounted(() => {
  var dataset = [
    [5, 20],
    [480, 90],
    [250, 50],
    [100, 33],
    [330, 95],
    [410, 12],
    [475, 44],
    [25, 67],
    [85, 21],
    [220, 88]
  ];

  var width = 400; // グラフの幅
  var height = 300; // グラフの高さ
  var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };

  // 2. SVG領域の設定
  var svg = d3.select("#foo").append("svg").attr("width", width).attr("height", height);

  // 3. 軸スケールの設定
  var xScale = d3.scaleLinear()
    .domain([0, d3.max(dataset, function (d) { return d[0]; })])
    .range([margin.left, width - margin.right]);

  var yScale = d3.scaleLinear()
    .domain([0, d3.max(dataset, function (d) { return d[1]; })])
    .range([height - margin.bottom, margin.top]);

  // 4. 軸の表示
  var axisx = d3.axisBottom(xScale).ticks(5);
  var axisy = d3.axisLeft(yScale).ticks(5);

  svg.append("g")
    .attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
    .call(axisx)
    .append("text")
    .attr("fill", "black")
    .attr("x", (width - margin.left - margin.right) / 2 + margin.left)
    .attr("y", 35)
    .attr("text-anchor", "middle")
    .attr("font-size", "10pt")
    .attr("font-weight", "bold")
    .text("X Label");

  svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + 0 + ")")
    .call(axisy)
    .append("text")
    .attr("fill", "black")
    .attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
    .attr("y", -35)
    .attr("transform", "rotate(-90)")
    .attr("text-anchor", "middle")
    .attr("font-weight", "bold")
    .attr("font-size", "10pt")
    .text("Y Label");

  // 5. プロットの表示
  svg.append("g")
    .selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle")
    .attr("cx", function (d) { return xScale(d[0]); })
    .attr("cy", function (d) { return yScale(d[1]); })
    .attr("fill", "steelblue")
    .attr("r", 4);
})

</script>
```

# 表示例

<img width="540" alt="image" src="https://user-images.githubusercontent.com/13635059/220295376-2a844285-6340-43d2-b945-d9ce1d25b15c.png">

# 参考

https://wizardace.com/d3-scatterplot/


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
【Spring WebFlux】WebTestClientで認証を迂回してテストを行う

# TL;DR
- `SecurityMockServerConfigurers`に定義された`Mutator`を`WebTestClient`にセットすることで認証を迂回できる
  - 少なくとも記事にまとめたやり方ではパス・メソッド・Authority周りのチェックは迂回できない（逆に言うと、それらの設定に関してテストを行うことができる）

# 注意書き
最小構成でのチェックはできておらず、あくまで自分の環境での実装例であることにご注意ください。
また、`org.springframework.security:spring-security-test`は導入されている前提で書きます。

https://mvnrepository.com/artifact/org.springframework.security/spring-security-test

サンプルコードは`Kotlin`で記述しますが、基本的な部分は変わらないはずです。

# やること
`WebTestClient`を利用したテストを実装する際に、`JWT`認証をスキップします。
ここでは`SecurityMockServerConfigurers.JwtMutator`を設定するやり方を紹介します。
サンプルコードは`JWT`ベースで書きますが、`SecurityMockServerConfigurers`ドキュメントを見る限り`OAuth2`や`OIDC`なども同じようなやり方で対応できそうでした。

https://spring.pleiades.io/spring-security/site/docs/current/api/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.html

# サンプルコード
サンプルコードは以下の通りです。
注意点として、この書き方では、`pathMatchers`で設定するような、パス・メソッド・Authority周りのチェックは迂回できません（逆に言うと、それらの設定に関してテストを行うことができます）。

```kotlin
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers
import org.springframework.test.web.reactive.server.WebTestClient

@SpringBootTest
@AutoConfigureWebTestClient
class FooTest @Autowired constructor(
    val baseClient: WebTestClient
) {
    // Authorityが設定されたWebTestClientを返す関数
    private fun WebTestClient.toAuthoritiesAwareClient(vararg authorities: String): WebTestClient {
        val mutator: SecurityMockServerConfigurers.JwtMutator = SecurityMockServerConfigurers.mockJwt()
            .authorities(authorities.map { GrantedAuthority { it } }) // 権限を設定

        return this.mutate()
            .apply(mutator)
            .build()
    }

    @Test
    fun test() {
        val client: WebTestClient = baseClient.toAuthoritiesAwareClient(/* 設定したいAuthorityを記述 */)

        // 通常同様にWebTestClientを使ったテストを記述
        val result = client.get()...

    }
}
```

## 呼び出し結果のステータスコードに関する補足
自分の環境では以下のようになりました。
割と当たり前の結果だと思いますが、これによってパス・権限周りのテストを行うことができました。

- `JWT`認証を突破できない -> `UNAUTHORIZED`
- 権限不足 -> `FORBIDDEN`
- どちらもOK -> `API`の実行結果に応じたステータス
What's New from CircleCI - 2023/02/21

CircleCIに関する最近2週間(2023/02/13~21)くらいの情報をまとめてみました。
気のつく限りの情報は拾ってみたつもりですが、見落としなどありましたら、Twitterで [@CircleCIJapan](https://twitter.com/CircleCIJapan) をメンションしてタレ込んでいただけると幸いです。
少しでもお役に立てていましたら、いいね(❤️)クリックいただけると嬉しいです！

[＜ What's New from CircleCI - 2023/02/14](https://qiita.com/CircleCIJapan/items/fc140f54692b3625e339) | 今週 | [What's New from CircleCI - 2023/02/28 ＞](https://qiita.com/CircleCIJapan/items/8780a3035afa39e1018e)
    
# ユーザーブログ・スライド
- CircleCI活用ブログ
    - [プライベート npm パッケージを CI/CD でインストールできるようにする方法](https://zenn.dev/bicstone/articles/npm-private-packages-ci) by [@bicstone_me](https://twitter.com/bicstone_me) さん

# CircleCI 公式ブログ
- [日本語ブログ](https://circleci.com/ja/blog/)
- [英語ブログ](https://circleci.com/blog/)

# Changelog (更新履歴)
- クラウド版の更新履歴: https://circleci.com/ja/changelog/
    - 02/14 [`setup_remote_docker` のアーキテクチャ更新](https://circleci.com/ja/changelog/#setup-remote-docker-のアーキテクチャ更新)
    - 02/14 [Arm fleet update](https://circleci.com/changelog/#arm-fleet-upgrade)
- サーバー版の更新履歴: https://circleci.com/ja/server/changelog/
- セルフホストランナーの更新履歴: https://circleci.com/ja/changelog/self-hosted-runner/
    - [コンテナランナー バージョン 3.0.4](https://circleci.com/ja/changelog/self-hosted-runner/#コンテナランナー-バージョン-3-0-4)
- プロダクト ロードマップ(今後の提供予定機能): https://circleci.com/ja/product-roadmap/

# YouTube (動画コンテンツ)
- [CircleCI チャンネル (日本語)](https://youtube.com/playlist?list=PL9GgS3TcDh8x71MTG2uvZ-ljhIkuveSHZ)
- [CircleCI Channel (English)](https://www.youtube.com/c/CircleCI-Videos)

# CircleCI Knowledge Base
- [CircleCI ナレッジベース (日本語)](https://support.circleci.com/hc/ja)
- [CircleCI Knowledge Base (English)](https://support.circleci.com/hc/en-us/)
    - [I have split my tests by timing, but why is the split not even?](https://support.circleci.com/hc/en-us/articles/12925459291419-I-have-split-my-tests-by-timing-but-why-is-the-split-not-even-)
    - [Context error preventing job re-run with SSH](https://support.circleci.com/hc/en-us/articles/12970731656347-Context-error-preventing-job-re-run-with-SSH)
    - [How to Delete an Organization](https://support.circleci.com/hc/en-us/articles/13006651761307-How-to-Delete-an-Organization)
    - [Why Can't I View Organization Settings as an Admin?](https://support.circleci.com/hc/en-us/articles/13008326147099-Why-Can-t-I-View-Organization-Settings-as-an-Admin-)

# CircleCI 関連のイベント、ウェビナー等
- 03/07(火) [はじめてのCircleCIハンズオンワークショップ 内製化への第一歩～効率的にCircleCIについて学ぼう～](https://circleci.connpass.com/event/274810/) - クラスメソッド様との共催
- 03/09(木) [DevSecOpsを実現するための最適なソフトウェア開発とシフトレフト](https://www2.circleci.com/2023-03-09-Fortinet-Joint-Webinar.html) - フォーティネット ジャパン様との共催
- 03/14(火) [Jenkins / オンプレミスユーザーのためのクラウドCI/CD入門](https://circleci.connpass.com/event/274191/)
- 04/13(木) [モバイルアプリ開発者向けCircleCI入門セミナー](https://circleci.connpass.com/event/274192/)
---
それでは今週も Happy Building⌨!
微分  |x|√(x2+1)「2023慶應大理工1(2)」をwolframalphaとsympyでやってみた。

グラフがでます。wolframalphaもsympyも。
オリジナル

http://kamelink.com/blog/2023/02/19/14-2-23-keiodai-riko-1-2/

# wolframで

https://www.wolframalpha.com/input?i=++%7Cx%7C%E2%88%9A%28x2%2B1%29&lang=ja

https://www.wolframalpha.com/input?i=++%7Cx%7C%E2%88%9A%28x2%2B1%29%E3%81%AE%E5%BE%AE%E5%88%86&lang=ja

　上と同じです。

https://www.wolframalpha.com/input?i=+diff%28%7Cx%7C%E2%88%9A%28x2%2B1%29%29&lang=ja

https://www.wolframalpha.com/input?i=d%2Fdx%28abs%28x%29+sqrt%28x%5E2+%2B+1%29%29+&lang=ja

#### 微分係数

https://www.wolframalpha.com/input?i=++%7Cx%7C%E2%88%9A%28x2%2B1%29%E3%81%AEx%3D0%E3%81%AE%E5%BE%AE%E5%88%86&lang=ja

結果
(未定義)
ステップごとの解説　をクリック
解説すべてがご覧になりたい方は...ｐroのお申込み　だそうです。

https://www.wolframalpha.com/input?i=++%7Cx%7C%E2%88%9A%28x2%2B1%29%E3%81%AEx%3D0%E3%81%AE%E5%BE%AE%E5%88%86%E4%BF%82%E6%95%B0&lang=ja

#### 極限
以下が、解答に近いです。

https://www.wolframalpha.com/input?i=lim_%28x-%3E0%29+%E3%80%80%28d%2Fdx%28abs%28x%29+sqrt%28x%5E2+%2B+1%29%29+%29&lang=ja

(両側極限は存在しません)左極限、右極限

# sympyで
diffでエラーがでました。
```python
from sympy import *
var('x')
y=abs(x)*sqrt(x**2+1)
print("#",     y )
print("#",diff(y))
print("#",      y.subs({x:0})  )
print("#",limit(y,x,0,dir="-" ))
print("#",limit(y,x,0,dir="+" ))
print("#",limit(y,x,0,dir="+-"))
print("#",       diff(y).subs({x:0})  )
#print("#",limit(diff(y),x,0,dir="-" ))
#print("#",limit(diff(y),x,0,dir="+" ))
#print("#",limit(diff(y),x,0,dir="+-"))
#
print("#",diff( x*sqrt(x**2+1)).subs({x:0})  )
print("#",diff(-x*sqrt(x**2+1)).subs({x:0})  )
#
plot(     y ,(x,-1.5,1.5))
#plot(diff(y),(x,-1.5,1.5))
# 0
# 0
# 0
# 0
# nan
# 1
# -1
```
plotコマンドは、縦横比？異なります。

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/67caadf6-5465-5830-9724-ae33a5688412.png)


# 参考
Limits

https://docs.sympy.org/latest/tutorials/intro-tutorial/calculus.html#limits
【Swift】処理を一時的に止める

# はじめに
スレッドに関して、あまり理解していないので、間違っていることがあればコメントください

# Thread
```swift
// 3秒中断
Thread.sleep(forTimeInterval: 3)
```

# Task
```swift
// 3秒中断
try? await Task.sleep(nanoseconds: 3 * NSEC_PER_SEC)
```

# おわり
何が違うんでしょう？？
わかったら記事を更新します
paizaラーニング レベルアップ問題集 新・Bランクレベルアップメニュー JavaScript 【条件判定 3】過剰コンプライアンス

【条件判定 3】過剰コンプライアンス (paizaランク B 相当)

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__over_conpriance

# 解答例
文字列を配列に変換はsplit。
前半分、後半分は、sliceを使って作った。文字列の前半と後半に中央の文字が含まれることに注意した。
完全一致や部分一致はeveryを使った。
文字の置き換えはmapを使った。
配列を文字列に変換はjoin。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N] = lines[0].split(" ").map(Number);
const S = lines[1].split("");
const S_front = S.slice(0, Math.ceil(N / 2));//S前半分
const S_back  = S.slice(Math.floor(N / 2));//S後半分

for (let i = 1; i <= N; i++) {
  const V = lines[i + 1].split("");
  const V_front = V.slice(0, Math.ceil(N / 2));//V前半分
  const V_back  = V.slice(Math.floor(N / 2));//V後半分

  if (V.every((v, i) => v === S[i])) { //完全に一致
    console.log("banned");
  //文字数が同じで、前半分または後ろ半分が同じ  
  } else if (V.length === S.length && V_front.every((v, i) => v === S_front[i])) {
    console.log(V.map((v, i) => i < Math.ceil(N / 2) ? v = "x" : v).join(""));
  } else if (V.length === S.length && V_back.every((v, i) => v === S_back[i])) {
    console.log(V.map((v, i) => i >= Math.floor(N / 2) ? v = "x" : v).join(""));
  //その他  
  } else {
    console.log(V.join(""));
  }
}
```
Toyota Programming Contest 2023 Spring Qual B C問題(Pythonコード付)

# 初めに　
　本記事はPythonでAtcoderにチャレンジしているけど、Pythonはコード例がないため解説がわかりにくい！と感じている方を対象としています。
　私自身大してレートも高くないので、不備等あるかもしれませんがご了承くださいm(_ _)m
　質問や指摘などもコメント等に書いてくださったら対応していきたいと考えていますのでどしどしコメントしてください。(内容がわかりにくいぞ！みたいな文句でもオールオッケーです笑)

# Toyota Programming Contest 2023 Spring Qual B（AtCoder Beginner Contest 290）
　問題のURLはこちらです。[Toyota Programming Contest 2023 Spring Qual B C問題](https://atcoder.jp/contests/abc290/tasks/abc290_c)

# 考え方
　問題文の条件として、「順序を変えずに抜き取る」という文言が書かれていますが、これは無視して構いません。なぜなら、MEXの出力に、入力した数列の順序は影響を及ぼさないからです。

例として、$B=[0,2,1],B=[2,0,1]$という数列を考えてみると、

どちらも$MEX=3$となることがわかります。


  今回重要なポイントは、与えられた数列Aを調べていき、「0,1,2,・・・・・」と値が入っているのかどうかが重要です。


　従って、今問題の解法としては数列Aをソートし、0から順番に値が格納されているのか調べることで、解を求めることができます。

# 実装例
```python
#標準入力
n,k = map(int,input().split())
a = list(map(int,input().split()))

#aをソートした配列を作成
re_a = sorted(a)

#mexの初期値を設定
num = 0
 
for i in re_a :
  if num == i :
    num += 1
    
  if num >= k :
    break
    
print(num)

```
 
# 最後に　
 私は最初、以下のようなコードを書きました。　
```python
n,k = map(int,input().split())
a = list(map(int,input().split()))
num = 0
count = 0
booler = True
while booler :
  if num in a :
    count += 1
    num += 1
  else :
    booler = False
    break
  if count >= k :
    break 
    
print(num)
```
　今コードはソートをかけずに、numを0から1ずつ増やしていって、配列aの中にその値が入っているのか調べるコードです。

　これはTLEしたのですが、この原因は「if num in a」というコードが邪魔しているからです。
　配列の中にある値が格納されているのか否かを調べる「in list」という処理は、ここだけで計算量が$O(N)$ かかります。　

　従って、今コードの計算量は$O(N^2)$となっているため、TLEしました。


　これまであまり内部の処理に気を配っていなかったので、今後は気をつけたいです汗
　ちなみに、その他処理にかかる計算量が[こちらの記事](https://qiita.com/Hironsan/items/68161ee16b1c9d7b25fb)にまとめられているので、ぜひぜひ読んでみてください。
FFmpeg-pythonでディレクトリ内にある画像から動画を作成する


## 目的
- 時系列で撮影した画像からタイムラプス動画を作りたい
  - 動画を作るためだけにリネームはしたくない

## FFmpegを使うと連番画像から動画を作成できる、が

FFmpegを使えば、連番がついた画像から動画を作成することができる。

```winbatch:実行例
ffmpeg -framerate 10 -i 'img-%03d.jpeg' out.mkv
```

ただし、ファイルの命名規則によってはうまくいかない。


## FFmpeg-pythonを使って作成
FFmpeg-pythonを使って作成する。動画の元になるファイルのリストをpathlibで作るようにすれば
ファイルの命名規則をあまり気にしなくても良くなる。

``` python:timelapse.py
import pathlib
import argparse
import ffmpeg as fp
import tempfile

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('pic_dir')
    parser.add_argument('--framerate',type=int,default = 30)
    parser.add_argument('--filter',type=str,default = None)
    parser.add_argument('--suffix',type=str,default = 'mp4')
    parser.add_argument('--filename',type=str,default = None)
    parser.add_argument('--qscale',type=int,default = 0)
    parser.add_argument('--output_path',type=str,default = None)

    args = parser.parse_args()

    pic_dir = pathlib.Path(args.pic_dir)

    if args.filename == None:
        filename = pic_dir.stem
    else:
        filename = args.filename

    if args.filter == None:
        expression = '**/*'
    else:
        expression ='**/*{}*'.format(args.filter)

    file_list = list(pic_dir.glob(expression))
    file_list = list(map(str,file_list))
    file_list = ["file '{}'".format(line) for line in file_list]


    with tempfile.TemporaryDirectory() as tmpdir:
        file_path = (pathlib.Path(tmpdir) / 'filelist.txt')

        with open(file_path,mode='w',encoding ='utf-8') as f:
            f.write('\n'.join(file_list))
        
        stream_input = fp.input(file_path, f='concat',r=args.framerate, safe=0)
        
        if args.output_path == None:
            output_path = pathlib.Path.cwd() / '{}.{}'.format(filename,args.suffix)
        else:
            output_path = pathlib.Path(args.output_path)
            
        stream_output = fp.output(stream_input,str(output_path), **{'qscale:v': args.qscale})
        fp.run(stream_output)

if __name__ == '__main__':
    main()

```

```:実行例
python timelapse.py 画像があるディレクトリ
```


## 参考
https://ffmpeg.org/ffmpeg-formats.html#image2-1

https://github.com/kkroening/ffmpeg-python

https://blog.shikoan.com/ffmpeg-python-concat/
Laravel9でポートフォリオの管理CMSを作ってみた

ポートフォリオ管理CMSはGitHubに公開しているので、ご自由にダウンロードして使ってください。
https://github.com/newstandard-space/Portfolio_System

:::note warn
色々とバグフィックスする必要があると思いますので、ご自身で修正してご利用ください。
:::


# どんなサービスか
管理画面で登録したAbout（自分について）とWork（これまでの仕事）をインターネット上で公開することができます。
※GitHubからダウンロードいただき、ご自身でWebサーバー上に設置していただく必要があります。

公開されたポートフォリオのTop画面のイメージ
![フロント画面_Top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/b10cb3dc-580f-5122-4484-30fe868908eb.png)
「詳しく見る」を押すとAbout MeとMy Worksのページに飛びます。

About Meページのイメージ
![フロント画面_About_詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/979b798e-6e60-81ef-c356-a74246528904.png)

My Worksページのイメージ
![フロント画面_Work_詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/24ea6904-5961-cb75-0869-9ff2b279bf02.png)

このように、About（自分について）とWork（これまでの仕事）を公開することができます。

# どのようにAboutとWorkを登録するか
※AboutとWorkの登録方法は同じです。
1\. 管理画面にアクセスする。
管理画面にアクセスするURLはドメイン/adminです。

:::note warn
ログイン機能を作っていないので、インターネット上に公開する場合は、ログイン機能を実装してください。
:::

2\. Aboutページをクリック
![管理画面_About_クリック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/5765e33b-236e-c225-26d7-ee97604ffa1e.png)
すると、Aboutページに飛びます。
![管理画面_About_ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/311aa11b-0f3c-0ae7-c742-02dd8db6f1a8.png)
3\. 新規登録ボタンをクリック
そうすると、About新規登録ページに飛びます。
![管理画面_About新規登録画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/67dfc479-6462-a826-a911-9f33310c34e5.png)
4\. ここでタイトルと詳細を記入して新規登録ボタンをクリック
これでAboutの新規登録が完了します。
登録されるとAboutページで登録した内容が確認できます。
![管理画面_About画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/ba78e0c6-7ea0-9f00-0888-8b53116d48df.png)
このようにしてAboutを登録していきます。
複数登録することもできます。
![管理画面_About_複数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/c88e7359-3d6f-220f-12ff-5e746656df0d.png)

並び替えもできます。
![並び替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/40bea572-592c-0d60-c2a1-e120585a3c30.gif)

ここまで、Aboutを登録してから並び替えるまでを説明しました。

次に、詳細ボタンをクリックすると詳細ページに飛びます。
詳細ページで更新と削除ができます。

About詳細ページのイメージ
![管理画面_About_詳細ページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667974/91428c0f-f7d8-9ace-731c-60dd1cb4d45d.png)

Aboutの登録、更新、削除、並び替えを説明しました。

※Workを登録する方法はAboutを登録する方法と同じです。

AboutとWorkの登録方法は以上になります。

# 管理画面で登録したAboutとWorkはポートフォリオ画面で表示されます
管理画面で登録したAboutとWorkがポートフォリオTopページで表示されます。
AboutとWorkを2つ以上登録している場合、一番目のAboutとWorkのみTopページでは表示されます。
二番目以降は詳しく見るボタンを押して、About MeページとMy Worksページで見ることができます。
STM32 ST-LINK Utility が起動しなくて焦った💦話

　10年程前に購入し、今も時々遊んでいる元気なSTM32VLDiscoveryボード。
![STM32VLD.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/6d6a6d93-0b95-334d-cd76-14402cd996a2.jpeg)
　最近手に入れ,、Windows11にアップグレードした中古パソコンで遊んでみようと思った。STM32CubeIDEと、このボードは古くてSTM32CubeProgrammerでは書き込めないので、ST-LINK Utility をインストール。ビルドし、さあbinファイルを書き込もうとST-LINK Utilityを起動。えっ？まさかのエラー💦。mfc140.dll、msvcp140.dll、vcruntime140.dllがないという。一足先にWindows11にアップグレードしたメインマシンはどうかと慌ててやってみたが、こちらは無事起動、書き込みもできる。
新しい(といっても中古)PCでも何とかしたいと、3個のdllをコピーしてみてもダメ。ネットを探ると、外国の方もこのdllが無いとかで困っているよう。残念だが諦めるかと。SSDに交換し容量の余裕もあるので何か他の事をとVisual Studio Community 2022をインストール。ひょっとするかもとST-LINK Utilityをダブルクリック。ありがたい:heart_eyes_cat:、起動する。今まで通り書き込みもできる:o:。
![STLINK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/5c5d1eb8-cbdb-fe8d-875e-714c702c0a82.jpeg)
ボード本体の黒のリセットボタンを押しながらの Connect to the target で接続、無事書き込めて一件落着。
　今回の件はWindows11をクリーンインストールしたためか❓:thinking:
今さらのH8マイコンプログラミング


　初投稿です。何か問題や参考になる事があれば教えてください。お願いします。

永くArm、Arduinoで遊んでいたが、突然H8マイコンを動かしてみようと思い立った。早速、秋月からH8/3664Fボードや開発キットを購入し動かしてみた。ところが取説通りにしてみても書き込みに一苦労、やっと出来たと思ったら Sample が説明書通りに動かない:cold_sweat::interrobang:これゴミになるかも💦(-_-;)？
　古い本、ネットの情報も少なかったけれどやっと何とか一つまとまった物ができたので、私のような物好きな初心者のお役に立てればと上げてみた。

---
　シリアル通信で0～255までの数を送り、それの2進数(bit)に対応したLEDを点灯させるもの。
![H8_3664_1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/293e26af-ac5c-8c37-1933-31e57285d73b.jpeg)
![KIMG0379_1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/15a6a497-de0e-5b56-8d40-f8a3a89e3cb9.jpeg)

　RenesasのHEW7.0.0でプログラム。SCI3とPORT8(大電流可)を使用している。SCIの扱いに苦労した。Sample通りではターミナルソフトから入力した文字が2回戻されて来るので修正。数字の入力も1桁ではなく255までにしたくて工夫してみた。
```c:
#include "iodefine.h"

void sci_init(void);
void putch(unsigned char ch);
void crlf(void);

void sci_init(void){			/* SCI3 Initialization */
	short i;
	IO.PMR1.BIT.TXD = 1;		/* Change P22 to TXD */
	SCI3.SCR3.BYTE 	= 0;		/* clear all flags	*/
	SCI3.SMR.BYTE	= 0;		/* シリアルポートの初期値 */
	SCI3.BRR 		= 25;		/* 19200baud (CPU=16MHz) */
	SCI3.SCR3.BYTE 	= 0x30;		/* Enable SCR3=0011 0000 (TE=1,RE=1) */
	
	for (i = 0; i < 256; i++);	/* Wait Time */
	
	SCI3.SSR.BYTE;				/* Dummy Read */
	SCI3.SSR.BYTE 	= 0x80;		/* Clear Error Flag (TDRE=1) */		
}

void crlf(void){	/* 改行 */
	putch('\r');
	putch('\n');
}

void putch(unsigned char c){	/* char送信 */
	int i;
	while(SCI3.SSR.BIT.TDRE != 1);	/* SCI3.SSR.BIT.TDRE=0 で未送信データあり
													 	 1 になるまで待つ     */
	SCI3.TDR = c;				/* これだけで送信 */
	for (i = 0; i < 256; i++); 	/* Wait Time */ 
}

void main(void){
	int i;
	unsigned char ch;
	
	/* Port8 Initialization */
    IO.PCR8      = 0xff;        /* Port-Cntrol ; Set P8x for Output Pin */
    IO.PDR8.BYTE = 0x00;        /* Port-Data   ; Output 0 to P8x */
	
	sci_init();

	crlf();
    putch('*');		/* 通信が正常なら表示される */
	crlf();
	crlf();

	while(1){
		i=0;	/* Port8 に代入する10進数 */
		do{
			SCI3.SSR.BIT.FER = 0;			/* Clear Error Flag */
			while(SCI3.SSR.BIT.RDRF != 1);	/* 受信完了待ち */
			ch = SCI3.RDR;
			if( (ch>47) && (ch<58) ){ 
				putch(ch);				/* 受信１数字送信 */
				i = i*10 + (ch-48) ;	/* ２桁以上作成 */
			}
		}while( (ch>47) && (ch<58) );	/* 0～9 なら繰り返す */
        crlf();				/* 0～9 以外なので確定で改行 */
        IO.PDR8.BYTE = i;	/* 10進数に対応する2進数をLED表示 */
	}	/* 繰り返す */
}
```
---
　その他にもいろいろ苦労したこと.
１．マイコン書き込み時にはCPUボード上の赤いジャンパーピンをセットしブートモード。それは良いのだが、HTERMでの書き込みがTimeout Error でなかなかできない。やっとそれらしい解決法を見つけた。
　「TERA2のPowerSWをONにするとほぼ同時(0.1秒後？)にPCのリターンキーを押す」

２．いざ赤いジャンパーピンを外し動かそうとするのだが、直ぐには上手く通信を始めてくれない。タクトスイッチを押したりパワースイッチを入れ直したり。

　ArmやArduinoに慣れきって、したことのないビット操作もやってみた、マイコンのマニュアルも日本語で読めるし。それにArduinoだとloop内で、シリアル通信中の１文字待ちしかできなかったかな？
　このやんちゃ坊主のようなマイコンも孫のようでまた楽しい、69歳のじっちゃんでした。
px4のログをcsvにする

### px4のログ（.ulg）を表計算ソフトで編集したい

- QGroundControlなどからログを吸い出すか、SDカードから直接とりだしたあと、データを表計算ソフトで操作したい。
- 調べると、「pyulog」というpythonのツールが存在するらしい。pipでインストールできるようで、お手軽。

### 導入

- [ここ](https://github.com/PX4/pyulog)の手順通り。
- インストールは以下の１行

```bash
python3 -m pip install pyulog
```

### 試しに何かをcsvに変換

- 例えば、次のコマンドで全てのログがcsvに変換できます

```bash
$ ulog2csv (変換したいログ).ulg -o (出力先ディレクトリ)
```
- 実際の例

```bash
tomiyuichi@tyxps:~$ cd ./sample/
tomiyuichi@tyxps:~/sample$ ls
testlog.ulg
tomiyuichi@tyxps:~/sample$ mkdir csv
tomiyuichi@tyxps:~/sample$ ulog2csv testlog.ulg -o ./csv
tomiyuichi@tyxps:~/sample$ ls ./csv/
testlog_actuator_armed_0.csv
testlog_actuator_controls_0_0.csv
testlog_actuator_outputs_0.csv
testlog_battery_status_0.csv
testlog_battery_status_1.csv
testlog_commander_state_0.csv
testlog_cpuload_0.csv
testlog_ekf2_timestamps_0.csv
testlog_ekf_gps_drift_0.csv
testlog_estimator_innovations_0.csv
testlog_estimator_innovation_test_ratios_0.csv
testlog_estimator_innovation_variances_0.csv
testlog_estimator_sensor_bias_0.csv
testlog_estimator_status_0.csv
testlog_hover_thrust_estimate_0.csv
testlog_logger_status_0.csv
testlog_manual_control_setpoint_0.csv
testlog_multirotor_motor_limits_0.csv
testlog_radio_status_0.csv
testlog_rate_ctrl_status_0.csv
testlog_safety_0.csv
testlog_sensor_accel_0.csv
testlog_sensor_accel_1.csv
testlog_sensor_accel_2.csv
testlog_sensor_baro_0.csv
testlog_sensor_combined_0.csv
testlog_sensor_gyro_0.csv
testlog_sensor_gyro_1.csv
testlog_sensor_gyro_2.csv
testlog_sensor_mag_0.csv
testlog_sensor_mag_1.csv
testlog_sensor_preflight_imu_0.csv
testlog_sensor_preflight_mag_0.csv
testlog_system_power_0.csv
testlog_telemetry_status_0.csv
testlog_trajectory_setpoint_0.csv
testlog_vehicle_acceleration_0.csv
testlog_vehicle_air_data_0.csv
testlog_vehicle_angular_acceleration_0.csv
testlog_vehicle_angular_velocity_0.csv
testlog_vehicle_attitude_0.csv
testlog_vehicle_attitude_setpoint_0.csv
testlog_vehicle_command_0.csv
testlog_vehicle_control_mode_0.csv
testlog_vehicle_gps_position_0.csv
testlog_vehicle_imu_0.csv
testlog_vehicle_imu_1.csv
testlog_vehicle_imu_2.csv
testlog_vehicle_imu_status_0.csv
testlog_vehicle_imu_status_1.csv
testlog_vehicle_imu_status_2.csv
testlog_vehicle_land_detected_0.csv
testlog_vehicle_local_position_0.csv
testlog_vehicle_local_position_setpoint_0.csv
testlog_vehicle_magnetometer_0.csv
testlog_vehicle_rates_setpoint_0.csv
testlog_vehicle_status_0.csv
testlog_vehicle_status_flags_0.csv
testlog_yaw_estimator_status_0.csv
tomiyuichi@tyxps:~/sample$
```

- 以上

偵察気球って作ってるエンジニアからすれば楽しいんだろうなあ

2023年2月21日
Apply new profile with OBEYFILE command

When you modify TCPIP profile and want to apply new parameter. You can use following command:
```
VARY TCPIP,tcpip-procname,OBEYFILE,tcpip profile dataset(member)
```
Note : Some of reserved ports are not released, then you need to restart TCPIP.

Reference:
https://www.ibm.com/docs/en/zos/2.5.0?topic=SSLTBW_2.5.0/com.ibm.zos.v2r5.halu101/varyp1b.html
【Python_pandas】applyとsort_value組み合わせ時におけるエラーと原因

# 本記事の前提
### groupbyによるグループ化
pandasのgroupbyメソッドを利用し、特定の情報ごとにデータをグループ化を行い、
グループ単位で平均等を計算することはよくあると思います。

例
```python:Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'B', 'A', 'B'],
    'value': [1, 2, 3, 4]
})

# group列でグループ化し、value列の平均値を計算
grouped_df = df.groupby('group').mean()

print(grouped_df)
```

結果
```css:css
       value
group       
A        2.0
B        3.0
```


### 最頻値の求め方
平均などは前述の通り、gropubyの後mean()を実行するだけですが、
最頻値はmodeをlambda関数でラップして実行する形になります。

例
```python:Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
    'value': [1, 1, 1, 2, 2, 3, 3, 4]
})

# group列でグループ化し、value列の最頻値を計算
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode())

print(mode_df)
```

結果
```css:css
group   
A      0    1
B      0    3
C      0    4
Name: value, dtype: int64
```


# 本題：sort_valueで、エラーとなる場合と対処
以下はエラーとならない。

例
```python:Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'B', 'A', 'B'],
    'value': [1, 2, 3, 4]
})

# group列でグループ化し、value列の平均値を計算後、ソートを実施
grouped_df = df.groupby('group').mean().sort_values(by='value', ascending=False)

print(grouped_df)
```
結果
```css:css
       value
group       
B        3.0
A        2.0
```


一方で、以下はエラーとなる
例
```python:Python（エラーとなる）
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
    'value': [1, 1, 1, 2, 2, 3, 3, 4]
})

# group列でグループ化し、value列の最頻値を計算
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode()).sort_values(by = 'value')

print(mode_df)
```

理由は単純で、sort_valuesを付与しなかった場合の結果を見るとわかるように、
applyの結果においてはインデックスが消滅しているため。

回避策はいくつかある。

１）DataFrame型に強制的に入れる
例
```python:Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
    'value': [1, 1, 1, 2, 2, 3, 3, 4]
})

# group列でグループ化し、value列の最頻値を計算
# その後DataFrame型に変換することでindexを復活させ、ソートを行う
mode_df = pd.DataFrame(df.groupby('group')['value'].apply(lambda x: x.mode())).sort_values(by='value')

print(mode_df)
```
結果
```css:css
         value
group         
A     0      1
B     0      3
C     0      4
```


２）reset_indexを行う
例
```python:Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
    'value': [1, 1, 1, 2, 2, 3, 3, 4]
})

# group列でグループ化し、value列の最頻値を計算
# reset_indexでindexを復活させ、ソートを行う
mode_df = df.groupby('group')['value'].apply(lambda x: x.mode()).reset_index().sort_values(by='value')

mode_df.head()
```
結果
|  | group | level_1 | value |
|:-:|:-:|:-:|:-:|
| 0 | A | 0 | 1 |
| 1 | B | 0 | 3 |
| 2 | C | 0 | 4 |
統計検定準1級を1回不合格になったのち、最優秀成績賞で合格した話【攻略法】

統計検定準1級を、一回不合格になった後に最優秀成績賞で合格したので、ノウハウをまとめました。

この記事を読めば、
・**統計検定準1級とは**
・**必要な教材**
・**暗記していくべきもの**
・**一発で合格するためには**
が明確になると思います！

# 自己紹介(学習歴)
データサイエンティストを目指して日々勉強している、慶應大学理工学部4年生（2023.12.31時点）

取得資格、コンペ優勝経験など、リアルタイムの情報は👇👇👇をみてね

X: @A7_data←こういう者です。
プロフィールページ👇👇👇

https://mohki7.notion.site/Mototsugu-Oki-c478f842c4de48f394e2e24b58e206bb?pvs=4

# 本記事はNoteに移行いたしました。
この記事は2024年より、Noteに移行いたしました。以下から無料で読むことができます。

https://note.com/a7_data/n/nb225cc0f8b0e

よろしくお願いします。
LivebookのSecretsを使う

# Livebookとは

Elixir版 JupyterNotebook のようなものです

https://livebook.dev/

@torifukukaiou さんの記事が勉強になります

https://qiita.com/torifukukaiou/items/223ad0fe1aa67a9fb151

# Secrets

名前の通り、秘密情報です
ノートブックに直接記載したくない値（ID、パスワード、トークンなど）を設定できます

## 設定

ノートブックを開き、左側の鍵マークを選択

<img width="799" alt="Screenshot 2023-02-21 16.41.47.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/318ca890-45c6-11a5-2ba3-89f3fe99bb91.jpeg">


`+New secret` を選択

<img width="800" alt="Screenshot 2023-02-21 16.23.02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/9e613663-2bff-42e3-9c15-79477ff6ab3b.jpeg">

各値を設定して`+Add`

Storage について
- only this session
    - ノートブックのSessionを閉じるまで保存される値
    - 他のノートブックから参照することはできない
- in the Livebook app
    - Livebookアプリ自体に保存される値
    - 複数のノートブックから利用できる
    - Livebookを再起動しても残ったまま
    - トグルボタンで各Secretの有効/無効を切り替えられる

## 利用

- 設定したSecretは、環境変数と同じように使うことができる
- ただし、**変数名の頭に `LB_` をつける**
- 出力でSecretの値が表示される
    - 出力は`.livemd`ファイルに書き込まれないので、ソース管理への混入は心配なし
    - セッションを閉じると出力セルも消えるので、セッション情報として管理されている？

<img width="676" alt="Screenshot 2023-02-21 16.44.43.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/41e643d0-c595-5c5f-4b87-cfca9ba6509c.jpeg">


## 削除

Secretを選択して、ゴミ箱マークで削除できる

<img width="375" alt="Screenshot 2023-02-21 16.40.51.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/486ac41a-fde8-7ff5-a17f-26135f2024eb.jpeg">

# 参考

https://hackmd.io/@hugobarauna/By6ulTnMi

# 感想

- トグルスイッチで簡単に切り替えられるのは便利そう
- セッションを閉じたタイミングで消したい値を扱う際に使える？
    - `Kino.Input`のほうが便利な気がする
- プレフィックス(`LB_`)が分かりづらく、export前提だと扱いづらい
    - ホストの環境変数と干渉しない点がメリットかと思ったけど、Livebook自体がそうだった
        - → Livebook上で確認できる環境変数とホストの環境変数がそもそも違った
- 個人利用だと、Settings → Environment variables で十分な印象
    - こちらだとプレフィックスがいらないので、export前提でもOK
    - 同じLivebookで大量のノートを複数人で扱う、みたいな場合は干渉しないよう注意が要るかもしれない
QNAP NAS remote access

本記事では、QNAPのNASへのremote accessについてまとめていく。

# 環境 
- [TS-259 Pro+](https://www.qnap.com/ja-jp/product/ts-259%20pro+)
- M1 MacBook(2020)

# 目標の設定 
TS-259 Pro+では、QNAPからのOSのサポートが終了しており、OSに付属しているcloudアプリが使用できない。そこで、本記事の目標は**このアプリを介さないリモート接続の実現とする**。 

# 接続方法の検討 
本節では、リモートでの家庭内のNASへの接続方法についていくつかの手法を接続の仕組みなどに触れながら考察していく。 
## VPN
そもそも、VPNとは以下のように説明されている[^1]。
[^1]:[VPN接続とは？VPNの基本とメリット・デメリットを紹介](https://www.nttpc.co.jp/column/network/whats_vpn.html)より引用

>「VPN」は「Virtual Private Network」の略で、日本語では「仮想専用線」と呼ばれます。
送信側、受信側にそれぞれに設置した機器で「カプセル化」と呼ばれる処理を行うことで、第三者には見えない仮想的なトンネルを形成して通信する仕組みです（「トンネリング」）。
また、通信時には正規の利用者であることを確認するために認証を行う、万一トンネルに侵入された場合に備えて通信内容は暗号化して送信する、などの技術を併せて採用することで、さらに通信の安全性を高めています。
これらの技術により、拠点間をいわば仮想の専用線で結び、安全に情報をやり取りすることができるわけです。

要するに**仮想的に専用線をインターネット上に用意し、かつ情報の暗号化をすることにより、(インターネットを介して)安全に情報のやり取りができるという仕組みのことである**。ただし、筆者が調べている限りだと、qnapのNASへのVPNの導入には、多くのサイトでQVPNserviceを利用していることを考えるとサポートの終了している筆者の所有している機種には不適当な方法であると考えられる。 

## ssh[^2] 
sshとは以下のように説明されている[^3]。 
[^2]:個人的に、最近のマイブームとなっている方法である。最近、ubuntuをMacBookに仮想環境で導入した。その際に仮想環境のubuntuとmacとの通信方法としてsshを利用したので、馴染みがあるというか懐かしさがあるというような感じである（完全な余談）。
[^3]:[SSH【secure shell】セキュアシェル](https://e-words.jp/w/SSH.html)
>SSHとは、主にLinuxなどのUNIX系OSで利用される、ネットワークを通じて別のコンピュータを安全に遠隔操作するための通信手順（プロトコル）およびソフトウェア（sshコマンド、sshデーモンなど）。通信経路が暗号化されるため、インターネットなどを経由しても安全にアクセスすることができる。

要するに、**unix系のOS[^4]で利用されるリモート接続の手法**と言える。
なお、sshについては「qnap ssh」と調べたところ接続や設定の方法に関する情報が豊富であった。

[^4]:これがmacのメリットであるのかと、少し考えた。

## 接続方法についての結言
以上の調査より、現状は**sshの公開鍵と秘密鍵を利用したリモート接続を行う**という方針で設定などを行っていきたいと考えている。

# sshを利用したリモート接続
本節では、sshと公開鍵、秘密鍵を利用して、外出先でも安全に家庭内のNASへアクセスする手法について模索していく。 
## sshを利用してNASへアクセスする 
実は、sshでのパスワードでの利用は意外と単純である。 
~~~
ssh [user name]@[ip address]
~~~
このコマンドのあとに、パスワードを入力するだけである。なお、筆者が利用しているNASについては父がセットアップしていたのであろうか、既にsshで接続され初期の設定(?)は終わっていた。[^5]
[^5]:この[サイト](https://www.qnap.com/ja-jp/how-to/faq/article/how-to-access-qnap-nas-by-ssh)の通常のシェル環境にまで到達していた。ただし、ここでの初期操作を初期設定というかが不明であったため、本文では「初期設定(?)」というような記述にした。

## sshの鍵の作成と共有 
ここでは、[参考サイト](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-to-connect-to-a-remote-server-ja)に従い、sshにおける鍵の作成方法とその共有について記述する。NASに特化したものではないので、作成方法と共有について記述したのちに、その詳細についても調べていく。まずは、ログイン元のコンピュータで鍵を生成する。以下のコマンドを使う。 
~~~
ssh-keygen -t rsa
~~~
これによって、鍵が~/.ssh/id_rsa.pubと*~/.ssh/id_rsa*に作成されることが報告されている。また、公開鍵をサーバーにコピーするために以下のコマンドをたたく。 
```
ssh-copy-id [remote_host]
```
以上で、鍵によるssh接続に関する所作は終了である。ここからは、NASに特化した注意点などについて調べていく。
データ圧縮

# データ圧縮とは
```データをある法則（アルゴリズム）で計算して変換```することで、この中で実質的に内容が損なわれることがない情報量を無くすことなく```データ量を減らす効率的な符号化```です

# ファイル圧縮
ファイル圧縮は、可逆圧縮であり```zip形式・lzh形式・rar形式・sit形式・7z形式・cab形式```などがあります。

# 静止画圧縮
静止画圧縮は、代表的なものとして```JPEG、GIF```があります。

# 動画圧縮においては、コーデックとコンテナ（フォーマットとも呼びます）の区別があります。
「コーデック」は```動画ファイルを圧縮する符号化```を示し、「コンテナ」は```圧縮された動画ファイルに拡張子のついたもの```を示します。

ここでは「コーデック」に関して説明します。動画の圧縮技術
コーデックでは、```H.264```が広く使われており、YouTubeなどでも使用されています。
AV1は圧縮率が最も高いと言われており、米国で開発され将来的に有望視されています。
```MPEG-4```はMPEG-2より圧縮率をさらに高めたもので、モバイル機器での視聴に適するものです。
ほかに、Googleが開発したVP9やMicrosoftが開発したWMV9などの形式があります。
また、高画質化で可逆圧縮、非可逆圧縮いずれにも対応するAMV Video CodecやHuffyuvなどもあります。

 
# 音声圧縮
音声圧縮では、非可逆圧縮としてドルビーデジタルの```AC-3```、ミニディスク（MD）で使用されている```ATRAC```、MPEGオーディオ用として```MP3```などがあります。
音声圧縮技術
また、可逆圧縮としてはiTunesなどで使用のApple Lossless、DVD等で使用されているMLP、国際標準のMPEG-4 ALSなどがあります。

ほかに可逆圧縮、非可逆圧縮いずれにも対応するWMA(Windows Media Audio)やDolby Digital Plus(DD+)などがあります。
動画圧縮、音声圧縮は特に多種多様なものが提案され使用されています。

# 出典
https://engineer-education.com/data-compression/#i

# 感想
データの圧縮符号方式の種類だったのか。
たくさんあるんだな。
WSL2で簡易プロキシサーバーを立てる

Windows環境で開発をしていて、動作確認のためにベーシック認証付きのフォワードプロキシが必要になりました。フォワードプロキシでは [Squid](http://www.squid-cache.org/) がよく使われますが、ここでは [tinyproxy](https://github.com/tinyproxy/tinyproxy) を使ってプロキシサーバーを立てて対応しました。

# 環境
* Windows 10 22H2
* Ubuntu 22.04.1 LTS (GNU/Linux 5.15.79.1-microsoft-standard-WSL2 x86_64)

WSL2の環境の構築については、以下のページなどに書かれています。
https://learn.microsoft.com/ja-jp/windows/wsl/install

# tinyproxyのインストール
Ubuntuのパッケージが提供されていますので、そのままインストールします。(あらかじめ `apt update` しておきましょう)
```
$ sudo apt install tinyproxy
```

# 設定ファイルの編集
ここではベーシック認証を設定するほか、プライベートアドレスからのアクセス許可を設定します。
```
sudo vi /etc/tinyproxy/tinyproxy.conf
```
* プライベートアドレスからのアクセス許可
    以下の部分のコメントアウトを解除します。必要に応じて範囲を絞ってもいいと思います。
```
Allow 192.168.0.0/16
Allow 172.16.0.0/12
Allow 10.0.0.0/8
```
* ベーシック認証
    コメントアウトされている `BasicAuth` に続けて、必要なユーザー・パスワードを書きます。平文でOKです。
```
#BasicAuth user password
BasicAuth user1 hogehoge
BasicAuth user2 fugafuga
```

# 起動
ここでは動作確認用なので、単純に起動します。
```
$ sudo tinyproxy
```
停止は、私は単純に以下のような感じで `kill` していました。
```
$ ps -ef | grep tinyproxy
tinypro+  2570    65  0 15:35 ?        00:00:00 tinyproxy
$ sudo kill 2570
```

# WSL2のportproxy
WSLではWSLで起動したプロセスに対してネットワーク側からアクセスできましたが、WSL2ではローカルのIPアドレスが付与され、ネットワーク側からアクセスできません。そのため管理者のPowerShellから以下のようなコマンドを実行してアクセスできるようにします。
```
> netsh interface portproxy add v4tov4 listenport=8888 listenaddress=0.0.0.0 connectport=8888 connectaddress=172.31.xxx.xxx
```
なお、 `connectaddress` はWSL2に付与されたアドレスです。WSL2の中で `ip address show eth0` コマンドなどで取得します。
このアドレス、PC再起動ごとに変わってしまうのが面倒だったりしますが、動作確認用なので気にしないでおきます。
以下のページを見たところ、この辺は今後改良されていくかもしれません。
https://learn.microsoft.com/ja-jp/windows/wsl/networking

# 最後に
動作確認用なので、できるだけ簡単にできる方法を選んでみた感じです。
ほかにもっと簡単な方法が、などあればコメントいただけるとうれしいです。
[mysql] range_optimizer_max_mem_size の確認方法

<h2>記載の動機</h2>
MySQL5.6→5.7のアップデートの際に range_optimizer_max_mem_size を確認したくなったのだが、<br>
ぐぐっても直球で書いているものをすぐに見つけられなかったので。

<h2>探し方</h2>
mysqlで以下のコマンドを実行して、結果の中から探せばすぐ見つかった。

```
show global variables;
```

<h2>参考</h2>

* <a href="https://qiita.com/yoheiW@github/items/23c5791b34da6f814056">運用MySQL ~その１~ DB状態確認</a><br>
* <a href="https://zenn.dev/muro/articles/417d84d75c2eb7
">MySQL5.6→5.7のアップデートで意図せぬスロークエリが発生した</a>
ちょっと便利なkubectlスニペット集

# kubectlをちょっと便利にするスニペット集
kubectlをちょっぴり便利にするためのコマンドを掲載していきます。

## kubectl with HEREDOC
コピーアンドペーストで簡易にマニフェストを実行したいなどの用途で利用してください。
```sh
cat <<EOF | kubectl apply -f -
ここにYAMLファイルを記述する
複数行記述できます
EOF
```
注1）ヒアドキュメント終了符号は任意のものを用いることができます。変更する場合は「EOF」（2箇所）を置き換えてください。

## curl即時実行（都度Pod破棄）
疎通確認等の目的で単発でcurlを実行したい、だけどPodの管理（破棄）はしたくないといった用途で利用してください。
```sh
kubectl run curl --image=curlimages/curl -n <TARGET_NAMESPACE> -it --rm -- curl -o - <URL>
```
注1）「-o」オプションで「<URL>」の結果を標準出力にリダイレクトしています。オプションはお好みで。
注2）「--rm」オプションによって実行後Podが削除されます。間を置かず本スニペットを連続実行すると下記のようなエラーが出ることがあります。これはPod削除が間に合わないためです。連続実行する場合は素直にPod内でcurlコマンドを実行しましょう。
`Error from server (AlreadyExists): pods "curl" already exists`

## Pod内でcurl実行（ログアウト後Pod破棄）
切り分け等で連続的にcurlを実行したい、だけどPodの管理（破棄）はしたくないといった用途で利用してください。
```sh
kubectl run curl --image=curlimages/curl -n <TARGET_NAMESPACE> -it --rm -- /bin/sh
curl -o - <URL1> #例1
curl -o - <URL2> #例2
```
注1）Podへのログイン後、例1・例2のように自身で`curl`コマンドを発行します。
注2）「`exit`+`enter`」「`ctrl+d`(同時押し)」でシェルを抜けることでPodが破棄されます。

## CentOS7環境をサクッと立てる
何かと揃っている環境をサクッと立てたいときはこちら（CentOS7）。
```bash
cat <<EOF | kubectl apply -n <TARGET_NAMESPACE> -f -
apiVersion: v1
kind: Pod
metadata:
  name: centos7
spec:
  restartPolicy: OnFailure
  containers:
    - name: centos7
      image: centos:7
      command:
        - "/sbin/init"
EOF
```

`/sbin/init`が使えない場合はsleepコマンドを組み合わせるとよいでしょう。
```bash
cat <<EOF | kubectl apply -n <TARGET_NAMESPACE> -f -
apiVersion: v1
kind: Pod
metadata:
  name: awscli
spec:
  restartPolicy: OnFailure
  containers:
    - name: awscli
      image: amazon/aws-cli
      command: [ "/bin/bash", "-c", "--" ]
      args: [ "while true; do sleep 30; done;" ]
EOF
```

作成後、下記コマンドでPodにログインします。
```bash
kubectl exec -it centos7 -n <TARGET_NAMESPACE> -- /bin/bash
```

以上
[ServiceNow] ATF - Choice型のParameterを使用する際の選択肢の設定方法


デフォルトのビューだと、選択肢を設定する箇所がない。
なので、選択肢を設定するための関連リストを表示する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358025/692a3513-5ee8-b081-7b4f-86ce9fb7d6bd.png)



コンテキストメニューから[Configure] > [Related Lists]を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358025/e237aeb6-aecd-1b91-a168-101897dad5bb.png)

**Variables Choice List** を選択してSave。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358025/d0695cba-8037-b493-70a6-2ce8344284f5.png)

選択肢を設定するための関連リストが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358025/4a4003ec-313b-d9bf-b545-04452d74f190.png)