OmniAICreator/Qiita-1.07M huggingface dataset:
TGWSを構成する技術1:全体的な構成

[TGWS](https://tgws.plus/)は、私の運営しているサイトです。[アンパンマンDB](https://tgws.plus/anpandb/)で知っている人もいるのでは？

https://tgws.plus/

https://tgws.plus/anpandb/

別に最新技術を使っているわけでも、特別すごい工夫があるわけでもないのですが、私のサイトを構成している技術について、紹介していきたいと思います。

全部で何回分にするのか決めてませんし、第2回以降をやるかどうかもわかりませんが、今回は、細かい工夫よりも、全体的な構成について紹介します。

# サーバー
シンプルに、共有レンタルサーバーを使っています。クラウドやVPSみたいなおしゃれなものではありません。

経緯として、無料ホームページサービス「トクトク」で何の機能もない静的サイトを作ったのが始まりで、そこからより高機能なサーバーへ移転しながら継ぎ足し継ぎ足しで作ってきたので、根本的な構成としては、FTPでアップロードする素朴なウェブサイトの構成から20年以上変わっていません。

で、2024年現在は、バリューサーバーを使っています。

https://www.value-server.com/

共有レンタルサーバーを提供しているホスティングサービスも、エックスサーバーなどいろいろあったのですが、移転前後の機能のギャップが少なそうという理由で、バリューサーバーを最終的に選びました。

# サーバー構成
まあ、バリューサーバーから与えられたものをそのまま使っているだけですが、一応、LAMP(Linux, Apache, MySQL, PHP)環境となっています。

https://meister-kentei.jp/magazine/programming/909/

## Linux
以前はシステム情報調べても「Linux」しか出なくてわかんなかった気がするんですが、今見たらUbuntuでした。

https://jp.ubuntu.com/

バージョンなどの細かいところはよくわかってないですが、そもそも共有サーバーを間借りしているだけの立場でコマンドをあんまり自由に扱えるわけでもないので、ここは細かくわからなくてもいいかな。

## Apache
https://httpd.apache.org/

こちらはバージョン2.4です。.htaccessの書き方が2.2と違っています。

Webサーバーと言えば、今はnginxのほうが主流っぽいですが、私のサイトでは以前から.htaccessを使っていたので、nginxではなくApacheを搭載していることを基準に事業者を選んでいました。

## MySQL
実はMySQLは、うちではWordPressにしか使っていません。

https://www.mysql.com/jp/

https://ja.wordpress.org/

ではWordPress以外では何を使っているのかというと、SQLiteです。

https://www.sqlite.org/

Liteって名前につくからには、ヘヴィな案件には全く向かないと思うのですが、うちだと大きなシステムでもアンパンマンDB程度がせいぜいなので、SQLiteで足りてます。
データがファイル1個で扱われるから取り回しが楽なんですよね。

だから、先ほど言ったLAMP環境は、実体としてはLASP環境と言えます。

## PHP
昔はPerlでCGIを組んでいたのですが、今はPHPです。

https://www.php.net/

こちらはサーバー事業者側が用意してくれた機能でバージョンを選ぶことができるので、時々新しいバージョンに移行しています。

今は8.2を使っていますが、サーバーにはすでに8.3まで入っているそうです。いずれバージョンアップ予定です。

# フレームワーク
これまでの継ぎ足し継ぎ足ししてきた経緯から、Laravelみたいなサイト全体を作れるようなフレームワークは導入していませんが、ライブラリを入れる利便性のためにComposerを、自動テストのためにPHPUnitを入れています。
それ以外は自作、いわゆる「オレオレフレームワーク」ってやつです。

## Composer
https://getcomposer.org/

PHPのパッケージ管理ツールです。Node.jsでいうところのnpmに近い存在ですね。

だいたいのライブラリはこれで入れていますが、対応してないのもあるにはあるので、そういうのはソースコードをダウンロードしてきて直接配置したりもしています。

## PHPUnit
https://phpunit.de/index.html

自動テストのツールです。

うちの場合、外部仕様を変えずに中の実装だけ差し替えるということを多々行っているので、過去動いていたものが今なお動くことを確認するリグレッションテストがとても重要です。

https://hnavi.co.jp/knowledge/blog/regression-test/

# ディレクトリ・ファイル構成
ここは都合上、省略や脚色を含んでいます。
個々の説明は後で個別に記事を作れたらいいなァ。

```
/
├── .git ...Git関連(アップロードしない)
│
├── .github ...GitHub Actions用(アップロードしない)
│
├── cron ...定期実行するファイルを入れてる
│
├── cache ...キャッシュが入る
│
├── data ...動的なデータが入る
│
├── docker ...Docker関連のファイルを入れてる(アップロードしない)
│
├── offline ...開発環境で動かすファイルを入れてる(アップロードしない)
│
├── public_html ...公開用ディレクトリのルート
│   ├── tgws.plus ...tgws.plusドメインのドキュメントルート
│   ├── (他のドメインとか)
│   ...
│
├── src ...自作のクラスとか入れてる(TGWSの実質的な本体)
│   ├── *.php
│   ...
│
├── tests ...テストコード(アップロードしない)
│
├── vendor ...Composerにより入れたライブラリ等
│
├── .gitattributes ...Gitの設定(アップロードしない)
├── .gitignore ...Gitの設定(アップロードしない)
├── .php-cs-fixer.php ...コード整形の設定(アップロードしない)
├── compose.yaml ...Dockerの設定(アップロードしない)
├── composer.json ...Composerの設定
├── composer.lock ...Composerの設定
├── phpunit.xml ...PHPUnitの設定(アップロードしない)
├── (その他もろもろ)
...
```

# 終わりに
今回は、以上となります。

細かいことを言うと、部分的にNode.jsやReactを使っていたり、ウェブサーバー単体でできないことはVPSにやらせていたりしますが、主要な部分としてはこんな感じです。

それぞれの技術をどう使っているかとか、工夫している場所なんかも、いずれ紹介できたらと思います。
DataFrameの高速処理: apply 関数 vs np.where

データサイエンスのプロジェクトにおいて、効率的なデータ処理は極めて重要です。Pandasのapply関数とNumPyのnp.whereは、データフレームの操作においてよく使われる方法ですが、その処理能力には大きな違いがあります。この記事では、具体例を交えて両者の性能差を詳しく見ていきます。

# apply 関数とは？
apply 関数は、Pandas DataFrameの行や列にカスタム関数を適用するための方法です。非常に柔軟で、複雑なロジックを簡単に実装できますが、Pythonのネイティブコードで動作するため、処理速度が遅くなることがあります。

例：apply 関数の使用
以下のコードは、DataFrameの各行に対して条件を評価し、新しい列を追加する例です。

```python
import pandas as pd

# サンプルデータフレームを作成
df = pd.DataFrame({
    'A': [10, 20, 30, 40, 50],
    'B': [1, 2, 3, 4, 5]
})

# apply関数を使って新しい列を追加
df['C'] = df.apply(lambda row: row['A'] * 2 if row['B'] > 2 else row['A'] + 2, axis=1)

print(df)

```
この例では、列Bの値が2より大きい場合に列Aの値を2倍し、それ以外の場合は列Aの値に2を加える新しい列Cを作成しています。

# np.where とは？
np.where は、NumPyのベクトル化された操作を利用するため、非常に高速です。特定の条件に基づいて要素を選択するのに適しています。

例：np.where の使用
同じ条件をnp.where を使って実行してみましょう。

```python
import numpy as np

# np.whereを使って新しい列を追加
df['C'] = np.where(df['B'] > 2, df['A'] * 2, df['A'] + 2)

print(df)

```
この場合も、列Bの値が2より大きい場合に列Aの値を2倍し、それ以外の場合は列Aの値に2を加える新しい列Cを作成していますが、np.where を使用することで、より効率的に処理できます。

# 処理速度の比較
次に、100万行のデータフレームを使用して両者の処理時間を比較してみます。

```python
import pandas as pd
import numpy as np
import time

# 大きなデータフレームを作成
df_large = pd.DataFrame({
    'A': np.random.randint(0, 100, size=1000000),
    'B': np.random.randint(0, 10, size=1000000)
})

# apply関数で処理時間を計測
start_time = time.time()
df_large['C_apply'] = df_large.apply(lambda row: row['A'] * 2 if row['B'] > 2 else row['A'] + 2, axis=1)
apply_time = time.time() - start_time

# np.whereで処理時間を計測
start_time = time.time()
df_large['C_where'] = np.where(df_large['B'] > 2, df_large['A'] * 2, df_large['A'] + 2)
where_time = time.time() - start_time

print(f"apply関数の処理時間: {apply_time:.4f}秒")
print(f"np.whereの処理時間: {where_time:.4f}秒")

```

# 結果
大規模なデータセットで実行すると、np.where が apply 関数よりもはるかに高速であることがわかります。以下は実際の処理時間の例です：

apply 関数の処理時間: 約30秒
np.where の処理時間: 約0.5秒

# 結論
apply 関数: 非常に柔軟で、複雑なロジックを実装するのに適していますが、処理速度が遅くなることがあります。
np.where: ベクトル化された操作により、高速で効率的に動作します。大量のデータに対して特に有効です。
特定のタスクやデータセットに応じて、適切な方法を選択することが重要です。apply 関数は柔軟性が求められる場合に、np.where は処理速度が重視される場合に最適です。

このように、PandasとNumPyの各関数の特性を理解し、効果的に活用することで、データ処理の効率を大幅に向上させることができます。
【Linux】ディストリビューションってなんじゃ

# はじめに

Linuxの学習で躓くポイントの一つに「ディストリビューション」というものがあり、初学者の方だとこれがなんなのかよくわからないこともあると思います。（私もその一人でした。）

「ディストリビューションってよくわからんな～」と思いながら色々見ていたところ、LPI-JAPANさんの記事 [「Linux道場入門編 第2回 ディストリビューションとは」](https://lpi.or.jp/lpic_all/linux/intro/intro02.shtml) が非常に分かりやすかったので、こちらを参考にまとめました。

# 概要

- Linuxとは
- ディストリビューションとは
- ディストリビューションの種類


# Linuxとは

Linuxは本来「**OSのコアであるカーネル**」を指す言葉であり、カーネルはOSが持つコア機能の管理を行う部分になります。

> Linuxとは、本来OSのコアであるカーネルといわれるものをさす言葉です。カーネルとは、OSの本来の役割であるハードウェアの制御やファイル、ソフトウェアの実行、リソース等の管理を行う部分で、普段ユーザがカーネルの動作を目にすることはありません。実際にユーザが目にする部分はアプリケーションであったり、OSの管理機能を利用するユーティリティソフトであったりします。最近のOSパッケージには様々なソフトウェアが最初から入っているため、 OS本来の部分がどの部分なのかが非常に見えにくくなっているのも事実です。たとえば、カーネルとその他のソフトウェアは以下の図のように表現することもできます。

※「Linux道場入門編 第2回 ディストリビューションとは」より引用

<br>

普段私たちが目にするOSはOSのコア以外の部分も含まれており、それをOSとして認識することが一般的です。

ですが上記の引用文に書かれているようなコア機能が本来のカーネル部分となり、**この部分が本来Linuxと呼ばれるもの**になります。

これが狭義の意味でのLinuxですが、**実際にLinuxカーネルのみで存在していてもそれを利用するソフトウェアが存在しなければOSとしては成り立たない**ため、**「カーネル」＋「それを利用するソフトウェア」を組み合わせた一式の状態**を広義の意味でLinuxと呼ぶことが多く、一般的にはこちらの意味で使われています。


# ディストリビューションとは

カーネルだけをユーザーが利用するのは非現実的であり、一般的なOSとして利用するためには様々なソフトウェアを組み合わせる必要があります。

しかしそのような構成をユーザー自身が一から構築するのはかなり難しいため、そのセットを配布してくれているものが「ディストリビューション」です。

※「ディストリビューション」＝「カーネル＋ソフトウェア群」のセット

一般的にLinuxと呼ぶ場合はこのディストリビューションを指します。

# ディストリビューションの種類

ディストリビューションにもいくつか種類があります。個人的に馴染み深いのはUbuntuやDebian、Redhatあたりです。

- Slackware（最初のディストリビューションで最もシンプル）
- Redhat
- SUSE
- Fedora
- Ubuntu
- Vine
- Debian
- CentOS
- GNU/Linux

これらは大きく3つの系統に分類することができます。

- Slackware系
    - Slackware
- Redhat（rpm）系
    - Fedora
    - CentOS
    - Vine
    - SUSE
- Debian系
    - Debian/GNU Linux
    - Ubuntu

いずれもLinuxカーネルを使用していることが共通していますが、異なる点としてはカーネルと組み合わせるアプリケーションの種類、インストール形式、パッケージの管理方法、システム構成があります。

# 最後に

使用するハードウェアやソフトウェアに合わせてディストリビューションを選ぶことになると思いますが、根本的な部分の仕組みはどれも同じだということがわかりました。

これを機に、読んでくれた方のLinuxへの苦手意識が減ると嬉しいです。（自分への戒めも兼ねて）

元の記事にはLinuxに関する様々な記事が掲載されているので、よかったら読んでみてください。

- [LPI-JAPAN 「Linux道場」](https://lpi.or.jp/lpic_all/linux/)
【CodeWars】4kyuの問題解いてみた

# はじめに
:::note
CodeWarsとはなんぞや？という方はこちら
:::
https://qiita.com/kohki_takatama/items/2ae2808b931e943262b8#comment-96c3c72b0c403eed8a9b

この記事は先日執筆したものですが、その中で以下のようなことを書きました。

> ![スクリーンショット 2024-07-03 22.44.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/4ad4257b-bb1b-2327-6809-18581f4fc901.png)

`kyu`というのは難易度の指標です。

すると、以下のコメントをいただきました。

> ![スクリーンショット 2024-07-03 22.48.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/0eb5ce70-e683-cc0b-3661-8cae120756e9.png)

**これは・・・やるしかない！！！**

# 問題
https://www.codewars.com/kata/521c2db8ddc89b9b7a0000c1/train/javascript

Google翻訳

> ![スクリーンショット 2024-07-03 22.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/a6f894dc-1b62-081b-1e8e-d5ae8ca80dfd.png)

「2次元配列が与えられるので、左上から内にぐるぐる回って、1次元の配列にしてね」ですね。

わかりやすい図

> ![スクリーンショット 2024-07-03 22.51.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/a2fc9218-11ed-7d93-3a5f-a51597dd078f.png)

# 回答・考え方

問題を解きたい方はぜひやってみてください。

<details><summary>私の考え方（ヒントになるかも）</summary>

## 最も大切な、最初にやること：<font color="red">「**例示**」</font>

特に、物理媒体でやることがオススメです。

例示をすることで、以下のメリットがあります。

:::note
法則性に気づく
:::

:::note
後々テストケースになる
:::

| ![IMG_6375.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/95c8cec6-0fcf-c45c-d285-ba7a921843b4.jpeg) |
|:-:|
| 汚い画像ですみません💦  |

例示してみたところ、以下の点に気が付きました。

- 最初は、**1行目（`index = 1`）がそのまま入っている**な
- 途中に、**最後の行（`index = -1`）が逆順（`reverse()`）になって入っている**な
- 1行目と最後の行の間は、**「間にある行」の「最後の要素」** が入っているな
- 最後の行の後には、**「間にある行」の「最初の要素」** が入っているな
- **外周1周だけなら、アルゴリズムがわかった**ぞ
- ということは、**1周ごとに分けて同様の処理をすれば、解ける**んじゃないか？

よし、いけそうです。

</details>

<details><summary>私の回答</summary>

汚いコードですが、とりあえずクリアしたもの

```js
const snail = (array) => {
  
  const form_outer_to_line = ([square, line]) => {

    if(square[0].length === 1) {
      line.push(square[0][0])
      return line
    }
    
    let right_line = [];
    let left_line = [];
    let inner_square = [];
    
    square.map((e, i) => {
      if(i !== 0 && i !== square.length -1) {
        right_line.push(e[e.length -1]);
        left_line.push(e[0]);
        inner_square.push(e.slice(1, -1));
      }
    })
    
    line.push(...square[0], ...right_line, ...square[square.length -1].reverse(), ...left_line.reverse())
    
    if(inner_square.length) {
      return form_outer_to_line([inner_square, line])
    } else {
      return line
    }
  }
  
  return form_outer_to_line([array, []])
}
```

</details>

# 最後に
心地よく疲れました。

CodeWarsの良いところである「他人の回答から学べる」はまた今度、エンジニア仲間とやろうと思います。

@htsign さん 教えていただきありがとうございました！
Azure Pipeline で GUI で Trigger 設定できて楽ちんとか思ってたら、yaml trigger 死んでた :(

# 背景

YAML Trigger の設定が効かない！？
となっていた現象の対処記録 :sweat: 

# 現象

件名のままに、YAML trigger が反応しなくなった。

# 原因

まさに、この設定を、✅ していた為だった :sweat_smile: 

![](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/repos/media/pipelines-options-for-git/yaml-pipeline-override-trigger.png?view=azure-devops)

[UI の設定が YAML のトリガー設定をオーバーライドしている](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#ui-settings-override-yaml-trigger-setting)

# なぜそうなった？

- てっきり GUI で楽に設定できるようになったと思った

で、
- yml ファイルの更新がされない
- trigger も動作しない

ってことで原因に行き着いた

# あとがき

他にもやっちゃいそうなものが、トラブルシューティングにまとめられてて助かります。

[pull request トリガーが Azure Repos でサポートされていない](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#pull-request-triggers-not-supported-with-azure-repos)

[[暗黙的な YAML CI トリガー設定の無効化] が有効になっている](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#disable-implied-yaml-ci-trigger-setting-is-enabled)
[CI トリガーと PR トリガーでブランチ フィルターが正しく構成されていない](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#branch-filters-misconfigured-in-ci-and-pr-triggers)

[スケジュールされたトリガーのタイム ゾーンの変換](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#scheduled-trigger-time-zone-conversions)
[UI 設定によって YAML のスケジュール トリガーがオーバーライドされる](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#ui-settings-override-yaml-scheduled-triggers)

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/troubleshoot-triggers?view=azure-devops#ui-settings-override-yaml-scheduled-triggers
【過去記事】Google Cloud(GCP)環境にWordPressを導入する

## はじめに
- この記事は、Qiitaアカウントの整理のため、別のアカウントで投稿した過去の記事を移行してきたものです。全く同様の記事があるかもしれませんが、盗作等ではありませんのであしからずご容赦ください。
- 過去記事　投稿日：2019年10月08日

## GoogleCloudでWordPressを動かしてみよう
なんとなくブログを始めてみようと思い立ち、最近試してみているGoogle Cloud環境にWordPressを入れてみたので、その手順。

（とりあえずざっくり手順。）

手順といっても簡単で、 Google Cloud の環境にはすでにWordPress入りの仮想マシンのイメージが用意されている。（なんて便利な世の中）

1. GCPのメニューから「Marketplace」を開いて「WordPress」で検索。クリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962/54072d58-c74e-f8e7-949a-be81042bafda.png)

1. 「COMPUTE ENGINE上で起動」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962/5787a45d-d8ff-9c04-bec5-549f4047b28d.png)

1. あとはポチポチ進めるとDeployment Manager経由でWordPress入りのLinux VMを作成、起動してくれる。最低限の設定はすでにされているので、デプロイ完了したら「Log into the admin panel」ボタンをクリックするとWordPressの管理サイトログイン画面が開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962/3898a9c0-58c4-8978-f0e1-a6ee716e9cd6.png)

　※ 「Log into the admin panel」ボタン の上の方に書いてある「WordPress Admin User」と「WordPress Admin password」でログインできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962/da0ced8f-fdbc-9c64-ac38-9317f5e982b7.png)

これだけでもうWordPressの設定に入れる。とりあえず試しに入れてみるだけならめちゃくちゃ簡単だな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962/8d103182-98a4-b3c0-56a2-a44a0341cb29.png)

ちゃんと使うとしたらStatic IPの設定、ドメインの設定なんかも必要だけど、とりあえず今回は割愛。また今度。

まずはWordPressの使い方を学ばなければ・・・・・
Railsで共通パーツの一部をページごとに変更する方法

## はじめに

アプリ制作の過程で、ヘッダーの一部を特定のページで戻るボタンに変更するという実装を行いました。
ここではその実装過程で得られた気づきをまとめます。

## 本記事の内容
Railsで共通パーツとして使っているものの一部分を特定のページで変更する方法。

## ヘッダーのView
```ruby:_header.html.erb
<div id="header" class="sticky-top">
  <nav class="navbar navbar-dark bg-dark py-3">
    <div class="container-fluid">
        <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBothOptions" aria-controls="offcanvasWithBothOptions">
          <span class="navbar-toggler-icon"></span>
        </button>
    </div>
  </nav>
</div>
```
上記は修正を加える前のトグルボタンを持った一般的なヘッダーです。
パーシャル化してあり`application.html.erb`で読み込まれているため全ページで共通の表示がされます。
例えばトグルボタンの表示を一部のページでは戻るボタンに変更したいという場合があったとします。

## 単一のページの場合

1. コントローラーでヘルパーメソッドを定義して、現在のページが戻るボタンを表示すべきかどうかを判断します
2. ビューテンプレートを条件分岐で更新し、適切な場合に戻るボタンを表示します

まず、ApplicationControllerに以下のようなヘルパーメソッドを追加します

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
  helper_method :show_back_button?

  private

  def show_back_button?
    # ここに戻るボタンを表示すべきページの条件を記述
    # 例: %w[show edit].include?(action_name) || controller_name == 'some_specific_controller'
    false
  end
end
```
次に、先ほどのヘッダーを以下のように更新します
```ruby:_header.html.erb
<div id="header" class="sticky-top">
  <nav class="navbar navbar-dark bg-dark py-3">
    <div class="container-fluid">
      <% if show_back_button? %>
        <%= link_to :back, class: 'navbar-toggler', aria: { label: '戻る' } do %>
          <i class="bi bi-arrow-left"></i>
        <% end %>
      <% else %>
        <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBothOptions" aria-controls="offcanvasWithBothOptions">
          <span class="navbar-toggler-icon"></span>
        </button>
      <% end %>
    </div>
  </nav>
</div>
```
上記の実装では、`show_back_button?`メソッドがtrueを返す場合に戻るボタンが表示され、それ以外の場合は元のトグルボタンが表示されます。
特定のコントローラーやアクションでのみ戻るボタンを表示したい場合は、その条件をメソッド内に記述することにより、柔軟にヘッダーの内容を切り替えることができます。

# 複数のページの場合
複数のページの場合も基本的には単一のページの場合と考え方は変わりません。
ヘルパーメソッドに以下のような記述をします。
```ruby:application_helper.rb
module ApplicationHelper
  def show_back_button?(controller_name, action_name)
    (controller_name == 'posts' && action_name == 'show') ||
    (controller_name == 'users' && action_name == 'edit') ||
    (controller_name == 'products' && action_name == 'index')
  end
end
```
これを汎用化させるために以下のような記述をすることもできます。
```ruby:application_helper.rb
# app/helpers/application_helper.rb
module ApplicationHelper
  BACK_BUTTON_PAGES = [
    { controller: 'posts', action: 'show' },
    { controller: 'users', action: 'edit' },
    { controller: 'products', action: 'index' }
  ]

  def show_back_button?(controller_name, action_name)
    BACK_BUTTON_PAGES.any? { |page| page[:controller] == controller_name && page[:action] == action_name }
  end
end
```

## まとめ
本記事では、Railsアプリケーションでヘッダーの一部を特定のページで戻るボタンに変更する方法を紹介しました。単一のページや複数のページでの条件分岐の方法を理解することで、柔軟にヘッダーの表示を変更できるようになります。
【CVPR 2024】Session: Orals 3B Vision, Language, and Reasoning

CVPR 2024でのオーラルセッションが面白い内容盛りだくさんだったので各タイトルとリンクをメモ。
１つ１つじっくり読みたい。。。

## Comparing the Decision-Making Mechanisms by Transformers and CNNs via Explanation Methods
[https://cvpr.thecvf.com/virtual/2024/oral/32036](https://cvpr.thecvf.com/virtual/2024/oral/32036)

## MMMU: A Massive Multi-discipline Multimodal Understanding and Reasoning Benchmark for Expert AGI
[https://cvpr.thecvf.com/virtual/2024/oral/32050](https://cvpr.thecvf.com/virtual/2024/oral/32050)

## Eyes Wide Shut? Exploring the Visual Shortcomings of Multimodal LLMs
[https://cvpr.thecvf.com/virtual/2024/oral/32016](https://cvpr.thecvf.com/virtual/2024/oral/32016)

## LISA: Reasoning Segmentation via Large Language Model
[https://cvpr.thecvf.com/virtual/2024/oral/32020](https://cvpr.thecvf.com/virtual/2024/oral/32020)

## Visual Program Distillation: Distilling Tools and Programmatic Reasoning into VisionLanguage Models
[https://cvpr.thecvf.com/virtual/2024/oral/32045](https://cvpr.thecvf.com/virtual/2024/oral/32045)
mdbookを使ってみる　 記事作成編


個人的「質はともかく継続する」25日目です

## mdbookを使ってみる　 記事作成編

前回はインストールからデフォルト記事をビルドするところまでやりました。
今回はもう少し深く記事を書いていきます。

### 記事を増やす

３つくらい記事を増やして見ます。
ますはsrcの中に記事を追加します。

```sh
touch 明日の日記.md
touch 今日の日記.md
touch 昨日の日記.md
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/b13e9787-f78d-125d-9aa8-d1f1aa10626a.png)

中身は適当に。

### SUMMARYを更新する

mdbookは、デフォルトだとSUMMARYがトップになります。
さらに、ここに記事のリンクが貼られるので、
SUMMARYに先ほど作った記事のリンクを書いていきます。
SUMMARYを起点に、相対パスで記事の場所を指定します。

```markdown
- [今日の日記](./今日の日記.md)
- [明日の日記](./明日の日記.md)
- [昨日の日記](./昨日の日記.md)
```

できたらビルドしてみます。

```sh
mdbook build --open
```

記事が増えました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/6940a221-1a1d-e7d5-0008-eb48ada37e38.png)

### 階層を分ける

日記を年と月別にわかりやすく分けます。
まずはsrc配下にフォルダを作成します。

```sh
mkdir 2025
mkdir 2026
mkdir 2025/December
mkdir 2026/June
mkdir 2026/July
mkdir 2026/August
```

それぞれのディレクトリに適当に記事を作ります。
各記事が月なのかわかりやすくするために、
各月のまとめ記事も合わせて作っておきます。

```sh
touch ./2025/December/1224.md
touch ./2025/December/Dec.md

touch ./2026/August/0801.md
touch ./2026/August/Aug.md

touch ./2026/July/0731.md
touch ./2026/July/July.md

touch ./2026/June/0606.md
touch ./2026/June/0608.md
touch ./2026/June/0611.md
touch ./2026/June/0618.md
touch ./2026/June/0627.md
touch ./2026/June/June.md
```

SUMMARYに追記します。
リンクの前にタブをいれると階層構造を作ってくれます。

```markdown
# Summary

- [今日の日記](./今日の日記.md)
- [明日の日記](./明日の日記.md)
- [昨日の日記](./昨日の日記.md)

# 2025

- [December](./2025/December/Dec.md)
    - [1224](./2025/December/1224.md)

# 2026

- [June](./2026/June/June.md)
    - [0608](./2026/June/0608.md)
    - [0611](./2026/June/0611.md)
    - [0618](./2026/June/0618.md)
    - [0627](./2026/June/0627.md)

- [July](./2026/July/July.md)
    - [0731](./2026/July/0731.md)

- [August](./2026/August/Aug.md)
    - [0801](./2026/August/0801.md)
```

いいかんじです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/333829b7-1d20-0778-7d7e-8b4a93a8ce7b.png)

中の記事も書けてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/dde51207-9712-92cd-caeb-73bfdb2aa257.png)
システム攻撃手法のバックドアとは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/21a1ec69-59da-352f-0e8e-6a5808708a4a.png)

