OmniAICreator/Qiita-1.07M huggingface dataset:
Zenhubと紐づいたGithubのPRをCSVに出力する方法

## はじめに

- Zenhub公式ではCSV出力をサポートしていない
  - APIはあるので自分でコード書いてねというスタイル
- この記事では自身が必要な情報だけ出力しているが、 他に欲しい情報がある場合は`export_to_csv`のissue変数を出力して各自ピックアップしてもろて

## 前提
- Python環境が用意されていること
  - requestsを入れてない場合は `pip install requests`
- Zenhub側でやること
  - 取得したい課題のZenhubリポジトリIDをメモする
  - トークンを発行する
- Github側でやること
  - 以下をメモする
    - リポジトリ名 
    - 組織名 or ユーザー名
  - トークンを発行する

:::note warn
メモした内容はコード内の定数に入れる
:::


## コード

```py:fetch_zenhub_issues.py
import csv
import datetime
import requests 

GITHUB_TOKEN = ''

ZENHUB_AUTHENTICATION_TOKEN = ''
ZENHUB_REPO_ID = ''
REPO = ''  # format is organization/repo or username/repo


def iterate_pages(repository):
    headers = {"Authorization": f"token {GITHUB_TOKEN}"}
    results = []
    page_number = 1

    # URL for the first page of issues
    issues_url = f'https://api.github.com/repos/{repository}/issues?state=all&per_page=100&page={page_number}'
    while issues_url:
        # Request issues from the current page
        request = requests.get(issues_url, headers=headers)
        if request.status_code != 200:
            print(f"Error fetching issues: {request.status_code}")
            break

        # Append the JSON response to results
        issues_data = request.json()
        results.extend(issues_data)

        # Check if there is a 'Link' header to get the next page
        if 'link' in request.headers:
            links = request.headers['link'].split(',')
            next_url = None
            for link in links:
                if 'rel="next"' in link:
                    next_url = link.split(';')[0].strip('<> ')
                    break
            issues_url = next_url  # Set URL for the next page, or None if it doesn't exist
        else:
            issues_url = None  # No more pages

    return results

def export_to_csv(filename="zenhub_issues.csv"):
    keys = ["PR_No", "title", "state", "body"]
    with open(filename, "w", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=keys)
        writer.writeheader()

        for issue in total_result:
            if isinstance(issue, dict):
                if issue.get('pull_request') is not None:
                    writer.writerow({
                        "PR_No": issue.get("number", ""),
                        "title": issue.get("title", ""),
                        "state": issue.get("state", ""),
                        "body": issue.get("body", ""),
                    })

if __name__ == '__main__':
    total_result = iterate_pages(REPO)
    export_to_csv()
```

### 補足
- 定数の内容及びコードは合ってるのに取得できないIssueがある場合はGithubトークンの権限が狭すぎるかも？
  - その辺いじったけど記憶にない

## 終わりに
- ChatGPT使ってベース作った後に軽くしか修正してないので、コードはお察し()
- どこ調べても記事でまとめられてなかったのつらい
  - 質問サイトで「解決しました！」だけ書くのやめてね（経緯も書いてもろて）

## 参考
- [Github API](https://docs.github.com/ja/rest?apiVersion=2022-11-28)
- [ZenhubからCSVに出力するリポジトリ](https://github.com/agrando-de/zenhub-to-jira/tree/master)

:::note alert
上記リポジトリ内のコードは動作しない模様
:::

## (追記)
- 本当はZenhubで作成した課題を出力したかったが想定と異なり、GithubのPRしか取得できなかったためタイトルを変更


以上
Docker logsのファイルの場所

# はじめに
`docker-compose`でコンテナを立てたときに、コンテナが原因不明にexitedとなったらどうしますか？
おそらく以下コマンドを使ってログの確認しますよね。

```
docker logs container_id
```

ただ、コンテナを立ててから時間が経つと量が多すぎるので、ファイルで扱いたいとかないですか？

今回はその方法を紹介します。

# 手順
結論を言うと、ホストOSの以下パスに配置されています。
`/var/lib/docker/containers/ハッシュ値/ハッシュ値-json.log`

そのため以下コマンドで、コンテナのハッシュ値を調べてください。

```
docker ps
```
あとは、cpコマンドなど使って、ログファイルをコピーしてください。以上。
[ThoughtSpot]キーワード「VS」を使ってみる

## はじめに
みなさんはThoughtSpotのキーワードどれくらい活用していますか？？
キーワードがあることは知っていても使いどころがわからなかったり、そもそもキーワードの意味がわからなかったり。はい、私のことです。
ということで今回はキーワード「VS」を紹介します。

## 「VS」の使い方とは
ということで公式の説明文を引用します。

> *vs, versus*
>   **Example** 
> * revenue east vs west
> * state name begins_with 'a' state name begins_with 'c' vs state name begins_with 'd' 

**ぶっちゃけどういう意味かわかりません（でした。私は。）**
いやわかるのか？みんなこれでわかるのか？？わからない私がいけないのか？？？
なんか不安になってきました。
とりあえずvsでもversusでも使えるということはわかった。

簡単に言うと **数字を「比較」** したいときに使います。
ユースケースとして「昨年度と今年度の金額」を出したいときに、このように使います。

↓検索バーの入力
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/a272a319-8c50-95aa-e6ad-197c07e34906.png)

↓結果のグラフ
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/9bf0bd5f-59cc-3630-00fa-f242aef4b4f3.png)

はい。ここで「昨年度と今年度でフィルターかけた場合と何が違うの？」と思った方、賢い。

確かにグラフ上は若干見た目が異なるものの、「VSキーワードを使った場合」と「フィルターをかけた場合」では表示される結果は同じです。

↓日付フィルターを使ったとき
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/aef07cdb-d81f-ddab-06b6-b4a86734d436.png)

決定的に違うのは、 **「VSキーワードを使うと比較したものが数式で数値項目として使えるようになる」** というところです。
と言っても良くわからないと思うので実際に見てみましょう。

## 最大の特徴：数式で使えるようになる
ユースケースとして、先ほどの「昨年度と今年度の売上金額」を出した後、その隣に **「昨対比」を出したい** となったら、みなさんどう出しますか？
そういうときに「VS」キーワードが生きてきます。

VSキーワードを使うと、こういう感じで、数式項目で比較したものが数値項目として使えるようになるんです。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/9313ef48-f410-2187-6db3-bd736b4cee57.png)
しかもこちら、数式を書くときの候補として勝手に出てきます。
なので昨対比を出すのであれば、このようにそのまま割り算させれば良いだけですね。

ということで、VSキーワードの使いどころと特徴のお話しでした。

## おわりに
vsのキーワード使うたびに頭の中で格ゲーみたいな戦闘画面が頭をかすめるのは私だけ……ですか、そうですか。失礼しました。
ポート3000を占領する不届き者を倒せ！WindowsユーザーのためのローカルURL奪還作戦

こんにちは、みんな。今日はローカル開発で頻繁に遭遇する問題について話すわ。特に、`http://localhost:3000/`を使おうとしたら、何者かに占領されていた時の対処法よ。


ふんっ、大切なポート3000が使えないなんて、本当に迷惑よね。でも心配しないで。この記事を読めば、あなたもその謎を解き明かせるわ。Windows PCでポート3000を占領している犯人を特定して、安全に解放するまでの手順を解説するわ。


## 1. コマンドプロンプトを開く
まずは、Windows PCでコマンドプロンプトを開くわよ。

1. Windowsキー + Rを押して「ファイル名を指定して実行」ウィンドウを開く
2. `cmd`と入力して実行

これでコマンドプロンプトが開くわ。準備はいい？次に進むわよ。

## 2. 占領者を調査する
次に、ポート3000を占領している不届き者を特定するわ。以下のコマンドを入力して：

```bash
netstat -ano | findstr :3000
```

これで、ポート3000を使っているプロセスのリストが表示されるはずよ。例えば：

```bash
  TCP    0.0.0.0:3000           0.0.0.0:0              LISTENING       12345
  TCP    127.0.0.1:3000         0.0.0.0:0              LISTENING       54321
```

この表示で最後にある数字がプロセスID（PID）よ。ここでは`12345`と`54321`ね。

## 3. 犯人を特定する
さて、このPIDを使って犯人が何者かを突き止めるわ。以下のコマンドを入力して：

```bash
tasklist /FI "PID eq 12345"
```
（12345は先ほど調べたPIDに置き換えてね）
```
イメージ名                     PID セッション名     セッション# メモリ使用量
========================= ======== ================ =========== ============
wslrelay.exe                 12345 Console                    1      8,660 K
```
```bash
tasklist /FI "PID eq 54321"
```

```bash
イメージ名                     PID セッション名     セッション# メモリ使用量
========================= ======== ================ =========== ============
node.exe                     54321 Console                    1    121,588 K
```



