OmniAICreator/Qiita-1.07M huggingface dataset:
WordPressで時間のズレを解消！current_time()で正確な日時を取得する方法

WordPressで通常、PHPのdate()やtime()関数を使って日付や時刻を取得すると、サイトに設定されたタイムゾーンとは異なる時間が表示されることがあります。これは、サーバーのデフォルトタイムゾーンが考慮されるためで、特にグローバルなユーザーや異なる地域のタイムゾーンに対応するサイトにとって問題になります。

そこで、WordPressの**current_time()関数**を利用すれば、サイトのタイムゾーンに基づいた正確な日付や時刻を取得できるようになります。

### current_time()とは？


current_time()は、WordPressで現在の時刻や日付を取得するための便利な関数です。特にサーバーのデフォルト時間ではなく、WordPressに設定されたタイムゾーンに基づいた時間を取得することができるため、異なる地域のユーザー向けに時間ベースのコンテンツを出し分ける場合に役立ちます。

```php
current_time( string $type, int|bool $gmt ): int|string
```

- $type: 取得する情報の形式を指定。'timestamp', 'mysql', 'G', 'U', 'H', 'n'など、様々な[フォーマット](https://www.php.net/manual/ja/datetime.format.php)で時間情報を取得可能。
- $gmt: trueに設定するとUTC時間が返り、false（デフォルト）だとWordPressのタイムゾーンに基づいた時間を返します。


### 例 月ごとに異なる画像を表示する

では、実際に偶数月と奇数月で異なる画像を表示する例を示します。この方法では、現在の月をcurrent_time()を使用して取得し、それが偶数か奇数かを判定して画像を切り替えます。

```php
<?php
function display_image_based_on_month() {
    // WordPressのタイムゾーンに基づいた現在の月を取得
    $current_month = current_time('n'); // 'n'は1〜12の月を返す
    
    // 偶数月か奇数月かを判定
    if ($current_month % 2 == 0) {
        // 偶数月の場合
        echo '<img src="' . get_template_directory_uri() . '/images/even-month.jpg" alt="偶数月の画像">';
    } else {
        // 奇数月の場合
        echo '<img src="' . get_template_directory_uri() . '/images/odd-month.jpg" alt="奇数月の画像">';
    }
}
```

### 例 月ごとに異なる画像を個別に表示

さらに、偶数・奇数の判定ではなく、各月ごとに個別の画像を表示する方法も考えられます。たとえば、1月にはjanuary.jpg、2月にはfebruary.jpgといったように、月ごとに画像を切り替えるコードは次の通りです。

```php
<?php
function display_image_by_month() {
    // 現在の月を取得
    $current_month = current_time('n');
    
    // 月ごとに画像を表示
    switch($current_month) {
        case 1:
            echo '<img src="' . get_template_directory_uri() . '/images/january.jpg" alt="1月の画像">';
            break;
        case 2:
            echo '<img src="' . get_template_directory_uri() . '/images/february.jpg" alt="2月の画像">';
            break;
        case 3:
            echo '<img src="' . get_template_directory_uri() . '/images/march.jpg" alt="3月の画像">';
            break;
        // ...続けて各月の画像を追加
        case 12:
            echo '<img src="' . get_template_directory_uri() . '/images/december.jpg" alt="12月の画像">';
            break;
        default:
            echo '<img src="' . get_template_directory_uri() . '/images/default.jpg" alt="デフォルトの画像">';
    }
}
```

### タイムゾーン設定の確認

この機能を正しく動作させるためには、WordPressのタイムゾーン設定が適切であることを確認する必要があります。以下の手順で確認・設定が可能です。

WordPress管理画面にログイン。

- **「設定」** →  **「一般」** をクリック。
- **「タイムゾーン」** で、自分の地域に合ったタイムゾーンを選択。

これにより、サーバーの時間ではなく、WordPressの設定に基づいた時間で画像の切り替えが行われます。

### 参考資料

- [current_time](https://developer.wordpress.org/reference/functions/current_time/)
【Docker+VSCode】Devcontainerの最小構成テンプレート

# 概要

VSCodeでDockerDevcontainerの最小構成テンプレートです。  
以下の方に有用だと思います。
- Devcontainerのためだけに、`Dockerfile`、`docker-compose.yml`を二重で作成している方
- 検証用や勉強用にとりあえず早く環境を作りたい方

# ディレクトリ構成

```bash
.tree 
├── .devcontainer
│   └── devcontainer.json
├── Dockerfile
├── app
│   └── index.html
└── docker-compose.yml
```

# docker-compose.yml

```yaml
version: "3"
services:
  app:
    build: .
    volumes:
      - .:/src
    tty: true
```

※ docker-compose.ymlの説明については省略します。

# .devcontainer/devcontainer.json

```json
{
  "dockerComposeFile": "../docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/src",
  "customizations": {
    "vscode": {
      "extensions": [
        "GitHub.copilot",
      ]
    }
  }
}
```

以下に`.devcontainer/devcontainer.json`の各定義について説明します。

1. 以下で参照する`docker-compose.yml`のpathを指定します。
    
    ```json
      "dockerComposeFile": "../docker-compose.yml",
    ``` 
    　

2. 以下で`docker-compose.yml`にて定義したサービスを指定します。
   これにより、Devcontainerでどのサービスで作業をするかを指定できます。  
   今回は`app`サービスを定義したので、`app`を指定しています。
   
    ```json
      "service": "app",
    ```
    　

3. 以下で、Devcontainerでコンテナを起動した際に最初に開くディレクトリを指定します。  
   今回は`docker-compose.yml`にてコンテナ内の`/src`ディレクトリにバインドマウントするように設定しているため、`/src`を指定しています。
    ```json
      "workspaceFolder": "/src",
    ```
    　

4. 以下で、Devcontainerでコンテナを起動した際にインストールしたい任意のVSCode拡張機能を指定します。  
  今回は`GitHub.copilot`を指定しています。

    ```json
      "customizations": {
        "vscode": {
          "extensions": [
            "GitHub.copilot",
          ]
        }
      }
    ```

※ 追加方法はこんな感じでGUIから追加できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487776/4e0fa9d4-22ab-c6e8-ca72-ca8ef1a5d656.png)

# 実用例

以下、私がUdemyのReact講座を受講した際に、速攻で構築した実用例です。

## .devcontainer/devcontainer.json

```json
{
  "dockerComposeFile": "../docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/src",
  "customizations": {
    "vscode": {
      "extensions": [
        "GitHub.copilot",
        "ritwickdey.LiveServer"
      ]
    }
  },
}
```

## docker-compose.yml

```yaml
version: '3'
services:
  app:
    image: node:22-bookworm
    ports:
      - "3000:3000"
    volumes:
      - .:/src
    entrypoint: tail -f /dev/null
```

以上！！
python classの理解を深めるための記事（自分用）

とにかくclassがいまいち理解できていないので、ここに記述しながら理解を深める

1.classとは
-
classとはオブジェクト指向における中核的をなす概念・・・いや、わからんわ:angel:
そのため、自分なりに色々と調べて自分なりに理解できるように纏めてみる。
classに関連するものとしてinstanceやinitについても記述する。

2.classの構造
-
クラスの構造は以下のとおりであり、処理の意味を記述しておく。

<strong>クラス = 設計図</strong>
<strong>インスタンス = 設計図に基づいて作ったもの（オブジェクト）</strong>

```
# Dogクラスという設計図
class Dog: 
    def __init__(self , name , breed):
        self.name = name
        self.name = breed

    def bark(self):
        print(f"{self.name} is barking")

# my_dogとしてインスタンス化する（設計図に基づいて作成したオブジェクト）
my_dog = Dog("Rex" , "Labrador")
my_dog.bark()

# 出力　⇒　Rex is barking
```
3.まとめ
-
python自体がオブジェクト指向言語であり、普段から使っているprint文等もクラスであるということを考えるとクラスが少しだけ取っつきやすいものに思えなくもないかな
もっと理解が深まれば、この記事に追記していくこととする。
<a href="https://qiita.com/ishigen/items/2d8b6e6398743f2c8110">クラスの理解を深めるための参照</a>
```
x = 1
print(type(x))

# 出力　⇒　<class `int`>  （intクラスのインスタンス）
```
PythonでEOFError: EOF when reading a lineのエラー

Atcoderでコードテストをしたら「<b>EOFError: EOF when reading a line</b>」が表示された。

・その時のソース。
```python
a = int(input())
b = int(input())

product = a * b
if product % 2 == 0:
  print('Even')
else:
  print('Odd')
```

・エラー
```
Traceback (most recent call last):
  File "/judge/Main.py", line 1, in <module>
    a = int(input())
            ^^^^^^^
EOFError: EOF when reading a line
```

input()の中に何も入れてないから入力がないよって怒られた。

```python
a = int(2)
b = int(3)

product = a * b
if product % 2 == 0:
  print('Even')
else:
  print('Odd')
```

これで直った。
提出するときはinputの引数入れないけど、コードテストの時は具体的な値を入れてあげないとエラーになってしまうってことでした。
C言語　データ型についてちゃんと知りたい！

# はじめに
C言語学び始めの#42Tokyoの生徒です。曖昧に理解していたデータ型について整理しました。

# データ型の種類
| 型の種類 | 型の名称 | バイト数 | 値の範囲 | 
| ---- | ---- | ---- | ---- |
| 型なし | void | - | - |
| 文字型 | char | 1 | 0 ~ 255 |
| 整数型 | int | 4 | -2147483648 ~ 2147483647 |
| 浮動小数点型 | float | 4 | ※符号部(正もしくは負)1ビット、指数部(×10^n のnの部分) 8ビット、仮数部(1.xxxxの部分) 23ビット |
| 浮動小数点型 | double | 8 | ※符号部(正もしくは負)1ビット、指数部(×10^n のnの部分) 11ビット、仮数部(1.xxxxの部分) 52ビット |

# 整数型についてもう少し調べてみる

(unsigned もしくは signed)intは4バイト、shortがつくと2バイト、long long がつくと8バイトなんですね！

| 型の名称 | バイト数 | 値の範囲 | 
| ---- | ---- | ---- |
| unsigned short int | 2 | 0 ~ 65535 |
| (signed) short int　| 2 | -32768 ~ 32767 |
| unsigned int | 4 | 0 ~ 4294967295 |
| (signed) int　| 4 | -2147483648 ~ 2147483647 |
| unsigned long int | 4 | 0 ~ 4294967295 |
| (signed) long int　| 4 | -2147483648 ~ 2147483647 |
| unsigned long long int | 8 | 0 ~ 18446744073709551615 |
| (signed) long long int　| 8 | -9223372036854775808 ~ 9223372036854775807 |


## 補足
・intとlong intで表せる値の範囲同じ！？と思って調べたのですが、
環境によって違いがあるので一概に同じではないようです。

・文字型(char)は、基本的に1バイトの範囲で表現できる文字コードに対応しており、ASCIIコードだけでなく、数値でも扱えるようです。
　例：
 ```
  char c1 = 'A' // 'A'のASCIIコード(65)が格納される
  char c2 = 65  // 'A'のASCIIコード(65)が格納される
```
レーザー3Dスキャナーの応用例

レーザー3Dスキャナーの応用は様々な業界で急速に拡大しており、多くの分野で不可欠なツールとなっています。精密で迅速、かつ非接触の測定技術として、レーザー3Dスキャナーはレーザービームを照射し、その反射光を捉えることで物体の三次元モデルを生成します。この技術は、詳細なキャプチャと複雑な表面の測定が求められるシーンにおいて、効率性と精度を大幅に向上させています。

製造業における応用
製造分野では、レーザー3Dスキャナーは品質検査やリバースエンジニアリングで広く使用されています。部品の3Dデータを迅速に取得し、CADモデルと比較することで、製品の寸法や形状が設計通りであることを確認します。レーザースキャンの高解像度により、微細なズレも正確に検出でき、製品品質の一貫性を確保します。また、リバースエンジニアリングでは、既存の部品をスキャンし、3Dモデルを生成して、設計の最適化や製造プロセスの迅速な反復を実現します。

建設・土木工学
建設業界では、レーザー3Dスキャナーは建築物の測量において非常に効率的なソリューションを提供しています。従来の測量方法は時間がかかり、誤差が大きくなりがちですが、レーザースキャン技術により、短時間で建物の詳細なデータを取得し、正確な3Dモデルを生成することができます。これらのデータは建築設計だけでなく、施工進捗の追跡や竣工検査にも活用されます。また、橋やトンネルなどの土木工事プロジェクトでは、構造の変形監視に使用され、安全性を確保します。
![a836c22a027b8333986be9024ae1a8c6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/d004b34d-18f9-ae66-a3e5-cbfa2dc3716a.png)

医療と医療機器
レーザー3Dスキャン技術は医療分野でも応用が広がっています。義肢のカスタム設計や、複雑な手術における人体部位の3Dモデル生成に使用され、卓越した精度と詳細なキャプチャ能力を提供します。さらに、医療機器の製造業者は、3Dスキャン技術を利用して製品の形状や寸法を検査し、厳しい医療基準に適合していることを確認できます。
![933d0394ad7f51a029dadcb3bb5289ea.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/d00cc4b0-c89e-b2a2-67e4-5c6fc914778a.png)

文化遺産の保護
文化遺産保護において、レーザー3Dスキャン技術は不可欠な役割を果たしています。古い建築物や彫刻などの文化財を精密にスキャンし、高精度の3Dモデルをデジタルアーカイブとして保存、または仮想展示に使用できます。これにより、文化財の長期保存に寄与し、修復作業にも重要なデータが提供されます。他の方法と比較して、レーザースキャンは文化財に接触せずに高精度のデータを取得でき、潜在的な損傷リスクを大幅に軽減します。

エンターテイメントと映像制作
レーザー3Dスキャン技術は、特に映画やゲーム制作において、エンターテイメント業界でも広く利用されています。人間の俳優や物体、さらにはシーン全体をスキャンすることで、チームは高度にリアルな3Dモデルを迅速に生成し、それをアニメーション、特殊効果、VR体験などに応用できます。レーザースキャンの高解像度と高速処理能力により、デジタルコンテンツ制作の重要なツールとなっています。

レーザー3Dスキャナーと構造光3Dスキャナーの比較
レーザー3Dスキャナーを語る際に、構造光3Dスキャナー（https://www.revopoint3d.jp/ ） にも触れざるを得ません。レーザースキャナーに比べ、構造光スキャナーは光の格子を投影し、物体表面での光の歪みをキャプチャして3Dデータを生成します。構造光スキャン技術は、精細な表面のディテールを取得するのに優れており、スキャン速度も速いため、中小型の物体に適しています。しかし、広範囲のスキャンや屋外での作業が必要な場合、レーザー3Dスキャナーは光の干渉に強く、長距離スキャンが可能であるため、より優れた性能を発揮します。
GROWIのスクリプトテンプレートで、編集時のプレビューに対応しました

[オープンソースの社内WikiであるGROWI](https://growi.org/ja/)にはプラグイン機能が用意されています。自社のデータを表示したり、表示をカスタマイズするのに利用できます。

先日、GROWIのプラグイン開発に利用できるテンプレートを作成したのですが、エディタ時のプレビューには対応していませんでした。

[goofmint/growi-plugin-script-template](https://github.com/goofmint/growi-plugin-script-template)

今回、ついにプレビューに対応できましたので、その手順を紹介します。

## プラグインの種類

GROWIのプラグインには、以下の3種類があります。

- script
- theme
- template

今回はスクリプト（script）を対象として紹介します。

## 動作について

実際の動作は以下のようになります（左側がエディタ、右側がプレビューです）。これは、 `a` タグに対して `Hello from plugin:` というラベルを追加するだけのプラグインです。

入力が変更されると、右側のプレビューも変わっているのが確認できるかと思います。

![001.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/94fdaa46-25eb-8e41-8a1c-216729c79feb.gif)

## client-entry.tsxの内容

client-entry.tsxにてプラグインの設定を行いますが、下記を追加します。 `customGeneratePreviewOptions` と、 `generatePreviewOptions` を設定するのがポイントです。

```typescript
const activate = (): void => {
  if (growiFacade == null || growiFacade.markdownRenderer == null) {
    return;
  }

  const { optionsGenerators } = growiFacade.markdownRenderer;

  // For page view
  optionsGenerators.customGenerateViewOptions = (...args) => {
    const options = optionsGenerators.generateViewOptions(...args);
    const { a } = options.components;
    options.components.a = helloGROWI(a); // Wrap the default component
    return options;
  };

  // For preview
  optionsGenerators.customGeneratePreviewOptions = (...args) => {
    const preview = optionsGenerators.generatePreviewOptions(...args);
    const { a } = preview.components;
    preview.components.a = helloGROWI(a); // Wrap the default component
    return preview;
  };
};
```

これでプレビュー時にも、プラグインの適用結果が確認できるようになります。すでにプラグインを開発している場合には、上記のコードを追加してください。

## 現状の課題

なお、これですべてのプラグインが対応できてはいません。ネットワーク操作を伴うような、async/awaitを使ったものや、カレンダー表示のようなDOM操作を伴うものには現状未対応です。

## まとめ

プラグインを使うと、リンクをOGP表示にしたり、カレンダーや地図の追加を行えるなど、GROWIがさらに便利になります。プラグインテンプレートを使って、手軽にプラグイン開発をはじめてください。

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://origin.growi.org/ja/)
【Microsoft Office Excel 】基礎知識

<h2>Excelとは</h2>
<p>表計算ソフトです。<br>
本来は表を作成して合計などの計算や、これを基にしたグラフの作成などに用いられるものとなります。<br>
主に、「表作成・グラフ作成・カレンダー作成・スケジュール管理(ガントチャートなど)など」で利用します。<br>
1ファイルを1ブックといい、1ブック内にあるのがシートと呼びます。<br>
テンプレート利用でオリジナルで作成せず、作成済のものを利用する方法もあります。<br>
Excelファイルを開くと上部に以下のリボンがあり、この各機能を理解して活用することで、事務作業やタスク管理や進捗管理、企画書などに有効です。</p>

<h3>リボン内の機能名</h3>
<p>リボンは、様々な機能のボタンやメニューを表示する画面です。<br>
各機能の詳細は次の投稿で記載いたします。</p>
<ol>
<li>ファイル</li>
<li>ホーム</li>
<li>挿入</li>
<li>ページレイアウト</li>
<li>数式</li>
<li>データ</li>
<li>開発　※設定で追加</li>
<li>校閲</li>
<li>表示</li>
<li>ヘルプ</li>
</ol>

![content1_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840057/6033066a-8d60-9059-5bb3-3923ba8fae11.png)

<h3>Excel利用で主な表</h3>
<p>上記の説明の投稿後に各表作成についても投稿していきたいと思います。<br>
各表作成でもやりたいことが検索しても出てこないってことありますよね？<br>
それがこの投稿によって解消されればと思っおります。</p>
<h5>表</h5>

![content1_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840057/11d126ed-caad-a35d-7b2c-5e494a726cf5.png)

<h5>タスク管理表</h5>

![content1_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840057/6631fa68-733d-bfe7-0ac4-90e58bf559a6.png)

<h5>進捗管理表</h5>

![content1_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840057/36a464ae-2865-3ba6-9e1a-3f60d92e689d.png)

<p>以上、Excelに関する最初の投稿でした。</p>

<p>他の投稿と合わせて不定期に投稿いたしますので、よろしくお願いいたします。<br>
Excelについて、聞きたいことなどございましたら、コメントください。<br>
記事の編集に関するコメントは、確認して判断して対応いたします。<br>
※使い慣れているHTMLで投稿しておりますので、こうした方が良いなどあるかと思いますが、
一旦は、書きやすいやり方でやらさせていただきます。</p>
実務でAWSのECRを作成する際に注意したこと

## はじめに
ECRを作成するにあたり、どんな設定が必要なのか？何に注意しないといけないのか？がわからなかったのでざっくりしらべたことをまとめる

## 調査する要件
AWSでECRを作成するにあたり必要な要件は以下を考える必要がある。

例：amazonlinux2-aarch64-3
- OSをどうするか？
- CPUアーキテクチャをどうするか？
- バージョンをどうするか？

## OSについて
Amazon Linux2やさまざまなOSを選択でき、他のLinuxディストリビューションやWindows Server等も選択可能である。

一方で、Amazon Linux2は安定性とOSのサポートが受けられる。

AWSが提供しているOS？だから優遇されているなと所感を感じたが、サポート期間を考慮しないといけない。

https://blog.serverworks.co.jp/al2-vs-al2023

### Amazon Linux2とLinux2023のそれぞれのサポート期間
サポート期間は以下となっている。
- AmzonLinux2：2025年6月30日
- AmazonLinux2023：2028年3月15日

## CPUアーキテクチャ
aarch64（ARM64）とamd64（x86-64）の違いを調査してみました。

aarch64
- ARM 64ビットアーキテクチャを指します。主にモバイルデバイスやサーバー向けの省電力プロセッサで使用

amd64
- x86-64アーキテクチャを指し、Intel/AMDの64ビットプロセッサで使用

## perplexityで質問してみました...
Q：aarch64とamd64ってどっちが世の中のトレンドなの？


A：2024年現在、aarch64(ARM64)とamd64(x86-64)の両アーキテクチャが重要な役割を果たしていますが、以下の理由から<b>aarch64</b>がより注目を集めているトレンドにあります。

### ポイント1：エネルギー効率えぐい！
- aarch64アーキテクチャは、同等の性能を低消費電力で実現できる点が大きな強みとなっている。
- データセンターやクラウドプロバイダーにとって、電力効率の向上は運用コスト削減につながるため、重要な要素となっている。

### ポイント2: モバイルデバイスでの優位性
- スマートフォンやタブレットなどのモバイルデバイスでは、ARMベースのプロセッサが長年にわたり主流となっています。この分野での経験と実績が、サーバーやデスクトップ市場への展開を後押ししています。

### ポイント3: 大手テクノロジー企業の採用
- Apple社のM1/M2チップ、Amazon Web ServicesのGravitonプロセッサ、Microsoftの独自ARMチップ開発など、大手テクノロジー企業がaarch64アーキテクチャを積極的に採用しています。これらの動きが業界全体のトレンドを牽引しています。

### ポイント4: パフォーマンスの向上
- 最新のaarch64プロセッサは、多くのワークロードにおいてamd64プロセッサと同等以上の性能を発揮するようになっています。特に、AIや機械学習の分野では、ARMベースのカスタムチップが注目を集めています。

### ポイント5: ソフトウェアエコシステムの成熟
- 以前は、aarch64向けのソフトウェア対応が課題でしたが、近年ではほとんどの主要ソフトウェアがaarch64をサポートするようになっています。これにより、aarch64プラットフォームの採用障壁が大きく低下しています。

トレンド的には、aarch64（ARM64)が推奨されているみたいです。


## おわりに
ECR作成時に色々考えることがあると思いますが、現場で相談してみましょう。ECRひとつとっても考えることは多いですね。次は参考文献をちゃんとはります笑

（バージョンについては後書きで修正していきます。）
Laravelでのルート、コントローラ、モデルの基本的な役割を、できるだけ簡単に説明

# Laravelでのルート、コントローラ、モデルの基本的な役割を、できるだけ簡単に説明します。

## 1. ルート (Route)
* **役割**: ルートは、ユーザーがブラウザで入力したURLを基に、どのコントローラやアクションを実行するかを決定する設定です。
* **仕組み**: ルートはURI（Uniform Resource Identifier）とHTTPメソッド（GET, POSTなど）に基づいて、適切なコントローラのメソッドにリクエストを渡します。
* **例**:
~~~PHP:php
Route::get('/login', [AuthController::class, 'showLoginForm']);
~~~
* この例では、`/login`というURLにアクセスしたときに、`AuthController`の`showLoginForm`メソッドが呼ばれます。
## 2. コントローラ (Controller)
* **役割**: コントローラは、ルートによって指定されたロジックを実行する部分です。ユーザーからのリクエストを処理し、ビューを返したり、データベースとのやり取りを行ったりします。
* **仕組み**: コントローラには複数のメソッドがあります。それぞれが特定の動作（例えばログイン処理やデータの表示）を担当します。
* **例**:
~~~PHP:php
class AuthController extends Controller
{
    public function showLoginForm()
    {
        return view('auth.login');
    }

    public function login(Request $request)
    {
        // ログイン処理のロジック
    }
}
~~~
* `showLoginForm`はログインページを表示し、`login`はユーザーのログイン処理を行います。
## 3. モデル (Model)
* **役割**: モデルは、データベースのテーブルを表現し、そのデータにアクセスするための窓口となる部分です。Laravelでは、主にEloquentというORM（Object-Relational Mapping）を使ってデータベース操作を行います。
* **仕組み**: モデルはテーブルと1対1で対応づけられ、テーブルのデータに対する処理（作成、取得、更新、削除など）を簡単に行えるようになっています。
* **例**:
~~~PHP:php
class User extends Model
{
    protected $fillable = ['name', 'email', 'password'];
}
~~~
* `User`モデルは、通常、`users`テーブルと対応します。`$fillable`は、配列内のプロパティを一括代入可能にする設定です。
### 組み合わせ
* ブラウザでユーザーが`/login`にアクセスすると、ルートが`AuthController`の`showLoginForm`メソッドを呼び出します。
* `showLoginForm`メソッドがログインページを表示します。
* その後、ユーザーがログインフォームを送信すると、`login`メソッドが呼び出され、`User`モデルを使ってデータベースのユーザー情報を確認し、認証を行うことができます。

このように、ルート、コントローラ、モデルが協力して、ユーザーの操作を管理し、アプリケーションの動作を実現しています。Breezeを使うと、これらの基本構造が自動生成されるため、初心者でもすぐに認証機能を実装し始めることができます。
FFmpeg の drawtext が Windows上で動かない時に見るメモ

# 前提条件
* OSはWindows(10)
* 公式から紹介されているWindows向けビルド(gyan)を使用
    * (fullを選んでいるがessentialでもdrawtextに必要なライブラリは入っている)
* filterにdrawtextを含めるとエラーもなくFFmpegが終了する
    * fontの指定/無指定、fontfileのファイル名のみorフルパス指定に無関係に落ちる
* 環境変数 Env:FC_CONFIG_DIR, Env:FONTCONFIG_PATH, Env:FONTCONFIG_FILEを指定するとFontconfigのWarningは出るが落ちる
    * Env:抜きではFontconfigのエラーも出ずに落ちる
    * https://blob.pureandapplied.com.au/solved-ffmpeg-fontconfig-woes-on-windows/ を参考

## 個人的環境
* ver4.4では自分で適当に書いた fonts/fonts.conf をbinディレクトリ内に入れておけば問題なかった
    * \<fontfonfig>タグ内に\<dir>タグでWindowsのfontディレクトリと、ユーザーごとのfontディレクトリを指定したのみ
        * \<dir>c:/Windows/Fonts\</dir>
        * \<dir>c:/Users/__USERNAME__/AppData/Local/Microsoft/Windows/Fonts\</dir>
    * 環境変数等は未指定で動作していた
* ver6.0以降に乗り換えようとした途端、同様の方法では上記の通りエラーもなく終了するようになった
    * 現在最新のver7.1も同様
* changelogにはそれらしい記載なし
    * https://github.com/FFmpeg/FFmpeg/blob/master/Changelog


# 解決方法
いろいろやってみた結果とりあえず最悪の解決方法として、
* カレントディレクトリ(ffmpeg.exeの位置、ではなく)にフォントファイルを配置
* fontfile=フォント名.ttc と指定(font=フォント名、ではなく)

にてdrawtext filterを指定しても落ちずに成功するようになった。環境変数は指定しなくていい。

これなら[この記事](http://fftest33.blog.fc2.com/blog-entry-45.html )のように  フォントファイルのフルパス指定なら通るのではないかと思うのだが通らなかった。
fontfile=C\\\\:Windows/Fonts/フォント名.ttc
(:はエスケープしてやる必要あり)

## 原因の推測
上記記事によるとfonts/fonts.confを自動的に見に行っていたようだが、4.4~6.0までの間で見に行かないようになったのだろうか？(ソース追え)
各種 3D ソフトや手法のカメラ座標軸の定義まとめ

何度調べても、ソフトや手法毎のカメラ座標軸の定義を忘れてしまうので備忘録として残しておきます。
間違っていたらコメントを頂けると嬉しいです。
取り上げているものは基本的に私に関係するものだけなので、一貫性には欠けるかもしれないです...
また、いつかここに戻ってきたときにもう一度確認できるよう（特に自分）、できる限りその証拠となる公式のソースを張り付けたり、根拠となる箇所を示したりしておきます。

z 軸が画像平面に向かって延びている場合を、（z 軸が）forward、画像平面とは反対方向に向かって延びている場合を backward としています。
今後、気になって調べたものがあったらその都度追加する予定です。

# 右手座標系
## z 軸が forward
### OpenSfM
> These online docs say that, from the POV of a camera (a.k.a. a Shot object):
The z-axis points forward
The y-axis points down
The x-axis points to the right

[Camera Coordinate System and Conventions](https://opensfm.readthedocs.io/en/latest/cam_coord_system.html, "https://opensfm.readthedocs.io/en/latest/cam_coord_system.html")

### COLMAP
> The local camera coordinate system of an image is defined in a way that the X axis points to the right, the Y axis to the bottom, and the Z axis to the front as seen from the image.

[Output Format](https://colmap.github.io/format.html, "Output Format")

COLMAP データを入力として用いている 3DGS もこの座標系を用いています。

## z 軸が backward
### NeRF系
- NeRF
- nerfstudio
> +X is right, +Y is up, and +Z is pointing back and away from the camera.

[Data conventions](https://docs.nerf.studio/quickstart/data_conventions.html, "Data conventions")

### Volume Rendering + SDF 系
- NeuS
- sdfstudio

ソースは見つけられなかったが、NeRF と同じ前処理が必要なことや、sdfstudio が nerfstudio の拡張機能の一つとされていることから、NeRF と同じ座標系を取り扱っていると考えられる。
[SDFStudio](https://docs.nerf.studio/extensions/sdfstudio.html, "SDFStudio")

# 最後に
ここで紹介したソフトウェアや手法以外のものについて、カメラ座標系の座標軸の向きが気になる場合があると思います。
その時は、ソフトウェアや手法の名前に加えて、```coordinate system``` や ```z-axis direction``` 、```camera convention``` などのキーワードと一緒に検索すると情報を見つけやすいです。

3 次元のデータを扱った手法を考えたり、カメラの真値データを使って 3 次元データを作成したりする場合は、このカメラ座標系の定義の間違い一つで結果がめちゃくちゃになることがあります。
問題の特定のためにも、カメラ座標系の定義をきちんと見直して、まずはデータが間違っていないかを確かめることが大事だと思っているので、このまとめが誰かの研究や開発の一助になれば幸いです。
GROWI TypeScript/JavaScript SDKの紹介（その3：ユーザーグループの操作）

[オープンソースの社内WikiであるGROWI](https://growi.org/)ではREST APIが公開されています。このAPIをより簡単に使えるよう、TypeScript/JavaScript SDKを開発しています。まだ途中ですが、徐々に機能追加していきます。

今回は権限管理などに利用する、ユーザーグループの操作方法を解説します。

## 注意点

こちらはコミュニティSDKになります。公式への問い合わせはご遠慮ください。

## ソースコード

GROWI TypeScript/JavaScript SDKのソースコードはGitHubにて公開しています。ライセンスはMITです。

[goofmint/growi-sdk-alpha](https://github.com/goofmint/growi-sdk-alpha)

## インストール

インストールはnpm/yarn経由で行います。

```bash
$ npm install @goofmint/growi-js
# または
$ yarn add @goofmint/growi-js
```

## 使い方

まずはSDKをインポートします。

```javascript
const { GROWI, UserGroup } = require('@goofmint/growi-js');
// または
import { GROWI, UserGroup } from '@goofmint/growi-js';
```

そして、初期化します。この時、GROWIのAPIトークンを指定します。

```javascript
const growi = new GROWI({ apiToken: 'your-api-token' });
```

この他、以下のパラメーターを用意しています。

- `url` : GROWIのURLを指定します。デフォルトは`http://localhost:3000`です。
- `path` : GROWIのページパスを指定します。デフォルトは `` です。サブディレクトリにインストールしている際に指定します。

## ユーザーグループの作成

ユーザーグループの作成時には、名前と説明を加えて `save` メソッドを実行します。

```javascript
const group = new UserGroup();
group.name = 'Test';
group.description = 'グループの説明';
const bol = await group.save();
```

## ユーザーグループの取得

1件ごとの取得の場合は、 `get` メソッドを実行します。 `id` が必須です。

```javascript
group.id = '999999';
await group.get();
group.name; // Test
```

## グループの一覧取得

グループの一覧取得は、 `groups` メソッドを実行します。

```javascript
const { groups } = await growi.groups();
```

## 子グループの取得

あるグループ以下にある子グループを取得する場合は、 `children` メソッドを実行します。

```javascript
const children = await group.children();
```

### さらに子グループを取得する

子グループの下にあるグループを取得する場合は、引数に `true` を指定します。その後、 `grandChildren` プロパティで取得できます。

```javascript
const children = await group.children(true);
const { grandChildren } = group;
```

## 親グループの取得

あるグループの親グループを取得する場合は、 `ancestors` メソッドを実行します。

```javascript
const ancestors = await group.ancestors();
```

## 子グループの作成

子グループを作成する際には、 `parent` プロパティに親グループを指定してください。

```javascript
const childGroup = new UserGroup;
childGroup.name = 'Child Group';
childGroup.description = '子グループの説明';
childGroup.parent = group;
await childGroup.save();
```

## グループの更新

グループの更新は、 `save` メソッドを実行します。

```javascript
group.name = 'Test2';
group.description = 'グループの説明2';
const bol = await group.save();
```

## グループの削除

グループの削除は、 `delete` メソッドを実行します。

```javascript
const bol = await group.delete();
```

## まとめ

GROWIは社内Wikiとして、社内システムとのデータ連係ニーズが出やすいでしょう。ぜひ、Node.js SDKを使って、GROWIをシステムから操作してください。

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://growi.org/)
OpenSSL コマンドで自己署名 SSL/TLS サーバ証明書を作成する (SAN 対応)

Web アプリケーションの開発時に、Web ブラウザから (`localhost` ではなく) 特定のドメイン名で Web サーバに対して HTTPS アクセスする必要が生じることがある。その場合、自己署名証明書を発行して設置するのが最も簡単である。

## 自己署名証明書を作成する
自己署名証明書は OpenSSL コマンドで簡単に作成できる。

以下は `example.com` とそのサブドメインのワイルドカード `*.example.com` の証明書を発行するコマンド例。

``` console
$ openssl req \
    -x509 \
    -newkey rsa:4096 \
    -noenc \
    -keyout example.com.key \
    -subj "/CN=example.com (self-signed)" \
    -addext "subjectAltName = DNS:example.com, DNS:*.example.com" \
    -days 365 \
    -out example.com.crt
```

秘密鍵ファイル (`.key`) と証明書ファイル (`.crt`) が作成されるので、これらを Web サーバに設置すればよい。

### オプションの解説
より詳しくは `man openssl-req` を参照。

- `-x509`
    - そもそも `openssl req` は証明書署名リクエスト (CSR) を作成するコマンドだが、`-x509` オプションを使用した場合は CSR ではなく自己署名した証明書が作成される
- `-newkey rsa:4096`
    - 秘密鍵を指定するのではなく新規作成する
    - 新規作成する秘密鍵は 4096 ビットの RSA 鍵とする
- `-noenc`
    - 新規作成する秘密鍵ファイルは暗号化しない
- `-keyout example.com.key`
    - 出力する秘密鍵ファイル名
- `-subj "/CN=example.com (self-signed)"`
    - 証明書の CN (Common Name) を指定する
    - 昔は CN にドメイン名を指定していたが、最近の Web ブラウザは SAN が指定されている場合は CN を見ないらしく「指定する文字列はなんでもいいのでは？」ということでこの例では `(self-signed)` などと入れてみている
- `-addext "subjectAltName = DNS:example.com, DNS:*.example.com"`
    - SAN (Subject Alternative Name) を指定する
    - このオプションは OpenSSL 1.1.1 以降で使用可能で、それ以前の場合は別の方法で SAN を指定する必要がある
- `-days 365`
    - 証明書の有効期限は 365 日とする
- `-out example.com.crt`
    - 出力する証明書ファイル名

## 自己署名証明書を信頼する (macOS)
自己署名証明書は Web ブラウザから信頼されていないので当然のようにエラーが出る。何らかの方法で Web ブラウザまたは OS に対して「この証明書は信頼してもよい」と設定する必要がある。

macOS の場合、証明書をキーチェーンに追加した上で「SSL」「X.509 基本ポリシー」を信頼するように設定すれば Web ブラウザから見たときにエラーが出なくなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/36599e6d-50fb-9c8e-3aa6-4b7d718dc29d.png)
golandにて、goのsdkをダウンロードする方法

# 概要

golandにて、goのsdkを手軽にダウンロードする方法を記した。

ローカルのgoのversionをサクッと上げたいなぁと思って調べたら、思いの外情報がまとまっておらず、golandではとりあえず一瞬でできたのでメモとして残す。

# 結論

https://pleiades.io/help/go/configuring-goroot-and-gopath.html#download-go-sdk
これ。

```
1. 設定を開き Go | GOROOT に移動します。

2. SDK の追加ボタン（the Add SDK icon）をクリックして、ダウンロードを選択します。

3. バージョンリストから SDK のバージョンを選択します。

4. ロケーションフィールドで、SDK のパスを指定します。ファイルブラウザーを使用するには、参照アイコン the Browse icon をクリックします。

5. 「OK」をクリックして「Go SDK のダウンロード」ダイアログを閉じます。

GOROOT ページで適用または OK をクリックすると、GoLand は GoSDK のダウンロードと解凍を開始します。
```

globalには変更されないけど、goで開発するときはgolandでやるから正味困らない。
コードはほとんど生成AIに書いてもらう！スプレッドシートへの書き込みのところをSteinで実施

生成AIそこそこ使っていたり コード書いたり ClaudeのartifactとかV0とか触っている人！
どんどん作って 解っていこう







## 作ってみよう

お題
スーパーマーケットとか小売の人って競合店の価格調査するらしいやん
今時紙をもって 店内で書きかきなんて照れるやん
スマホにポチポチ 数字だけ入力すればいいやつ作りたい
ローコードツールとかノーコードツールだと
入力欄の大きさとかチョットしたところが調整できなかったりするし
作ればいい （コードはほとんど生成AIに書いてもらう！）


## １ どんなのを作りたいのかをhttps://claude.ai/chat/f とか https://v0.dev/ とかに話す 

・アプリの仕組み Googleスプレッドシートに商品や価格データを保存したいんでStainってのをつかって
・商品名や価格が見やすく 入力しやすい様にして
・★codepenを使っても出来る様に HTMLとCSSとJSファイルで作って
・相手は24時間365日不休で働ける化物なので 遠慮なく！
・書いたコードに どんな処理をしているのかとかのコメントを初心者でもわかるようにつけて


### 重要なのはどんな感じにつくりたいか こだわりはどこか 
どんなプログラム言語で作りたい どんな構成にしたい それすらも質問しよう
あと  生成AIの提案に時々他にいい方法は無いかを必ず問う事

:::note warn
ClaudeとかV0とか使うとだいたい Ractとかいう初心者にはわけわからんプログラム言語で書く 頑張ればなんとかなるけど 解らない人は上記「HTMLとCSSとJSファイルで作って」のように指示をして codepenとかにコピペで何とかなるようにしましょ もしくは 勉強する
:::

## 2  不思議な力でいろいろやってくれて プレビューしてくれる
 最初っからこれでいい！とかならない まだまだできるだろうと生成AIにどん欲に指示を出す

・価格入力欄とその文字はもっと大きく
・スマホ対応でレスポンシブル？対応して
・保存できたのかわからんから 保存出来たら 「正しく保存できました」とかポップアップで表示して
・あと Stainのどこをどうすればいいのかも 超初心者にわかるように手順教えて
・コードのなかでAPIキーとかURLとか変えた方が良い所は★ココ変えろ！とわかりやすく指示する事  コード内にもコメントして 
**※あせらず指示は一個ずつ！プレビュー見ながら少しずつ理想に近づける**

:::note warn
コードを生成AIに書いてもらってコピペしても動かないってなる躓きポイント！
APIキーとかいうやつ URLとかは自分の環境によって変えなければいけないのに コピペしていたら気づかなかったり忘れる    スプレッドシートの名前とか列名やシート名とかも気をつけたい 賢くなりたい！
:::


## 3  とりあえず形にしてみるまで何とかする

まずは形だけつくる できたら機能を付け足していく こうしたいんだけど言語化できない   ならスクショ取って投げてこうしたいんだけどどう伝えたらわかりやすい？？ と会話する  なんとなくこんな感じのを作りたいをイメージして 伝えて  帰ってきたレスから もっとこうしようと考える

## ４  世界へ解き放つ

Claudeとかでプレビューつくってもパソコンの中でしか動かなかったりするし スプレッドシートとの連携とかさせるために codepenやGithubやnetlifyにあげて 共有できるようにして配布して 使ってもらって感想を聞く

https://prog-8.com/docs/github-pages

https://www.tsone.co.jp/tech-blog/archives/1524


プログラムとかの知識が増えたら生成AIに指示も伝えやすくなるんだよね

https://prog-8.com/

https://ai-island-media.com/2023/08/28/chatgpt-prompt-20/

https://miralab.co.jp/media/code_generation_chatgpt_tips/



****

アプリを作っていてデータを扱うようになるとスプレッドシート使ったりAPI使ったり webhookとか使えたらできる事の幅が広がる
ノーコードツール ローコードツールも便利で速い けど 作った方が早いし自分に合った細かい調整が出来た良いなと思います


あと 競合店の価格調査そのものが非効率なのかもしれない、、、、
[Program] 再入、再帰、再使用、再配置

# 一覧
|プログラム特性||
|:--|:--|
|再入可能|複数のプログラムから同時に呼び出されても、正しい結果を返すことができる|
|再帰可能|自分自身を呼び出すことができる<br>- 再入可能である|
|再使用可能|一度実行したプログラムをロードしなくても、正しい結果を返すことができる<br>- プログラムの最初または最後で変数を初期化している|
|再配置可能|主記憶上のどこにプログラムを配置しても、実行できる|





# 参考リンク
- [R4S6_再入可能](https://www.fe-siken.com/kakomon/27_haru/q7.html)
- [R3A6_再使用可能](https://www.ap-siken.com/kakomon/03_aki/q6.html)
- [H16S41_再入可能](https://www.ap-siken.com/kakomon/16_haru/q41.html)
Google ClassroomのcourseId等一覧を取得する（その2）

以前、自分の関係しているGoogle Classroomの一覧をスプレッドシートに書き出すスクリプトを書いたのですが、表示する情報はクラス名とcourseIdのみでした。  
（過去記事[【GAS】Google ClassroomのcourseId等一覧を取得する](https://qiita.com/freshcl/items/ad79fe433e776f5517dd)）   
  
今回、ついでに他の情報も取得・表示するようにしてみました。下のスクリプトで、変更1と変更2と書いているところ、2行の変更です。
ownerId、enrollmentCode（クラスコード）、teacherGrompEmail、courseGroupEmail、courseState　も取得できるようにしました。
teacherGrompEmail（教師のグループID）やcourseGroupEmail（クラスのグループID）は、他の方法でも調べられますが、知っているといろいろ便利かもしれない。

```JavaScript:classroom_s.gs
//listMyCourses
'use strict';
function listMyCourses() {
  const sheetname = 'myclasslist';  //リストを書き出すシート
  const myfile = SpreadsheetApp.getActiveSpreadsheet();  //このスプレッドシート
  const newSheet = myfile.insertSheet(); //シートの作成
  //シート名がnameと同じシートがあれば削除
  const isSheetExist = myfile.getSheetByName(sheetname);
  if (isSheetExist) {
    myfile.deleteSheet(isSheetExist);
  }
  newSheet.setName(sheetname); //新しいシートの名前をsheetnameにする
  newSheet.clear();
//変更1
  newSheet.appendRow(["name", "courseId", "ownerId", "enrollmentCode（クラスコード）", "teacherGrompEmail", "courseGroupEmail", "courseState"]);
  const response = Classroom.Courses.list();
  const courses = response.courses;
  if (!courses || courses.length === 0) {
    console.log('No courses found.');
    return;
  } else {
    for (let i = 0; i < courses.length; i++){
      Logger.log('%s(%s)',courses[i].name,courses[i].id);
//変更2
      newSheet.appendRow([courses[i].name,courses[i].id,courses[i].ownerId,courses[i].enrollmentCode,courses[i]
.teacherGroupEmail,courses[i].courseGroupEmail,courses[i].courseState])
    }
    newSheet.activate(); //作成したシートを表示
    Browser.msgBox(sheetname+"作成"); //メッセージを表示
  }
}
```


【GAS】Google ClassroomのcourseId等一覧を取得する
https://qiita.com/freshcl/items/ad79fe433e776f5517dd
EUWメニュー追加

自分へのメモも兼ねて、Qita記事を投稿します。
今回は、カスタムのメニューについてになります。
情報はいくつかあったのですが、情報の整理と選定に時間が取られ、今回の実現に一番合ってそうな方法まで落とし込むのに時間がかかりました。


# 今回やりたかった事

作成したエディタユーティリティウィジェットをメニューからも呼び出せるようにする事です。

1. 独自のメニューを追加する
1. 自作したエディタユーティリティウィジェットを呼び出す
1. エディタユーティリティウィジェット

:::note alert
C++からメニュー追加する事も可能ですが、エディタで後から追加したエディタユーティリティウィジェットを呼び出す事ができないという問題がありました。
:::


# 検証環境

UnrealEngine5.3.2

# 作業手順

1. メニュー登録用ブループリントを作成
1. Run走らせ用のブループリントを作成
1. 実行したいEUWの作成
1. Configの登録

基本的には、こちらの[キンアジさんの記事](https://kinnaji.com/2020/04/08/toolmenus/)で説明されている事と手順は同じです。
ですので、細かいノードの説明はしません。
最後に、参考したURLを貼ってあります。
複数のサブメニューの登録の仕方が読み取れなかったので、そこは今回、検証したところです。

# メニュー登録用ブループリントの作成

メニューに独自のメニューを登録処理を行うブループリントになります。
最終的には、Startupも登録して、エディタ起動時に呼ぶようにしておきます。
エディタユーティリティブループリントでEditor Utility Objectで作成します。
**※写真の場合は、『ExecuteAddMainMenuCustomLabel』と『ExecuteAddMainMenuCustom_B_Label』二つのメニューを登録しています。**

![メニュー登録ブループリントの全体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/698e5fdc-7d5b-09f1-c04a-b61a2c3b561f.png)

:::note info
『EUB_AddMainMenuCustom』『EUB_AddMainMenu_B』と『EUW_AddMainCustom』『EUW_AddMainCustom_B』がありますが、呼び出しの検証で識別する為、ブループリントが2パターン用意してあります。
『<font color="red">**EUB_AddMainMenu_B**</font>』は『<font color="red">**EUB_AddMainMenuCustom**</font>』を複製したもので、『<font color="#1e90ff">**EUW_AddMainCustom_B**</font>』は、『<font color="#1e90ff">**EUW_AddMainCustom**</font>』を複製したものです。
:::


# Wigetトリガー用のブループリントを作成

メニューからコールバックで『Widget』を起動する処理を行います。
直接、エディタユーティリティウィジェットを呼び出すのが無理そうだったので、エディタユーティリティブループリントがキックします。
エディタユーティリティブループリントでEditor Utility Objectで作成します。

:::note info
『EditorUtilityToolMenuEntry』を親クラスした方法と2種類ある
:::


![Wigetトリガー用のブループリントの全体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/a3d75dd2-0471-a8bd-acda-f208268e3730.png)

ちなみに、EUWでもEUBと同様に、Run(イベント)をオーバーライドできる為、『メニュー登録用ブループリント』から『EUWのRunを実行』する事はできます。


# 実行したいEUWの作成

実際に、メニューから立ち上げたいWidgetになります。
エディタユーティリティウィジェットを作成します。
呼び出しの確認テストなので、ボタンを一つ置いて、PrintStringを呼び出すだけです。

**デザイナー**

![エディタユーティリティウィジェット_デザイナー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/c1235699-41a1-5489-26d5-50491c32b6c3.png)

**グラフ**

![エディタユーティリティウィジェット_グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/3668dad5-ca14-5779-e621-5a3728bf80d1.png)



# Configの登録

『メニュー登録用ブループリントの作成』をStartupメニューに登録する事で、エディタ起動時にメニューを登録するようにしておきます。




```
[/Script/Blutility.EditorUtilitySubsystem]
+StartupObjects=/Game/MainMenuCustom/AddMainMenuCustom_ResisterMenus.AddMainMenuCustom_ResisterMenus

```


# おまけ C++でやる

こちらは、C++で実現している方が居たので、参考情報として載せておきます。
今回の実現とは、やり方がマッチしなかったので、使用しませんでした。

[UnrealC++でレベルエディタに独自メニューを追加する](https://qiita.com/Naotsun/items/7954d18304d2d09f0bf9)

[独自のタブをエディタのメニューから呼び出す方法](https://qiita.com/Naotsun/items/22b27936112addd4d4e4
)
【Qiita Web API②】Qiita APIを使ったアプリを開発！データ取得から可視化まで

# はじめに
[前回](https://qiita.com/churaumi0097/items/c5182625a42191667938)に引き続き、今回もQiita APIに関する内容です。
Qiita APIを活用して検索機能を使用したデータの収集、グラフによる可視化をできるアプリを開発したので、本記事ではそのアプリを紹介します。

# アプリの開発環境
コードエディタ：VSCode
フレームワーク：Streamlit
使用言語：Python

# Streamlitとは
Streamlitはデータアプリケーションや機械学習のモデルを簡単に作成し、WebブラウザでデプロイするためのオープンソースのPythonライブラリです。
以下がStreamlitの特徴です。

・Pythonコードを書くだけでアプリ開発を作れる
・リアルタイムでの更新が可能
・MatplotlibやSeabornなどによるグラフやチャートの作成
・テキストや数式をマークダウン形式で記述できる
・アプリを簡単にデプロイできる

# アプリの概要
今回開発したアプリには、次のような機能があります。

・Qiita記事の検索機能
・検索結果のデータが収集できる
・検索結果を可視化できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816986/3f623e93-7111-f032-725f-60fb58be3542.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816986/58dbf125-702b-751d-9289-b4ff5da7d8ad.png)


アプリのURL
https://qiitasearchapl-z2ypv35alzh2q2hkcz5ogn.streamlit.app


# おわりに
本記事では、Streamlitを活用してQiita APIを利用したアプリを紹介しました。皆さんも興味があれば、ぜひQiita APIを使ったアプリの開発に挑戦してみてください。
pythonの日付操作をまとめてみた

## 問題
プログラミングの勉強を始めて、９ヶ月程度経過した。日付や時間に関する操作が曖昧のままここまできてしまったのでまとめていきたい

## 基本
### モジュール
日付や時間を操作する際は、pythonの標準モジュールであるdatetimeモジュールを使用し、コードを書く際は以下を記述する
```python
from datetime import date
from datetime import datetime
```

### データの型
日付や時刻を取得すると一見、文字列型のように見えるが、datetimeモジュールの中のdate型やtime型、datetime型などのクラスのインスタンスになる。
以下を参照。（※以下は日付のみを取得しているため、datetime.date型となっている）
```python
from datetime import date
date = date.today()
print(date)
print(type(date))

#結果
#2024-10-12
#<class 'datetime.date'>
```


## 日付
### 今日の日付取得
```python
from datetime import date,datetime,time
date = date.today()
print(date)

#結果
#2024-10-12
```
### datetime型に変更
```python
from datetime import date,datetime,time
date = date(2024,10,12)
print(date)
print(type(date))

#結果
#2024-10-12
#<class 'datetime.date'>
```

## 時間
### 現在の時刻取得
```python
from datetime import date,datetime,time
time = datetime.now().time()
print(time)
print(type(time))

#結果
#14:39:16.030922
#<class 'datetime.time'>
```

### 現在の時刻取得（秒、マイクロ抜き）
```python
from datetime import date,datetime,time
time = datetime.now().time()
formatted_time = time.strftime('%H:%M')
print(formatted_time)
print(type(formatted_time))

#結果
#14:43
#<class 'str'>
```
::: note warn
strftimeメソッドを使用すると任意の形に変更できるが、型が文字列型になるので注意！
:::

## 日付、時刻の計算

:::note 
日付や時刻の計算をするとtimedelta型で結果が返ってくる.
:::
```python
day1 = date(2024,10,12)
day2 = date(2024,10,11)
date = day1 - day2
print(date)
print(type(date))

#結果
#1 day, 0:00:00
#<class 'datetime.timedelta'>
```

## 学んだこと
・datetime型を意識してデータ操作を行うこと
・datetime同士で計算をするとtimedelta型で返ってくる。
・初心者の方の手助けになれば幸いです
初心者が覚えておきたいコマンド一覧

今回は初心者が覚えておきたいコマンド一覧を記事にしたいと思います。

1. ディレクトリ（フォルダ）操作のコマンド
現在のディレクトリを表示
```bash
pwd
```
pwd（print working directory）は、現在自分がどのディレクトリにいるかを表示します。ファイル操作を行う前に、どの場所にいるかを確認するために便利です。
ディレクトリの内容を表示
```bash
ls  # Mac/Linux
dir # Windows
```

ls（list）は、現在のディレクトリ内のファイルやフォルダの一覧を表示します。
dir は、Windowsで同じことを行うコマンドです。
ディレクトリの移動
```bash
cd [フォルダ名]
```

cd（change directory）は、指定したディレクトリに移動します。例えば、cd Documents と入力すると Documents フォルダに移動できます。
一つ上のディレクトリに移動
```bash
cd ..
cd .. は、一つ上の階層に戻るコマンドです。現在のフォルダの親フォルダに移動したいときに使います。
```

2. ファイル操作のコマンド
ファイルやディレクトリを作成
```bash
touch [ファイル名]  # ファイルを作成
mkdir [フォルダ名]  # フォルダを作成
```
touch は、指定した名前の空のファイルを作成します。例えば、touch index.html で index.html というファイルを作成します。
mkdir（make directory）は、新しいディレクトリ（フォルダ）を作成します。mkdir myfolder で myfolder フォルダを作成します。

ファイルやディレクトリを削除
```bash
rm [ファイル名]      # ファイルを削除
rm -r [フォルダ名]    # フォルダとその中身を再帰的に削除
rmdir [フォルダ名]    # 空のフォルダを削除
```
rm（remove）はファイルを削除します。rm file.txt で file.txt を削除できます。
rm -r を使うと、フォルダとその中身を削除できます。
rmdir は空のディレクトリのみを削除する場合に使います。

ファイルのコピーや移動
```bash
cp [コピー元] [コピー先]  # ファイルをコピー
mv [移動元] [移動先]      # ファイルやフォルダを移動
```
cp（copy）はファイルをコピーします。cp file.txt backup.txt で file.txt を backup.txt としてコピーします。
mv（move）は、ファイルやディレクトリを移動または名前変更する際に使います。mv oldname.txt newname.txt でファイルの名前を変更したり、mv file.txt ~/Documents で別のフォルダに移動したりできます。


3. システム情報の確認コマンド
実行中のプロセスを表示
```bash
ps  # Mac/Linux
tasklist  # Windows
```
ps（process status）は、現在実行中のプロセス一覧を表示します。
tasklist はWindowsで同様に現在実行中のプログラムを確認するコマンドです。

ディスクの空き容量を確認
```bash
df -h  # Mac/Linux
```
df -h は、ディスクの使用状況と空き容量を表示します。-h オプションで、わかりやすい単位（KB、MB、GB）で表示されます。

4. 開発ツール関連のコマンド
Git（バージョン管理）関連コマンド
リポジトリの初期化

```bash
git init
```

新しいGitリポジトリを作成します。
ステータスの確認

```bash
git status
```
現在の変更内容や、追跡されていないファイルの状態を確認します。
変更をステージング
```bash
git add [ファイル名]
```
変更されたファイルをステージングエリアに追加します。git add . とすると、全ての変更を追加できます。

コミット
```bash
git commit -m "コミットメッセージ"
```
ステージングされた変更をローカルリポジトリに保存します。

リモートリポジトリにプッシュ
```bash
git push origin main
```
変更をリモートリポジトリ（例: GitHub）に反映させます。
Node.js関連コマンド

プロジェクトの初期化
```bash
npm init
```
package.json を作成し、Node.jsプロジェクトを初期化します。
依存関係のインストール
```bash
npm install
```
package.json に定義された依存パッケージをインストールします。

サーバーを起動
```bash
npm start
```
package.json で定義された start スクリプトを実行し、サーバーを起動します。


5. 便利なユーティリティコマンド
ファイル内容の表示
```bash
cat [ファイル名]
```
cat（concatenate）は、ファイルの内容を表示します。例えば、cat README.md で README.md ファイルの内容を表示できます。

テキストの検索
```bash
grep [検索する文字列] [ファイル名]
```
grep（global regular expression print）は、指定した文字列をファイル内で検索します。grep "error" log.txt で、log.txt 内の「error」という文字列を含む行を表示します。

ファイルの行数や文字数をカウント
```bash
wc [ファイル名]
```
wc（word count）は、ファイルの行数、単語数、文字数をカウントします。wc -l file.txt とすれば、行数だけをカウントします。


6. ヘルプを表示
コマンドの使い方を確認
```bash
man [コマンド名]  # Mac/Linux
[コマンド名] /?   # Windows
```
man（manual）は、コマンドの詳細なマニュアルを表示します。例えば、man ls と入力すると ls コマンドの使い方を確認できます。

今回はコマンドについて記事にしました。
【Ruby】sortメソッドとUFO演算子（<=>）を完全にマスターしたい

どうもこんにちは。

今回は、`sort`メソッドとUFO演算子（`<=>`）について完璧に理解しようと思ったので、備忘録として残しておきます。

# 使用例

```rb
ary = [2, 4, 8, 1, 16]
puts ary.sort                      #=> [1, 2, 4, 8, 16]
puts ary.sort{ |i,j| i <=> j }     #=> [1, 2, 4, 8, 16]
puts ary.sort{ |i,j| -i <=> -j }   #=> [16, 8, 4, 2, 1]

ary2 = [-1, 8, -7, 2, -14]
puts ary2.sort { |i,j| i.abs <=> j.abs }   #=> [-1, 2, -7, 8, -14]
```

`sort`メソッドはそのまま使用すれば、要素を昇順に並び替えてくれます。
また、ブロックを使用して条件を与えて要素を並び替えることもできます。
（単純な昇順だけでなく、絶対値の昇順/降順などに並び替えることもできます。）

# UFO演算子 (`<=>`) の役割

UFO演算子 (`<=>`) は、2つのオブジェクトを比較し、以下の3つの値のいずれかを返します：

| 戻り値 | ケース |
| --- | --- |
| -1 | 左側のオブジェクトが右側より小さい場合 |
| 0 | 左側のオブジェクトと右側のオブジェクトが等しい場合 |
| 1 | 左側のオブジェクトが右側より大きい場合 |

これらの値を基に、`sort`メソッドは配列の要素を並び替えます。

# sort メソッドの動作原理

`sort`メソッドは、配列の要素同士をペアで比較し、UFO演算子の結果に基づいて順序を決定します。以下のステップで動作します：

1. 配列の要素を2つずつ選び、比較します
2. 結果に基づく並び替え
    1. -1 が返された場合：**左側の要素が右側より小さいため、左側を前にします**
    2. 0 が返された場合：**要素の順序は変更しません**
    3. 1 が返された場合：**左側の要素が右側より大きいため、左側を後ろにします**
3. 全体のソート

全てのペア比較が完了するまで、このプロセスを繰り返し、最終的に配列全体がソートされます。

自分のイメージだと、要素ごとにリーグ戦をやって並び替える感じですかね？

以下の例題を載せました。

# 例題

```rb:例1
ary1 = [6,2]
puts ary1.sort{ |i,j| i <=> j } # 6<=>2を実行すると`1`が返ってくるため、順番を2,6とする。
#=> [2,6]
```

```rb:例2
ary2 = [6,2,3]
puts ary2.sort{ |i,j| i <=> j }
# 6<=>2を実行すると`1`が返ってくるため、順番を2,6,3とする。
# 6<=>3を実行すると`1`が返ってくるため、順番を2,3,6とする。
# 2<=>3を実行すると`-1`が返ってくるため、順番を2,3,6とする。
#=> [2,3,6]
```

```rb:例3
ary3 = [6,2,3,1]
puts ary3.sort{ |i,j| i <=> j }
# 6<=>2を実行すると`1`が返ってくるため、順番を2,6,3,1とする。
# 6<=>3を実行すると`1`が返ってくるため、順番を2,3,6,1とする。
# 6<=>1を実行すると`1`が返ってくるため、順番を2,3,1,6とする。
# 2<=>3を実行すると`-1`が返ってくるため、順番を2,3,1,6とする。
# 3<=>1を実行すると`1`が返ってくるため、順番を2,1,3,6とする。
# 2<=>1を実行すると`1`が返ってくるため、順番を1,2,3,6とする。
#=> [1,2,3,6]
```

以上
WEB三層アーキテクチャでのクラウド活用

# まえがき
おつかれさまです。Mochiです。
今回は最近知識としてインプットしたばかりの『WEB三層アーキテクチャ』について記録できればと思います。
# WEB三層アーキテクチャとは？
WEB三層アーキテクチャとは、クライアントからのリクエストを処理するサーバにおいて構成される構造を指します。
プレゼンテーション層・アプリケーション層・データ層の3つから成り立っています。

![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726585/5d86b2f9-5af6-3666-aa11-ce240c16196b.jpeg)
#### プレゼンテーション層
プレゼンテーション層では、クライアントからのリクエストに対してサーバとのやりとりをコントロールするだけでなく、クライアントへの画面表示を行います。
ユーザーが直接触れる部分となります。
役割としては、ユーザーに最も近く、視覚的な表示を提供します。また、ユーザーからの入力を受け取ります。
#### アプリケーション層
アプリケーション層では、クライアントからの実際のリクエストを処理します。
そしてその結果をプレゼンテーション層に返します。
ファンクション層とも呼ばれるようです。
役割としては、データの処理や検証、DB等との連携を行います。
#### データ層
データ層は、アプリケーションが使用するデータを管理し、永続化する部分となっています。この層はデータベースだけでは無く、ファイルシステムやオブジェクトストレージなどから構成される層です。主な役割としては、データの保存や取得、更新や削除を行います。
# クラウドベースでのWEB3層アーキテクチャ運用
WEB3層アーキテクチャはオンプレミスでもクラウドでもインフラを構築することが可能ですが、私はクラウド環境でのデプロイを推奨します。
基本的な話になりますが、WEB3層アーキテクチャ以前にハードウェアの保守やメンテナンスの必要がなくなります。
また、クラウドでの運用を選択すればマルチリージョンでの災害復旧の観点から、可用性の向上も見込めます。
# AWSを使用したWEB3層アーキテクチャの運用
![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726585/acbde49b-df54-79f7-2337-448371e94b01.jpeg)

クラウドでの運用となった場合、シェア率の高さから選択肢として入ってくるのはAWSなのかなと思います。
AWSを使用して環境を構築する場合、プレゼンテーション層にCroudfront・EC2を使用します。静的リクエストにはS3でも対応できるかと思います。
また、アプリケーション層にはEC2を使用できますが、状況に応じてLambdaやECS等も選択肢に入ってくるのかなと思います。また、複数のEC2インスタンスを使用して夜間帯等のトラフィックが集中するタイミングでオートスケールさせる設計を組むことも重要です。ロードバランサを使用した負荷分散もこのアーキテクチャで実現しています。
データ層ではRDSを使用できます。AWSが自動的にバックアップやスナップショットを作成し、データベースの管理が容易になります。
# Google Cloudの場合
![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726585/396f3d04-8afa-2cb6-0882-f17c1dec0485.jpeg)

Google Cloudの特徴は、VPCがリージョンの外側に配置されていることです。このメリットはマルチリージョンでのシステム運用をしていても単一のVPCでそれを行うことができます。添付の設計図通りにアーキテクチャを組む場合、プレゼンテーション層にCloud CDNやCompute Engineを設置します。アプリケーション層にはCompute Engineを複数使用して冗長化を行っています。先程のAWSでのアプローチと同様にオートスケーラーを使用しています。また、アプリケーションの負荷分散を目的にロードバランサを設置しています。これによりトラフィックの増加にも対応でき、複数のCompute Engineにトラフィックを分散することができます。
データ層ではCloud SQLを使用してデータのバックアップやレプリカの作成を実現できます。
# あとがき
AWSやGoogle Cloudを使用したクラウドベースでのWEB3層構造について説明しました。従来ではオンプレミス環境でのレガシーな運用が主流だったと思います。ですが近年ではオンプレからクラウドへのマイグレーションやハイブリッド運用の需要が徐々に増えてきています。WEB3層構造についてガッツリ書くつもりが、途中から結局クラウドの話になってしまいました、、インフラエンジニアにとってどんなアーキテクチャを組む時もクラウドは切っても切り離せないものになってきているなと感じました。
### 引用元
https://www.softbank.jp/biz/blog/cloud-technology/articles/202206/web-3-tier-architecture/

https://ryonotes.com/web-3-layer-architecture/
1次元配列の足し算をして、平均を求める

```
public class Exercise {
    public void run(){
        int array[] = new int[] {98, 12, 9, 102, 88};
        int i = 0;   // インデックスを初期化
        int sum = 0; // 合計を保存するための変数

        // whileを使って合計を計算
        while (i <= array.length - 1) {
            sum = sum + array[i]; // 合計に現在のiの要素を足し算する
            i++;                  // iに1を足す
        }
        System.out.println(sum / array.length) // 平均を求める
    }
}
```

結果
```
61
```

配列の要素をwhileで繰り返し計算する時には、
int i =0; でiを初期化し、int array = 0;で合計を保存するための箱を作っておく。

iがarray.length（配列の要素数） - 1と等しいか小さい数の場合、
sum += array[i];でiに現在のiの値を足し、
i++でiに1ずつ足していく。
<br>

{98, 12, 9, 102, 88}の
インデックス番号は0, 1, 2, 3, 4
array.lengthは5

// 初期値はi = 0
初期値0にインデックス番号0の98を足した数がsumの値となる（sum = 98）
<br>

i = 0はarray.lengthの5よりも小さいのでiに1が足される（i(0) + 1）
// i = 1
sum = 98にインデックス番号1の12を足した数がsumの値となる（sum = 110）

i = 1はarray.lengthの5よりも小さいのでiに1が足される（i(1) + 1）
// i = 2
sum = 110にインデックス番号2の9を足した数がsumの値となる（sum = 119）

i = 2はarray.lengthの5よりも小さいのでiに1が足される（i(2) + 1）
// i = 3
sum = 119にインデックス番号3の102を足した数がsumの値となる（sum = 221）

i = 3はarray.lengthの5よりも小さいのでiに1が足される（i(3) + 1）
// i = 4
sum = 221にインデックス番号4の88を足した数がsumの値となる（sum = 309）
<br>
仮にi = 4に1を足すとi = 5となり
i <= array.length - 1の条件を満たさなくなるのでwhileのループを抜けて繰り返し処理は実行されない。
<br>
平均を求めるためには
sum = 309　÷　array.length(5)を計算すればいいので
System.out.println(sum / array.length) を実行した結果61となる。
（intのため整数部分しか表示されない）
7日間でハッキングを始める本 - 6日目 -

# 本記事の目的
書籍「7日間でハッキングを始める本」の
Day6に出てきたコマンド・用語などの整理

## Day5まで

- [Day5](https://qiita.com/akebono-san/items/7103ba63a983103da7c3)

## コマンド・ツール

### nmap
|オプション|役割|
|:--|:--|
|-p <port>|指定したポートのみスキャン対象とする|
|-Pn|pingによるホスト発見プロセスを省略する|
|-sV|ポートとそのポートのサービス・バージョンを特定する|
|-A|OS、バージョン、スクリプトスキャンなどをすべて行う|
|-oN <file名>|outputのフォーマット(normal)で<file名>に結果を出力する|
|-v|詳細を表示する|
|--script vuln|nmapに付属するスクリプトを用いて脆弱性の検出を併せて行う|

### kerbrute
Active Directoryのアカウントの列挙やパスワードの総当たり攻撃などができるツール

### Impacket
通信を行うために使用されるさまざまなプロトコルをプログラムから操作しやすくするためのライブラリやツールの集まり
pythonで記述されている
/usr/share/doc/python3-impacket/内にある

### hashcat
ハッシュ値からパスワードを解析するためのツール

```
hashcat <option> <解析対象ファイル> <辞書ファイル>
```

データの種類に応じた番号（ハッシュタイプ）をオプションとして与える必要がある(-m <ハッシュタイプ>)
ハッシュタイプはヘルプから調べる

### Evil-WinRM
Winsowsリモート管理(WinRM)サービスを利用して、リモートのWindowsにアクセスするためのツール

```
evil-winrm -i <target> -u <user> -H <hash>
```


## セキュリティ攻撃関係の用語集

### AS-REP Roasting攻撃
Kerberos認証に関する攻撃（Kerberos認証についてはこうじゅつ）
通常は事前認証をしてから認証レスポンス（AS-REP)を受け取るが、設定によっては事前認証がOFFになっていることがあり、この事前認証をOFFにしているとAS-REP(TGTを含むASのレスポンス)をなりすましで取得できるため、そこから解析して申請ユーザーのパスワードが取得できる可能性がある。
この攻撃のことをAS-REP Roasting攻撃という。

### DCSync攻撃
MS-DRSRというドメインコントローラー間でのデータ複製に使用されるプロトコルを悪余殃して、既存のドメインコントローラーに対して、データの同期を要求してパスワードハッシュを取得する攻撃
実行にはドメインコントローラーを複製できる権限を持ったアカウントが必要

### Pass the Hash攻撃
ハッシュ値を認証値としてそのまま利用することでなりすます攻撃

## その他の用語集

### Active Directory
Windowsサーバー上で動作するユーザ・PC一元管理のシステム
- ドメインコントローラー：ドメイン情報を持っているサーバー
- ユーザーポリシー：ユーザーの管理
- コンピューターポリシー：コンピューターの管理

### Kerberos認証
Active Directoryが使っている認証方式
AS/TGTがクライアントの身分証明
TGS/STが身分証明されたクライアントに対して、特定のサービスを利用の認証

- AS(Authentication Servive):認証サービス
    - 認証を受け付けて、成功したらTGSに向けてTGTを発行する
- TGS(Ticket-Grainting Service):チケット付与サービス
    - ASが発行したTGTを確認して各サーバー利用のためのSTを付与する
- TGT(Ticket-Grainting Ticket):チケット付与チケット
    - ASが発行するチケット（クライアントの身分証明）
- ST(Service Ticket):サービスチケット
    - TGSが発行するチケット（特定サービスの認証）
- KDC(Key Distributin Center):キー配布センター
    - AS,TGSを含むKerberos認証のチケット発行サービス
    - KDCとクライアント間で利用する鍵の情報が設定されている

### Base64
64進数を意味している、すべてのデータをアルファベット(26*2)、数字(10)、一部の記号(+ /)の64文字で表すエンコード方式

### NTLMハッシュ
windowsのパスワードのハッシュ化方法
- 昔はLM(LAN Manager)ハッシュが使われていたが14桁までした対応していないため、現在は使われていない
- これの新しいバージョンがNTLM(NT LAN Manager)ハッシュ
windowsではパスワードをNTLMハッシュでハッシュ化したあと暗号化して保存されている
MAMPインストール後、サーバーStartをすると「Apache couldn't be started. Please check your MAMP installation and configuration.」というエラー

今回、PHPの開発環境を構築するためにMAMPを導入しました。
MAMPは、Mac上でApache、MySQL、PHPを手軽にセットアップできるアプリケーションです。
MAMPは無料版と有料版のMAMP PROがあり、間違えてPRO版を起動しないよう注意が必要です。

まず、以下のリンクからMAMPをダウンロードし、インストールします。
https://www.mamp.info/en/mac/

インストール後、MAMPのアプリケーションを起動し、"Start"ボタンをクリック。しかし、以下のエラーメッセージが表示されました。

```「Apache couldn't be started. Please check your MAMP installation and configuration.」```

PHPとMySQLは正常に動作しているものの、Apacheが起動しない状態です。

## エラー原因の特定
Apacheが起動しない原因を探るため、エラーログを確認しました。
エラーログは以下のパスに出力されます。
```Applications/MAMP/logs/apache_error.log```

ログには以下のエラーが記録されていました。
```
/Applications/MAMP/fcgi-bin/php.fcgi: line 4: /Applications/MAMP/bin/php/php8.3.1/bin/php-cgi: No such file or directory
```
このエラーは、MAMPが指定している/Applications/MAMP/bin/php/php8.3.1/bin/php-cgiが存在しないことを示しています。

実際に/Applications/MAMP/fcgi-bin/の中身を確認すると、存在しているPHPバージョンは以下の通りでした。
```
doianna@doiannanoMacBook-Air ~ % cat /Applications/MAMP/bin/php/
browscap.ini*  php7.1.33/     php7.4.33/     php8.3.9/
composer*      php7.2.34/     php8.1.29/
php@           php7.3.33/     php8.2.20
```
この結果から、MAMPが指定しているphp8.3.1はインストールされておらず、最新のphp8.3.9を使用する必要があることがわかりました。

## 設定ファイルの修正
次に、MAMPが参照する設定ファイルを修正します。まず、以下のファイルを編集します。

```/Applications/MAMP/fcgi-bin/php.fcgi```
内容は以下のようになっています。
```
exec /Applications/MAMP/bin/php/php8.3.1/bin/php-cgi -c "/Applications/MAMP/bin/php/php8.3.1/conf/php.ini"
```

この行を、存在するphp8.3.9に変更します。

```
exec /Applications/MAMP/bin/php/php8.3.9/bin/php-cgi -c "/Applications/MAMP/bin/php/php8.3.9/conf/php.ini"
```

さらに、```/Applications/MAMP/fcgi-bin/php8.3.1.fcgi```というファイルも存在していたため、これも```php8.3.9.fcgi```にリネームし、内容も同様に修正します。
```
exec /Applications/MAMP/bin/php/php8.3.9/bin/php-cgi -c "/Library/Application Support/appsolute/MAMP PRO/conf/php8.3.9.ini"
```
これで設定は完了です。

## MAMPの再起動
設定を修正した後、MAMPを再起動し、再度"Start"ボタンを押すと、無事にApacheが起動しました！
![スクリーンショット 2024-10-12 14.52.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3070807/cdb90045-e46c-f975-eb21-bff57eedbc59.png)


## その他試したけど効果がなかったこと
- MAMPの再インストール
- 下記を参考にMac標準のApacheが起動していないか確認
    - https://qiita.com/yurippine/items/f3465af4ae24053ca8ee
- MAMPのApacheが正しくインストールされているか確認
    ```
    doianna@doiannanoMacBook-Air ~ % /Applications/MAMP/Library/bin/httpd -v
    Server version: Apache/2.4.58 (Unix)
    Server built:   Dec 29 2023 10:08:39`
    ```
    正常に動作していました。
- アプリケーションを介さずにApacheを手動で起動
    - ```doianna@doiannanoMacBook-Air ~ % sudo /Applications/MAMP/Library/bin/apachectl start```
    - 手動ではApacheが起動しました

これらの試行錯誤の結果、最終的にエラーログを確認し、原因を特定することで解決に至りました。
【karabiner-elements】新しいワイヤレスキーボードにしたらかなと英数の変換ができなくなった

Mac用に新しいBluetoothキーボード買ったけど、karabiner-elementsで設定していたかなと英数変換が効かなくなったときの対処法

Devicesタブを開いて、使いたいキーボードを選択すればできます。
まさかこんな簡単だったとは。

![スクリーンショット 2024-10-12 15.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629116/216374ad-3a46-109e-25af-951e7eeab463.png)
Pythonのファイルオープンでの"a+"

# "a+"でファイルの中身を読めなかったけど、やっと使い方を理解したのでメモ
```python
titles = [ "title1", "title2", "title3" ]
with open("file1.txt", "a+") as fd:
    fd.seek(0)
    lines = fd.read().splitlines()
    for title in titles:
        if title in lines:
            print(f"{title} already exist")
        else:
            fd.write(f"{title}\n")
            print(f"{title} added")
```
1次元配列arrayの宣言＆初期化と値を1行ずつ表示する

基本情報技術者試験 科目Bの勉強の中でJavaに触れる機会があったので忘備録として...

```
public class Exercise{
    public void run(){
        // 1次元配列arrayを宣言し、同時に初期化
        int array[] = new int[] {98, 12, 9, 102, 88};
    
        // 配列の要素を1行ずつ表示する
        for (int i = 0; i < array.length; i++){
            System.out.println(array[i]);
        }
    }
}
```

または
```
// 配列の要素を1行ずつ表示する
for (int value: array){
    System.out.println(value);
}
```

結果
```
98
12
9
102
88
```

配列の要素をforで繰り返し表示する時には、
int i =0; で初期化してから
iがarray.length（配列の要素数）よりも小さい数の場合、i++でiに1ずつ足していく
<br>
{98, 12, 9, 102, 88}の
インデックス番号は0, 1, 2, 3, 4
array.lengthは5

// 初期値はi = 0
System.out.println(array[i = 0]);
インデックス番号0の98が最初に表示される
<br>
i = 0はarray.lengthの5よりも小さいのでiに1が足される（i(0) + 1）
// i = 1
System.out.println(array[i = 1]);
インデックス番号1の12が表示される

i = 1はarray.lengthの5よりも小さいのでiに1が足される（i(1) + 1）
// i = 2
System.out.println(array[i = 2]);
インデックス番号2の9が表示される

i = 2はarray.lengthの5よりも小さいのでiに1が足される（i(2) + 1）
// i = 3
System.out.println(array[i = 3]);
インデックス番号3の102が表示される

i = 3はarray.lengthの5よりも小さいのでiに1が足される（i(3) + 1）
// i = 4
System.out.println(array[i = 4]);
インデックス番号4の88が表示される

仮にi = 4に1を足すと5となりarray.lengthの5よりも小さくならない（i < 5とならない）のでここで繰り返し処理はストップし、forのループを抜ける
<br>