## はじめに
セキュリティの世界には「バックドア」という概念があります。
バックドアは、攻撃者がシステムに忍び込み、知らぬ間に情報を盗んだり改ざんしたりするための**裏口**です。
自分自身、エンジニア同士の会話でしか聞いたことない程度でしたが、改めて調べるとエンジニアとして認識すべき知識が詰まっている概念だと思いました。
この記事でまとめてみたので是非読んでみてください！

## バックドアとは
バックドアは、システムやアプリケーションに通常の認証手続きをせずにアクセスできる隠れた経路や手段のことを指します。
いわば、PCやサーバー、システム・アプリケーションなどに不正侵入するための入り口です。バックドアを仕掛けると、攻撃者はその後いつでも認証を回避して侵入できるようになります。

---

## バックドアが利用される一般的な手法と具体例

- **ソフトウェアの脆弱性を悪用**
  - ソフトウェアの脆弱性を悪用してバックドアを設置する手法です。
  - 脆弱性を狙った`SQLインジェクション`や`OSコマンドインジェクション`などのサイバー攻撃は、バックドアを設置する手段としても有名です。
  - パッチを適用されていなかったり[ゼロデイ](https://www.sompocybersecurity.com/column/glossary/zero-day#:~:text=%E3%82%BC%E3%83%AD%E3%83%87%E3%82%A4%EF%BC%880%2Dday%2C%20Zero,%E3%81%AE%E3%81%93%E3%81%A8%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)の場合にバックドアを設置されるリスクが高まります。

- **フィッシング攻撃**
  - メールの添付ファイルや、Webサイトからダウンロードしたファイルに[マルウェア](https://www.ntt.com/bizon/glossary/j-m/malware.html)が仕込まれていて、ファイルを開くことでバックドアが設置されることがあります。

- **ハードウェアバックドア**
  - デバイスのファームウェアに意図的に設置されたバックドアより、攻撃者がデバイスをリモートで操作できるようになるケースがあります。

- **開発時に設置する**
  - 開発やメンテナンス時に開発者が自らバックドアを設置してテストを施し、除去せずにリリースしてしまうパターンもあります。
    - これを攻撃者に発見されてしまい、被害を受けることもあり得ます。
  - また、バックドアが設置されているオープンソースを利用することで被害を受けることもあります。

---

## バックドアの被害

- **データが漏洩する**
  - 個人情報や機密情報、事業計画などの企業秘密が漏洩する恐れがあります。

- **操作記録が窃取される**
  - キーボードやマウス操作の記録を行う`キーロガー`と呼ばれるツールを仕掛けられる場合があります。
  - キーロガー自体は悪質なものではないのですが、操作記録を盗まれることでIDやパスワード、カード情報などが抜き取られてしまいます。
    - 結果としてアカウント乗っ取りやクレジットカードの不正利用などの被害につながります。
  - また、ログからも機密情報が漏洩することもあります。

- **通信が傍受される**
  - メールやチャット、通話、Webミーティングなどの通信を傍受されて漏洩する被害もあります。

- **データやシステムが改ざん・破壊される**

---

## バックドアに対する基本的な対策方法

- **従業員のセキュリティ意識を高める**
  - 従業員がセキュリティ意識を高めるために、情報漏洩の危険性や対策の重要性を理解する研修や声掛けをしてリテラシーを教育する必要があります。
  - 従業員のリテラシーを高めることで下記のリスクを軽減できます。
    - 添付ファイルを開いてマルウェアに感染してしまう。
    - 不審なソフトウェアを無断でダウンロードし、バックドアを仕掛けられる。

- **OS・アプリケーションなどを最新の状態にする**
  - ソフトウェアやOSの脆弱性を突かれて、バックドアを設置されるパターンがあります。
  - 常に最新のバージョンにアップデートすることで、脆弱性を改善する修正パッチが適用され、安全性を保つことが期待できます。

- **セキュリティパッチの適用**
  - ソフトウェアやシステムの脆弱性を修正するセキュリティパッチを迅速に適用することが重要です。
    - 脆弱性をついたバックドアの設置を防ぐことができます。

- **セキュリティ監査の実施**
  - 定期的にシステムやネットワークのセキュリティ監査を行い、バックドアが設置されていないかを確認することが重要になります。
  
- **多重防御の導入**
  - ファイアウォール、IDS/IPS、アンチウイルスソフトウェアなどの多層防御を導入し、複数のセキュリティ対策を組み合わせて使用することで、バックドアの設置や活動を防ぎます。


## おわりに
バックドア、恐ろしいですね。だからこそ対策を入念に行って多大な被害を受けないようにすることが重要だと思っています。
対策が面倒になってきたら被害面に着目して改めて対策の重要性を認識してもらえたらなと思います。


## 参考リンク

https://www.ntt.com/bizon/backdoor.html

https://www.softbanktech.co.jp/special/blog/it-keyword/2022/0036/

https://www.lanscope.jp/blogs/cyber_attack_cpdi_blog/20231128_16662/
【Expo + React Native】Expoを51にアップデートしたら、iOS Simulator が動かなくなった話

個人アプリ開発をしていると、「Expo SDKを51にバージョンアップせよ」とのお達しが来ていたので、[Expo 公式](https://expo.dev/changelog/2024/05-07-sdk-51#%EF%B8%8F-upgrading-your-app)を参考にアップデートを行ないました。
アップデート作業が無事終わり、さっきまで動いていたiOSシュミレーターを起動させようとすると**動かない**。
ターミナルには、以下のようなメッセージが出ていました。

```ruby:terminal
Could not update simulator linking permissions:....
```

ネット検索しても有益な情報出てこず...。

よく考えると、Expo アップデート前まで使えていた `npx expo start` が、`sudo` 付けないと出来なくなってました。
何やら権限問題が怪しいと見立て、`npx expo start`できるまで、権限変更を行いました。

```ruby:terminal
# 権限なくて実行できない時は、「sudo」 付けました
chmod -R [所有者名] [対象ディレクトリ]
```
全ての権限変更作業を完了したところ、`npx expo start` が実行できるようになりました。
起動したExpoサーバにて、「shift + i」 を押して、iOSシュミレーターの端末選択したところ、**シュミレーターへのExpoアプリインストールが開始！**
そのまま待つこと数十秒で、iOSシミュレーターにてアプリの起動に成功しました:tada:

原因不明で苦しみましたが、ちゃんとエラーで出た権限をひとつずつ潰すことで解決できました。
【Outsystems】DateTime型を年月日で表示したい　FormatDateTime()


基本だと思うけど、毎回忘れちゃうので備忘録として。
初心者向け。
誰かの役に立てたらいいな。

## この記事でわかること
DateTime型の値を「yyyy年MM月dd日」の形に直す

## 非推奨例
これは毎回やっちゃう、良くない方法。
Text形に変換して、`yyyy-MM-dd | hh:mm:ss:`の形で返ってくるから、
それをSubstrして、、、ってやってたら、こんなに長くなっちゃってた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/75433b4a-1919-c44b-0dc2-87d8d4b59d66.png)

## 解決策
FormatDateTime()を使えばめっちゃ短い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852394/e28dd783-b54c-47da-faf7-136458265cb9.png)

## 比較すると
同じのを出力するのにこんなに変わる。FormatDateTimeの方がミスも減りそう

```outsystems:比較
Substr(DateTimeToText(CurrDateTime()),0,4) + "年" + Substr(DateTimeToText(CurrDateTime()),5,2) + "月" + Substr(DateTimeToText(CurrDateTime()),8,2) + "日"
→ "2024年07月03日"

FormatDateTime(CurrDateTime(),"yyyy年MM月dd日")
→ "2024年07月03日"
```


## 他にも
他にもこんな感じに使える
（FormatDateTimeで指定されている文字を出力する場合は、その前に「\」を付ける）
```
FormatDateTime(#2024-07-03 22:56:20#, "ddd, dd MMM yyyy") 
→ "Wed, 03 Jul 2024"
FormatDateTime(CurrDateTime(),"To\da\y i\s: dddd")
→ "Today is: Wednesday"
```
WSL2上のSQLiteファイルにGUIアプリでアクセスする方法

# 概要
WSL2上のvscodeにインストールした拡張「SQLite」や、WindowsにインストールしたDB Browser(SQLite)では、WSL2上のSQLiteファイルにアクセスできなかった。

本記事では、この問題の解決方法を紹介する。

# バージョン
Ubuntu 22.04.3 LTS
SQLite 3.41.0
DB Browser for SQLite 3.12.1

# 解決方法

#### ①WSL2にDB Browser for SQLiteをインストール

WSL2で以下のコマンドを実行
`sudo apt install sqlitebrowser -y`

#### ②DB Browser for SQLiteを起動

WSL2で以下のコマンドを実行
`sqlitebrowser`

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213285/223299e2-6389-f6a9-aa1d-994676dc83e2.png">


#### ③WSL2から起動したDB Browser for SQLiteだとWSL2上のSQLiteファイルにアクセスできる。

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213285/5d9b7f18-4e8b-1c70-26a4-0184bc6e0cbf.png">

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213285/6f8699de-09ca-2414-e7d9-d942a10c4dce.png">

以上

# 参考

https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps
ページレイアウトを変更し関連リストを変更する方法

今回は取引先責任者のページレイアウトを編集し関連リストを変更する方法をお伝えします


## オブジェクトマネージャーから取引先責任者を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c071b961-0c4c-8850-e129-5ede1a30a5e6.png)


## ページレイアウトから編集したいページレイアウトをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/603e4273-93e0-4f0d-0314-6baaa63e87a1.png)


## ページレイアウトを編集し保存

関連リストパレットから表示したいものを表示させ表示させたくない関連リストをひっこめて「保存」をクリック![関連リスト001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/0854030d-1bf3-eb54-2f0b-9f10effb6450.png)
【過去記事】How To Play Google Play Music On Alexa

## はじめに
- この記事は、Qiitaアカウントの整理のため、別のアカウントで投稿した過去の記事を移行してきたものです。全く同様の記事があるかもしれませんが、盗作等ではありませんのであしからずご容赦ください。
- 過去記事　投稿日：2019年03月26日

# How To Play Google Play Music On Alexa
我が家にもやってきたAlexa、有効活用したいけどなかなか使い道が・・・
Amazon Music契約すれば音楽再生に使えそうだけど、いろいろあってGoogle Play Musicから離れられない・・・
AlexaからGoogle Play Musicを流せないものか・・・

で調べてたらYouTubeにこんなぴったりのタイトルの動画がありました。
[How To Play Google Play Music On Alexa](https://www.youtube.com/watch?v=nFzhZbmhFCQ)

英語なので手順書き起こしてみます。

# やってること
Amazon Echoと自分のAndroid端末がBluetoothでつながっていることが前提みたい

Echo(Alexa)にトリガーフレーズを話しかける
↓
IFTTT経由でAndroid端末にPushbulletメッセージが飛ぶ
↓
Pushbulletメッセージを受け取ったら、TaskerがGoogle Play Musicを立ち上げて再生
↓
Andoroid端末で再生される音楽がBluetoothでEchoのスピーカーから流れる

自分がやりたいことと違いました・・・
Alexa(Echo)から直接Google Play Musicを流せるのかと思った・・・
※途中でやる気なくしたので、Dash Automation以降の説明は割愛

## 1.IFTTTの設定
**Alexaに「Trigger Google Play Music」と話しかけると、IFTTT経由Pushbulletよりメッセージが飛ぶ**

IFTTTの"New Applet"：以下のAppletを作成する

- this:"Amazon Alexa" -> "Choose trigger":"Say a specific phrase":「Google Play Music」
- that"Pushbullet" -> "Push a note" -> "Message"に"Playgoogleplay"（内容は任意）

## 2.Taskerの設定
**Pushbulletで"Playgoogleplay"というメッセージが送られてきたら、Google Play Musicで音楽再生（あくまでAndroid端末上での再生）**

- ... -> "Preference" -> "Allow External Access"にチェック
- ... -> "More" -> "Android Settings" -> "Notification Access Service" -> "IFTTT"と"DashAutomation"と"Tasker"の通知許可
- "TASKS" -> "+" -> タスク名入力 -> 
    - "Task Edit" -> "+" -> "Media" -> "Media Control" 
    - "Action Edit" -> "Cmd": "Play [Simulated Only]"を選択 -> "App":"Google Play Music"を選択
- "PROFILES" -> "+" -> "Event" -> "UI" -> "Notification" 
    - "Owner Application" -> "IFTTT"と"Pushbullet"を選択
    - "Text" -> "Playgoogleplay"（※IFTTTのthatでPushbulletより送られるText）

## 3.Dash Automationをつかって何かしてる
以降割愛

# まとめ
**Alexa(Amazon Echo)から直接Google Play Musicを呼びたい！**
新卒エンジニアonlyでグループ開発をしてみたら盛大に失敗した

## はじめに
こんにちは！私たちは新卒エンジニアチームでwebアプリの作成に取り組みました。結果的に、納期までに成果物を作りきることができなかったのですが、その過程で多くの学びを得ました。  
この記事では、私たちが直面した課題とその解決策をシェアします。私たちの失敗談が、同じような道を歩む後輩エンジニアたちの参考になれば幸いです！

## プロジェクト概要説明

### 目的
- プログラミング言語の学習
- チームでの開発経験の積み重ね

### 背景
私たちは社内でボツになった案を引き継ぎ、新卒エンジニアメンバーが中心となってプロジェクトをスタートしました。

### 作成予定だったもの
- サバゲーに特化したレビューサイト ꙳⋆🔫

### チーム構成
- プロジェクトマネージャー: 1名（エンジニアの先輩）
- バックエンドチーム: 5名（新卒）
- フロントエンドチーム: 5名（新卒）
- バックエンドとフロントエンドチームの中からリーダーを1人選定

### 技術スタック
- 言語…PHP, JavaScript, HTML, CSS
- フレームワーク…Laravel, Next.js
- ツール…GitHub, Docker, Figma
- その他…LIFF

### スケジュール
2023年10月〜2024年5月の間、毎月一回集合して全員で作業しました。どうしても時間が足りなかった部分は空いた別の時間を利用して各自進めました。

### 開発の目標
言語学習とチーム開発の実践を通じて、プロジェクトをリリースすることを目指しました。

### 実装予定だった機能と実際の進捗

#### フロントチーム
- 画面の実装  
  ↪︎全14画面中10画面が未完成
- 画面デザイン  
  ↪︎全デザイン完成
- LIFFでのログイン機能  
  ↪︎DB連携等ができておらず未完成

#### バックエンドチーム
- 管理画面(ユーザー管理、レビュー管理など)の実装  
  ↪︎全16画面中10画面が未完成
- フロントへのAPI連携  
  ↪︎画像の取得等ができておらず未完成

## 問題点の洗い出し
大きく分けると、以下の5点かと思います。

### 1. 事前計画が不明瞭
プロジェクトの初動時に、最終的な成果物のイメージや詳細なWBSが十分に明確化されていませんでした。そのため、進行中に混乱が生じ、タスクの優先順位判断や進捗管理が困難になりました。

#### 解決策
- チーム全員で必要なルールやドキュメントを漏れなく作り込む
- 作りこんだものを、エンジニアの先輩にレビューしていただく
- 作成したドキュメントは、いつでも誰でも見やすいように管理する（notionやbacklog等を用いる）

### 2. 情報共有不足
情報共有の場や手法が確立されておらず、メンバー間での情報共有が少なかった。情報共有が内輪で完結し、他チームや先輩に報告されない場合も多々ありました。また、先輩PMに相談する回数が少なく、新卒だけで全部進めようとしてしまいました。

#### 解決策
- チーム全体での進捗・情報・課題の共有を目的とした場を開催  
  （朝会などの定例会議、必要とあらば突発的な会議も）

### 3. ドキュメントの不備
環境構築資料やDB設計書などに不備(記載漏れなど)があり、認識齟齬が生まれることが多かったです。ドキュメントに記載がないものはチームリーダーに聞くことが多く、そこで両者の時間を取られることも多かったです。

#### 解決策
- ドキュメント作成時に第三者のレビューを挟むことで、不備が無いかチェックする
- 作成したドキュメントは、いつでも誰でも見やすいように管理する（notionやbacklog等を用いる）

### 4. プロジェクト管理の課題
開発着手以降、タスクの進捗管理が不十分であり、チーム全体の連携が十分に行われませんでした。また、実装時に必要な機能がわかるような資料等もなく、進捗の把握が難しかったです。

#### 解決策
- WBSの作成
- タスク一覧表（各タスクの状況が一目でわかる資料）

### 5. モチベーションの課題
メンバーのモチベーションが低下し、プロジェクトへのコミットメントが揺らいでいました。社内のみのプロジェクトだったため、納期までに完成させなければいけない等の焦りがありませんでした。

#### 解決策
- チーム全員でプロジェクトへのモチベーションや温度感を揃え、プロジェクトへの意欲を高める。  
  そのためには、成果の評価方法や、報酬などが事前に定まっていることが望ましい。

## まとめ
今回の失敗から学んだ教訓は、私たちにとって貴重な成長の機会となりました。  
同じミスを繰り返さないために、事前計画の徹底、情報共有の改善、ドキュメントの充実、プロジェクト管理の強化、そしてモチベーションの維持を意識してまいります。  
この記事を読んでくださった方々のプロジェクトでも、この記事が役立つことを願っています！
Azure Pipeline で Configuring the trigger failed, edit and save the pipeline again. が消えない時は、Default branch がずれているかも

# 背景

Azure Pipeline を作ろうとしてた際のエラーのようでエラーではない問題？の対処記録

# 問題

Pipeline は正常に動作するにもかかわらず、以下が出た
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4028bb6b-cb06-787c-66a8-100006c19efd.png)

[view details] では以下表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a925a967-fab5-6c26-b843-d9912183cfb3.png)