これで、ポート3000を占領しているプログラム名が分かったわ。例えば`node.exe`ならNode.js関連のプロセス、`com.docker.backend.exe`ならDocker Desktop関連のプロセスね。

## 4. プロセスの処理
さて、占領者が分かったところで、どうするか決めましょう。

### ①ポート番号の変更
もし可能なら、自分のアプリケーションで使用するポート番号を変更するのが一番安全よ。例えば、aituber-kitなら、`package.json`の`scripts`セクションで以下のように指定できるわ：

#### 安全な方法：ポート番号の変更
```json
{
  "name": "aituber-kit",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev -p 3001",
    "dev-https": "next dev --experimental-https -p 3001",
    "build": "next build",
    "start": "next build && next start -p 3001",
    "export": "next export",
    "lint": "next lint",
    "lint:fix": "eslint --fix .",
    "format": "prettier --write .",
    "electron": "wait-on http://localhost:3001 && electron ./electron.mjs",
    "desktop": "NEXT_PUBLIC_BACKGROUND_IMAGE_PATH=\"\" run-p dev electron"
  },
  // ... 他の部分は変更なし
}
```

主な変更点：

1. "dev" スクリプト: -p 3001 を追加してポート3001を使用するように設定
2. "dev-https" スクリプト: 同様に -p 3001 を追加
3. "start" スクリプト: next start の後に -p 3001 を追加
4. "electron" スクリプト: wait-on コマンドの URL を http://localhost:3001 に変更

これで、`npm run dev`のコマンドを実行すれば、3001番ポートが使われるようになるわ。

### ②プロセスの停止
どうしてもポート3000を使いたい場合は、占領しているプロセスを停止させることもできるわ。でも、これは慎重に行う必要があるから注意してね。

```bash
taskkill /PID 12345 /F
```
（12345は特定したPIDに置き換えてね）

ただし、これを実行する前に、そのプロセスが本当に不要かよく確認しなさいよ。システムに必要なプロセスを停止すると、問題が起こる可能性もあるからね。

```bash
成功: PID 12345 のプロセスは強制終了されました。
```
これで、不届き者は倒されたわ。

### 5. ポートが解放されたか確認する
最後に、ポート3000が無事に解放されたか確認しましょう。もう一度このコマンドを実行するのよ：

```bash
netstat -ano | findstr :3000
```

何も表示されなければ成功よ。これで、新たな利用者がポート3000を使えるようになったわね。

### まとめ
ローカル開発環境でポートが占領されているのは珍しくないわ。でも、この記事の手順を覚えておけば、簡単に対処できるはずよ。ポート番号の変更が難しい場合は、占領しているプロセスを特定して適切に対処することが大切。

---


犯人はコイツだったようだ。

https://github.com/open-webui/open-webui
2024-09-18 共有記事ログ

# 概要
現職の開発部のメンバーに共有した記事のログ

# 技術系
## [「ペアプロしようぜ！」　技術力とコラボレーションを高める新たな取り組み](https://note.com/dev_onecareer/n/nc847ae55e12e)
ペアプロをしてみて良かった点改善点の紹介記事です
当社でも定期的なペアプロを取り入れてみるのも良いかもしれません

## [レビュー指摘事項からふりかえる、良くない設計の傾向と対策](https://zenn.dev/neinc_tech/articles/5927f5c9d5d87c)
オブジェクト指向でのテスト容易性や単一責任の原則のためのリファクタリングに関する記事です
ついつい一つのClassに責任を詰め込みがちですが、しっかり分離して設計することでメンテナンスコストもさがり
改善もしやすくなるので、中長期の早さも考えて実装していく必要があると思いました！


# その他
## [テストエビデンスについて](https://tech.emotion-tech.co.jp/entry/2024/09/06/120000)
何故テストエビデンスが必要なのかという記事です
この記事ではテストにフォーカスされていますが「テストエビデンスを適切なものにする為に」のセクションにある内容はテストエビデンスに限らずあらゆる仕様書などのドキュメントに必要な内容だと思います
曖昧な表現をしない、主語を省略しない、用語の揺らぎをなくす、読みやすい文章を心がける

## [テスト自動化ツールの検討をしている話](https://tech.unifa-e.com/entry/2024/09/09/194407)
テスト自動化ツールを導入するさいの検討フローに関する記事です
現在サポートの方々にテストを行なっていただいておりますが、規模が大きくなるとリグレッションテストまでは行えていないのが現状かと思います
そこでコーティングを必要としないE2Eのテストを、新規でテストしたものだけでも自動化して継続的にテストできれば、網羅はできないにしても多少のデグレを防ぐ効果はあると思います共有いたします！

## [直近数ヶ月でやったチームの仕組み化のふりかえり](https://zenn.dev/vs_blog/articles/e67d0db114cc94)
筆者のチームで行なっていた内容の仕組み化についての記事です
APIをOpenAPIで管理したり、Githubの自動ラベル付は上手く使えば業務効率が上がりそうだと思いました！

## [やる気はある、「めんどくさい」だけなのだ。](https://qiita.com/zunbero_zunbero/items/9f6f8ac447cf7cb83326)
何かをするときには大体の理由はめんどくさいことであるとともに、それは仕方ないことなのでどう向き合っていくかという記事です
確かに多くのことは面倒なことが多いですが、ある程度の強制力を持たせるとやらざるを得なくなるので、面倒だと思うことほど、やらないといけない状況を作る方が良いのかもしれないと思いました


