OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP】なぜarray_push()は遅いか？

## 結論
関数呼び出し分のオーバーヘッドで遅い

## 環境情報
Windows11機から、WSL2でUbuntu20.04を立ち上げています。
CPU: `13th Gen Intel(R) Core(TM) i7-13700F`

```
# php -v
]PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies
```

## `array_push()`は遅い
「PHP 配列 追加」と検索するとまず紹介されるのが`array_push()`ですが、これは[遅すぎの王、遅すぎキング](https://qiita.com/uts1_6/items/11e348ead4bae71571b8)と有名ですね。

代わりに`$(変数名)[] = (追加要素)`という文法を推奨されます。

実際に時間計測してみましょう。

```php:test.php
<?php

$time_start_0 = microtime(true);
for ($cnt = 0; $cnt < 1000000; $cnt++){
        $a = [1,2,3,4,5,6,7,8,9,10];
        array_push($a, 11);
}
$time_0 =  microtime(true) - $time_start_0;
var_dump($time_0);

$time_start_1 = microtime(true);
for ($cnt = 0; $cnt < 1000000; $cnt++){
        $a = [1,2,3,4,5,6,7,8,9,10];
        $a[] = 11;
}
$time_1 =  microtime(true) - $time_start_1;
var_dump($time_1);

//何倍速くなったか
var_dump($time_0 / $time_1);                               
```

```:結果
# php test.php
float(0.03344011306762695)
float(0.021086931228637695)
float(1.5858216970998926)
```

**1.5倍**と出ました。[人によっては3倍になるらしいですね](https://qiita.com/buntafujikawa/items/ef52f40eee9f67cb71ed)

しかし、これは両者とも時間計算量は`O(1)`とのことです。

## なぜ？
`phpdbg`で下記コードの中間コードを表示してみましょう。
```php:test.php
<?php

$a = [];

array_push($a, 1);

$a[] = 2;
```

```:中間コード
# phpdbg test.php
prompt> print e
[Context /test.php (8 ops)]

$_main:
     ; (lines=8, args=0, vars=1, tmps=3)
     ; /test.php:1-8
L0003 0000 ASSIGN CV0($a) array(...)
L0005 0001 INIT_FCALL 2 112 string("array_push")
L0005 0002 SEND_REF CV0($a) 1
L0005 0003 SEND_VAL int(1) 2
L0005 0004 DO_ICALL
L0007 0005 ASSIGN_DIM CV0($a) NEXT
L0007 0006 OP_DATA int(2)
L0008 0007 RETURN int(1)
```

`L0005`の中間コードを見てください。5行目は`array_push()`でしたね。
上から
* `array_push`という名前の関数を拾ってくる
* 引数`$a`の参照を送信
* 引数`2`を送信
* 関数の処理を呼び出し（`DO_ICALL`）
という感じのニュアンスです。（厳密にはたぶん違います）

`L0007`は`$a[] = 2`のコードですが、 実は **これは`L0005 0004`の`DO_ICALL`と同内容です**
つまり、`array_push()`は **関数呼び出しの分だけ** 無駄な処理を行っているわけです。

一方、`$a[] = 2`はオペレーターに処理を埋め込まれている(?)ので、 **余計な処理がない** ということですね。

このような標準関数の中間コード変換問題については、こちらの記事が面白いです：[ZendEngineにえこひいきされる標準関数たち (前篇)](https://qiita.com/tadsan/items/643a7cd0b4d7f27dd3ed)
Amazon API Gatewayと、REST API, HTTP API, WebSocket APIと、APIとVersion（V1, V2）


やたら長いタイトルになってしまいましたが、API Gatewayに関して、これらの関係がややこしくて最初ものすごく混乱したので、思考整理も兼ねて、簡単にまとめておきます。

## API Gateway

AWSの提供するAPIを作成・管理などするためのサービス。

API Gatewayにまつわる基本的な事柄は、

- [Amazon API Gateway とは何ですか? | aws - デベロッパーガイド](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html)
- [API Gateway のユースケース | aws - デベロッパーガイド](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-overview-developer-experience.html)
- [Amazon API Gateway の概念 | aws - デベロッパーガイド](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-basic-concept.html)

あたりを参照。


## API Gatewayの種類

API Gatewayには、以下の2カテゴリ3種類あります。

### ステートレス

- REST API
- HTTP API

### ステートフル

- WebSocket API

### 補足説明など

図を使ってカテゴライズすると以下のような感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/c87f6b20-7059-ab64-3a81-ecda9c6a94ed.png)



[コチラ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-vs-rest.html)のページなどでREST APIとHTTP APIのみ比較がなされていますが、この2つが同じステートレスのため。

<b>機能重視ならREST API、コスト重視ならHTTP API</b>といったところでしょうか。

## API Gateway V1 および V2 API

公式サイトでは、[このページ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html)とかに出てくるやつ。

名前からしてややこしいですが、、<b>API Gateway APIは、API Gatewayを操作、すなわち、作成・更新・削除などするためのAPI</b>のこと。
V1（Version1）とV2（Version2）があり、それぞれ以下のような違いがあります。

### API Gateway Version 1 API

API Gatewayのうち、REST APIを操作するためのもの
リファレンスは、[コチラ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/api/API_Operations.html)

### API Gateway Version 2 API

API Gatewayのうち、HTTP API、WebSocket APIを操作するためのもの
リファレンスは、[コチラ](https://docs.aws.amazon.com/ja_jp/apigatewayv2/latest/api-reference/api-reference.html)

### 補足説明など

図を使ってカテゴライズすると以下のような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/16d8a411-689e-ad2f-d885-cdd6d2237cda.png)


Versionによって操作できるAPIの種類が違うというわけですね。
なお、IaCサービスである[CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/AWS_ApiGateway.html)や[Terraform](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_rest_api)においても、API同様、

- V1（無印）: REST APIを操作するためのもの
- V2: HTTP API、WebSocket APIを操作するためのもの

となっています。
API Gateway APIの拡張的なポジションかと思うので、当たり前かもですが、、


## まとめ

ここまでの内容を表にまとめると、以下のようになります。

|  |カテゴリ  |用途  |操作用APIのVersion |
|---|---|---|---|
|REST API  |ステートレス  |機能重視  |Version 1  |
|HTTP API  |ステートレス  |コスト重視  |Version 2  |
|WebSocket API  |ステートフル  |双方向通信  |Version 2  |

ここでREST APIに焦点を当てると、Version1 → 古いので非推奨、ではなく、昔からある重鎮といった感じですね。

## 終わりに

上記の内容ですらややこしいのに、独自の概念も相まって、なかなかとっつきにくい、、

概念に関しては、

- [イラストで理解するAPI Gateway | Zenn](https://zenn.dev/fdnsy/articles/86897abce0bbf5)

が、とてもわかりやすかったので、一度見てみるとよいかと。
JacksonでJSONをオブジェクトに変換する

JacksonはJavaでJSONとオブジェクトを変換する場合などに使用されるライブラリです。
Jacksonを使うと簡単にJSONを扱うことができます。

### JSON文字列をオブジェクトに変換する
下記のJSON文字列をオブジェクトに変換したいとします。
```java:JSON
String json = "{" +
                "\"message\": null," +
                "\"results\": [" +
                "   {\"address1\": \"北海道\"," +
                "   \"address2\": \"美唄市\"," +
                "   \"address3\": \"上美唄町協和\"," +
                "   \"kana1\": \"ﾎｯｶｲﾄﾞｳ\"," +
                "   \"kana2\": \"ﾋﾞﾊﾞｲｼ\"," +
                "   \"kana3\": \"ｶﾐﾋﾞﾊﾞｲﾁｮｳｷｮｳﾜ\"," +
                "   \"prefcode\": \"1\"," +
                "   \"zipcode\": \"0790177\"}]," +
                "\"status\": 200}";
```

```java:変換したいオブジェクト
public class Response {
    private String message;
    private String status;
    private Result[] results;
}

public class Result {
    private String address1;
    private String address2;
    private String address3;
    private String kana1;
    private String kana2;
    private String kana3;
    private String prefcode;
    private String zipcode;
}
```
以下のようにObjectMapperインスタンスを生成し、`readValue()`を呼び出すだけでJSONからオブジェクトに変換できます。
```java
ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(json, Response.class);
```
### JSONの一部のプロパティを無視したい場合
ただし、上記はJSONのデータとオブジェクトのフィールドが一致していないときにはエラーが発生します。
例えば以下のようにフィールドに定義されていないプロパティ（hoge）が入っている場合はエラーとなります。
```java
String json = "{" +
                "\"message\": null," +
                "\"results\": [" +
                "   {\"address1\": \"北海道\"," +
                "   \"address2\": \"美唄市\"," +
                "   \"address3\": \"上美唄町協和\"," +
                "   \"kana1\": \"ﾎｯｶｲﾄﾞｳ\"," +
                "   \"kana2\": \"ﾋﾞﾊﾞｲｼ\"," +
                "   \"kana3\": \"ｶﾐﾋﾞﾊﾞｲﾁｮｳｷｮｳﾜ\"," +
                "   \"prefcode\": \"1\"," +
                "   \"zipcode\": \"0790177\"}]," +
                "\"status\": 200," +
                "\"hoge\": \"hoge\"}";
```

エラーを避けるためには`@JsonIgnoreProperties(ignoreUnknown = true)`を指定する必要があります。
このアノテーションをつけることでJSONから変換される場合に、オブジェクトに定義されていないプロパティは無視されます。
```java
@JsonIgnoreProperties(ignoreUnknown = true)
public class Response {
    private String message;
    private String status;
    private Result[] results;
}
```

### JSONから一部の値を取得したい場合
JSONから値を取得するためにわざわざオブジェクトを作成したくないときもあるかもしれません。
そんなときは`readTree()`を使いJsonNodeを作成することでJSONのプロパティにアクセスすることができます。
配列はArrayNodeにキャストして配列として扱うことができます。
```java
JsonNode status = mapper.readTree(json).get("status");
System.out.println(status.asText());

ArrayNode results = (ArrayNode) mapper.readTree(json).get("results");
for (JsonNode jsonNode: results) {
    System.out.println(jsonNode.get("address1").asText());
}
```
```:実行結果
200
北海道
```
Python でメールファイルから本文を取り出す

Python でメールファイルから本文取り出す方法を調べていたところ `Message` クラスを使っている例ばかりが出てきて、「なんで `EmailMessage` クラスを使わないのだろう」と思ったのでやってみた。

``` python
from email.message import EmailMessage


def parse_message(message: EmailMessage) -> tuple[str, str, list[tuple[str, str, str | bytes]]]:
    """EmailMessage から プレーンテキスト, HTML, 添付ファイル を取り出す"""
    text, html, attachments = "", "", []

    for part in message.walk():
        if part.is_multipart():
            continue
        content_type = part.get_content_type().lower()
        filename = part.get_filename()
        content = part.get_content()
        if filename:
            attachments.append((content_type, filename, content))
        elif content_type == "text/plain":
            text += content
        elif content_type == "text/html":
            html += content
        else:
            raise Error(f"Unknown Content-Type: {content_type}")

    return text, html, attachments
```

Amazon S3 にあるメールファイルを読み込んで本文を取り出す例がこんな感じ。

``` python
from email import message_from_binary_file
from email.policy import EmailPolicy
import boto3

s3 = boto3.client("s3")
obj = s3.get_object(Bucket="...", Key="...")
message = message_from_binary_file(obj["Body"], policy=EmailPolicy())
headers = message.items()
text, html, attachments = parse_message(message)
```

`message_from_binary_file` の引数 `policy=` は Python 3.2 と後方互換がある `Compat32` がデフォルトになっており、このポリシーで読み込むと `Message` 型のメッセージが返ってくる。明示的に `EmailPolicy` を指定することで `EmailMessage` 型のメッセージを得ることができて、こちらのほうが parse する際に少し便利なので良い。(そこまで違いはないが)

## 参考
- [email.message: 電子メールメッセージの表現 — Python 3 ドキュメント](https://docs.python.org/ja/3/library/email.message.html)
- [email.policy: ポリシーオブジェクト — Python 3 ドキュメント](https://docs.python.org/ja/3/library/email.policy.html)
デジタル環境を回避する: ソーシャル メディア マーケティングを成功させるための SMMpaneldeals の力を明らかにする




成長を続けるデジタル マーケティングの分野では、経済的で効果的なソリューションを見つけるのは終わりのない苦労です。それでも、https://smmpaneldeals.com/
![uploading...0]() は隠れた宝です。このブログでは、SMMpaneldeals を使用して優れたソーシャル メディア マーケティング プランを作成することが、どのように変革体験となるかを検証します。

SMMpaneldeals でデジタル探検に出発し、企業やエンタープライズ向けに特別に設計された手頃な価格の選択肢を数多く検討することから始めます。 SMMpaneldeals がマーケターを成功に導く羅針盤として台頭し、ソーシャル メディア マーケティングの環境の変化が示されています。

予算を超過せずにインターネットでのプレゼンスを向上させる方法を学びましょう。 SMMpaneldeals は、企業に理想的なプッシュを提供することを目的とした、手頃な価格の SMM パネル サービスのセレクションを提供します。ビジネスの規模に関係なく、特定の要件に合わせた予算に優しいオプションがあります。

SMMpaneldeals が提供する重要な機能、つまり従来のマーケティングを超える強力な戦術を調べてください。ターゲット層に永続的な効果をもたらし、ソーシャル メディアでの存在感を高める効果的なキャンペーンを作成する方法を学びましょう。

インターネットでの影響力を劇的に高めるこの素晴らしいチャンスを逃さないでください。 SMMpaneldeals は、サービス プロバイダーであるだけでなく、オンラインでの成功のパートナーでもあります。プラットフォームの使用方法を確認し、効率性と手頃な価格の連携によってもたらされる利点を活用してください。
指令の最適化（プロンプト）よりも有用な、3つのChatGPTのコツ


実際には、多くの場合でコマンドの最適化が最も効果的なChatGPTの使用方法ではないことがわかっています。指令を最適化しようとしても、得られる回答があまりにも広範囲で、実用性や一貫性に欠けることがよくあります。

この記事では、低品質な回答の主な原因と、頭をあまり使わずに望んだ回答を得るための3つのシンプルで効果的な方法を簡単に共有します。

![DALL·E 2024-01-30 23.15.07 - An illustration showcasing three useful ChatGPT tips, represented by three characters or symbols. The first character is disassembling a large questio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3306294/ffce8833-df17-901b-9233-8b18deaf9842.png)


# なぜ高品質な回答が得られないのか？

ChatGPTは非常に強力ですが、その運用は1)計算能力と2)背景知識の制限を受けます。

ChatGPTが「正確な回答」を見つけるプロセスを登山に例えると、計算能力は体力で、背景情報は地図のようなものです。これらはそれぞれ、どれだけ遠くまで行けるかと、どのように進むかを制限します。

体力が十分にある時は、地図がなくても山頂に登れるかもしれません（もちろん途中で何度か転ぶかもしれません）。情報が十分にある時は、省エネルギーで迅速に山頂に到達できます。

このうち、計算能力はOpenAIが決めたもので、各回答で消費できる計算量には最大値があります。一方、背景知識は主にモデルの訓練データと、指令に含まれる追加情報から構成され、私たちが制御できる唯一の部分です。

したがって、質問があいまいで複雑すぎる場合、ChatGPTは「体力」を使い果たし、山の中腹で停止するしかありません。あまりに抽象的で具体性に欠ける回答は、このような途中で力尽きた半端な回答が多いのです。

# 指令の最適化だけが解決策ではない

だから、高品質な回答を得るためには、指示をより正確に、情報をより完全にする努力をするしかありません。しかし、これは指令を盲目的に最適化することを意味するわけではありません。

この種のAIツールとの対話時には、指令の設計に多くの時間を費やしたくないし、ChatGPTがどのような情報を必要とするかを予測することも不可能です。特に私たちがそもそも何も知らない問題（例えば量子力学）に直面した場合、適切な質問を構築するための十分な知識がないのです（そうでなければChatGPTに質問する必要はありません）。

指令の最適化だけでは解決策にならないので、他のより効果的な方法を探さなければなりません。

何度も試行錯誤した結果、最も簡単な方法は、以下の3つの相互ガイド原則を用いてChatGPTとの対話を行うことだとわかりました：

1. 問題を分割する
2. 誘導的な質問をする
3. 論理をフィードバックする

これらの原則は、ChatGPTとの対話プロセス中に必要な情報をタイムリーに補足し、彼の論理の誤りを探り、適時に改善方向を提案するのに役立ちます。

## 問題を分割する

複雑な問題をいくつかの単純な問題に分割し、ChatGPTに一つずつ解決してもらうことができます（登山の比喩を使うと、直接頂上を目指すのではなく、段階を踏んで登ることに相当します）。これにより、問題の範囲を制限し、記述をより正確にすることができます。

例えば、「理想の結婚式をどのように開催するか？」という質問は、「適切な結婚式のテーマを定義する」->「予算を計画する」->「イベントの詳細を詰める」といったサブトピックに分解できます。

問題の分解方法がわからない場合は、ChatGPTを利用して助けを求めることもできます。具体的な指令を入力する前に、以下のような指令を入力するだけです：

> 次の質問を5つのより具体的なサブクエスチョンに分解し、背後にある考え方を教えてください：[あなたの質問]
> 

## 誘導的な質問

ChatGPTに、回答する前に能動的に情報を求めさせることで、一連の質問と補足を通じて、回答を徐々に最適化することができます。私のやり方は、各質問の際に、以下のようなルールを加えることです：

 

> 質問に回答する際、以下のルールに従ってください：
> 
> 
> a. 最初の回答前に、私のニーズを理解し、回答の正確性を高めるために、私に5つの開放的な質問をしてください。
> b. 各回答の後に、回答の正確性を高めるために役立つ3つの質問を挙げ、それらの情報を使って回答を修正してください。
> 

## 論理のフィードバック

最後に、ChatGPTにその思考のロジックを説明させることができます。これにより、彼の発想の方向をさらに監視する（まるで思想警察のように）と同時に、AIの動作方式を理解するのにも役立ちます：

> 各回答時に、その回答を生成する際の背後にある論理と思考を簡潔に説明してください。
>
Goの最初に行うinitでの初歩的なミス備忘録

## 発現法

Goのプロジェクトを立ち上げて、`main.go`を作成します。`package main` を記述して`go mod init`コマンドを打ち込んで初期化を行おうとしました。下記のエラー発現。

## エラー内容

```tsx
go: cannot determine module path for source directory /Users/hogehoge(outside GOPATH, module path must be specified)

Example usage:
        'go mod init example.com/m' to initialize a v0 or v1 module
        'go mod init example.com/m/v2' to initialize a v2 module

Run 'go help mod init' for more information.
```

## 解決策

`go mod init あなたのプロジェクト名(モジュール名?)` と最後にモジュール名を指定する必要がありました。例えば、あなたの作成したプロジェクト名が`test`だとしたら、行う初期化コマンドは`go mod init test`になります。
nohup(no hangup)

```sample.sh
[linuxstudy@xxxx ~]$ cat sample.sh
#!/bin/sh
    while true; do
	    sleep 3s
	    echo "i'm looping"
    done
```
```
linuxstudy@xxxx ~]$ nohup ./sample.sh &  //nohupでシェルを起動
[1] 23484
nohup: 入力を無視し、出力を `nohup.out' に追記します
[linuxstudy@xxxx ~]$ less nohup.out
[linuxstudy@xxxx ~]$ jobs
[1]+  実行中               nohup ./sample.sh &
[linuxstudy@xxxx ~]$ fg %1
nohup ./sample.sh
^C
[linuxstudy@xxxx ~]$ jobs
[linuxstudy@xxxx ~]$ cat nohup.out     //標準出力ではなくnohup.outに出力されている
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
i'm looping
```
```
NOHUP(1)                                           User Commands                                          NOHUP(1)



NAME
       nohup - run a command immune to hangups, with output to a non-tty

SYNOPSIS
       nohup COMMAND [ARG]...
       nohup OPTION

DESCRIPTION
       Run COMMAND, ignoring hangup signals.

       --help display this help and exit

       --version
              output version information and exit

       If standard input is a terminal, redirect it from /dev/null.  If standard output is a terminal, append out‐
       put to 'nohup.out' if possible, '$HOME/nohup.out' otherwise.  If standard error is a terminal, redirect  it
       to standard output.  To save output to FILE, use 'nohup COMMAND > FILE'.

       NOTE:  your  shell  may have its own version of nohup, which usually supersedes the version described here.
       Please refer to your shell's documentation for details about the options it supports.

       GNU coreutils online  help:  <http://www.gnu.org/software/coreutils/>  Report  nohup  translation  bugs  to
       <http://translationproject.org/team/>

AUTHOR
       Written by Jim Meyering.

COPYRIGHT
       Copyright   ©   2013  Free  Software  Foundation,  Inc.   License  GPLv3+:  GNU  GPL  version  3  or  later
       <http://gnu.org/licenses/gpl.html>.
       This is free software: you are free to change and redistribute it.  There is NO  WARRANTY,  to  the  extent
       permitted by law.

SEE ALSO
       The  full  documentation  for  nohup is maintained as a Texinfo manual.  If the info and nohup programs are
       properly installed at your site, the command

              info coreutils 'nohup invocation'

       should give you access to the complete manual.



GNU coreutils 8.22                                 November 2020                                          NOHUP(1)```
PHP８初級技術者認定試験を受験してみた

## はじめに
著者はphp実務経験１年目エンジニアです。  
1ヶ月ほどの勉強でPHP８初級技術者認定試験を合格することができました！  
php8を対象とした過去問の教材が少なく勉強しにくかったので、これから試験を受ける人の役に立てばと思い、試験内容や勉強方法を振り返りたいと思います。  


## 受験してみた所感
プログラムの知見が多少あれば十分合格が目指せる試験だと思いました！  
※プロゲート・パイザ・プログラミングスクール（PHPじゃなくてもOK）  
php8の試験ですが、問題のメインはPHPそのものだと感じました。  
「php7の過去問は沢山あるのに、肝心のphp8の過去問は全然無い。。。」と悲観する必要はなく、後述するphp8に対応の本と、ベータ版の過去問を解けば十分に対応可能だと思います。  

## 問題について  
問題は選択式で、実際のソースコードは書きません。  
「4つの中から正しいものを２つ選びなさい。」みたいな感じです。  
時間の体感ですが、見直しをガッツリ出来る程余裕はなかったです。  

試験の詳細(URL)  
https://www.phpexam.jp/summary/novice8

#### php8技術者認定試験(サイトから引用)  
概要：PHPプログラミングの基本知識を問う試験  
ITスキル標準（ITSS）：レベル1　　
受験料金：12,000円（税抜）　　
※学校法人の生徒、先生は50％オフで受験できます。詳細はオデッセイ コミュニケーションズにお問い合わせください。（2019年4月から事前申請が不要になりました）  
試験会場： 全国のオデッセイコミュニケーションズCBTテストセンター  
試験日：試験会場にてほぼ一年中実施しています。  
試験時間：60分  
設問数：40問  
試験時間：1時間  
出題形式：選択式（複数または単一選択）  
合格ライン ：7割正解で合格  
主教材： 独習PHP 第4版（翔泳社）  

|                           |  出題率  |  
|           ---             |   ---   |  
| 第1章   イントロダクション    | 2.5%    |  
| 第2章   PHPの基本           | 2.5%    |  
| 第3章   演算子              | 12.5%   |  
| 第4章   制御構文            | 10.0%    |  
| 第5章   組み込み関数         | 13.8%    |  
| 第6章   ユーザー定義関数      | 8.8%    |  
| 第7章   標準クラスライブラリ   | 7.5%    |  
| 第8章   リクエスト情報        | 10.0%   |  
| 第9章   データベース連携      | 5.0%     |  
| 第10章  オブジェクト思考構文 | 17.5%    |  
| 第11章  高度なプログラミング   | 5.0%     |  




## 勉強に使った教材
勉強に使った教材を紹介します。  

① 本  
▪️ 独習PHP 第4版  
https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92PHP-%E7%AC%AC4%E7%89%88-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4798168491


② 過去問  
▪️  php8模擬試験（β版）  
https://study.prime-strategy.co.jp/study/ph8el1/  
▪️  php7模擬試験  
https://study.prime-strategy.co.jp/study/ph7el1/  
▪️  エバンジェリスト三雲勇二からの出題
https://www.phpexam.jp/archives/category/column/mikumo  

③ 動画  
▪️ PHP8とPHPの教え方を解説するセミナー  
https://www.youtube.com/watch?v=xMLEbA8i_3U  




## 勉強方法
過去問はそれぞれ３回ずつくらい解きました。  
期間が１ヶ月ちょっとしかありませんでしたので、網羅的に勉強する余裕はなく、解いてく中で自分に苦手の分野を更に深掘りするといった感じです。
上記に記載した出題率の通りに問題は出題されますので、過去問を解く中で出題率が高いのに間違えが多いところを重点的に深掘りました。

3週間：本を読む＆本の過去問を解く  
↓  
2週間：過去問を解く＆間違えたところを復習  
↓  
受験  

## 問題を振り返ってみて
実際に受験してみて、phpのバージョンにとらわれることなく、phpそのものを理解することが大事だと感じました。  
php8ならではの問題は少ないと感じたため、過去問が理解できるようになれば十分対応できると思います。  
PHP8ならではの処理について詳しく知りたいと思ったら「独習PHP 第4版」を読めばバッチリだと思います。  
とても分かりやすい本で、PHPで開発するなら必ず読んだ方がいいと感じました。

## 受験してみて  
試験というと「経験が少ない」とか「自信がない」とかでハードルが上がってしまうと思いますが、演算子やオブジェクト指向など、そもそもプログラミングの基本的なレベルのところが出題されるので、駆け出しエンジニアでも受験しやすいと思いますし、詳しくphpについて知りたいと思ってる方にはピッタリだと感じました。  

著者は実務経験１年で受験しましたが、なんとなく分かってた事が確信に変わったり、phpの知識が深まり、受験して良かったなと感じました。
【React】`value` prop on `input` should not be null という警告について

# 概要
この記事では、Reactで開発を行っている際にconsoleに表示された `'value' prop on 'input' should not be null`という警告の解決方法について言及しています。

# 環境
- **react** : ver 18.1.0
- **node.js** : ver 18.17.1

# エラー文
下記の文がアプリケーション起動時に、ブラウザのconsoleにて出力された警告文です。
```sh:Terminal
react-dom.development.js:86 Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components.
```

# 問題が起きたコード
アプリ全体ではなく、該当のコードのみ貼り付けさせていただきます。
```tsx:Form.jsx
import { useState } from "react"

const Form = ({todos, setTodos}) =>{

    // 入力値保持用の変数
    const [newTodo,setNewTodo] = useState(null);

    // タスク追加処理
    const Submit = () =>{
        if (newTodo){
            setTodos([...todos,{id: todos[todos.length-1].id+1,content: newTodo}])
        }
    }

    return(
        <>
            <div style={{border: "solid", padding: "10px"}}>
                <p>Form.js</p>
                <input
                    type="text"
                    value={newTodo}
                    onChange={(e)=>{setNewTodo(e.target.value)}}
                />
                <button onClick={Submit}>追加</button>
            </div>
        </>
    )
}

export default Form

```

# 解決方法

```diff_tsx:Form.jsx
- const [newTodo,setNewTodo] = useState(null);
```

ではなく

```diff_tsx:Form.jsx
+ const [newTodo,setNewTodo] = useState("");
```

に初期値を変更することで解決しました。


# 原因
初期化するときにnullではなく""(空文字)を渡しておかないと、inputタグのvalueにnullが渡ってしまい、警告が出るという内容でした。
valueには常に有効な値を渡すことを意識しておけば大丈夫そうでした。


# さいごに
Reactについてはまだまだ駆け出しの状態ですので、間違っている点や追記すべき点があればコメントをいただけると幸いです。


# 参考文献

https://qiita.com/TK_WebSE/items/b4dd4b519ee1d0ead969

https://cpoint-lab.co.jp/article/202205/22820/
数値変換判定処理

数値に変換できるかチェックできるプログラムを2通りで実装しました。

1.例外処理を使う場合

```python
str1 = input()
try:
    num1 = int(str1)
    print("YES")
except:
    print("NO")
```

2.isdigitメソッドを使う場合
```python
s = input()

if s.isdigit():
    print("YES")
else:
    print("NO")

```

追加
正負記号を入れた整数はisdigitメソッドでは判定できません
下のプログラムを実行しました。

![タイトルなし.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/29706047-7973-53f3-255f-5389d305a26a.jpeg)
AIを活用したペアプログラミング「Github Copilot」

![copilot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633992/eb38fd9f-a977-7e82-7848-3f8da711d035.jpeg)

エスプリフォートでは日々アンテナを張りながら技術力を高め、積極的に新しい事を取り入れ、日々のシステム開発に生かしていっています。
これら磨きあげた技術力が、お客様に高いクオリティでシステムを提供する一助になっています。

## はじめに

近年、AI技術の進化とともに、多くの業界でその恩恵を受けているのは明らかです。特にプログラミングの世界でも、この波は静かではありません。この記事では、AIを活用したプログラミングのツール「[Github Copilot](https://copilot.github.com/)」について探ることにします。

## Github Copilotとは？

Github Copilotは、GitHubとOpenAIが共同で開発した、
VS Codeの拡張機能として動作するコーディングアシスタントです。AI技術を駆使して、
開発者が書きたいコードを予測し、提案してくれるのが主な特徴です。

## 主な機能

1. **コードの予測**:
   - 入力を基に、次に書くべきコードの提案を行います。
2. **ドキュメントからのコード生成**:
   - コメントやドキュメントの内容に基づいて関数やクラスを生成します。
3. **多言語対応**:
   - Python, JavaScript, Go, Ruby など、多数の言語に対応しています。


### 具体的な機能の例を紹介

hello.cというファイルを作成します。

コードを作成します

```
int main()
```

すると以下のようにコードの候補が現れ、選択するとコードが生成されます。
![草稿2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633992/848d6c69-bacf-82f6-9d30-d5e056ed5fc9.png)


上記は簡単な一例ですが、
実際にはメソッド名、引数やコメントなどに応じたコードを生成してくれます。

## Copilotのメリット
:::note info
#### 効率の向上
コードのヒントを得ながら書くことで、開発速度を向上させることができます。
:::

:::note info
#### 学習のサポート
未知の言語やフレームワークに取り組む際のサポートとしても利用できます。
そのため、不慣れな開発言語でもコーディングが容易になります。
:::

:::note info
#### 既存エディターとの結合が可能で、新たな環境構築の必要がない
既存エディターと統合できるため、新しく環境を構築したり、別のソフトウェアを同時に起動する必要がありません。そのため、ユーザーの利用ハードルは比較的低く、使いやすいです。
公式に対応しているのは、Visual Studio Code、Visual Studio、JetBrains IDE、Neovimの4種類のみになります。その他の一部のテキストエディターやIDEでも利用できるようです。
:::

## Copilotのデメリット

:::note alert
#### 著作権法上の危険
GitHub CopilotによりAIがソースコードを自動生成する場合、その前提として他者のソースコードを学習しているため、OSSなどの他者のソースコードの著作権を侵害している可能性もあります。また、AIが自動的に作った生成物について、基本的には著作物性が認められず、著作権は発生しないため、GitHub Copilotにより自動生成したソースコードは、著作物として認められない可能性が高くなります。
:::

:::note alert
#### セキュリティ上の漏えい
入力したコードが機械学習に使用されることにより、社外に流出する可能性があります。また、提案されたコードが脆弱である可能性があり、システムの脆弱性に繋がる可能性があります。
:::

## 料金について

Github Copilotは、当初はプレビュー期間中として無料で提供されていましたが、
現在は有料プランとして提供されています。

1 か月あたり 10 ドルです。

注意: 実際の料金は変動する可能性がありますので、最新の情報は[GitHub公式サイト](https://github.com/pricing)で確認してください。


## まとめ
現段階のGithub Copilotは完璧ではありません。
提案されるコードがそのまま使用できない場面も、少なくありません。
これは、AIが提案するコードが常に最適とは限らないことを意味しています。
そのため、AIへの過度な依存は避け、基本的なコーディング技術やアルゴリズムの構築能力を磨くことが重要です。

このAIの進化に伴い、エンジニアの役割や業務も変わってくることでしょう。
AIの力をうまく活用しつつ、人間独自の思考や判断を取り入れるバランスが、
今後のエンジニアにとって大切な事の一つとなるのではないでしょうか。

https://www.esprit-fort.co.jp/


https://www.esprit-fort.co.jp/recruit/
バックグラウンドでプロセスを起動する

```
[linuxstudy@xxxx ~]$ gnome-calculator &     //&をつけることでバックグラウンドで起動
[1] 21832                                   //JOBID:1
[linuxstudy@xxxx ~]$ fg %1                  //background -> foreground
gnome-calculator
^Z                                          //Ctrl + z (一時停止)
[1]+  停止                  gnome-calculator
[linuxstudy@xxxx ~]$ bg %1                  //foreground -> background
[1]+ gnome-calculator &
[linuxstudy@xxxx ~]$ 

```
SPM→Swiftlintでめちゃくちゃ「The package product '〇〇' requires minimum platform version XX.X for the iOS platform, but this target supports YY.Y」って言われた

## 環境
- MacOS Sonoma 14.3
- Xcode Version 15.2
- SPM経由でSwiftlintを導入

### 今回遭遇したこと
![スクリーンショット 2024-01-30 19.53.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688344/85714d11-17d4-f59c-4238-963887ce22ca.png)
図のようにThe package product '〇〇' requires minimum platform version XX.X for the iOS platform, but this target supports YY.Yというエラーがめちゃくちゃ出てきました。


![スクリーンショット 2024-01-30 17.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688344/6820e2ae-c169-5505-cd0f-608ebc34dbfb.png)
minimum Deploymentsは15.0以上に設定しているのに何故？

### 回避策
以下２つ紹介。
- ```Target -> FrameWorks, Libraries, and Embedded Content```に```SwiftlintFrameWorks```があるはずなので削除する

![スクリーンショット 2024-01-30 22.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688344/0faad7a2-3116-f556-dfdc-1b9ed38b78b8.png)

- 導入時SPM(Swift Package Manager)で導入するとき```SwiftlintFrameWorks```をNoneのままにする！


### まとめ
```SwiftlintFrameWorks```が悪さをしていると考えられます。
```import Swiftlint```のような使い方をするときにこの```SwiftlintFrameWorks```が必要そうです。Swiftlintはimportして使うことは基本的にありませんので、チェックを入れなくてもいいわけです。
では何故、Swiftlintにこのチェックがあるのかですが、おそらく「便宜的にライブラリ配布なら作らなきゃいけない」という可能性があります。また、[こちら](https://github.com/search?q=%22import+Swiftlint%22&type=code&p=1)のように、Swiftlint自体のプログラムに対して処理を記述する際のために用意されているものである可能性があります。
用途に合わせて、このエラーが出たら```SwiftlintFrameWorks```を疑ってみてください。
バグ修正とデバッグの実例

# 導入

- ユーザーからの報告により、アプリケーションの動作遅延が確認された。
- 特定の AWS EC2 サーバーでのみ問題が発生しており、CPU 使用率が 100%に達していたことが判明。
- この問題は他の環境では観察されなかったため、特定のサーバー固有の問題である可能性が高い。

# 問題の特定

- 初回報告を受け、他のサーバー環境と比較して異常がないか調査。
- 過去の事例から、特定のバッチ処理が原因である可能性を考慮し、実行時間を調べたが、異常は見られなかった。
- JVM のヒープダンプを取得し、メモリ使用の異常がないか詳細な分析を実施。
- 認証処理におけるメモリ使用量が異常に高いことが判明し、これが問題の核心であると特定。

# デバッグプロセス

- ヒープダンプの詳細分析により、特に認証処理のメモリ使用に着目。
- 認証処理を管理するハッシュマップが原因であることを突き止めた。
- 認証処理のロジックにおいて、同じユーザーが再ログインする際にハッシュマップからそのユーザー情報を適切に除去する処理が欠けていたことが原因であると判明。

# 修正の実施

- 問題のある認証処理をハッシュマップからより効率的なユーザーテーブルベースの管理方式へ変更。
- 新しい認証処理の Java コードを実装し、システムに統合。
- 修正後、メモリリークの問題が解消され、サーバーの CPU 使用率とメモリ使用量が正常値に戻ったことを確認。

# テストと検証

- 社内のテスト環境で新たな認証処理を含むアプリケーションの広範囲なテストを実施。
- CPU 使用率とメモリ使用量の正常化を確認し、性能改善を実証。
- 実際の顧客環境においても同様のテストを実施し、問題が完全に解消されたことを確認。

# 結論

- このバグは特定の API を使用する特定の顧客環境においてのみ発生していた。
- リリース前に異なる顧客環境での十分なテストの重要性を痛感し、今回の経験から学んだ。
- 今後は多様な環境での問題発生を未然に防ぐため、テストの範囲と深度をより広げることの重要性を認識した。
renice NICEの再設定

NICEを11から0に優先度を上げた例。
rootでないと優先度を上げるのはエラーになる
```
[root@xxxx linuxstudy]# ps -el | grep -e bc -e PRI
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  21344   3076  0  91  11 - 29272 n_tty_ pts/0    00:00:00 bc
[root@xxxx linuxstudy]# renice 0 -p 21344
21344 (process ID) old priority 11, new priority 0
[root@xxxx linuxstudy]# ps -el | grep -e bc -e PRI
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  21344   3076  0  80   0 - 29272 n_tty_ pts/0    00:00:00 bc
[root@xxxx linuxstudy]# 
```
Laravel URLのパスにはnameをつけるとパス呼び出しが楽！

## URLのパスにname()で名前をつけていろんな箇所でパスを呼び出せる
実務業務で実際にプロジェクト関わるまでの未経験時代ではweb.phpに定義したパス(URL)をbladeやコントローラ等で直接URL指定して呼び出してましたが、定義したパスにname()で名前指定して呼び出すことで色々便利と感じました！

## メリット
 - 定義したパスにname()で名前をつけることで長いURLを毎回書く必要ないこと
 - もしURLが変わった場合、パスを呼び出してるファイル全部修正しなければならないという面倒なことをしなくても、web.phpやapi.phpに定義したURLだけ修正するだけでいいのが最大のメリットかなと思います
 - name()で名前を付けておくと、そのパスの使用目的をざっくり把握できること

## name（）の書き方
```
// 未経験時代(コントローラ呼び出しもいちいち階層指定でやってた...)
    Route::get('/main', 'App\Http\Controllers\FoodController@show');
    Route::get('/foods/update/{id}', 'App\Http\Controllers\FoodController@foodUpdate');

// 実務経験後
    Route::get('/foods/{id}/test-name', [FoodController::class, 'testShow'])->name('foods.test-name.show');

``` 

## パスの呼び出し方
```
//　パスを呼び出かた、未経験時代
 <a href="/main"
 <a href="/foods/update/{{ $data->id }}"

//　パスを呼び出かた、実務経験後
<a href={{route('foods.test-name.show',['id' => $userId])}}>testShow</a>
```
PRI,NI 優先度

## ps -eo 項目指定型
PRIは140段階ある。低0→高139
NIは40段階ある。高-20→低19
PRIの優先度が低い部分の40段階（低0→高39）にNI（高-20→低19）が割り当てられている。
```
[linuxstudy@xxxx ~]$ ps -eo pid,pri,ni,comm | grep -e systemd -e migration -e PRI -e tracker-extract
   PID PRI  NI COMMAND
     1  19   0 systemd          //          PRI:19, NI:0
     7 139   - migration/0      //優先度MAX。PRI:139
    13 139   - migration/1
   544  19   0 systemd-journal
   582  19   0 systemd-udevd
   845  19   0 systemd-logind
  2828   0  19 tracker-extract    //優先度MIN。PRI:0, NI:19
```
## ps -el 詳細情報
PRIは140段階ある。高-40→低99
NIは40段階ある。高-20→低19
PRIの優先度が低い部分の40段階（高60→低99）にNI（高-20→低19）が割り当てられている。
```
[linuxstudy@xxxx ~]$ ps -el | grep -e systemd -e migration -e PRI -e tracker-extract
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0      1      0  0  80   0 - 32102 ep_pol ?        00:00:12 systemd        //          PRI:80, NI:0
1 S     0      7      2  0 -40   - -     0 smpboo ?        00:00:00 migration/0    //優先度MAX。PRI:-40
1 S     0     13      2  0 -40   - -     0 smpboo ?        00:00:00 migration/1
4 S     0    544      1  0  80   0 -  9859 ep_pol ?        00:00:06 systemd-journal
4 S     0    582      1  0  80   0 - 12520 ep_pol ?        00:00:01 systemd-udevd
4 S     0    845      1  0  80   0 -  6607 ep_pol ?        00:00:02 systemd-logind
0 S  1000   2828   2298  0  99  19 - 203854 poll_s ?       00:00:14 tracker-extract      //優先度MIN。PRI:99, NI:19
```
# 感想
表示フォーマットを変えると、PRIの意味が変わるのが、とてもわかりにくいと感じる。。
仕事でpsコマンドを使いなれている人はどちらを好むのだろう。。。
なお、カーネル内部の優先度は140段階で、高0→低139の模様。。。。
【DocumentUnderStanding】Studioで使用する各アクティビティの解説

# はじめに
UiPathの機能群『DocumentUnderStanding（DU）』を学習補助を目的として、Studioで使用するアクティビティを注釈付きで配置したサンプルフローを作成しました。UiPathのドキュメントやQiitaブログと一緒に、学習の参考にしていただければと思います。

※巨大な機能群のため、実際にはStudio以外に以下も理解する必要があります（後述）

:::note info
DocumentUnderStandingで使用するアクティビティの配置の仕方はお作法として決まっていると考え、まずは真似してみることがおすすめです
:::

アクティビティ解説の例）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776370/03ac4434-4865-333d-93df-7a719ee20916.png" width="50%">


UiPath社のフレームワークは高機能で入門者の学習にはリッチなため、サンプルフローは必要最小限のアクティビティを淡々と並べています。

また、2023/12時点のバグ情報も記載しています。
例）
- ActionCenter使用する場合、プロジェクト名には日本語を使用するとエラー
- フォルダ内繰り返しを使用すると、関数[CurrentFile.FullName]は[ドキュメント検証アクション完了まで待機し再開]アクティビティでエラー


# サンプルフロー
以下からダウンロードしてください。

https://github.com/Gaboz-Osawa/UiPathDU/tree/main/Document%20UnderStanding%20Sample%20Flow_%E8%A7%A3%E8%AA%AC%E4%BB%98%E3%81%8D%EF%BC%88%E5%A4%A7%E6%BE%A4%EF%BC%89

# Studio学習以外にすべきこと
実際にはStudio以外に以下も理解する必要があります
- Orchestrator：ストレージバケットの設定やActionCenterのフォルダ設定に関連。
- ActionCenter：検証作業場所。アクションカタログなどの機能も設定可能。
※検証場所をローカルでのみやる場合は設定不能。実際の運用でそうすることはなさそうですが・・・。
- AICenter：ML抽出器のトレーニングや設定に必要

# Qiitaのブログリンク
DocumentUnderStandingの学習にあたり、多くの方のブログを参考にさせていただきました。以下に紹介させていただきます。

【概要理解】

https://qiita.com/Kajiita/items/0dd8d410b572e076dcfe

https://qiita.com/Kajiita/items/1cd174ada00dd3055707

https://qiita.com/Kajiita/items/dd99eb753813d31fbe6a

https://qiita.com/Kajiita/items/e9cacc4313026efc2f12

日本語で入りがちな半角スペースの除去方法の説明あり

 
【開発の流れ理解】

https://qiita.com/utanesuke/items/8cdcd1276fe248fafea7

https://qiita.com/utanesuke/items/95e49a3f21d81c4393a9

https://qiita.com/utanesuke/items/d26c9636a078a2ebcabb

https://qiita.com/utanesuke/items/c59aaaa96db2f93bc83a

https://qiita.com/utanesuke/items/1cac422f8e4b2ecee26e

https://qiita.com/utanesuke/items/103cae121fc695b77f36

https://qiita.com/utanesuke/items/ae5364720fbad4c088ac

https://qiita.com/utanesuke/items/1a0342261a7907215a12

 
https://qiita.com/Jun96427231/items/2cdea161a61cbd10a3eb

https://qiita.com/Jun96427231/items/0ab0c0c7d47b834714aa

https://qiita.com/Jun96427231/items/f3bae2ec8d4d0e773b48

https://qiita.com/Jun96427231/items/7aa1b8eeedd32dec26b4

https://qiita.com/Jun96427231/items/bfff4bbb58de5289ae68

https://qiita.com/Jun96427231/items/df69a914462087058c15
 
【最新情報系】

https://qiita.com/Kajiita/items/313ed26bb92307148ef1
【Python】Atcoder勉強記録⑦

Atcoderの勉強した記録を書いていきます。
勉強の参考にしてください。
[解いた問題一覧](https://kenkoooo.com/atcoder/#/table/kenbo0224)

## 過去に投稿した記事
<font color="Magenta">①</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/6330d9ff7fcd4adb591e)
<font color="Magenta">②</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/32bac04e37b0d8cf6600)
<font color="Magenta">③</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/4f39c87af6982c1dd337)
<font color="Magenta">④</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/0cdf451bc440d5d5bbbe)
<font color="Magenta">⑤</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/e4e685ff256a3efa7b66)
<font color="Magenta">⑥</font>[Atcoder勉強記録](https://qiita.com/kensaka1228/items/5417d6ebbda2f5a68541)

# 1.問題①
[A - Capitalized?](https://atcoder.jp/contests/abc296/tasks/abc296_a)（<font color="SpringGreen">Difficulty21</font>）

## 解答
```python
S = input()

if len(S) == 1:
    if S.isupper():
        print('Yes')
    else:
        print('No')
else:
    flg_upper = S[0].isupper() # 大文字かを判断
    flg_lower = S[1:].islower() # 小文字か判断

    if flg_upper and flg_lower:
        print('Yes')
    else:
        print('No')
```

## 解法
1文字で大文字だった場合は「Yes」をする。
文字列をスライスで受け取り、1文字が大文字か、1文字目以降が全て小文字なのかをpythonのメソッドを使用して確認する。

# 1.問題②
[B - Frequency](https://atcoder.jp/contests/abc296/tasks/abc296_a)（<font color="SpringGreen">Difficulty48</font>）

## 解答
```python
from collections import defaultdict
S = input()
cnt = defaultdict(int)
for i in S:
    cnt[i] += 1

ans = 'a'
for i in sorted(cnt):
    if cnt.get(i) == None:
        continue
    if cnt.get(i) > cnt[ans]:
        ans = i
print(ans)
```
## 解法
defaultdictを使用して辞書を作成する。
defaultdictとは、どのようなキーがきても指定したデフォルト値を初期値として要素を追加します。
初期値でint型をセットしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/c018355a-96f3-aa2a-a613-e21a704c762d.png)
上記画像のように、cntの変数で辞書が作成されています。
後は、getメソッドを使用して出現回数の多い文字を確認してansに答えを格納します。
【SwiftUI】文字の色をprimaryとsecondaryで指定するように、文字の大きさもdefaultとsecondaryで指定する（iOS17）

# はじめに
タイトルは黒文字で大きめに、説明文は灰色文字で小さめになっているUIをよく見かけます。
これをフォントサイズを指定せずに実装することができるようになりました。

今回はサンプルアプリを作成するために、ChatGPTを使って、飲料水の新商品名とキャッチフレーズを考えてもらいました。

# サンプルアプリ
![simulator_screenshot_AA5A1380-D835-4CB7-A758-1C816A5D01AF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4fe188db-2b19-6e0d-307c-c0d3df2392b3.png)

# 実装
```swift
import SwiftUI

struct NewProduct {
    let name: String
    let catchphrase: String
}

struct ContentView: View {
    @State private var newProducts: [NewProduct] = [
        .init(name: "クリスタルドリーム", catchphrase: "純粋な夢の味わい、毎日の活力をクリスタルクリアに。"),
        .init(name: "フルーツエーテル", catchphrase: "宇宙的な果実のエネルギーが広がる、新しいフルーツの次元へ。"),
        .init(name: "アクアブリスト", catchphrase: "自然の恵みが凝縮された、究極の水。日常に輝きをプレゼント。"),
        .init(name: "インフィニティサラス", catchphrase: "限りない清涼感と未知の美味しさ。未来への一口、インフィニティの中で感じて。"),
        .init(name: "エレメンタルフュージョン", catchphrase: "自然の要素が融合した至福の一滴。五感で感じる、新しい次元の調和。"),
        .init(name: "セレスティアルミスト", catchphrase: "空から舞い降りた神秘的な水。心地よい霧のような口当たりでリフレッシュを体感。"),
    ]
    
    var body: some View {
        VStack {
            ForEach(newProducts, id: \.name) { newProduct in
                GroupBox {
                    Text(newProduct.name)
                        .foregroundStyle(.primary)
                        .textScale(.default) // これ
                        .frame(maxWidth: .infinity, alignment: .leading)
                    Text(newProduct.catchphrase)
                        .foregroundStyle(.secondary)
                        .textScale(.secondary) // これ
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
        }
        .padding(20)
    }
}
```

# おわり
Text.Scaleを拡張してオリジナルのText.Scaleを定義できるようになると嬉しいですね
多分今は出来なさそう

# 公式ドキュメント
https://developer.apple.com/documentation/SwiftUI/View/textScale(_:isEnabled:)
[Git] 基本コマンド

## リポジトリの初期化
新しいローカルGitリポジトリを初期化
```
git init
```
## ステージングとコミット
特定のファイルをステージングエリアに追加
```
git add <ファイル名>
```
現在のディレクトリのすべての変更をステージングエリアに追加
```
git add .
```
ステージングされた変更をリポジトリにコミット
```
git commit -m "コミットメッセージ"
```
## ブランチ
ローカルのブランチ一覧を表示
```
git branch
```
新しいブランチを作成
```
git branch <ブランチ名>
```
指定したブランチに切り替える
```
git switch <ブランチ名>
```
新しいブランチを作成し、そのブランチに切り替える
```
git switch -c <ブランチ名>
```
## リモートリポジトリ
リモートリポジトリの最新のコミット、ブランチ、タグなどの情報をローカルリポジトリにダウンロードする
```
git fetch
```
最新化とリモートリポジトリに存在しなくなったブランチに対応する、ローカルのリモート追跡ブランチを削除する
```
git fetch -p
```
リモートリポジトリを追加する
```
git remote add origin <リモートリポジトリのURL>
```
現在のブランチをリモートリポジトリにプッシュする
```
git push origin <ブランチ名>
```
リモートリポジトリから指定したブランチを現在のブランチにマージする
```
git pull <ブランチ名>
```
## ステータスとログ
現在の作業ディレクトリの状態（変更されたファイル、ステージングされたファイルなど）を表示する
```
git status
```
コミットの履歴を表示する
```
git log
```
## ヘルプ
指定したGitコマンドの詳細なヘルプを表示する
```
git help <コマンド>
```
hyper-v上のwindows serverを物理端末と同じネットワークする

# ○やりたいこと
hyper-v上の仮想サーバのwindows server2019を物理端末と同じネットワークにする。

# ○NW環境
Fortigate(dhcpサーバ)
| Lan
|
win11 home(ip dhcp)
|
|
仮想swich
|
|
win ser 2019 ★DHCPサーバーからIPもらいたい
仮想マシン　hyper-v

# ○やったこと
•仮想スイッチを作って仮想マシンに適用
仮想スイッチを作る
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683457/e86373ec-5056-8db8-8b4d-135d7f2c8782.png)

hyper-vマネージを開いて仮想スイッチの名前を付ける。外部ネットワークを選択して物理PCの有線lanのNICを指定。仮想マシンで使っていないインターフェースを指定するとうまくいかないから注意。無線とか
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683457/2196c7de-b226-8905-a945-8492af05651e.png)

仮想マシンの設定を開く
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683457/0677892d-2e9a-2222-ee75-47b2f28798c7.png)

仮想サーバのネットワークアダプターで作成した仮想スイッチを選択する
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683457/bcdd1816-36be-5c7f-b836-e21e6625ddb1.png)

仮想マシンでWindows serverを起動してコマンドプロントを確認する
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683457/ffe26770-bbb0-2589-c6a1-eed6bdf83685.png)
IPコンフィグを実行すると自動でIPを受けっとっていることを確認できた。


# ○結果
Fortigate(dhcpサーバ)からIPを受け取れた

# ○その他
仮想スイッチのイメージ
デフォルトのNWは物理PCのNICでNATして仮想サーバにIPを与えている？ようだ。
Fortigateで SSL-VPN接続 + AD認証 を実現したかったので深堀はせずとりあえず設定だけ行った。

# ○参考書
ひと目でわかるHyper-V Windows Server... https://www.amazon.jp/dp/4822253929?ref=ppx_pop_mob_ap_share
p5.js で手軽にキャンバス全体の色変更： drawingContext.filter で hue-rotate() を利用

過去に、以下の試作をする際に使った方法に関する記事です。
（以下は、カメラ映像を表示させたキャンバスに、炎などのエフェクトを描画したキャンバスを重畳していて、エフェクトを描画したキャンバスの色を変化させるという処理を行っています）

<iframe width="560" height="315" src="https://www.youtube.com/embed/Ay1gAJYi6Pw?si=CR8ufQAG6lQ4reTQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

最近、以下のカスタムシェーダーを使った描画を行う際に、上記で使った方法を用いました。以下では、シェーダーで描画した結果の色を変更する、ということをやっているのですが、冒頭・以下の事例で用いている「drawingContext.filter で hue-rotate()」の使い方の話を、自分用メモを兼ねて記事化しようと思います。

https://twitter.com/youtoy/status/1752118290976284924

## hue-rotate() について
タイトルに書いている drawingContext は、p5.js の仕組みです。

●reference | drawingContext
　https://p5js.org/reference/#/p5/drawingContext

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/43dd5e2b-fdf7-6c19-6fd7-295d0190155b.png)

これを用いることで、p5.js で以下の Canvas API を直接利用できます。

●CanvasRenderingContext2D - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D

その中の 1つに filter の hue-rotate() があります。

●CanvasRenderingContext2D: filter property - Web APIs | MDN
　https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9ecec8c2-4720-232f-206e-46fae6839c08.png)

### 使い方
JavaScript での使い方は、以下のとおりです。

●CanvasRenderingContext2D: filter property - Web APIs | MDN
　https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter

▼ JavaScript で filter を使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1de1b7ae-c51f-6788-8ef1-125193268c67.png)

▼ JavaScript で filter の hue-rotate() を使う

```javascript
const ctx = canvas.getContext("2d");
ctx.filter = "hue-rotate(90deg)";
```

## p5.js で hue-rotate() を使う
上記を p5.js で使います。

今回のお試し用のプログラムは、以下のシンプルなものにしました。

```javascript
function setup() {
  createCanvas(640, 480);
  noStroke();
  fill(100, 100, 200);
}

function draw() {
  background(0);

  const maxD = 60 * 3;
  const d = map(frameCount % maxD, 0, maxD, 0, 360);
  drawingContext.filter = `hue-rotate(${d}deg)`;

  circle(width / 2, height / 2, width * 0.3);
}
```

上記のお試しでは、frameCount に剰余演算を行った値と、map() を使った値域の変更の処理で、0〜360 をひたすらループする値を d に格納しています。そして、その値を hue-rotate() で使っています。

その実行結果は以下のとおりです。
上記の処理により、元は RGB の「100, 100, 200」という値の色で塗りつぶされていた円の色が、時間変化しました。もう少し補足すると、HSB の H を変化させた見た目になります。

![2024-01-30_11-29-08 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/abb03e7d-e395-2af6-d8e0-54cddccd6770.gif)

### hue-rotate() の活用について
上記のシンプルなお試しなら、fill() の色指定を　HSB にして、Hue の値を直接変えるという方法もあり、そちらのほうが簡単に書けます。

一方、冒頭で掲載していたような事例だと、hue-rotate() を使うことで、簡単に炎のエフェクト全体の色を、デフォルトの色から別の色に変更することができて便利です。
【PHP】0はnull？

## はじめに
超初歩的なところなんでしょうけど
知らなかったので反省をこめ、書いていきます。

## 変数==0
以下のような条件式を書いてました。
```.php
$test = null;

if($test == 0){
  echo $test."はZEROです。(実際はNULL)<br>";
}else{
  echo "ZEROじゃない";
}
```

```.結果
はZEROです。(実際はNULL)
```
なお、`false`でもそうなるそうです。

## 正しい条件式

単純に`===`にして
型も比較すればよいのです。
反省します。
```.php
$test = null;

if($test === 0){
  echo $test."はZEROです。(実際はNULL)<br>";
}else{
  echo "ZEROじゃない(思い通り)";
}
```

```.結果
ZEROじゃない(思い通り)
```
Vue.jsの復習

### はじめに
Vue.jsをUdemyで学習したのですが、
時間が経ってしまったので
基本的な部分を思い出すために記事にしました。


### データバインディング
データと描画を同期する仕組み
以下のようなコードでブラウザ上では
`Hello Vue.js!`と表示されます。

```.html
<div id="app">
  <p>{{ message }}</p>
</div>
```
```.js
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue.js!'
  })
})
app.mount('#app')
```

## ディレクティブ
`v-`から始まる属性。
directive(指令) Vue.jsに指示する仕組み

### `v-bind`
htmlの属性に紐づける。

```.html
<div id="app">
  <input type="text" v-bind:value="message">
</div>
```
```.js
const app = Vue.createApp({
  data: () => ({
    message: 'Hello Vue.js!'
  })
})
app.mount('#app')
```
#### ※省略も可能
```html
<div id="app">
  <input type="text" :value="message">
</div>
```

### `v-on`
イベントを発生させることができる。

```.html
<div id="app">
  <button v-on:click="onClick">Click!</button>
  <p>{{ now }}</p>
</div>
```
```.js
const app = Vue.createApp({
  data: () => ({
    now: '-'
  }),
  methods:{
    onClick:function(){
      this.now = new Date().toLocaleString()
    }
  }
})
app.mount('#app')
```
#### ※こちらも`@`に省略可能
```.html
<div id="app">
  <button @click="onClick">Click!</button>
  <p>{{ now }}</p>
</div>
```
【CSS】横に並べる【Chrome】


## 横並びってどうやるんだっけ？
ってなる度に検索しちゃうので覚えるためにも記事にしていきます。

## Flexboxで横になりました
なぜフレックスボックスがいいかはMDNさんに書いてありました。
浮動要素と位置指定などはイライラするから らしいです。

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Flexbox


```.html
<div class="yoko">
    <div class="yokoNarabi">YOKO1</div>
    <div class="yokoNarabi">YOKO2</div>
    <div class="yokoNarabi">YOKO3</div>
    <div class="yokoNarabi">YOKO4</div>
    <div class="yokoNarabi">YOKO5</div>
    <div class="yokoNarabi">YOKO6</div>
</div>
```
```.css
.yoko{
        display: flex;
    }
```
<img width="600" alt="yoko.html.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/58fb8762-bd4c-25a3-ae39-5dbab2022a22.png">

## Chromeのデベロッパーで色んな並び方が見れる
これが何よりも楽。
<img width="600" alt="Chrome flex.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/8873ebcc-407d-f978-2f3c-5d99b951658a.png">


この中でも`justify-content`をよく使うと思うので以下より紹介

## `justify-content: center;`
<img width="210" alt="Chrome_dev_center.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/75a8fa8f-2857-9630-6973-8c3ca06d9912.png" >
<img width="800" alt="flex_center.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/f326d3f5-2fe8-75a4-16fb-c8c908be80b8.png" >

## `justify-content: flex-start;`
<img width="200" alt="Chrome_dev_start.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/9d258eef-3d96-f058-6e83-320cbd1f607a.png" >
<img width="800" alt="flex_start.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/6b036c7d-f22e-e9af-19c7-5def5139e9d4.png" >

## `justify-content: flex-end;`
<img width="200" alt="Chrome_dev_end.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/baf7ba82-d884-7201-d1a1-409e2b8d9fd2.png
" >
<img width="800" alt="flex_end.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/4ba03166-c287-d5ab-8811-6e5550ea468b.png" >

## `justify-content: space-between;`
<img width="200" alt="Chrome_dev_spacebetween.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/beb97576-1448-6ae5-f007-8ff9c81002bc.png
" >
<img width="800" alt="flex_spacebetween.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/27b26c49-e4f8-a56c-ae01-df3dac9331dc.png" >

## `justify-content: space-around;`
<img width="200" alt="Chrome_dev_spacearound.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/1f7f6201-2f13-e6dd-1fdb-419491dfb90b.png
" >
<img width="800" alt="flex_spacearound.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/3526b1c9-8cd4-295c-5dce-9370e8b75a9d.png" >

## `justify-content: space-evenly;`
<img width="200" alt="Chrome_dev_spaceevenly.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/68a8b09a-1b92-6c34-1922-1a997eea2452.png
" >
<img width="800" alt="flex_spaceevenly.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537139/2d78d254-e48b-0969-5c6c-f7fdfa5ba8cb.png" >
Git よく使うコマンド②


### はじめに
初心者なのでよく使うコマンドを備忘録第2弾。

### 1. `git add ファイル名`
`git add ****`
* 変更したファイルをステージングエリアへ追加する。

### 2. `git commit -m "コメント"`
`git commit -m "****"`
* ステージングにあるファイルをリポジトリに更新する。
* `-m`で任意のコメントを付けられる。

### 3. `git push リポジトリ名 ローカルブランチ名:リモートブランチ名`
`git push push origin ****:****`
* ローカルのリポジトリからリモートのリポジトリへ更新する。
Git よく使うコマンド①


### はじめに
最近、業務でGitを使うようになり、
初心者なのでよく使うコマンドを備忘録がてら記載していきます。

### 1. `git branch -a`
`git branch -a`
* branch一覧を表示。`-a`をつけることで
リモート含めた全てのbranchを見ることができる。

* 今、どこのbranchにいるのかを確認するために使用してます。

### 2. `git fetch`
`git fetch`
* リモートリポジトリの最新の履歴を取得だけを行える。
正確にはローカルにある
リモートを追跡してるbranchへ取得してるそうです。

### 3. `git merge`
`git merge`
* ローカルの`master`を最新へ更新する。

### 4. `git checkout -b 新しいブランチ名`
`git checkout -b *****`
*  最新の`master`から派生させてローカルに新しいbranchを切る。
*  `-b`をつけることでブランチを切り替えられる。



### 参考記事

【初心者向け】git fetch、git merge、git pullの違いについて

https://qiita.com/wann/items/688bc17460a457104d7d
AWSathenaゼミ活動内容まとめ　＃AWS

## AWS athena、Glueのハンズオン資料
athena　glueのサービス説明

きっかけ
https://aws.amazon.com/jp/builders-flash/202401/security-contents-summary/?awsf.filter-name=*all
のブログでおすすめの本として
AWSからはじめるクラウドセキュリティという本があり、買って読んでみたところサービスの一つとしてAthenaが紹介されていたため。
セキュリティのサービスというよりログを分析することで不審な状況を判断できるという触れ込みで紹介されていました。
Glueに関してはAthenaを色々調べるうちに結構密接するサービスであったのでせっかくならやろうということで取り上げています

Athenaは、Amazon Web Services（以下、AWS）が提供するクエリサービスです。データストアに保存されたデータを、標準SQL（Structured Query Language）を使って分析することができます。

サーバレスであるので利用コスト低くて、素早く利用可能

SQLを使用しているので学習コスト低い→自分はまだ、、、







#### Amazon Athena +Glueの比較
２回目　athenaやglueに関する記事や動画を見ているとベストプラクティスについて色々見る
S3 + AthenaだけなのかS3 + Glue + Athena 
実際にAthenaのハンズオンを行いながら2つの構成の比較をしました




https://docs.aws.amazon.com/ja_jp/athena/latest/ug/getting-started.html
https://blog.mmmcorp.co.jp/2022/11/24/athena_glue/

手順S3に任意のバケットを作成、そこにCSVファイルをアップロード

![スクリーンショット 2024-01-30 203222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/7c7de349-f826-3d23-36a1-541836509895.png)

Athenaに移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/12cad97b-4109-f055-3f83-4387a4ebb9d5.png)

設定で参照したいS3の場所を設定

エディタでデータベースを作成![スクリーンショット 2024-01-30 203500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/618ea7cb-e6b6-7cf3-0944-dd2657ea320f.png)
オレンジ色のところを実行
データベースで作成したものを選択可能
作成を押しS３バケットデータを選択
テーブルの作成、CSVファイルを選択、列の作成を行う
テーブルを作成を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/cc421869-dfe8-b65a-cc68-3df1a4d4bc9d.png)
クリエの実行を行うことで以下のようなテーブルができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/07b7d00f-a600-0214-bb6d-52e16336b258.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/79b15a73-4612-77eb-81f7-095c2520eecc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/b2097b28-e9b9-089b-25c4-18c0c6b3028f.png)
IAMロールの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/b9d063f7-0db8-579d-cf91-8ccb34ff6f04.png)
AWSglueの実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/480ac50e-70c6-0b32-680d-cdbc66ded0c3.png)
実行後クリエで内容を参照すると以下のようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688241/14d4e235-945f-da61-828e-5a0cbfe3821b.png)

Amazon glueを使うことにより自動でCSVの内容を判断して持ってきている

S3＋AthenaだけでよいのはS3に格納するデータについて事前に情報が把握できているとき
SQLについて抵抗感がなければわざわざGlueを使うという手間を省いて作業ができるので便利である

一方でGlueを使用することでCSVファイルを自動的に読み取りを行ってくれるのでかなり便利である
SQLやデータ型について理解ができていなくても作成できる
適当にやって文字化けした時でもGlueを使用したらデータベースの作成ができたのでより
属人化が防げるような気がしました、、