# 原因

default の branch がずれている場合に**も**発生

:::note info
勿論、pipeline が正常動作しない場合にも、今回のエラーは出る。
:::

# 対処法

1. Pipeline Edit へいき、Triggers を選択
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d325e149-a460-f836-4712-f0340a00f9b5.png)

1. で、YAML -> Get sources -> [Default branch for manual and scheduled builds] で、Default branch を作っている pipeline と同じところに合わせてやる。 
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/504e8611-9634-6358-0583-080d4d6d46d7.png)

:::note warn
:exclamation: このDefault のずれが今回の原因
:::


https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/pipeline-default-branch?view=azure-devops

# あとがき

動作上問題はないんだけど、やっぱり気持ち悪いよね・・と
Gitで別ブランチの変更を1ファイルだけ持ってくる

## はじめに
gitで別ブランチの変更をコミット単位で持ってこれる、cherry-pickコマンドはありますが、その変更の全てがほしいわけではなく、一部ファイルの変更だけが欲しい場面がたまにあります。

そういうときに使えるコマンドがあったので、紹介します。

```zsh
git checkout <欲しい変更があるブランチ> -- <欲しい変更があるファイルの相対パス>
```

たとえば、featureブランチにある特定ファイルの変更が欲しい場合は下記のようになります。