# 共有するほどではないけど興味があったもので読んだもの
* [意思決定に基づくはずのオペレーションを追跡し、監査を効率化する話](https://tech.layerx.co.jp/entry/2024/09/06/125031)
* [Zendeskヘルプセンターを動的コンテンツで柔軟に運用する](https://tech.pepabo.com/2024/09/09/zendesk-help-center-dynamic-content/)
* [円安を乗り越えるための Arm アーキテクチャへの移行が完了！ そのプロセスを公開します](https://kaminashi-developer.hatenablog.jp/entry/2024/09/09/migration-to-arm-architecture)
* [Git｜作業ブランチ名を常にターミナルへ表示したい（Mac）](https://qiita.com/ho_na/items/1cc21e14aadb60c7d164)
* [生成AIを信用しすぎてハルシネーションに引っかかった話](https://qiita.com/suzuyu0115/items/d6137ac2894d9b0d5385)
* [フォントサイズを表すremって何者!?](https://qiita.com/taka_2525/items/7e778dce3102d63fa9ab)
* [新しく公開されたAnthropic Quickstartsがサンプルの域を超えている](https://qiita.com/moritalous/items/e4e66e39ce17a768a8b1)
* [「絶対にdisabled属性を避けて、aria-disabled属性を使わなければならない」わけではありません](https://qiita.com/ymrl/items/0bfb691e98e153e90fc5)
* [【バルス】もしもの時に個人情報を守る方法](https://qiita.com/weeding_test_5/items/e79958e577246a537ec8)
* [要素を非活性にするのに、まさか disabled を使ってないよね？](https://qiita.com/kobayashimakoto/items/e8e19cc019c863990237)
* [Slackのデフォルトのフォントが変わってしまったのでSlackのフォントを元に戻したい！](https://qiita.com/cha84rakanal/items/70fd11816a802e7bf17b)
* [『MySQLを使うと会社が潰れる』から学ぶ初心者の情報発信](https://qiita.com/Sicut_study/items/d07cb14bf15eefd74cc5)
* [実務未経験者の人に読んでほしいGitHubの実務tips](https://qiita.com/yamadagenki/items/5e4ee79a7a680b1675e8)
* [GitHubプルリクエストのマージを理解する](https://qiita.com/tonnsama/items/2baca909d39dc9e23b07)
* [こどおじがAndroidアプリ作ってたらGoogleに子供部屋を追い出された話](https://qiita.com/votepurchase/items/96d83796dd41a59bc93c)
* [ふりかえりの目的を見つめ直した話](https://techblog.openwork.co.jp/entry/retrospective-of-retrospectives)
macrobenchmarkでsetupBlockが終了するとアプリが終わってしまいテストが実行できない(失敗する)

## Macrobenchmarkとは
アプリの起動時間とか、フレーム時間とかを簡単に計測できるテストライブラリです。
https://developer.android.com/topic/performance/benchmarking/macrobenchmark-overview?hl=ja

UiAutomatorというのを使ってテストを書き、その上でいろいろ計測してくれます。
なのですごく細かい操作をして計測したい場合などは、UiAutomatorでのテストの書き方の知識も必要になってきます。
まあ、起動時間計測くらいなら比較的容易に出来るようになっています。

簡単なサンプルはこちらから。
https://developer.android.com/codelabs/android-macrobenchmark-inspect
（情報は古めなので注意)

## 実施環境など

| ライブラリ | バージョン|
|:--|:--|
uiautomator | "2.3.0" |
benchmark-macro-junit4 | "1.2.0-beta01" | 

## 遭遇した問題
リストを最下部までスクロールして描画が完了するまでのフレーム時間計測を行いたいと思い、以下のようにテストを書きました。
ほぼcodelabのサンプルのままです。

```kotlin
@RunWith(AndroidJUnit4::class)
class ScrollBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun scroll() = benchmarkRule.measureRepeated(
        packageName = "xx.xxx.xxxx",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.COLD,
        setupBlock = {
            pressHome()
            startActivityAndWait()
            // リストの行が表示されるまで待つ
            if (!device.wait(Until.hasObject(By.res("list_items")), 25_000)) {
                fail("Could not find resource in time")
            }
        },
    ) {
        val contentList = device.findObject(By.res("list"))

        // Set gesture margin to avoid triggering system gesture navigation
        contentList.setGestureMargin(device.displayWidth / 5)

        // Scroll down the list to bottom
        while (contentList.fling(Direction.DOWN)) {
            // Wait for the scroll to finish
            device.waitForIdle()
        }

        // Wait for the scroll to finish
        device.waitForIdle()
    }
```

ところが、`contentList`がnullになってしまい、テストが落ちます。
端末での動作を見る限り、どうも`setupBlock`を実行後にすぐにアプリが終了されてしまっています。
`measureBlock`の時点でアプリが終了しているので、当然`list`が見つからないわけです。


## 解決策
`benchmarkRule.measureRepeated`のパラメータ、`startupMode=StartupMode.COLD`がいけないようです。
`startupMode=StartupMode.WARM`にするとよいようです。

```kotlin
    @Test
    fun scroll() = benchmarkRule.measureRepeated(
        packageName = "xx.xxx.xxxx",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.WARM, // ←ここ
        setupBlock = {
```

あるいは、`StartupMode.HOT`にして、毎回setupBlock内で`killProcess()`するのもよいようです。
`StartupMode.WARM`だと、Activityは再作成されますがアプリプロセスは同じなので、設定値とかグローバル変数上のものなどは引き継がれて残ってしまうのでその辺が注意でしょうか。

## 参考ページ
あまり情報が無くて困っていましたが、最終的にはやっぱりStackoverflowにありました。

https://stackoverflow.com/questions/78591545/android-macrobenchmark-1-2-4-startupmode-cold-breaks-the-benchmarks-inside-mea

スレッドで提示されているissueを見ると、担当者は「期待された動作だ」と説明していますが、setup後にアプリを動かして計測したいのが普通じゃないのと思いますけどね。なんでsetup後にアプリのプロセスをkillするのが期待値なんだろう・・・？
現時点ではStatusは`In Progress (Accepted)`になっているので、今後修正される可能性はありそうですが。
完全未経験から三か月で合格！基本情報技術者試験攻略【新形式】

# はじめに
初めまして！juuunと申します。今回は新形式の基本情報技術者試験合格までの道のりを記していこうと思います。Qiita初投稿で拙い部分もあるかと思いますが、目をつぶっていただけると幸いです。

### 取得したきっかけ
・自分にエンジニアとしての適性があるのか
・転職の際のアピール

目的としては主に上記の２つです。エンジニアは常に知識のアップデート、新技術のキャッチアップ等、継続的な学習が必要な職種です。他業界で働いている身として、そもそもITについて興味をもって勉強できるのか、自分に適正があるのかの確認の意味も込めて学習を始めました。

また、未経験での転職にあたり、意欲をアピールする手段として、基本情報技術者試験を選択しました。

# 基本情報技術者試験とは
IPAによると
>ITエンジニアの登竜門。ITエンジニアとしてキャリアをスタートするには、まず基本情報技術者試験から受験することをお勧めします。しっかりとした基礎を身に付けることにより、その後の応用力の幅が格段に広がります。

とのことです。

|      |試験時間|出題形式|出題数|回答数|合格基準|
|:----:|:-----:|:----:|:----:|:----:|:-:|
| 科目A|90分|多肢選択式（四肢択一）|60問|60問|1000点満点中、600点以上|
| 科目B|100分|多肢選択式|20問|20問|1000点満点中、600点以上|

[試験概要](https://www.ipa.go.jp/shiken/kubun/fe.html)

ちなみにですが、あくまで **国家試験** であって **国家資格** ではないので注意！人に話す際や履歴書に書くとき注意しましょう。

# 学習時間
まず学習期間としては2024年2月16日～5月6日（試験日）の計81日間を費やしました。
月ごとの具体的な学習時間は下記のようになります。
    |      |２月|３月|４月|５月|合計|
|:----:|:-----:|:----:|:----:|:----:|:----:|
|学習時間|17.7時間|29.2時間|47.7時間|19.6時間|114.2時間|

科目Aが50時間、科目Bが64.2時間くらいの配分でした。

# 勉強方法
## ①科目Aの参考書を一周する
[キタミ式イラストIT塾 基本情報技術者 令和06年](https://amzn.asia/d/1lHSB4A)
私はこの参考書を利用しました。イラストが多いので初学者には分かりやすく、丁寧に書かれていると思います。 

**コツは一周にとどめることです。** 概要を把握するタイプの参考書は何周もしてもあまり定着しません。ササっと一周して科目Bの参考書に移りましょう。

## ②科目Bの参考書を解く（理解できるまで！）
[情報処理教科書 出るとこだけ！基本情報技術者［科目B］第4版](https://amzn.asia/d/8N9VAyM)
私はこの参考書を利用しました。科目B対策が基本情報技術者試験における学習のメインになります。時間をかけるべき部分なので根気よく取り組みましょう。

この参考書では、慣れるまではトレース推奨だったので、それに倣いひたすらトレースをしていました。事実、本番の試験では全てトレースをしていると間に合わないので、本当に意味があるのかと悩んだ時期もありました。

ですが、気づいたときには最低限のメモ、変数の動きを書き留めるだけで問題が解けるようになっていました。

## ③科目Bのサンプル問題を解けるようにする
科目Bは科目Aと違い過去問が公開されていません。ただ、IPAがサンプル問題というものを公開しているので、その問題を何度も繰り返し、時間内で解けるようにしましょう。

[基本情報技術者試験 科目B試験サンプル問題](https://www.ipa.go.jp/shiken/syllabus/henkou/2022/20220425.html)
↑このサイトの下の方にDLリンクがあります。

このサンプル問題には解説がないので、私はYoutubeを参考にしていました。
[文系でもわかる! IT勉強会](https://youtube.com/playlist?list=PLCHgb5A4oO6nEUBzD960_yU3W1JGNz0ZD&si=tqfN8Xfy6A8mykrs)
この方は公開されている全ての科目Bサンプル問題の解説を投稿されており、かなり勉強になりました。

## ④科目Aの過去問を解く
科目Aの過去問を解けるサイトやアプリはいくつかあります。機能として間違えた問題にチェックをつけることができれば、どれを使っても大丈夫だと思います。
[2024年版 基本情報技術者試験問題集(全問解説)](https://apps.apple.com/jp/app/2024%E5%B9%B4%E7%89%88-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%85%A8%E5%95%8F%E8%A7%A3%E8%AA%AC/id1211959354)
私はこのアプリで５年分の問題を解けるようにしました。試験を受けた感想として、この５年分という量はかなり最低限だと思います。余裕があればもっと年数を増やした等が安心だと思います。

過去問を解いていると、参考書で見たことあるけどどういうものなのか忘れてしまったワードがたくさん出てきます。私はその都度、参考書の索引で確認していました。①の参考書は辞書のように使うことをおすすめします。

参考書でも見たことがない初見のワードはスマホのメモに簡単にまとめていました。
![IMG_0792.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830821/b78279da-ca53-2e46-bcd8-50971f1b546c.png)
少し手間ですが、問題を解かずともいつでも見返すことができますし、このまとめる作業が記憶の定着率を高めてくれたと感じています。

# 試験本番
科目Aに関しては過去問演習をきっちりこなしていれば時間にかなり余裕をもって取り組むことができます。

科目Bは時間との勝負になります。単純計算１問５分で解いていく必要があります。コツとして最初にセキュリティ分野の４問を解いてしまいましょう。おそらく得点源になるので時間が足りず解けなかった、焦ってミスしたという状況を防ぎましょう。
また、２分くらい考えて解法が思いつかなかったら、次の問題に移ってしまう方が良いと思います。

# 最後に
資格を取得する理由は様々です。知識、仕事を得るチャンスだと思ってとりあえず取得してみることをおすすめします。

最後まで読んでいただきありがとうございました。
【Drupal】EntityQueryでConditionにカラムを指定したい

EntityQueryでカラムを指定して、フィルタリングやソートを行いたい時ってありますよね。

例えば、「参照フィールドのValue値ではなく参照元のID」だったり、「カスタムフィールドの特定のカラム」だったり...。

今回私は [Key value field](https://www.drupal.org/project/key_value_field) を利用したときに、Key値でのフィルタリングに躓いたので共有させていただきます。

## EntityQueryについて
こちらの記事がわかりやすいです 🐾

https://qiita.com/863/items/111c0f73be175ed67a74

```php:基本的な使い方(引用)
$nids = \Drupal::entityQuery('node')
  ->condition('type', 'page')
  ->condition('status', TRUE)
  ->execute();
```

## KeyValueフィールドでカラムを指定する方法
```php
$nids = \Drupal::entityQuery('node')
  ->condition('field_key_value.key', 'リンゴ')
  ->condition('field_key_value', '100円')
  ->execute();
```

## 参照元のIDでソートする方法
```php
$nids = \Drupal::entityQuery('node')
  ->sort('field_ref_user.entity_id', 'ASC')
  ->execute();
```
この場合は、シンプルに`sort('id', 'ASC')`でもいいんでしょうけど...。

## ちなみに...。
KeyVauleFieldのフィールド構成はこんな感じ。
```php
[
  'key' => '',
  'value' => '',
  'description' => '',
];
```
Slack APIとLINE Notify APIの比較

## はじめに
Slack APIとLINE Notify APIの違いについてまとめました。

| 比較項目                        | Slack API                                   | LINE Notify API                            |
|---------------------------------|---------------------------------------------|--------------------------------------------|
| **認証方法**                    | トークンをペイロード内で送信                 | ヘッダー内に`Authorization: Bearer {token}`|
| **チャンネルの指定**             | `channel`パラメータで指定                   | チャンネル指定は不要                       |
| **ペイロード**                  | `token`, `channel`, `text`を含む             | `message`のみを含む                        |
| **成功時のレスポンス確認方法**   | `result.ok`（レスポンス内の`ok`を確認）      | `response.getResponseCode() === 200`       |

---

## 認証方法
Slack APIでは、APIトークンをペイロードの一部として送信します。一方、LINE Notifyでは、HTTPヘッダーの`Authorization`フィールドに`Bearer {token}`形式でトークンを指定します。この認証方法の違いが両APIの使用方法に影響します。

---

## チャンネルの指定
Slackではメッセージを送信する際、チャンネル名（例: `#general`）を指定する必要があります。これに対してLINE Notifyでは、メッセージの送信先はトークンによって自動的に決まるため、チャンネル指定は不要です。この仕様のため、LINE Notifyの方がシンプルなコードでメッセージ送信が可能です。

---

## ペイロードの違い
Slack APIでは、ペイロードに`token`、`channel`、および`text`の3つのキーを含める必要があります。これに対して、LINE Notifyでは送信するメッセージのテキストを`message`キーに持つだけで済みます。LINE Notifyのペイロードはシンプルであるため、開発やメンテナンスが容易です。

---

## レスポンスの処理
Slack APIでは、レスポンスの`ok`フラグを確認することで、リクエストが成功したかどうかを判断します。LINE Notifyでは、HTTPレスポンスコードが`200`であれば成功とみなされます。このため、LINE Notifyのレスポンス処理はHTTP標準に近く、直感的に扱うことができます。

---

## まとめ
Slack APIとLINE Notify APIの違いは、以下の通りです。

- **メッセージ送信の簡便さ**: LINE Notifyはチャンネル指定が不要で、シンプルなメッセージ送信が可能。
- **認証方法の違い**: Slack APIではペイロード内でトークンを送信、LINE NotifyはHTTPヘッダーでトークンを送信。
- **レスポンスの確認方法**: Slackはレスポンス内の`ok`フラグを確認、LINE NotifyはHTTPステータスコードで確認。

---

**参考文献**
- [Slack API Documentation](https://api.slack.com/)
- [LINE Notify API Documentation](https://notify-bot.line.me/doc/en/)
XmlDocumentをXElementに変換する方法

# 記事製作の経緯
あるプロジェクトをやっているときにXMLをXmlDocumentで取り込む関数をXElementで読み込む箇所にも使いたいという話になった。
なんでそんな事をしなければならないのかと思われるかもしれないが、XmlDocumentを読み込む関数で結構長めの読み込みが失敗したときの処理があったためだ。
オーダーとしては出来ればこの長い処理を一か所しか使わないXElementのためにまた作り直したくないとの事だったので、調べることになった。

結論から言うと見つかりはしたが日本語の記事が見つからず、そこそこ探すのに時間がかかってしまった。よって後続のためにこの方法を日本語で書こうと思う。


## 方法
XmlDocumentからXElementに変換は難しいので、この記事では間にXDocumentを挟む。
つまりXmlDocument→XDocument→XElementとなるわけだ。


# バージョン

Windows 10 Pro 22H2 OSビルド 19045.4894
Microsoft Visual Studio Express 2015 (64 ビット) - Current Version 14.0.23107.0
Microsoft .NET Framework Version 4.8.09037

## XmlDocumentからXDocumentへの変換

まずはXMLをXmlDocumentで読み込む。
```C#:XmlDocument
XmlDocument xmlDoc = new XmlDocument(); //XMLの読み込み
xmlDoc.Load(xmlFile);// XMLの読み込み
```

その後、XmlDocumentをXmlNodeReaderを使いXDocumentへ変換する。
```C#:XmlDocument→XDocument
XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc)); //XDocumentへの変換
```

## XDocumentからXElementへの変換
最終的にXDocumentをパースを使ってXElementへ変換する。
```C#:XDocument→XElement
XElement xEle = XElement.Parse(xDoc.ToString()); //XElementへの変換
```

## おまけ：XDocumentからXmlDocumentへの変換
一応XDocumentをCreateReaderを使うことでXmlDocumentに変換する方法も書いておく。
```C#:XDocument→XmlDocument
xmlDoc.Load(xdoc.CreateReader()); //XDocumentへの変換
```

## おわりに
以上でXmlDocumentからXElementへの変換は出来た。
本当に簡単な方法だが日本語の記事で存在している事が重要だと思うので、
どうか役立てていただけたら幸いだ。

## 参考
XDocument to XElement
https://stackoverflow.com/questions/13460461/xdocument-to-xelement
transforms.ToTensor()は何をしている？

## 概要

`torchvision.transforms.ToTensor()`は、PyTorchで画像データ（PILなど）をTensorに変換するのによく見る関数です。しかし、「このメソッドは正規化もしてくれている」という誤解が広まっていることがあります。本記事では、この点を明確に解説します。

## `transforms.ToTensor()`の役割


```mermaid
flowchart LR
I1("numpy.ndarray(H, W, C)")
I2("PIL Image")
T("Tensor, (C x H x W)[0.0, 1.0]")
I1 --> T
I2 --> T
```

[公式](https://pytorch.org/vision/stable/generated/torchvision.transforms.ToTensor.html)の説明によると、`transforms.ToTensor()`は、2つの操作を行うようです：

1. **画像データ（PIL Imageもしくはnp.ndarray）をPyTorchのTensor型に変換する**  
   画像データが標準的なPythonライブラリ（PILなど）で扱われる形式から、PyTorchで扱えるテンソル形式に変換されます。変換後に(C, H, W)の次元になっていることにも注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253735/9e7a7aaa-bec8-e0e9-2f75-f36b21c0360f.png)
   
   
2. **画素値のスケールを0〜255から0〜1に変換する**  
   画像データの画素値は一般的に0〜255の範囲で表されますが、`transforms.ToTensor()`を使用すると、これを0〜1の範囲に**スケーリング**されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253735/602a2397-725a-2c56-6653-7cf11913b7b7.png)


### 注意：正規化とは異なる

`ToTensor()`が行っているのは「画素値を0〜1にスケーリングする」という処理であり、これは厳密には「正規化」とは異なります。**正規化（Normalization）**とは、画像の平均と標準偏差に基づいてデータを変換する処理です。

具体的には、以下のような形で正規化は通常行われます：

```python
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
```

※これらの数値[0.485, ...]は、ImageNetベースで計算された数値のようです。独自のデータセットを用いる場合は、独自の正規化のための係数を使用する必要があります

この操作では、画像の各チャンネルごとに平均値を引いて標準偏差で割ることで、ピクセルの値を正規化します。`ToTensor()`はこの処理を含まないため、追加で`Normalize()`を適用する必要があります。


## まとめ

- `transforms.ToTensor()`は画像をテンソルに変換し、画素値を0〜255から0〜1にスケールします
- 正規化（Normalization）とは別の処理です。正規化を行いたい場合は、`transforms.Normalize()`を追加で使用する必要があります
CentOSサーバを構築してみた

# 前置き

VM上にCentOSをインストールして操作できる環境を構築する備忘録です。
今回はCentOS バージョン8.5を構築します。

# 1. 準備 VM稼働環境の構築

CentOSを稼働させる環境の準備をします。
今回はVMware Workstationで構築します。
構築方法は私が実施した際の備忘録の下記を参考にどうぞ！

https://qiita.com/tacky0127/items/527bd9a2a2bbde6b6080

# 2. CentOSダウンロード
下記リンク先から使用したいCentOSのisoファイルをDLしてください。今回はCentOS8.5をDLします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/bb38edff-164b-dcfe-5579-567c46dfc4f3.png)


:::note info
リンク先はミラーサイトです。CentOSのサポート切れの影響に伴い、公式サイトからDLが出来なくなっています。
:::


https://vault.centos.org/

<リンク先参考>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/54e425d0-b5e8-0dc6-c9ea-c54930aed7ac.png)

# 3. VM作成
下記手順で実施します。
```
VMware Workstationを起動する
新規仮想マシンの作成を押下する
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/cee91da1-f457-9c07-e14b-14c21fcced69.png)

```
標準を選択して次へクリック
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/8d073cb9-3eab-5270-a90c-b1827031ab82.png)

```
インストーラディスクイメージファイル(iso)を選択し、
DLしたisoファイルを選択する
次へクリック
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/dbe34e3a-d1ae-eba7-ed31-32aa2cdc3d26.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/74eba2bd-3c08-3ead-9cc2-65e737ecd43c.png)

```
下記任意に入力する

フルネーム欄入力
ユーザ名欄入力
パスワード欄入力
確認欄入力
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/f2f3490b-591e-18c1-acc9-0f9b3bf786b3.png)

```
仮想マシン名入力
→VMware Workstationのサイドバーに表示されるvm選択時の表示名です
次へクリック
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/edf1abb8-e6e0-0a0b-03ad-ae101484f2a9.png)

```
ディスク容量サイズ選択
仮想ディスクを複数のファイルに分割を選択
次へクリック
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/1a7f7ca6-f093-84e0-bc54-cc753ad821f8.png)

```
仮想マシンを作成する準備完了ダイアログ表示
→設定が問題ないか確認
メモリ等変更したい場合はハードウェアをカスタマイズから任意に設定変更

完了クリック
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/947f68fc-eb99-d783-5e94-fffc6479e189.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/dc5617bf-cad1-522e-5226-689c0efd2d5d.png)

```
Bootが始まります。
構築まで待機します。
インストールが開始されます
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/9a76e162-34a0-f2e5-25c5-13f15ad359c7.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/492a90c7-03ec-0f79-e558-828d415bb234.png)

```
トップ画面が表示される
入力設定した、パスワードを入力してログインする
ログインが完了するとデスクトップが表示される。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/1a23e774-f58d-41b0-7fda-242ce2068f6e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/577c6dc1-0c02-d71a-dbbb-df687364f039.png)

以上で、CentOSの構築は終了です。
お疲れ様でした。
【Unity】親についてこない子の作り方

# はじめに
uGUIでマスクの処理をする場合、マスクオブジェクトの子として対象を入れなければならず、動かすと中身も一緒について来てしまいます。
そんなときに使える便利コンポーネントのご紹介です！

# 今回やりたいこと
透視できる機械のようなものを通してスライムの中が見えるようにしたい
ユーザーが操作して任意の場所を見ることができる

### 理想
![sample_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/547e3b88-b2f0-7339-9558-5fad86aef762.gif)
口の方から徐々に動かして人だ！
みたいに見せたいです

### 現実
![sample_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/e6cdeb5c-b531-dc14-6eb6-c77efefae6c3.gif)
普通に実装すると骨も一緒について来てしまいます。
これでは最初から何がいるか丸わかりですね、、、


# やり方
まずこのよう構成で作成します
通常のマスクをかける場合と同様です
![スクリーンショット 2024-09-17 9.55.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/35e6689d-d100-95a0-1f63-1b66d3acca1d.png)

メインとなるスライムの画像
![スクリーンショット 2024-09-17 13.55.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/98a6c4ef-44f9-7d95-e8b2-e28ef8f31f2c.png)

マスク
![スクリーンショット 2024-09-17 13.55.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/478e0fd4-52fa-beab-cda6-89b317525607.png)

マスク対象
こちらが今回のポイントです！
[**Position Constraint**](https://docs.unity3d.com/ja/2021.1/Manual/class-PositionConstraint.html "Position Constraint")をつけています！
![スクリーンショット 2024-09-17 13.58.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/7c1eb615-3d9b-92ad-2f51-ae40a6ad2020.png)

SourcesにSlimeを設定することで、親であるマスクの位置に追従させずSlimeの位置に追従させています
（微妙な位置の調整はPosition Offsetなどで行っています）

これでスライムにとんでもないものを食べさせてみんなを驚かせられます！

### 他にも
Freeze Position Axcesのチェックを外すことで、特定の方向のみ追従させるなどもできたりします
![sample_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2125059/4fd57797-3bf2-bd68-49c2-70f6dd4abf59.gif)



# おわりに
今回のような構成でマスクをライトに見立てて何かを探すなど、表現の参考にしてもらえると幸いです！
【Rails】いいね機能の実装ー中間テーブルとはなにか？ー

## はじめに
初学者向けのRails講座には、大抵の場合いいね機能の実装が含まれていると思います。
ただ、いいね機能を実装するための”中間テーブル”は、概念的で理解しにくいところがあるため、自分の整理のためにもアウトプットします。

### 前提
- インスタ風のアプリを作成
- userがpostを投稿する感じ
- 他のuserのpostにいいねできる機能を作りたい

### 何がしたいのか
- いいね機能を実装したい
- postの一覧画面（post/index.html)からいいねできるようにしたい

### どうする必要があるのか
- 中間テーブル（likesテーブル）を作成する
- 一意性制約をつける
- likesテーブルを通していいねしたPostを取得できるようにする
- routesの工夫

## 実装方法
### 中間テーブルを作る
1. 普段通り`rails g model Like`でモデルを作る
1. マイグレーションファイルを編集
    1. reference でuserとpostを追加
    1. 複合インデックスを追加し、一意性制約をつける
1. `rails db:migrate`の実行

#### マイグレーションファイルの内容
```
class CreateLikes < ActiveRecord::Migration[6.0]
  def change
    create_table :likes do |t|
      t.references :user, null: false, foreign_key: true
      t.references :post, null: false, foreign_key: true
      t.timestamps
    end
  
  add_index :likes, [:user_id, :post_id], unique: true
  end
end

```

#### 中間テーブルとは？
以下のようなものだと理解しています。
- 2つのテーブルの間ある
- 2つのテーブルの関係性を記述する
- 具体的な値を持たない

今回のケースで言うと以下のようになります
- usersテーブルとpostsテーブルの間にlikesテーブルを作る
- likesテーブルのカラムは、idとuser_id(外部キー)とpost_id(外部キー）のみ
- likesテーブルはuser_id=1のユーザーが、post_id=1のポストをいいねしているという関係性のみを表現している

中間テーブルがあることで、以下のことができるようになります
- user側から：自分がいいねしたpostの一覧を取得できる
- post側から：特定のpostをいいねしているuserの一覧を取得できる
※実際のuse case的にはuser側がメインになるかなと思います

#### 複合インデックスとは
- インデックスとは、検索速度を早めるためにデータベースに索引を作成すること
- referenceを使うと、自動的単一のインデックスが作成させる
- 今回の場合は、user_idとpost_idはほぼ必ずセットで使うので、user_idとpost_idをセットでインデックス化すると便利
- `add_index :likes, [:user_id, :post_id]`の箇所で実現している

#### 一意性制約とは
- 特定のカラムの内容をUniqueにする制約
- よくある例でいうと同じユーザー名は使えないとか、同じメールアドレスだと"すでに登録されています"というアラートが出るとか
- 今回の場合は、特定のユーザーが特定のポストにいいねできる回数を1回にしたいので一意性制約をつける
- `unique: true`で実現
- より具体的に言うと、user_id=1　ー　post_id=1　というセットがデータベースに存在すると、いいねしようとしてもできなくなる　ということ


### modelファイルに関係性を記述する
#### likeモデルの記述
```
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
```
- likeモデル側から見ると、userにもpostにも紐づいているので上記のような記述になる

#### userモデルの記述
```
  has_many :likes, dependent: :destroy
  has_many :liked_posts, through: :likes, source: :post
```
- `has_many :likes, dependent: :destroy`これはいつもどおりの記述
- `has_many :liked_posts, through: :likes, source: :post`　こちらがポイント
- `User.first.liked_posts`でUser.firstがいいねしたポストを取得できるようになる
- `through: :likes` はそのままlikesテーブルを経由して　という記述
- `source: :post` で何を取得したいのかを記述
- おそらくlikesテーブルに外部キーが2つ設定されているため、user側からのリクエストに対してuser_idカラムを検索し、同じ行にあるpost_idを返して、postsテーブルから該当のポストを引き出すという動作を行っていそう

ほぼ重複になるのであえて書きませんが、postモデル側でも似たような記述をすることで、post側でもも特定のポストをいいねしたuserの一覧を取得できるようになる

### routesの記述
```
  resources :posts, only: [:new, :create, :index] do
    resource :like, only: [:create, :destroy, :show]
  end
```
#### なぜネストするのか？
- リンクとして、`post/:post_id/like`の形だと扱いやすいため
- 流れとしてはuserがpostにlikeする
- あるポストに対して、いいねに対するリクエストを送る、というのがわかりやすいというか自然

#### なぜ`resources :likes`ではなく、`resource :like`なのか
- あるユーザーにとって、特定のポストに対するいいねは1つだけだから
- つまり`post/:post_id/like/id`のidは不要
- `post/:post_id/like`の形にすることで、deleteする際にidを指定しなくて良いので、処理の記述も短く済む
[T-DASH] 手動操作をはさむ： reCAPTCHAをセミ自動化にしましょう

# Outline

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/dab518d0-02fa-308b-0573-424871c84c60.png)

テスト自動化でやっかいなシロモノ！

Robotframeworkなどで試してもうまくいかない！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/abc3e44b-d45c-fca9-a87b-b2c0d4dfc254.png)

テスト自動化でchallangingなものとして

- CAPTCHA
- reCAPTCHA
- MFA

などである。

なんとかすれば、自動化できるかもしれないが、引き際も（すべての手動テストを自動化できない）肝心。

今回は、T-DASHでセミ自動化を実装する

https://service.valtes.co.jp/t-dash/?qiita

# 技術的情報

robotframeworkにDialogsというライブラリがある

https://robotframework.org/robotframework/latest/libraries/Dialogs.html

## Execute Manual Step

自動化の処理を中断し、手動処理を介入可能にする。
その後、その手動操作の過程で、問題なければ"PASS"、問題があれば"FAIL"させ、テスト自動化のステップに戻すことができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/bdb197b6-2518-01e1-4fd3-e43238471a34.png)

## Pause Execution

自動化の処理を中断し、手動処理を介入可能にする。
"Execute Manual Step"とは異なり、テスト自動化の中断を行うもので、手動操作の実行結果は反映されない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/0ccd357f-73d6-4783-6f23-c7f67e805f74.png)

# T-DASHの手順

## カスタム動作

以下設定内容を Dialogs.yamlのファイル名で保存する

```
ACT-CAT-CUSTOM-aa5c4bd0-9a0b-435d-8d2b-eabf3a8d7c79:
  action_category_name: Dialogs
  icon: ''
  color: '#60CB85'
  custom_data:
    file_name: Dialogs
    pip_list: []
    library_list:
    - Dialogs
  actions:
    ACT-CUSTOM-a15b9133-57e5-4a5a-aa4e-56fe99d8ee39:
      action_name: 手動操作を介入する
      action_type: operation
      action_format: 「設定値1」のメッセージ表示を出し、手動操作を行う
      action_note: ''
      action_args:
      - value1
      action_def:
      - - Execute Manual Step
        - ${value1}
    ACT-CUSTOM-e4aa3d86-3277-4e91-a2f9-a26d0d5d50ba:
      action_name: 一時停止する
      action_type: operation
      action_format: 「設定値1」のメッセージを表示し、一時停止する
      action_note: ''
      action_args:
      - value1
      action_def:
      - - Pause Execution
        - ${value1}
```
次に、作成された Dialogs.yamlをT-DASHの動作定義 -> カスタム動作 -> カスタム動作をインポート にてインポートする

2つの中断するカスタム動作があるため、状況に応じて使い分ける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/b19d13fb-44f8-6b71-ab67-90933fb6b346.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/f5e902b8-556f-7b21-3c4d-705d62edd489.png)


## スクリプト

テスト自動化を中断させたいところに、先ほどのカスタム動作を入れる。
また、中断させる目的・どんな手動操作をさせるかを引数にいれると、そのメッセージが出てくるため、実行者にとってkindlyになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/f6631a86-0714-abe7-c1f0-527687fc246c.png)
Snowflakeのタイムスタンプ型のデータ、半分くらい理解した

# 前置き
Snowflakeのタイムスタンプ型のデータ、例えば
```
select current_timestamp();
```
を実行すると
```
2024-09-17 18:21:21.851 -0700
```
という結果が得られます。
実際に実行している時間は9/18 10:21です。

![スクリーンショット 2024-09-18 102156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/135d5333-3f66-da7e-68a9-783c144daa77.png)
（現在のPCの時刻部分を切り取り。）

16時間の差があります。
わかりづらいですね。
前日日付のS3日付フォルダからファイルを読み込むタスク＋プロシージャーを作るときに「ムズイ」ってなりました。
そこでタイムゾーンを変更できないか調べました。

# やってみた

まずはタイムゾーンがどうなっているのか調べます。
```
show parameters like '%timezone%';
```
![スクリーンショット 2024-09-18 102106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/72804eed-9440-b1eb-e77f-c6e2a653b79f.png)
America/Los_Angeles
になってますね。オオタニさんのロサンゼルス。

次、現在時刻を取得します。
```
select current_timestamp();
```
![スクリーンショット 2024-09-18 102147.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/dff14ce1-bbc7-3cfc-48e4-06a6503d4031.png)
```
2024-09-17 18:21:21.851 -0700
```

これが最初に書いたわかりづらいと思っているやつ。

タイムゾーン＝America/Los_Angelesを日本のものに変えればわかりやすくなるはずです。

変更するにはACCOUTADMINで操作する必要があります。
```
use role accountadmin;
```

timezoneを'Asia/Tokyo'に変えます。
```
alter account set timezone = 'Asia/Tokyo';
```
![スクリーンショット 2024-09-18 102308.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/678e8203-bbdc-b072-9d5c-134ae1d164da.png)
無事成功。

再度、タイムゾーンを確認します。（初めに確認したのと同じクエリ）
```
show parameters like '%timezone%';
```
![スクリーンショット 2024-09-18 102333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/76e01c28-b0f1-1980-b1b1-43d57f07ea09.png)

valueがAsia/TokyoでdefaultがAmerica/Los_Angelesということで変わったようです。

現在時刻を再取得します。（初めに確認したのと同じクエリ2）
```
select current_timestamp();
```
![スクリーンショット 2024-09-18 102351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/de96df07-b30b-0475-2cc8-3a3613289325.png)

```
2024-09-18 10:27:48.457 +0900
```
自分の感覚と同じ時間になりました。

# まとめ
+9時間がグリニッジ標準時と日本時間の時差。
-7時間がグリニッジ標準時とロサンゼルス時間の時差。
合わせて16時間のズレがあったのが、タイムゾーンをAsia/Tokyoにしたことで非常に扱いやすくなりました。

# 疑問
日本国内のデータだけ扱ってるならこのように設定しちゃえばいいものの、
世界中のデータを扱うならまた別途考えなきゃいけない予感がしています。

みなさん、どうされてるんでしょう？
Ubuntu 22.04での送信限定のpostfix設定方法

# 概要
postfix で送信限定サーバをつくったのでその備忘録

## postfixのインストール方法
以下のコマンドで postfix をインストールします。

```bash:command
sudo apt update
sudo apt install postfix
```
インストール途中の設定画面では「インターネットサイト」を選択し、システムメール名を入力します。

## main.cfの設定方法
送信専用にするため、/etc/postfix/main.cfを編集します。

```bash:command
sudo nano /etc/postfix/main.cf
```
以下の設定を確認・追加します。

```bash:/etc/postfix/main.cf
myhostname = mail.example.com
myorigin = /etc/mailname
inet_interfaces = loopback-only
relayhost =
```
- `myhostname`：サーバのホスト名を設定します
- `inet_interfaces`：`loopback-only` に設定し、外部からのメール受信を無効化します
- `relayhost`：メールを中継する外部の SMTP サーバを指定します
  - **未設定または空欄の場合**：メールは直接宛先のメールサーバへ配送されます
  - **設定する場合**：指定した SMTP サーバ経由でメールを送信します

設定後、postfixを再起動します。

```bash:command
sudo systemctl restart postfix
```

## SPFレコードの設定方法
SPFレコードを設定し、送信元の正当性を示します。DNSのTXTレコードに以下を追加します。

```conf:sample
v=spf1 ip4:サーバのIPアドレス ~all
```

```conf:sample
v=spf1 ip4:192.0.2.1 ~all
```

### Google Workspaceを使っている場合
Google からもメールを送信する場合、SPF レコードに以下のように設定を追加します。

```conf:sample
v=spf1 ip4:192.0.2.1 include:_spf.google.com ~all
```

`include:_spf.google.com` を追加することで、Google の送信サーバも許可されます。

## SPF設定の確認
以下のサイトで設定確認をすることができる

https://powerdmarc.com/ja/spf-record-lookup/


## 参考
https://qiita.com/Sabuuuuu---nn/items/fc5448b7f5e3057365a1

https://qiita.com/motimotinoyamayama/items/ec08d6c6b4715d5f2e8c

https://qiita.com/kisama2000/items/1909bb56d0030c46b50c
【情報漏洩防止】Authorizationヘッダについて学ぶ

## これは何?

- Basic認証付きProxyを使っている人向け
- `curl -v`等でデバック情報を共有する際Proxy-Authorizationヘッダにproxyのクレデンシャルが載っており注意が必要だなと思ったので防備録

---

## Authorizationヘッダとは

[Authorization -HTTP](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Authorization)とは

Basic認証を使用して認証情報を送信する際に認証情報は
`ID:password`をbase64でエンコードした状態で送信されます。

base64は可逆エンコードのためAuthorizationヘッダを他人に見せる行為は他人にID/パスワードを晒す行為と同義になります。

---

## 実際に試してみる

まずbase64コマンドを使用してデコードしてみました。
これはcurl -vで表示される`Proxy-Authorization`ヘッダの値と一致しました。

```shell
echo sigma:sigmapassword | base64
c2lnbWE6c2lnbWFwYXNzd29yZAo=
```

次にこれをデコードしてみます。

```shell
echo c2lnbWE6c2lnbWFwYXNzd29yZAo= | base64 -d
sigma:sigmapassword
```

このようにもとのID:パスワードに戻ります。

---

## 感想

Authorizationヘッダに認証情報が入っていることは知っていましたが，何のひねりもなくデコードしているだけとは思っていませんでした。`curl -v`等でデバック情報を共有する時に自分の認証情報を共有してしまうことがないようにきちんとProxy-Authorizationヘッダを消してから共有したい。
swapoff -a忘れでserver xxx.xxx.xxx.xxx:6443 was refused

色々あってUbuntu 22.04のKubernetesノード群をリブートしたら、以下のようにコマンドが通らなくなった。


```
# kubectl get pods
The connection to the server xxx.xxx.xxx.xxx:6443 was refused - did you specify the right host or port?
```
なんてことはない、swapoff -aコマンドの実行し忘れ。

全てのノードでswapoff -aを実行して元に戻った。
[VS-Code]ターミナル周りのショートカットキーまとめ

## 🔰ターミナルのショートカットキーをまとめてみた

JavaScriptで簡単なWebサイトが作れるくらいのエンジニアの卵です🥚
Notionを使ってメモしていたんですが、ブログにも挑戦しようと思い初めて投稿してみました！
ショートカットすぐ忘れてしまうのでメモしていきます。
まだまだ少ないですが、出会う度に更新していきます💪

|アクション|ショートカットキー|
|----|----|
|VS-Codeでターミナル起動|⌘ + J|
|ファイルを作成|`> ファイル名`|
|ファイルを開く|`cd ファイル名`|
|フォルダを作成|`mkdir フォルダ名`|
|フォルダを開く|`cd フォルダ名`|
|ターミナルのクリア|⌘ + K|
|VS-Codeでディレクトリとファイルを開く|`code .`|
|ターミナルでコンソール出力|`node ファイル名`|
PHP8 新機能 'match'

PHP8リリースから4年が経ち、社内プロジェクトもPHP8へ移行されてしばらく経った。PHP8化した恩恵を受けるため、是非紹介したい新機能として `match` 式がある。

`switch`文のあまりイケてなかったところを改善したような機能であり、可読性の悪かった `switch` や `if/else` のネストで書かれた処理をより簡潔かつわかりやすく書ける可能性がある。

~~~php
<?php
$food = 'cake';

$return_value = match ($food) {
    'apple' => 'This food is an apple',
    'bar' => 'This food is a bar',
    'cake' => 'This food is a cake',
};

var_dump($return_value); // 出力 => string(19) "This food is a cake"
?>
~~~

~~~php
<?php
$age = 18;

$output = match (true) {
    $age < 2 => "Baby",
    $age < 13 => "Child",
    $age <= 19 => "Teenager",
    $age > 19 => "Young adult",
    $age >= 40 => "Old adult"
};

var_dump($output); //出力 => string(8) "Teenager"
?>
~~~

詳しい機能の仕様、使用例に関してはPHP公式ドキュメントを見るのが一番よい。まず目を通そう。

https://www.php.net/manual/ja/control-structures.match.php

この記事で言いたかったことはこれで全てだが、`match` が `switch` の完全上位互換というわけではないため、補足情報として `match` でできないことを挙げておく。

なお、記事のコードの一部はPHP公式ドキュメントから引用している。また、内容についても社内の周知を目的としているため他記事からの引用がメインであることに留意されたし(引用元は記事最後に記載)。

##  `match` にできないこと( `switch` と比較して)

### 複数行の実行

`match` は条件式に対して返却式をひとつしか取れないため、複数行の処理を実行することはできない。 `function` にまとめて呼び出すなどの方法を取る必要がある。

~~~php
switch ($value) { //こういうのはmatchではできない
    case 'abc':
        doA();
        doB();
        doC();
        break;
    case 'xyz':
        doX();
        doY();
        doZ();
        break;
}
~~~

### 条件によって一部だけ実行

`switch` ではbreakしないかぎり下に書いた `case` 以降の処理も行われるため、あえてbreakしないことで条件によって処理の一部だけを実行したりしなかったりできる(可読性がよくないため推奨はしない)。

`match` では条件式と一致した時点で返却式の値を返して処理を終了する。break;などが必要ないため、多くの場合 `match` の方が簡潔だ。

~~~php
switch ($value) { //こういうのはmatchではできない
    case 'XYZ':
        echo 'X';
        // breakしない
    case 'YZ':
        echo 'Y';
        // breakしない
    case 'Z' :
        echo 'Z';
        break;
}
~~~

`match` で対応できないケースを挙げはしたが、ほとんどの場面において `switch` より `match` を使った方がコードを見通してよく書けるだろう。条件分岐が必要な場面ではぜひ `match` を選択肢に入れよう。

## 参考資料

### 【PHP8】match 式のこれまでとこれから

https://qiita.com/tamiroh/items/36fd32b37797b86ada56

match式が導入されるまでの経緯

現行と異なる仕様が記事中で紹介されているので混乱注意

### switch文

https://www.php.net/manual/ja/control-structures.switch.php
Fuel\Core\PhpErrorException [ Fatal Error ]: The configured locale(s) "en_US" can not be found on your system.

Fuel\Core\PhpErrorException [ Fatal Error ]:
The configured locale(s) "en_US" can not be found on your system.

fuelPHPを設置する段階でもうローカルで開くことさえできないエラーが出されます。
(vscode, xampp使用)

「http://localhost/[プロジェクトフォルダ名]/public/」　
を開こうとしたらエラーが出ます。

対処法です。

fuel/app/config/config.php　をひらきます。

そこから「language」を検索します。



	/**
	 *  The default language.
	 */

	// 'language' => 'en',

	/**
	 *  Fallback language when file isn't available for default language.
	 */

	// 'language_fallback' => 'en',

	/**
	 *  PHP set_locale() setting. Use null to not set.
	 */

	// 'locale' => 'en_US',


ここからわかるようにデフォルトが「en_US」になっていることがわかります。

ではここの下に明示しましょう。

'locale' => '',

この明示によってエラーがなくなります。




ちなみに以下の対処法も試してみましたが、ダメでした。

'language' => 'ja',
'locale' => 'ja_JP.UTF-8',

もし、「'locale' => '',」が効かない方はこの方法も試してみてください。


参考：https://fuelphp.com/forums/discussion/6945/error-related-to-i18n/p1
H.265でYouTubeに上げる...あれ...?

### ※試行錯誤ばかりなのでこの記事はあまり役に立たない低品質な記事になりますが、何か参考になればという思いで投稿します。

---

最近H.265というフォーマットを知った。
試してみたけど...あれ?何か勘違いしている...?

1. 動画の切り出し
```shell:ffmpeg
ffmpeg -i C0026.MP4 -c:v copy -c:a copy -ss 1:02:44 -to 2:14:10 C0026.MP4
```
動画のビットレートは50M、60fps(約30GB)
これをH.265で圧縮してみる。
そしてYouTubeはだいたい8Mb/sっぽいと聞いたので(どこ情報?)きりのいい5Mb/sで。
```shell:ffmpeg
ffmpeg -i C0026_out.MP4 -c:v libx265 -c:a copy -b:v 5M E:¥YTupload.mp4
```
サイズを見ると...あれ?
2.1GB?
H.264エンコードとあまり変わらない...
ためしにH.264でエンコードしてみる。(ffmpegはH.264が標準っぽいので映像オプションなし)
```shell:ffmpeg
ffmpeg -i C0026_out.MP4 -c:a copy -b:v 5M E:¥YTupload_264.mp4
```
あっちゃー...2.1GBぐらい。
どうしよう...(試行錯誤は続く...がみんな待っているのでとりあえずH.265のほうを投稿...)

---

([このヘルプ](https://support.google.com/youtube/answer/1722171?hl=ja)からビットレート間違いは後から気がつきました、最近はYouTubeも高画質化してたんだね...)
PowerVS IBM i 日記(60):  2024/08/27 発表の IBM i 関連 EOM/EOS の PowerVS への影響について

 2024/08/27 に IBM から AD24-0665 として「[特定のプログラムの販売終了およびサポート終了：IBM Backup, Recovery and Media Services for i (non-expiring version)、IBM CICS Transaction Server for i、IBM i サービス プロバイダー月次ライセンス](https://www.ibm.com/docs/ja/announcements/eos-eom-non-expiring-brms-cics-msp)」が発表されています。
今回の PowerVS IBM i 日記は、この影響について考えていきます。
なお、EOM は End of Market で販売の終了、EOS は End of Support でサポート終了のことです。

# 5770-BR1 Backup Recovery and Media Services (永続ライセンス)

BRMS の永続ライセンス版の 5770-BR1 の EOM/EOS が発表されました。

* EOM: 2025/01/01
* EOS: 2025/09/30

それ以降も、5770-BR1 をお使いの場合、使用法と既知の不具合に対するサポートは提供されますが、新規の修正である PTF は作成されません。

後継は、サブスクリプションライセンスで提供される「**5770-BR2** Backup Recovery and Media Services」です。[AD23-0531](https://www.ibm.com/docs/en/announcements/offers-subscription-term-pricing-backup-recovery-media-services-i-cloud-storage-solutions-i) で 2024/01/09 に発表されました。

この時点で、IBM i 7.3 以前は EOS 済みのため、5770-BR2 は、IBM i 7.4 以降の対応になります。

BR1 と BR2 では LPP 番号が異なります。PTF 番号も異なります。BR1 の EOS 後、BR2 向けに作られた PTF は BR1 には適用できません。
一方、ライブラリーは QBRM、QUSRBRM のままです。LPP 番号以外のコード自体は同じようです。

## BR2 への移行方法
移行方法のガイドは IBM のサイトではなく Fortra のサイトにありました。
私は、これを見つけられませんでした。POWER の TechSales の方に教えてもらいました。
Fortra は[旧 HelpSystems で、そこから社名変更](https://www.imagazine.co.jp/fortra-re-brand/)した会社のようです。

移行手順はこちらです。

* [https://helpsystemswiki.atlassian.net/wiki/spaces/IWT/pages/2765848577/BRMS+5770-BR2+Installation](https://helpsystemswiki.atlassian.net/wiki/spaces/IWT/pages/2765848577/BRMS+5770-BR2+Installation)

ざっくりと説明すると、このような手順になるようです。

* 念のため「SAVLIB LIB(QUSRBRM)」でユーザーデータをバックアップ
* 「SEVSEVDTA」で Functional Usage 情報をバックアップ
* 「DLTLICPGM LICPGM(5770BR1) OPTION(*ALL)」で BR1 の削除
* 注意: QUSRBRM は削除しないこと!
* QUSRBRM のファイルに、ユーザー作成の従属ファイルが無いことを確認(あれば削除)
* 「RSTLICPGM LICPGM(5770BR2)」で BR2 の導入
* BRMS の PTF の適用

## PowerVS IBM i では、まだ BR2 は利用できません
BR2 の PowerVS への追加は調整中とのことでした。 BR2 が EOS になるまでには、利用可能になるはずです。
情報が得られれば、更新します。

# IBM CICS Transaction Server for i (5770-DFH)
IBM i (5770-SS1)の機能としてエンタイトルメントされています。そのため特定の EOM 日はありません。

* EOS: 2025/09/30

EOS後は、こちらも 使用法と既知の不具合に対するサポートは提供されます。
新規の不具合に対して PTF は作成されませんが、現在の CICS 関連の機能をそのまま使い続けることは可能です。十分に枯れた製品のため、実質的には、それで問題はないのかもしれません。

特定の後継製品があるわけではありません。
移行先は IBM i のネイティブ・オプション (CL コマンド、Rest API、またはその他のカスタム・アプリケーションなど)になります。
発表レターでは [HiComp](http://www.hicompllc.com/) などが移行サービスを提供しているそうです。

PowerVS 上でご利用いただいていた場合でも、もし、ご利用であれば同様の影響を受けます。

# IBM i サービスプロバイダー月間ライセンス (5770-MS1、 5770-MP1、 5770-MR1、 5770-MH1、 5770-MC1、5770-MSE)

こちらは、以前より IBM i を独自 Cloud で提供するサービスプロバイダー向けに、IBM i とその関連ソフトウェアを、月次ライセンスで提供しているものです。
ライセンスの契約方法だけの話で、導入ソフトウェアや機能の話ではありません。そのため EOS はありません。

* EOM: 2025/09/30

後継は、一般のお客様にも利用可能になった IBM i サブスクリプション・ターム・ライセンスです。
もともと PowerVS IBM i は時間課金であり、こちらの EOM は PowerVS IBM i のご利用には影響しません。

---
当日記のIndexは[こちら](https://qiita.com/6onoda/items/f146c78c0c1bbe905a42)です。

---
許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
第八章 統計的推定の基礎

# 例1
統計量とは標本$X_1....X_n$のみの関数を指す。平均$\mu$は未知のパラメータであるため統計量ではない

# 例2
$l(\bar{x},v) = -\frac{n}{2}\log(2\pi{v})-\frac{ns}{2v}$
$\frac{\partial}{\partial{v}}l(\bar{x},v) = -\frac{n}{2v}+\frac{ns}{2v^2}$
v=sのとき、尤度は最大値をとる

# 例3
回答の通り

# 点推定の性質
## ガウス・マルコフの定理
https://www.ikpi.co.jp/knowledge_archive/valuation/valuation_file108.html

## クラーメル・ラオの不等式
https://mathnyumon.com/cramer-rao-inequality/

## フィッシャーネイマンの分解定理
https://venoda.hatenablog.com/entry/2024/03/09/103850

## 例4
https://venoda.hatenablog.com/entry/2024/03/09/103850#%E6%AD%A3%E8%A6%8F%E5%88%86%E5%B8%83

# リサンプリング法（ジャックナイフ法）
https://note.com/outlifest/n/n7eaf710f2a89

## 例題8.1
③は誤り
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567074/41ccbafb-d5e4-3b75-66b2-21deb00e8698.png)
https://avilen.co.jp/personal/knowledge-article/unbiased-estimator/
④：誤り（例2を参照）
⑤：正しい。パラメータの最尤推定量は一致性及び漸近有効性を持つことが知られている（p65上部の記述）

## 例題8.2
(1) 回答の通り
(2) 回答の通り
(3) 回答の通り、、、だが二つ目の等号に飛躍があるように思える。ポアソン分布の性質を利用している？
(4) 回答の通り

## 例題8.3
ビジュアルプログラミングで高位合成

# 概要
ビジュアルプログラミングで組み合わせ回路を組み立てて、シュミレーションして、verilogを生成します。
高位合成です。
構想編

# 目標
ビジュアルプログラミングで、組み合わせ回路を記述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8facc7a2-655f-5723-581b-2faede658c97.png)

Toggle Buttonをクリックして、シュミレーションできます。

verilogを生成します。

```

module x(input in0, input in1, output out0);
	assign out0 = (in0 ^ in1);
endmodule


```

# 仕組み
- javascriptを使います。
- ビジュアルプログラミングは、simcirjsで行います。
- 設置には、Plunkerを使います。
- 必ず、Inデバイス、Outデバイスが必要です。
- DC、Toggle Button、LEDを繋げば、シュミレーションできます。
- 論理デバイスは、XOR、NOT、AND、NAND、OR、NOR、XNORを用意します。
- ネットリストをjsonで出力します。
- jsonをパースして、入力、出力、論理デバイスを取り出します。
- verilogテンプレートを用意して、入力、出力、論理デバイスを組み込みます。
- verilogを書き出します。
- 順序回路には、対応しません。
- 発動は、ctrl + クリックです。


以上。