```zsh
git checkout feature -- hoge/fuga/main.go
```

ディレクトリ単位で持ってくることもできます。

```
git checkout feature -- hoge
```

## 追記
restoreコマンドでも同じことができるようです。
むしろ、こちらのほうが推奨かも。
```zsh
git restore -s feature hoge/fuga/main.go
```

```zsh
git restore -s feature hoge
```

## 参考
- https://zenn.dev/nyatinte/articles/c4d5e02dfd5847
- https://zenn.dev/kumackey/articles/8a1bc63ccfb858fd63f6
x00万円の開発ボードにコーヒーこぼしちゃった

# TL;DR

居眠りがちのエンジニアの皆様、
コーヒー等の飲み物は、ぜひフタ付きタンブラーで飲みましょう。マジで。

---

# 経緯

デスクワークをすると、うつらうつらするときがありますよね。
そんなときのおとものコーヒーですが・・・
あまり効かないときもあります
・しこたま眠い（昔は過労死ラインくらい残業してました（眠）
・風邪薬、花粉薬のんだ（冬と春やばい）
・常態化してる（よくない）


うつらうつら・・・・カクンっってなったときに、
頭がデスク上のカップ（もちろんコーヒーin）にぶつかってこぼしてしまいました。
きゃー。やっちゃった。

※デスク上のドリンクをこぼすことは、人によっては全く無かったり頻発してたり、結構偏りがある印象です。

---

# よくある被害

* キーボードにこぼす
一番被害に会いやすいのが、まずキーボード。
ドリンクとキーボードのどちらも手元にあるため、よく被害に遭います。

キーボード内のプリント基板にコーヒー液が流れて、そのまま乾燥すると
意図しない接点同士が結合され、キー入力がデタラメになったり、押してもないのにキー入力しっぱなしになるとかならないとか。

うまく分解→洗浄すれば割とキーボードは助かりますが、
３０分くらい時間取られます。


* ノートPC、スマホにこぼす
アプリを実機開発してると、スマホも手元に置きがちです。
最近のスマホは防水高いから大丈夫なのかな？

それよりノートPCに入り込むとなかなか大変です。キーボードと違って分解が難しいため。
私は私物ノートを１台ダメにしました。
PC自体はいきていましたが、キーボード部分がやられたので、
ノートPCなのに、外付けUSBキーボードで動かしてました＞＜


* カーペットにこぼす
あなたのご自宅が絨毯だったり、
会社がちょっとオシャレなカーペットを敷いてたりすると被害が大きいです。

基本はびちゃびちゃの雑巾でカーペットをたたいて汚れを吸い上げてください。（家庭の掃除法）（でもできれば専門の人に聞いて）

クリーニング代うん万円取られるかも。。。

* 本にこぼす
デスクに技術書とか、書類とか積み上げてませんか？
茶色くしわしわになります。コーヒーの香りも紙につきます。
放置していると、ページとページがくっついて読めなくなるかも（想像でかいてます。実際はどうなんだろう）

相手先のハンコ押してある契約書とかだと最悪ですね。重要書類はさっさと処理して机に置かないようにして下しあ。


* 開発基板

組込み仕事やってると、開発用の試作ボードといものが度々作られます。
（組込界隈ではない方、ラズパイのおっきいバージョンをご想像ください）

バージョンアップ品とかだと、既存製品の基板を改造したもので開発とかするんですが
たまにマジモンの新製品とかなると１から基板設計して試作ボードを作ります。
そのため開発費が乗って、生産も電子屋さんに特注とかなので、１枚の値段が数十万円くらいします。（これに更に０が２個ついたスペシャル基板も見たことがあります・・・家買えちゃう）

さて、昔わたしが触っていたそれは、タイトルの通りx00万円クラスでした。
そんなボードにコーヒーをぶっかけちゃったわけです。

---

# どうなったか。

まず、しばらくタダ働きを覚悟しましたｗ

いそいで水気を拭き取ったところ、
今回はたまたま壊れず、ちゃんと通電して
起動して、破損無し。
セーフでした。。。

---

# どうすればよかったか。

このあと、「ドリンクはフタ付きで飲め」とのお達しが会社に回りました（猛省

そうです。フタ付きにすればよかったのです。

---

# ｘ年後・・・

あれからも度々ドリンクを倒しますが、
（手がぶつかってたおしちゃうことが多い）
なんと実害は通算０です。

倒したとき、蓋が完全にしまってない事も有りますが、
ちょっと水分が漏れる程度で、ササッと拭き取ってOKです。

フタ付きの代表格にペットボトルがありますが
ペットボトルの蓋がしまってないと、まあまあこぼれるのはご想像いただけるかと思います。
なのでペットボトルでも良いですが、もし可能ならフタ付きタンブラーを強くおすすめします。

大切な開発機材等を守りながら、健やかなエンジニアライフをお過ごしください。

（フタ付きタンブラー流行れ）
SalesforceのDISABLE_EXTERNAL_PASTE設定をTRUEにしてみた

本橋孝昭です

SalesforceのDISABLE_EXTERNAL_PASTE設定をTRUEにしてみたときの変更点を見てみた


※参考ヘルプ　

https://help.salesforce.com/s/articleView?id=sf.salesforce_app_security.htm&type=5

>DISABLE_EXTERNAL_PASTE	
TRUE
FALSE
Android、iOS	
TRUE に設定されている場合、Salesforce モバイルアプリケーションの内部および外部でコピーと貼り付けが無効になります。
FALSE (属性値が定義されていない場合のデフォルト) に設定されている場合、ユーザーは Salesforce モバイルアプリケーションの内部および外部でコピーと貼り付けができます。
DISABLE_EXTERNAL_PASTE 属性は、iOS の Share Extension には影響しません。

まずは設定についてみてきましょう


## 設定場所
「接続アプリケーションを管理する」から「Salesforce for iOS」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/250e68eb-1639-2120-8233-957a6f39a18d.png)


カスタム属性の新規ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2205d346-e571-bb6c-ecaa-3be1a33ae543.png)


属性キーを
DISABLE_EXTERNAL_PASTE

属性値を
"TRUE"
で保存


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ee8d566b-06cd-2ca3-5bc4-cd656b0b6dc7.png)


## 設定による変更点

iPhoneのSalesforceアプリで操作する際
・Salesforce内のデータをコピーして外部（例　iPhoneのメモ帳など）に貼り付けができない
・外部（例　iPhoneのメモ帳など）の内容をコピーをしてSalesforce内のデータに貼り付けができない

となります
つまりSalesforceのデータが外部出るリスクを減らし、外部の情報をSalesforceに入れることを防ぎます

なお、Salesforce内のデータをコピーしSalesforce内に張り付けることは可能ですのでご注意ください


※今回設定確認したメモはiPhoneの標準のメモです


https://support.apple.com/ja-jp/118442


なおFALSEにした場合

iPhoneのSalesforceアプリで操作する際
・Salesforce内のデータをコピーして外部（例　iPhoneのメモ帳など）に貼り付けができる
・外部（例　iPhoneのメモ帳など）の内容をコピーをしてSalesforce内のデータに貼り付けができる
となります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6adeee66-cade-d61b-4aee-f836e4c29f30.png)
PHP / Nginxにおけるタイムアウト値の変更手順

# PHPのタイムアウト値変更
### 方針
**max_execution_time**の値を変更する

以下は phpinfo() をプログラムで呼び出した php.ini の出力結果
![スクリーンショット 2024-05-31 12.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123079/422fbfed-ca2b-d010-7543-bd360c6f7a08.png)

### 変更方法
プログラムによる設定変更
- https://www.php.net/manual/ja/function.ini-set.php
- https://www.php.net/manual/ja/function.set-time-limit.php

### 注意点
https://www.php.net/manual/ja/function.set-time-limit.php
> 関数 set_time_limit() と設定ディレクティブ [max_execution_time](https://www.php.net/manual/ja/info.configuration.php#ini.max-execution-time) は、 このスクリプト自体の実行時間にのみ影響を与えます。[system()](https://www.php.net/manual/ja/function.system.php) を用いたシステムコール、ストリーム操作、 データベースクエリ等のスクリプト実行以外で発生する処理にかかった時間は スクリプトが実行される最大時間を定義する際には含まれません。 ただし、Windows ではこれは当てはまりません。 計測された時間は実際の時間と等しくなります。

特にストリーム操作やクエリ操作・DB更新に関連する処理時間はタイムアウト値の計測時間に含まれないため、[max_execution_time](https://www.php.net/manual/ja/info.configuration.php#ini.max-execution-time)の値を超えても処理が継続される場合がある。


# Nginxのタイムアウト値変更
### 方針
**fastcgi_read_timeout**の値を変更する

### 変更方法
nginx.conf に値を定義
```
http {
    ...
    fastcgi_read_timeout 30;  // サーバーからのレスポンスのタイムアウトを30秒に設定
    ...
```
nginx.conf を更新したため nginx を再起動
- Docker外では以下を参考
    - https://qiita.com/katzueno/items/44e02db2f1bfa0de5860
- Docker内では以下のコマンド
    - `docker compose restart nginx`
Ubuntu環境でPython環境構築

## 0. システムのアップデート
>開始する前に、システムが最新であることを確認することが常に良いアイデアです。ターミナルを開いて、次のコマンドを実行してください。
```
sudo apt update && sudo apt upgrade
```

## 1. Python3
##### バージョンの確認
```
python3 --version
>>> Python 3.10.12
```
バージョンが返ってこない場合は、インストールを行う。
(バージョンは3.10でも良いと思います)
```
sudo apt install python3.9
```

## 2. pip
##### pipのバージョン確認
```
pip3 --version
>>> pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
```
こちらもバージョンが返ってこない場合は、インストールを行う。
```
sudo apt install python3-pip
```


## 3. 仮想環境の作成
```
python3 -m venv venv
```
もし上記コマンドで仮想環境作成できない場合。

```
sudo apt install python3.9-venv
```

## 4. 仮想環境に入る
```
source venv/bin/activate
```
上記コマンド実行後、(venv)が付けば成功:sparkles:
```
(venv)user@userName:~/TEST/sample_python$
```

# 参考サイト

https://linuxy.top/ja/python-ubuntu

# 最後に
Ubuntuで作業する際、間違えやすかったのが
仮想環境に入る時のコマンド...。
```
./venv/Scripts/activate
```
に慣れすぎてなんでーーーーって何回かなりました笑

###### 仮想環境から出る際のコマンドは同じです。
```
deactivate
```
Cahce(キャッシュ) / Cookie(クッキー) / セッション(Session) について

# Cache（キャッシュ）
一度読み込んだ内容や情報を一時的に保存し、次回閲覧時に読み込み速度を上げる仕組み
代表的なキャッシュとして以下の2つ

### ブラウザキャッシュ
アクセスしたサイトのデータを、一時的にブラウザに保存しておくもの
- 通常ページを表示する際は、ページのデータをダウンロードしてから表示させるが、キャッシュがあることで改めてダウンロードする必要がなくなる

### サーバーキャッシュ
過去に作成したファイルやデータが一時的にサーバーへ保存されたもの
- 1回目にアクセスされるとブラウザに送信するデータを「キャッシュページ」としてサーバー上に保存（=サーバーキャッシュ）
- 2回目以降のアクセス時は、その「キャッシュページ」を表示することでデータ作成の処理時間を省く

# Cookie（クッキー）
IDやパスワードなどの個人情報やサイトの閲覧情報を保存する仕組み

### クッキーの種類
- ファーストパーティ
    - Webサイトの訪問先ドメインから発行されるCookie
    - 訪れたサイトのみでしか機能しない
- サードパーティ
    - 訪れたサイトに掲載されている広告配信事業社のドメインなどから発行されるCookie

### Cookieを使用するメリット
- 何度もログインする手間が不要
- ECサイトでのカートの中身が保持される

### Cookieを使用するデメリット
- 個人情報の流出・不正利用のリスクがある

# Session（セッション）
通信の開始から終了までの一連の流れ
セッションに定義されている基本的な有効時間は30分だが、任意の時間に変更可能

### セッション管理
- アクセスしているユーザの識別や処理の状態を管理することが目的

例）
1. セッションを識別するためのID（セッションID）を生成し、ユーザ情報や処理状態を紐づけてCookieに保存
2. 通信時にセッションIDからユーザ情報や処理状態を取得

### セッションの単位

例）有効時間は30分とした場合
1. あるWebサイトにアクセスし、そのサイト内で3ページ分を閲覧（1セッション目）
2. ページを開いたまま数時間放置
3. 数時間後に同じサイト内で別2ページを閲覧（2セッション目）
    ↑放置の間にセッションの有効期限が切れており、数時間後にまた通信が開始されている

# 参考記事
- https://koneta.nifty.com/koneta_detail/1141008005077_1.htm
- https://gmotech.jp/semlabo/seo/blog/cookie/
- https://gc-seo.jp/journal/session/
【Git】GitHubの基本操作（草生やすまで）

# ローカルリポジトリを作成する
1. ディレクトリ作成 `mkdir xxx_xxxxxxxx`
2. 作成したディレクトリへ移動 `cd xxx_xxxxxxxx`
3. リポジトリ作成 `git init`
4. リポジトリ作成されたかの確認 `ls -a`
上記コマンドで .git ディレクトリが表示されてればOK
# リモートリポジトリを作成する
1. ブラウザで自身のGitHubリポジトリに移動
2. Repositoriesタグをクリック
3. Newをクリック
4. 以下の項目を入力
Repository name：リポジトリ名を入力
5. Privateの項目にチェックを入れる
6. Create repositoryをクリック
# リモートリポジトリとローカルのリポジトリを紐付ける
1. 「Quick setup — if...」の文言そばにある ssh をクリック
2. 以下のコマンドをターミナルで実行
`git remote add origin git@github.com:GitHubアカウント名/リモートリポジトリ名.git`
`git branch -M main`（最下部の`git push -u origin main`はまだ行わない）
3. 紐付けができているかを`git remote -v`コマンドで確認
（以下のようなものが表示されればOK）
`origin git@github.com:GitHubアカウント名/リモートリポジトリ名.git (fetch)`
`origin git@github.com:GitHubアカウント名/リモートリポジトリ名.git (fetch)`
# ローカルのリポジトリの内容をリモートリポジトリに反映させる
1. `git add xxxx.xxx` (ワーキングツリーからステージングエリアへ)
2. `git commit -m 'xxxxx'` （ステージングからローカルリポジトリへコミット。xxxxxはコミットメッセージを入力）
3. `git push -u origin main`(この段階で実行。ローカルリポジトリに作成したコミットをリモートリポジトリにアップロード。)
4. ブラウザで自身のGitHub上からリモートリポジトリに移動
5. 内容が反映されているかを確認する
6. 草が生える
VSCodeをサクサク使うためのショートカットいくつか


https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf

ショートカットを使ってサクサクに開発を進めるための小技をまとめていきます。

環境はMacです。

## コーディング

### 任意の位置から改行

`Cmd + Enter` : カーソルの位置から改行

`Cmd + Shift + Enter` : カーソルの位置から上に改行

### 一行コピー/切り取り

選択していない状態で以下のショートカットを押すと、カーソルがある行全体で動作する。

`Cmd + c` : 一行コピー

`Cmd + x` : 一行切り取り



## ファイル名検索

`Cmd + P` : ファイル名検索

## ターミナルの表示

`Cmd + j` : ターミナルの表示

## 検索

### 選択中の文字列を選択/検索

`Cmd + D` : 選択中の文字列を選択

これを連打することで、同じ文字列を複数選択していくことができる。

まだ選択中の文字列を全て選択する場合は、`Cmd + Shift + L`を押す。（ファイル内の単語の変更にめちゃ便利）

### 特定の拡張子 or パスを検索

`Cmd + Shift + F` : 検索バーを表示

files to include: `*.go` or `src/`

files to exclude: `*_test.go`

### 正規表現

知っているか、VSCodeの検索バーに正規表現を使うことができることを。

`Cmd + F` : 検索バーを表示

`Cmd + Option + R` : 正規表現検索
ジョブ / キュー / ワーカー / バッチの違い

# 前提
私は普段Laravelのフレームワークを用いて開発しているため、参考記事にはLaravelの公式ドキュメントを記載しておきます。

# ジョブとは
- 「実際に実行される処理」を指す
    - コンビニを例に挙げると「ジョブ = レジでの会計処理」

# キューとは
- 「処理が実行されるのを待っているジョブのリスト」のことを指す
    - コンビニを例に挙げると「キュー = レジの会計を待って並んでいる人」
- 「ジョブをキューに投入する」（ディスパッチ）という表現も用いられ、これは実行したいジョブを実行待ちリストに加えるという意味

# ワーカーとは
- 「ジョブを実行する役割を持つもの」を指す
    - コンビニを例に挙げると「ワーカー = レジの会計をする店員」

# ジョブとバッチの違い
「ジョブ」と「バッチ」の違いがイマイチ分からない、、といった話を時々見かけるので比較しつつ違いを述べてみます。
||ジョブ|バッチ|
|:-----------|:------------|:------------|
|概要|CPUが行う処理の**単位**|CPUが一定期間や一定量ごとに処理を行う**方式**|
|データ処理|リアルタイム処理|予め指定されたスケジュールで処理|
|メリット|リアルタイム処理により、実行結果の反映が早い|大量データを一括扱えるためリソースの節約が可能|
|具体例|オンラインショッピングの決済|大量データのインポート|


# 参考記事
- https://readouble.com/laravel/6.x/ja/queues.html
- https://reffect.co.jp/laravel/laravel-job-queue-easy-setup
- https://trends.codecamp.jp/blogs/media/difference-word266
Outlook for Macのバックアップツールを実装

# 概要
Microsoft OfficeはMac版も開発されているため、MacでもメーラーのOutlookを利用出来ます。しかし、Windows版と比較すると実装されていない機能が頻繁に存在します。特にバックアップに用いる機能についてはとても貧弱です。今は昔、以下の記事でOutlook for Macのバックアップと復元について調査した内容を投稿しました。この時の内容を参考にバックアップツールをBashで実装し、簡単にバックアップ出来る様にしました。

https://qiita.com/y-vectorfield/items/02b34669a3c0180273f8#fn2

# 環境情報
以下の環境を用いて実装しています。
* macOS Sonoma 14.5
* Outlook for Mac 16.86.3
* Bash 5.2.26


# ツールの実装
ツールと言っても、単なるスクリプトファイルで、以下の様に実装しました。

```bash
#!/usr/bin/env bash

filename="outlook_backup_$(date "+%-y%m%d%H%M%S").tgz"
echo "Back up Outlook..."
cd /Users/$USER/Library/Group\ Containers/UBF8T346G9.Office/Outlook/Outlook\ 15\ Profiles/Main\ Profile/ && tar cvzf $HOME/${filename} Data &> /dev/null
echo "Finished!(${filename} was created.)"
```

特別難しいことはやっておらず、Outlookのメールや仕分けルールが格納されているディレクトリ配下でtarコマンドを実行し、アーカイブファイルをホームディレクトリ上に保存するという実装です。アーカイブファイルのファイル名にはdateコマンドの実行結果を用いてタイムスタンプが入ります。tarコマンドの実行結果が大量に出力されてしまうため、標準出力、標準エラー出力への出力は捨てています。

# 実行結果
実際に実行してバックアップファイルが作成されていることが確認出来ました。

```bash
$ ./outlook_backup.sh 
Back up Outlook...
Finished!(outlook_backup_240703221859.tgz was created.)
$ ls -alh outlook_backup_240703221859.tgz 
-rw-r--r--  1 user  staff   265M  7  3 22:19 outlook_backup_240703221859.tgz
```

# まとめ
Outlook for Macのデータディレクトリは階層が深いため、バックアップ作業が煩雑でした。今回実装したツールでバックアップ作業が楽になりました。Crontabを利用して定期実行出来る様にするのも良いなと思っています。

# Reference
https://qiita.com/TsuyoshiUshio@github/items/e2f7d881a57f4d4359ec

https://hydrocul.github.io/wiki/commands/date.html

https://qiita.com/harasakih/items/868a850fcdc99a2c37b0
Salesforceで画面フローを作成しよう～動的に表示項目を変えてレコード作成をする方法

　本橋孝昭です

 今回は画面フローを作成して項目の内容に応じて動的に画面を変えてレコード作成する方法をお伝えします


 今回は例として
 ・取引先にTodo作成画面を用意して画面の内容からTodo作成を可能にする
 ・画面内の「有効」チェックの有無で作成する項目の内容が変更する
 というフローを作成します


 これが作成後の様子です

 まず取引先画面にこのようにTodo作成画面が出ます

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b0b37b53-7d63-a0ee-05f8-87b136f5e592.png)


「有効」にチェックを入れると「Memo」項目が見えなくなることが分かります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7c9e040e-2874-d3d2-27d5-bc8f458c6b0f.png)


また「有効」にチェックを外すと先ほどの「Memo」項目が表示されるのが分かります


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d26dec3b-07df-69cc-ac39-1a2f628314ea.png)


入力して「次へ」をクリックするとレコード作成がされます


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/817629e3-ffd4-4fdf-6c45-f176d71c7413.png)


作成した項目には、もちろん先ほど入力した内容が反映されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9bd922d8-58e5-c0d0-2468-35ccfd9f359e.png)



このように項目の内容により表示項目が動的に変わるので、ユーザは入力すべき項目が何か分かりますね
（今回は力尽きてしまい項目は2項目しか用意してないですが、実際たくさん項目がある場合項目の表示や非表示が動的に変わるので便利ですよね）



では、このフローはどのように作ったか。
解説&スクリーンショットを交えてご紹介！

フロー全体像はこちら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/03b9124d-de71-a4a9-60fc-64df7d560149.png)


画面フローも見ていきましょう

これが画面の全体像です
仕組みとしては左にある「チェックボックス」などをドラッグ&ドロップで画面に持っていき画面を作ります



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a4695cbf-fd9b-a542-504b-077edf04ed41.png)


「Memo」は有効のチェック有無で動的に見え方が変わりましたが、これはこのような絞り込み条件をして項目の出しわけをしているからでした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/33510999-2456-2f2f-3403-6fb7be76d73a.png)


このスクリーンショットを見れば先ほど取引先に出ていた画面がどのようにして成り立っていたか分かりますね

では、次に画面の内容を元にTodo作成する仕組みを見てみましょう

まずはこのような変数を作成します


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c91f645a-edc6-a48d-4886-98ebe0518af3.png)

レコード作成画面はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9d0787df-9a0b-56ba-9891-135d8d29c6a2.png)


こだわりポイントとしては
WhatIDに先ほど作成した変数recordIdが入ります
これにより
・表示しているレコード画面に紐づくTodoを作成する
という設定にすることが可能です

他に、画面で入力した内容をレコード作成時に反映したい場合はこちらの画面でマッピングします
・Description項目にMemoの内容を入れる　という設定がされてますね

以上でフローは完成です

あとはフロー有効化もお忘れなく！

最後はレコードページの編集を行い画面フローをレコードページに表示させましょう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/499bb0e5-10c8-f8b8-c60f-6efb3a764b76.png)


お疲れ様でした！
バグ発生時の正しい対応

# はじめに
バグに限らず実装中になんかうまく動かんのだが？っていう相談を受けることがある。

こういうとき、きっちり前提や問題点を明確にした上で相談し解決方法を一緒に見つけて欲しいというスタイルの人と、**全く分からんからとりあえずお前に聞くわw**っていうのが透けて見える人がいる。。

自分でちゃんと考えない人が割といる気がするので、この記事ではバグとか問題が発生した場合どういう考え方を持って行動すべきか、について記載していきます。

記事にしてみると至極当然のことしか記載していません。
複数タスクを抱えている状態とか緊急的な問題に対応する場合は、目が曇りがちになるものなので、基本に立ち返って記事にしたいと思います。

# 大事なこと
重要なことは、
<font color="Red">現状整理を全くせずに思いつくままに行動して無駄な時間を過ごさないようにしよう</font>
です！

# ①まずは現状整理
どこを調査すれば良いのか当たりをつける意味でも、現状整理を行い問題点を明確にします。

### 問題の内容を明確化する
以下項目が問題の内容を明確化するポイントだと思います。
・何故問題と思ったのか？
・再現手順は？
・発生確率は？
・エラー表示されているんなら、内部でエラー出力してない？
・例えばサーバ連携している箇所なら、サーバーレスポンスでHttp Status Codeやレスポンスパラメータでエラーになっている？

### 限定的な要因はあるか？
また、対象の問題が限定的な条件で発生するかどうかも明確しておきたいポイントです。
・シミュレータ、もしくは実機に依存するか？
・OSバージョンによって動きが異なるか？
・OSによって動きに差異があるか？
  例)Androidアプリでは発生するが、iOSアプリでは発生しない、とかね

### 期待動作を明確にしておく
そして、期待動作を明確化することでどういうゴールを目指すかをはっきりさせます。
逆にここが不明瞭な場合は、まずは期待動作を明確化しましょう。
（ToBe, AsIs形式で書いても良いし、現象はこうだが期待動作はこうだよ、でまとめても良いと思う）

# ②次に可能性のある原因について深く考えてみる
いきなり試行錯誤しない、ということがまず大事、メッチャ大事。
現状整理したのであれば、考えて当たりつけてから行動しようぜ、ということになります。

まずざっとしたイメージで良いから問題が発生するシーケンスを考える。
で、そのシーケンスのどの領域で発生してそうかを考える。
例)
　アプリ側か？
　フロントサーバ側？
　それともバックエンド側か？
　はたまたFirebaseとか別サービスでエラーが発生しているのか？

どの領域が怪しそうか推測を立て、その領域の具体的などこで問題が発生しているかを考える。
例えば以下順番でドンドン具体的な部分をブレイクダウンしていく。
　どの画面？
　どの機能？
　関係してくるファイル、クラスは？
　どのメソッドで問題が発生してそうか？

# ③原因と思われる箇所の仮説が正しいことを証明する
ブレイクダウンできたら、原因箇所と思われる箇所と推測できる箇所が何箇所か出てくると思う。
仮説が正しいかどうか証明するために例えば以下を実施。
・ログを仕込む
　※ログの仕込み方も１つのスキルだと思います、この辺りは別記事にまとめる予定
・Break pointを貼る

ここまでできたら現象を再現させ、仮説が正しいことを確認する。

# ④仮説が外れた場合は？
もし仮説が外れ、自分の考え方が間違っている場合は
また②、③について再度検討し、原因を特定していく。

# ⑤原因特定後：修正方針の検討 > 修正 > 動作確認
### 修正方針の検討
原因が特定できた場合、期待動作になるように修正していきます。
ただし、既存処理の影響箇所なども考慮する必要があるため、**ひとまず適当に修正して動かしたら直ったで！っていうのはやめましょうw**

ここでも、まずは考えるという行動が必要になってきます。
つまり、「修正方針の検討 = 設計」ですね。

また、自分の考えが本当に正しい方向かどうか不安がある場合は有識者を探して、相談に乗ってもらうのも一つの手です。
不安がある状態で修正 > 何となく動いたからそのままリリース > また問題が発生。。
となる未来しか見えないので、ここは時間をかけて良い箇所だと思います。可能な限り確実に修正するためです。

そして、修正方針の検討がしっかりできていないと、動作確認の内容が非常にスカスカになります。
なぜなら、影響範囲が明確でないから動作確認の範囲も明確にはならないためです。

### 修正
修正方針の検討が完了したら、次のステップは修正です。
コードを修正し、修正時に必要と思われるコメントなども整備し、修正していきます。
修正内容に合わせ、テストコードも修正する必要があるのであれば合わせて修正する必要があります。

### 動作確認
修正方針の検討をしっかりしているのであれば、動作確認の観点もある程度見えてきていると思います。
簡易的に箇条書きでも良いので、動作確認の内容をリスト化し確認すべき内容を検討します。
（複数の端末で確認すべきか？OSバージョン違いでも確認すべきか？の観点も持つべき）

動作確認内容の検討が済んでから、動作確認を行い自分の修正の品質を確認してください。

# 最後に
どの工程でも**考える**という行動が非常に重要になってくると思います。
ここを行わないと、無駄な時間を使ってしまう可能性もあるため考える癖をつけましょう、というお話でした。

兎に角 やみくもにやらないこと。
やみくもにとりあえず動かしてみて何度もトライする人は考えずに動いている人だと思います。
結果的に再現方法の確立や原因特定に中々辿り着けずに、作業の遅延に繋がっている気がする。

ちなみに、理想通りにことが運べば試行回数は以下３回になるかと思います。
①再現確認
②原因特定のための再現
③修正後の動作確認

場合によっては上記①と②をセットにできる場合もあり、そういった意味では最小試行回数は２回になるかな？
試行回数が少なければ少ない程バグ対応の時間が少ないことになるので、試行回数を極力減らすように行動しましょう。

以上
Pythonでファイル一覧・更新日時取得

#### 覚えたてのメソッドをアウトプット:relieved:

# ディレクトリ内のファイル一覧取得
取得したファイル一覧がリストで返される。
>リストは任意の順序で、ディレクトリ内に存在する特別なエントリは含まれません。
この関数の呼び出し中にファイルがディレクトリから削除されたり、ディレクトリに追加されたりした場合、そのファイルの名前が含まれるかどうかは未指定です。

```python
import os

dir_path = "directory/"
files = os.listdir(dir_path)

print(files)
# ["main.py", "second.py", "third.py"]
```

https://docs.python.org/3/library/os.html#os.listdir:~:text=os.listdir%20(%E3%83%91%E3%82%B9%3D%20%27%20.%20%27%20)


# ファイルの更新日時を取得
###### os.path.getmtime(path)
>pathの最終変更時刻を返します。戻り値は、エポック (モジュールを参照) からの秒数を示す浮動小数点数です time。OSErrorファイルが存在しないかアクセスできない場合は例外を発生させます。

```python
import os
import datetime

updated_time = os.path.getmtime("sample.csv")
# 1718536513.7453966
updated_time_dt = datetime.datetime.fromtimestamp(updated_time)
# 2024-06-16 20:15:13.745397
```
https://docs.python.org/3/library/os.path.html#os.path.getmtime

# 参考サイト

https://note.nkmk.me/python-os-stat-file-timestamp/