OmniAICreator/Qiita-1.07M huggingface dataset:
シンボリック計算

SymPyは代数計算（数式処理）を行うPythonのライブラリ．

因数分解したり，方程式（連立方程式）を解いたり，微分積分を計算したりすることができる便利ツール．

# SymPyのインストール
ターミナル/コマンドプロンプトを開いて入力．
```
$ pip install sympy
```

# 基本的な使い方
* [変数と式の定義](#変数と式の定義)
* [変数に値を代入＆式を計算](#変数に値を代入＆式を計算)
* [式の展開と因数分解](#式の展開と因数分解)
* [(連立)方程式を解く](#(連立)方程式を解く)
* 微分・積分を使う
* 三角関数や対数を使う

## 変数と式の定義
```python:symbolic.py
import sympy as sp

# 方程式（シンボリック式）の中での変数は，シンボリック変数と呼ばれ，
## 通常の（コード内に書かれた）変数とは別に扱われる
x = sp.Symbol('x')    # シンボリック変数 x
y = sp.Symbol('y')    # シンボリック変数 y
expr = x**2 + y + 1   # シンボリック式 expr

# # 定数は通常通り変数を使って記述してもよい
# a = 2
# b = 1
# c = 1
# expr = x**a + b*y + c
print(expr)
```
どちらも`x**2 + y + 1`を返す．

## 変数に値を代入＆式を計算
```python:symbolic.py
import sympy as sp

# 方程式（シンボリック式）の中での変数は，シンボリック変数と呼ばれ，
## 通常の（コード内に書かれた）変数とは別に扱われる
x = sp.Symbol('x')    # シンボリック変数 x
y = sp.Symbol('y')    # シンボリック変数 y
expr = x**2 + y + 1   # シンボリック式 expr

# # 定数は通常通り変数を使って記述してもよい
# a = 2
# b = 1
# c = 1
# expr = x**a + b*y + c
print(expr)

# シンボリック式の変数（シンボリック変数）に
## 好きな値を代入
print(expr.subs(x,1))   # x=1を代入
print(expr.subs(x,y))   # x=yを代入
# x, y の2変数に値を代入するときは，
## subs()の引数にタプルで入力
p = expr.subs([(x,1),(y,2)])    # x=1, y=2を代入
print(p)
```

このときの出力は以下
```
x**2 + y + 1
y + 2
y**2 + y + 1
4
```
## 式の展開と因数分解
```python:symbolic.py
import sympy as sp

# 式の展開と因数分解
x = sp.Symbol('x')    # シンボリック変数 x
# 式の展開
before = (x+1)**2
after = sp.expand(before)
print(after)
# 式の因数分解
# before2 = x**2 + 2*x + 1
before2 = after
after2 = sp.factor(before2)
print(after2)
```
出力は以下
```
x**2 + 2*x + 1
(x + 1)**2
```

## (連立)方程式を解く
`solve()`メソッドを用いる．（）内の値は，`式=0`が成り立つような`式`を入力する．
連立方程式を解く際，引数はリストでもタプルでもどちらでもよい（代入の時の引数は必ずタプル）

```python:symbolic.py
import sympy as sp

# 式の展開と因数分解
x = sp.Symbol('x')    # シンボリック変数 x
y = sp.Symbol('y')    # シンボリック変数 y
expr = x**2 + y + 1   # シンボリック式 expr

# 式の展開
before = (x+1)**2
# 方程式を解く
print(sp.solve(before))     # (x+1)**2=0を解く
print(sp.solve(x**2 + x + 1)) # x**2+x+1=0を解く
print(sp.solve(expr, x))    # xについて解く
print(sp.solve(expr, y))    # yについて解く
# 連立方程式を解く
expr1 = 3 * x + 5 * y - 29
expr2 = x + y - 7
print(sp.solve([expr1, expr2]))     # 関係式をリストorタプルで引数に入力
```
この時の出力は以下となり，ちゃんと解けている．ただし，√は`sqrt()`，虚数*i*は`I`で表示される．
```
[-1]
[-1/2 - sqrt(3)*I/2, -1/2 + sqrt(3)*I/2]
[-sqrt(-y - 1), sqrt(-y - 1)]
[-x**2 - 1]
{x: 3, y: 4}
```
10言語でのHelloWorld表示方法

# 10言語でのHelloWorld表示方法

プログラミングを始める際、多くの人が最初に試すのが「Hello World」の表示です。このシンプルな例は、様々なプログラミング言語の基本的な構文や動作を理解するのに役立ちます。ここでは、10種類の異なる言語での「Hello World」の表示方法を紹介します。

## HTML: マークアップ言語での表示
```html
<!DOCTYPE html>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
    <p>Hello World</p>
</body>
</html>
```
HTMLでは、`<p>`タグを使ってテキストを表示します。

## JavaScript: Webブラウザでの動的表示
```javascript
console.log("Hello World");
```
JavaScriptでは、`console.log`関数を使ってコンソールにメッセージを表示します。

## PHP: サーバーサイドスクリプト言語
```php
<?php
echo "Hello World";
?>
```
PHPでは、`echo`文を使用してテキストを出力します。

## Ruby: オブジェクト指向スクリプト言語
```ruby
puts "Hello World"
```
Rubyでは、`puts`メソッドを用いてコンソールに文字列を出力します。

## Python: 汎用の高水準プログラミング言語
```python
print("Hello World")
```
Pythonでは、`print`関数を使用してメッセージを表示します。

## Go: Googleによって開発されたプログラミング言語
```go
package main
import "fmt"
func main() {
    fmt.Println("Hello World")
}
```
Go言語では、`fmt`パッケージの`Println`関数を使用します。

## Java: オブジェクト指向プログラミング言語
```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
```
Javaでは、`System.out.println`メソッドを使用してコンソールに出力します。

## C++: 汎用プログラミング言語
```cpp
#include <iostream>
using namespace std;
int main() {
    cout << "Hello World" << endl;
    return 0;
}
```
C++では、`cout`オブジェクトを用いて標準出力にメッセージを表示します。

## Perl: テキスト処理スクリプト言語
```perl
print "Hello World\n";
```
Perlでは、`print`関数を使用してテキストを表示します。

## まとめ
各プログラミング言語には、独自の構文や方法で「Hello World」を表示する方法があります。これらの基本的な例は、それぞれの言語の特徴や使い方を理解するための出発点となります。プログラミングの世界への最初の一歩として、これらの言語での「Hello World」を試してみてください。
Array.from()

# Array.from()
Array.from() 静的メソッドは、反復可能オブジェクトや配列風オブジェクトからシャローコピーされた、新しい Array インスタンスを生成します。
```js
console.log(Array.from('foo'));
// Expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], (x) => x + x));
// Expected output: Array [2, 4, 6]
```
# 出典
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from

# HTMLCollectionでも配列を作ることができる
idを基にしたhtmlの要素を取得した後、forEachで繰り返し処理ができないがこれを使えばできる

# 出典

https://stackoverflow.com/questions/15094886/why-is-foreach-not-working-for-children

# 感想
これで子要素に繰り返し処理ができる
PostmanからSalesforceのReports and Dashboards REST API を使ってみる *


[Salesforce Reports and Dashboards REST API Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_intro.htm)

# List Recently Viewed Reports 最近表示したレポートの一覧を取得する

https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_list_recentreports.htm


HTTP Methods : GET
```
{{_endpoint}}/services/data/v{{version}}/analytics/reports
```

レポートのIdを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a6321f8c-571d-d090-2af9-e93deee16bdd.png)

最近表示したレポートの一覧

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f9b51f2b-3266-c5a5-4ad6-6fdd8bf3a6e1.png)

```
{{_endpoint}}/services/data/v{{version}}/analytics/reports
```

上記を新たに追加して送信すると、ちゃんと結果が返ってきました。レポートのIdも一致しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/bb4dfa0e-a2a9-5920-0e38-66901c1cc974.png)

# クエリ　（Query）

https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_report_query.htm

HTTP Methods : POST
```
{{_endpoint}}/services/data/v{{version}}/analytics/reports/query
```

既存のレポートへの変更を保存したり、新しいレポートを作成したりせずに、レポート データを返します。


Postメソッドなのに、Bodyをしてないというエラーみたい。

```
[
    {
        "errorCode": "BAD_REQUEST",
        "message": "The request is invalid because there is no metadata. Specify metadata in the request body."
    }
]
```
Bodyでレポートを送信して、このレポートで表示されるレコードを返すみたい。思っていた機能とは違いました...
本当はある条件で一致するレポートのIdを取得したかったのですがね。


# レポートフィールド (Report Fields)

https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_get_fields.htm

HTTP Methods : POST
```
{{_endpoint}}/services/data/v{{version}}/analytics/reports/:reportID/fields
```

レポート フィールド リソースは、指定されたレポートで使用できるレポート フィールドを返します。このリソースを使用して、さまざまなソース レポートに共通するフィールドを確認することで、ダッシュボード フィルターで使用するのに最適なフィールドを決定します

Body

```
{
   "intersectWith": ["00O5i00000BZzQBEA1"]
}
```

結果を取得できるのですが、どのような意味で表示されているかがよく分からないですね。レポートに共通するフィールドを確認するとあるけど、オブジェクトの全ての項目がただ表示されているだけで、1901行もあってみる気がしませんでした。本当に便利な機能なのかは理解できませんでした。


個人的にはこのSalesforceのReports and Dashboards REST API の中にレポートを消す処理があるので、ある条件でレポートのIdを取得してレポートが消せたらなぁと思っているのですが、レポートIdの検索はSQLで行った方が早いのですが、自動化できないですよね。


[Report オブジェクト](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_report.htm)
S3互換OSS MinIO&Node.jsでローカル開発

# はじめに

最近、開発のためにMinIOを導入したが、Node.jsの`aws-sdk`でMinIOを操作するサンプルコードがなかなか見つからなくて少し苦労したので、備忘録のために投稿します。
（AWS CLIやNode.jsの`@aws-sdk/client-s3`でMinIOを操作するサンプルはたくさんある）

前半はMinIOの導入方法で、本題は後半の [Node.jsでMinIOを操作（本題）](#Node.jsでMinIOを操作（本題）)です。

# MinIOを導入
１． docker-compose.yamlファイルを用意する

```yaml:docker-compose.yaml
version: '3.9'

services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: example-minio
    environment:
      MINIO_ROOT_USER: root
      MINIO_ROOT_PASSWORD: password
    command: server --console-address ":9001" /data
    ports:
      - 9000:9000
      - 9001:9001
```

２． コンテナを起動

```bash
docker-compose up
```
これでMinIOが http://localhost:9000 で稼働する。
また、管理画面が http://localhost:9001 で稼働する。

# MinIO管理画面にログイン

ブラウザで http://localhost:9001 にアクセスすると下記の画面が表示される。
Username/Passwordは`docker-compose.yaml`に設定した`root/password`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191958/4ce125fe-8262-7bb3-131b-e5c82788cfac.png)

# Node.jsでMinIOを操作（本題）

以下のコードでMinIOにアップロードしたファイルをダウンロードできる

```javascript:test.js
const AWS = require('aws-sdk');

const s3 = new AWS.S3({
  accessKeyId: "root",
  secretAccessKey: "password",
  endpoint: "http://localhost:9000",
  s3ForcePathStyle: 'true',
  signatureVersion: 'v4',
})

const bucketName = "test"
const fileName = "sample.png"
const config = { Bucket: bucketName, Key: fileName }

(async () => {
    const file = await s3.getObject(config).promise()
    const { Body } = file
    // 取得したファイルをBase64に変換する
    const base64Result = Body.toString('base64');
})
```

実行方法

```
node test.js
```

# おわりに
昔は他のS3互換のOSSをローカルの開発に利用していたが、管理画面があるMinIOが圧倒的に便利と感じた

# 参考

- [MinIOの使い方：Amazon S3をローカル環境に構築](https://go-tech.blog/aws/s3-minio/)
ROS2をzshで使うとTab補完ができない件

## 環境
OS:Ubuntu 22.04 LTS
ROS2 version: Humble
Shell:zsh(Z shell)
## 現象
ROSの頃からあったことなのか不明なのですが例えば`ros2`まで打ってTabを連打しても今いるディレクトリのファイルが候補として出てきてしまう。

## 原因
[No completion for 'ros2 run' in zsh](https://answers.ros.org/question/394021/no-completion-for-ros2-run-in-zsh/)
ということでROS Answersに載っていました。実はzsh環境で且つaptで入れた場合にのみ発生する（随分前からあるバグっぽいのになぜ…？）ようで、ローカルでコンパイルするとうまく行くようです。

## 解決方法
`.zshrc`に以下の内容を追加しましょう。
```
# argcomplete for ros2 & colcon
eval "$(register-python-argcomplete3 ros2)"
eval "$(register-python-argcomplete3 colcon)"
```
### 注意点
この`eval`ですが`source /opt/ros/hogehoge/setup.zsh`するとリセットされます。なので必ず追加する際はそれより下に配置してください。また`source`するエイリアスを設定している方は`&&`で併記すると良いと思います。
openpyxlでExcelの最終行を取得する際に気を付けること

## はじめに
openpyxlを使用してPythonスクリプトからExcelを処理する際に，「最終行の取得」で躓いたので紹介します．備忘録です．

## 動作環境
- Python 3.12.0
- openpyxl 3.1.2

openpyxlはpipを使用してインストールできます．
```
pip install openpyxl
```

## 最終行取得コード
早速ですが最終行取得のソースコードを紹介します．
### ソースコード
```python
import openpyxl as px

# Excelファイルの指定
inputFile = r"C:\Qiita\test.xlsx"
# 指定したExcelを開く
wb = px.load_workbook(inputFile)
# 開いたExcelファイルの一番左のシートを選択
ws = wb.worksheets[0]
# 最大行番号を取得
max = ws.max_row
```
openpyxlの```worksheet.max_row```属性は最大行番号を取得します．下図の例では "9" を返します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/c2f0e579-4c62-1f07-bd2d-14732cbe0552.png)

うわめっちゃスッキリ書けるなぁ...と感心していると罠にハマってしまったわけです．

実はこのmax_row（最終行取得），<ins>**セルに値が入っていなくても書式が設定されているとそのセルを最終行と認識してしまうのです．**</ins>

試しにA10の書式を変更してみましょう．
今回は文字制御を「折り返して全体を表示」に変更してみます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/5255eee3-de81-bc9e-e950-004e18f3efec.png)

設定を更新して上記のコードを再実行するとmaxは10を返します．
新規でBookを作成する場合，このような事象は起きにくいとは思いますが，既存のファイルを処理する場合は注意が必要です．

個人的書式変更してるやんあるあるは，「フォント（サイズ，字体）の変更」「セルの白塗りつぶし（透明のつもり）」です．共有ファイルなんてのは何が起きてるかわかりません，いろんな方が触りますからね...

## 対応策
対応策としては，最終行を取得した後，「セルをディクリメントしていき，値が設定されているか確認する」というまあ力技です．以下ソースコードです．

```python
import openpyxl as px

# Excelファイルの指定
inputFile = r"C:\Qiita\test.xlsx"
# 指定したExcelを開く
wb = px.load_workbook(inputFile)
# 開いたExcelファイルの一番左のシートを選択
ws = wb.worksheets[0]
# 最大行番号を取得
max = ws.max_row

# 最終行に値があるか確認する
while True:
    if ws.cell(row=max, column=1).value == None:
        max -= 1
    else:
        break
```

## おわりに
```max_row```に限らず```max_column```でも同様のため，最終行列を取得する際は注意が必要です．
（そういえばVBAでも同じような仕様だったような...？）
KMSキーのエイリアス名をAWS CloudFormationパラメータの値として使用する際の注意点

## はじめに
AWS CloudFormationを使用してリソースを作成する際に、AWS Key Management Service (KMS) キーのAWS managed keysのエイリアス名をパラメータの値として指定する時の注意点についてご紹介します。

## AWS managed keysのエイリアス名を使用するメリット
>エイリアスを使用すると、AWS マネージドキー の認識が容易になります。  
プロジェクトやカテゴリの名前をエイリアスの前に付けるなど、プロジェクトに対して同様のエイリアス標準を設定できます。

https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/kms-alias.html

AWS managed keysを使用する際、CloudFormationテンプレートを異なるアカウントで利用したい場合があります。その際、KMSキーのAmazon Resource Name (ARN) を指定すると、該当アカウントでのみ使用可能になってしまいます。そこで、AWS managed keysのエイリアス名を使用することで、アカウントに関係なく異なるアカウントでも値として使用できるようになります。

## AWS managed keysのエイリアス名の指定方法

AWSのエイリアス名を指定する場合は、`alias/<エイリアス名>`の形式で指定する必要があります。AWS managed keysのエイリアス名も同様に、"aws/サービス名"の前に"alias/"を付ける必要があります。例えば、エイリアス名が`aws/backup`の場合は、`alias/aws/backup`と指定します。`aws/backup`のみ値として入力した場合、次のようなエラーが表示されます。

```yaml
  BackupVault:
    Type: AWS::Backup::BackupVault
    Properties:
      EncryptionKeyArn: aws/backup
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330696/0ade347c-9bf4-c479-8360-f721657b5740.png)


```yaml
  BackupVault:
    Type: AWS::Backup::BackupVault
    Properties:
      EncryptionKeyArn: alias/aws/backup
```
KMSキーのAWS managed keysのエイリアス名を`alias/aws/backup`と指定して、BackupVaultリソースの暗号化に使用できます。

## まとめ

AWSのエイリアス名を指定する場合は、`alias/<エイリアス名>`の形式で指定する必要があります。AWS managed keysのエイリアス名も同様に、"aws/サービス名"の前に"alias/"を付ける必要があります。
demo用

このエラーメッセージから判断するに、Spring Bootアプリケーションの起動中に javax.servlet.ServletContext.getVirtualServerName メソッドに関連する問題が発生しているようです。このエラーは、Servlet仕様またはそれに関連するライブラリのバージョンの不一致による可能性があります。

問題を解決するために、以下の手順を試してみてください：

依存関係のバージョンを確認： プロジェクトの依存関係がServletに関するもので、バージョンが整合していることを確認してください。pom.xml ファイル（Mavenプロジェクトの場合）または build.gradle ファイル（Gradleプロジェクトの場合）を確認し、Servletに関連する依存関係のバージョンが一致していることを確認してください。

```XML:title.xml

<!-- Mavenの例 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version> <!-- 適切なバージョンに調整してください -->
</dependency>


```

Spring Bootのバージョンを確認： 使用しているSpring BootのバージョンがServlet関連の依存関係と互換性があることを確認してください。Spring Bootの公式ドキュメントでバージョンの互換性に関する情報を探すことができます。

依存関係の除外： MavenまたはGradleの依存関係の除外機能を使用して、問題を引き起こす可能性のあるライブラリを除外してみてください。例：

```XML:title.xml
<!-- Mavenの例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
```
依存関係の更新： 使用しているすべての依存関係が最新バージョンであることを確認し、既知の問題やエラーを回避します。

エラーログの確認： より詳細なエラーログを確認し、問題の原因を特定できるかどうかを確認してください。エラーログには通常、問題を引き起こしているクラスやライブラリが示されます。

これらの手順を試しても問題が解決しない場合は、エラーログやプロジェクトの詳細な情報を提供いただければ、より具体的なサポートが可能かもしれません。
SwiftUIでカスタム評価ビューを自作する（続編）

こんにちは、[株式会社Globee](https://www.globee.io)の @toshi0383 です。
[前回の記事](https://qiita.com/toshi0383/items/f100a512662972de5a38) の続編です。
[SwiftUI Advent Calendar](https://qiita.com/advent-calendar/2023/swiftui)の6日目を埋めさせてもらいました。
宣言通り、⭐️を正式に実装します。

# コード

結論から共有しますと、こんなコードになります。
こちらのリポジトリに反映されています。
https://github.com/toshi0383/StarRatingView

```swift

struct StarShape: Shape {
    var points: Int = 5
    var innerRatio: CGFloat = 0.5 // The ratio of the inner radius to the outer radius

    func path(in rect: CGRect) -> Path {
        let drawPoints = points * 2
        let outerRadius: CGFloat = min(rect.size.width, rect.size.height) / 2
        let innerRadius: CGFloat = outerRadius * innerRatio
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()

        // Start from the top
        let startAngle = (-CGFloat.pi / 2)
        let angleIncrement = .pi / CGFloat(points)

        for i in 0..<drawPoints {
            let radius = i % 2 == 0 ? outerRadius : innerRadius
            let angle = startAngle + (angleIncrement * CGFloat(i))

            let point = CGPoint(
                x: center.x + radius * cos(angle),
                y: center.y + radius * sin(angle)
            )

            if i == 0 {
                path.move(to: point) // move to the start point
            } else {
                path.addLine(to: point) // draw line to next point
            }
        }

        path.closeSubpath()
        return path
    }
}
```

# How to Make a Star

このコードにたどり着いた経緯を紹介します。
前回の実装の後、星のビミョーなマジックナンバー実装をどうしようかと考えていたのですが、散歩中に閃きました。
「プログラムで五芒星を表現するのは難しいが、そういえばWebデザイナーとかはどうやって星のアイコンなどを作成しているのだろう？」

検索すると、YouTubeでこんな動画が見つかりました。
[![How to draw a star](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35008/0deb8e29-766b-8d92-5fc5-388558860117.png)](https://www.youtube.com/watch?v=UldSU23DJ0A)

なるほど、内側と外側の円を定義して、あとは`※`のようなアイコンの値（頂点の数かな）を変化させることでN芒星を描けるようです。
おそらくデザイナーの間では常識的な知識なのだと思いますが、こういった匠の技みたいなのは知識欲を駆り立てられます。

今回は大して難しい内容ではなかったですが、こういった発想の転換というのは普段の問題解決でも大事にしていきたいと思っています。

# ChatGPT

さて、作るものが決まりましたので、ここでまたもやChatGPTに登場してもらいます。
ChatGPTとはだいぶ連携してきましたので、直感的に、これは細かい実装詳細の指示など何にも必要なさそうだと理解しました。
上記のスクリーンショットをそのまま渡します。

`このFigmaの定義をSwiftUIのShapeにできますか？`

何度かコンパイルエラーを直してもらいましたが、無事上記のようなコードに辿り着きました。

# コードを読んでみる

少しコードを読み解くと、五芒星であれば5 x 2 == 10個の頂点を順番に描いていることがわかりますね。
N芒星のNも変数になっていますので、これを変えることで簡単に六芒星など他の形にもアレンジできます。

![starratingview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35008/f0684924-7c64-d39c-368a-bb566e22b93d.gif)

以前のバージョンからはマジックナンバーがなくなり、拡張性も担保され、綺麗なコードになった言えるのではないでしょうか。
強いていえばあと頂点の角丸だけ機能追加したいですね。

# まとめ

いかがだったでしょうか。
またもやChatGPTの時短実装オチになってしまいました。

> なおStarShapeの実装には納得がいっていませんので、続編で正式にプロのエンジニアっぽい実装にします。

プロのエンジニアだからと言って、ChatGPTを使わないわけではありません。
社会の変化を受け入れ、全力で活用していきましょう。

# 採用情報
現在株式会社Globeeではエンジニア採用を積極的に行っています。
まずはカジュアル面談にて弊社の「教育」にかける思いや「ものづくり」の考え方についてお話できればと思いますので、皆様お気軽にご応募ください。
https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc
RaspberryPiのベアメタル開発でCircleが「make: *** [all] Error 2」になった時にすること

# 発生した問題

RaspberryPi Zero W のベアメタル環境で [Circle](https://github.com/rsta2/circle) を使って C++ アプリの開発をしていたのですが、[自作のZ80エミュレータ](https://github.com/suzukiplan/z80)をビルドしてみたところ、以下のようなエラーになりました。

```bash
% make
cp ../src/* .
make -f Build.mak
make: *** [all] Error 2
```

どのようなエラーが原因なのか分からないですね...

# 原因が分からない原因

Build.mak の内容は次のようになっています。

```Build.mak
CIRCLEHOME = ./circle
OBJS = main.o
LIBS = $(CIRCLEHOME)/lib/libcircle.a
include $(CIRCLEHOME)/Rules.mk
-include $(DEPS)
```

Circle が提供する [Rules.mk](https://github.com/rsta2/circle/blob/master/Rules.mk) へ渡すオプション情報だけ定義したシンプルな Makefile です。

Rules.mk の内容をざっくり確認したところ、

1. コードの依存関係チェック
1. コンパイル

という流れでビルド処理をしていたので、試しに依存関係チェックを省略できる `CHECK_DEPS = 0` という環境変数を定義してみました。

```Build.mak
CIRCLEHOME = ./circle

# コレを追加
CHECK_DEPS = 0

OBJS = main.o
LIBS = $(CIRCLEHOME)/lib/libcircle.a
include $(CIRCLEHOME)/Rules.mk
-include $(DEPS)
```

すると、エラーが以下のように変わり、無事原因が分かるようになります。

```bash
% make
cp ../src/* .
make -f Build.mak
  CPP   kernel.o
In file included from kernel.cpp:29:
z80.hpp:29:10: fatal error: functional: No such file or directory
   29 | #include <functional>
      |          ^~~~~~~~~~~~
compilation terminated.
make[1]: *** [kernel.o] Error 1
make: *** [all] Error 2
```

要するに、functional（`std::function`）がCircleではまだ使えないようですね。

# 対策（参考）

__前章までが本記事の本題で、以下は具体的にこの問題をどう対処したかを参考までに記します。__

functional 以外にも map, vector, 例外あたりがベアメタル環境では使えない（[参考](https://arobenko.github.io/bare_metal_cpp/)）ので、それらを排除できるコンパイルオプションを追加する力技で対処することにしました。

以下Pull Requestの最新commitの状態で、

https://github.com/suzukiplan/z80/pull/57

Build.mak に以下を付与すれば無事コンパイルが通りました。

```
CPPFLAGS = -DZ80_DISABLE_DEBUG -DZ80_DISABLE_BREAKPOINT -DZ80_DISABLE_NESTCHECK -DZ80_NO_FUNCTIONAL -DZ80_NO_EXCEPTION
```

幸い、主要な機能ではSTLを使っていなかったので助かりました。

あまり美しい対処ではないですが仕方ないかなと。

> _美しく組みたければベアメタルでなんか組まずにLinuxを入れてしまうのがベスト_

:::note

**2023.12.12追記**
Circle での C++ STL (map や vector) の利用ですが [こちらのドキュメント](https://github.com/rsta2/circle/blob/master/doc/stdlib-support.txt) に使い方が書かれていました。Config.mk に `STDLIB_SUPPORT=3` を定義すれば C++ STL (map や vector) が使えるようです。


```Config.mk
STDLIB_SUPPORT=3
```
:::

:::note
**2023.12.13追記**
`STDLIB_SUPPORT=3` を定義してみましたが map や vector は使えないようでした。
一部C++標準ヘッダーは使えるが freestanding mode の範囲内に限られ、map　や vector はそれに含まれないようです。

`#include <map>` をすると以下のようなエラーになりました。

```
/Applications/ArmGNUToolchain/13.2.Rel1/aarch64-none-elf/aarch64-none-elf/include/c++/13.2.1/bits/requires_hosted.h:34:4: error: #error "This header is not available in freestanding mode."
   34 | #  error "This header is not available in freestanding mode."
      |    ^~~~~
```

freestanding mode：
https://stackoverflow.com/questions/23258415/whats-freestanding-mode-for-libstdc

ということで、やはりベアメタルであれば STL は基本使えないということで、当初記事に書いた通り「STL を使いたい場合は Linux を使う」のがベターかもしれません。

_どうしても STL を使いたい場合は EASTL とかかな（未検証）_
https://github.com/electronicarts/EASTL
:::
井（い）の中（なか）の蛙（かわず）大海（たいかい）を知（し）らず

こんにちは！

アリスです！！

今回は私の経験からの話をしてみたいと思います

一つの会社、プロジェクトに長く携わっている方がたくさんいらっしゃるかもですが、
私は数え切れないほどのプロジェクトを担当して、いくつかの会社を経験しました。


その中で得た大事な経験は、タイトル通りとなります。
環境によって、全てが変わります

プロジェクトが変わったとしても、新しい会社を経験したことがないと、
その分のスキルは得ることができないです
これはどうしても経験しないと埋められない部分になります

それをわかっているからこそ、私のグループのメンバーにはなるべく、
一つのプロジェクトに長くいて欲しくないので、
たくさんのプロジェクトに関わって欲しいと思っています。

それもそれで状況が難しいんですよねー
難しくてもやるのが仕事ですけど！

一つのプロジェクトに長くいて、一つの会社に長く勤めることも
もちろんメリットがあります！
ディスってるわけではないので、誤解はしないで欲しい！！

個人的に
色々動き回るのが、好きなのと、
そこで得られるスキルがたくさんあるよ！
ということを伝えたかったです！


以上！
PowerAppsのキャンバスアプリの開発手順

長い期間PowerAppsを触らなく、再びPowerAppsのキャンバスアプリを開発したら、
頭が真っ白になります。
そのため、キャンバスアプリの案件が来たら、どうやって着手するのかをメモーします。

# 手順
①画面サイズを確認する必要
キャンバスアプリを開発する前に、Figmaなどのデザインファイルがあると思いますが、
まず、デザインファイルから、画面のサイズを確認してください。

②デザインをpowerappsで再現
・デザインファイルのボタンや、文字などをpowerappsに反映
・コントロールをクリックし、プロパティ、詳細設定でwidthなどを調整(色設定ColorValue("#B9B9B9"))
・四角コントロールをうまく使って、pop、side panelなど作れる
・mapコントロールは、白と黒しか設定できない
※tableの場合は、ギャラリーを使ったほうがよい、
ギャラリーを枠線で囲む方法 
https://www.youtube.com/watch?v=NfD2tT2Gwa8

③データ取得の実装
ScreenのOnVisibleプロパティ
OnStart

・ClearCollect でテーブルからデータを取得する
```
ClearCollect(
    dataCol,
    Ungroup(
        AddColumns(
            Table1 As a,
            group,
            ShowColumns(
                Filter(
                    Table2 As b,
                    Value(a.id) = Value(b.id),
                    a.item_id = b.item_id,
                    b.target_date >= Today(),
                    b.target_date <= DateAdd(Today(),27,Days)    
                ),
                item_name,//Table2の物理カラム名
                item_price
                )
        ),
        group
    )
);
```
・テーブルのあるカラムを合計値を取得する
```
ClearCollect(
    SumTable3,
        AddColumns(
            GroupBy(
                ShowColumns(
                    table4,
                    "id",
                    "sales"
                    ),
                 "id",
                 "other_columns"
            ),
        "sumSales",Sum(other_columns,sales)
    )
);
```
SumTable3
id, other_columns, sumSales
1,  table,         100

other_columns
sales
20
48
32

・コレクション作成中にカラムの値に対して判定
```
ClearCollect(
    Table5,
        AddColumns(
            Table6 ad a
            "stock_amount",
            If(a.sales <
            ,"Out of stock"
            ,If(a.sales = 0,"Low","High")
            )
        )
);
```
・距離計算
https://live-style.jp/powerapps_bingmaps/

```
ClearCollect(
    Table6,
    ForAll(Table7,
        {
            id :table7_id,
            other_columns:table7_other_columns,
            dst:Round(BingMaps.GetRouteV3(
                      "Driving",
                      itemA.latitude & ","itemA.longtude,
                      itemB.latitude & ","itemB.longtude
                      ).travelDistance
                      ,0)
        }
    )
);
Salesforce B2B Commerce でゲストユーザを利用できるようにしてみる

※ これから記載する事項は、私が所属する会社とは一切関係のない事柄です。

今回は B2B/D2C Commerce でゲストユーザを有効にしてみたいと思います。
基本的にはヘルプの「[ストアへのゲストアクセスの有効化](https://help.salesforce.com/s/articleView?id=sf.comm_config_guest_browsing.htm&type=5)」と「[LWR ストアでのゲスト顧客のチェックアウトの設定](https://help.salesforce.com/s/articleView?id=sf.comm_configure_guest_checkout_for_unregistered_shoppers.htm&type=5)」をみていけばすぐできますし、その内容は下記のように画面上から確認できますので設定手順に従っていけばいいかと思います。
今回は実際にやってみて少しわかりずらかったポイントをピックアップして紹介します。

コマースのホーム画面の **[管理]** タイルから管理ページに遷移。
![home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/1a5f3ac1-3be1-4009-3844-e25b8d746b61.png)

**[バイヤーアクセス]** タブをクリック。
![guest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/6779a5b9-bbb4-f8fb-43e9-c3cb8c6c99df.png)

## ポイント

###  1：チェックアウトには個人取引先の有効が必要

これはヘルプにも記載がありますが、ゲストユーザがチェックアウトする場合は個人取引先を有効にする必要があります。方法に関しては[こちらのヘルプ](https://help.salesforce.com/s/articleView?id=sf.commerce_enable_person_accounts.htm&type=5)を参考にしてください。

:::note warn
※ 一度、個人取引先を有効にすると無効にできないので要注意。
:::

### 2：ゲストプロファイルの取引先のデフォルトのレコードタイプを個人取引先に設定する

チェックアウトを成功させるにはゲストユーザのプロファイルに対してデフォルトの取引先のレコードタイプを「個人取引先」にする必要があります。

ゲストのプロファイルは Experience Builder からの設定から **[全般]** タブの「ゲストユーザープロファイル」項目からアクセスできます。
![スクリーンショット 2023-12-06 12.39.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/ed7beafe-51e4-6a60-46fa-5c39df7fda57.png)


プロファイルの「取引先のデフォルトのレコードタイプ」の項目から個人取引先の **[編集]** リンクをクリックして下記の画面を表示し画像のように設定し保存します。
![スクリーンショット 2023-12-06 11.32.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/c12140f7-c2d6-cbaf-88f1-1758843d4f25.png)



### 3 ：ナビゲーションの一般公開設定

デフォルトではヘッダーやフッターなどのナビゲーションは一般（ゲスト）に非公開になっているので、Experience Builder からの設定から **[ナビゲーション]** タブから編集したいナビゲーションの項目の設定で下記のように **[一般公開]** にチェックを入れ、保存します。  
![スクリーンショット 2023-12-06 11.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/52dff1c3-3d1d-a205-f462-4672321dbd62.png)



### 4 ：B2BDeliverySample が入っていない場合

ヘルプの「[LWR ストアでのゲスト顧客のチェックアウトの設定](https://help.salesforce.com/s/articleView?id=sf.comm_configure_guest_checkout_for_unregistered_shoppers.htm&type=5)」で注文配送方法を取得する Apex メソッド（B2BDeliverySample）の変更がありますが、場合によっては入っていない可能性があるので、入っていない場合の設定方法は[こちらの Apex](https://github.com/forcedotcom/commerce-on-lightning/blob/develop/examples/b2b/checkout/integrations/classes/B2BDeliverySample.cls) を利用してチェックアウトインテグレーションとして登録してください。インテグレーションとしての登録方法は「[Salesforce B2B/D2C Commerce のチェックアウトインテグレーションを利用する](https://qiita.com/syunyama/items/52e6636eb297ad75d4af)」をご覧ください。



## ゲストとしてアクセスしてみる

コマースのホーム画面の **[管理]** タイルから管理ページに遷移して **[一般設定]** タブ　をクリックするとサイトの URL を取得してサイトにアクセスします。
![url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/02a7b339-2e1b-86b0-0de5-cb6a03a63ecc.png)

ヘッダーの右上に「ログイン」という文字が出ていたらゲストとしてログインしている状態です。
![スクリーンショット 2023-12-06 13.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/02fda0b2-a33c-d481-285c-ce1badcf333a.png)
日本一の競馬予想AIを決定する大会に参戦する話

この記事は[MIXI DEVELOPERS Advent Calendar](https://qiita.com/advent-calendar/2023/mixi) 2023の4日目の記事です。
## はじめに
本記事は私が普段業務・趣味で競馬等公営競技周りのAI開発をしている経験を活かして、
[netkeiba](https://www.netkeiba.com/)が主催する「AI競馬予想マスターズ」に参加した上でシステム構成やAIの戦略面で考えたことをまとめました。
AIの精度向上的な観点は素晴らしい他の記事が多数あるので軽く触れる程度に留めようかとと思います。

最終戦進出し、
本記事執筆現在最終戦が開催中なので「[湯けむり競馬部](https://yoso.sp.netkeiba.com/masters/ai2023/profile.html?id=17218481)」応援よろしくお願いします！

## 競馬AIとは
競馬AIの目的次第ですが今回の大会では馬券の収支成績を競うためのAIということになるので
競馬AIは何かしらの機械学習モデル単体ではなく
機械学習モデル等を含み最終的に購入する馬券を組み立てる戦略システム全体として話を進めます。

## 競馬AIには2種類ある
競馬AIを利用目的で2種類に分けてみました。
この限りではないのかもしれませんが、利用目的に合わせた設計は熟考すべきテーマです。
- 馬券投票で儲ける
    - 投票締め切り直前に投票することが可能
        - 最終に近いオッズを利用することが可能
        - 馬体重等直前発表の特徴量を利用が可能
        -> データ利用面で有利になる
    - 自分の投票資金によって戦略立てをできる
- 予想を販売する
    - 前日・前々日に予測を作ることが必要
        - ユーザーが購入する時間を用意する必要があるため
    - ユーザーが買いたいと思う買い目戦略が必要
        - ほとんどのユーザーは多数のレースを投票しないので結構的中寄りな買い目でないと1日的中なしなどの体験を提供してしまう
        
## 大会ルールの考察
- 予選1・予選２・最終戦の3部構成でラウンドごとに下位が脱落方式
    - ラウンドは1月単位で実施されるので、最終戦に安定して進むには1月分のレース数で成績が安定する馬券戦略を取る必要がある。
    - 逆に1日単位で安定している必要はないという意味では結構強気な買い目設計をして良さそう。
- 予選1・予選2はスタート時に500万円分の資金を配布。最終戦は予選1・予選2の払い戻し額が資金になる。
    - 予選で高額の的中をしておくと、決勝ラウンドで有利に働く戦略を取ることもできる
    - 100万円クラスの的中を狙いに行くと上記の`1月分のレース数で成績が安定する馬券戦略`の実現が難しくなる
- 1レースあたり、最大15万円分・最大点数200点を上限
    - ある程度レース数を投票する必要があり、一発ワンチャン戦法がある程度封じられている
- 馬券の最小単位は100円、ただしレースに参加する場合最低1万円分は投票
    - このルールはいまいち意図がわかりませんでした
- 予選1・予選2の500万円を使い切れなかった場合は差分を払戻金額から減算
    - 予選1ラウンドで残資金7千円くらいになってしまい。
    このルールと`レースに参加する場合最低1万円分は投票`の合わせ技で7千円使いきれず。ペナルティをもらってしまいました。
    ﾅﾝﾃﾞﾔ
- 投票時間は各レースの発走時刻3分前まで
    - 実際の投票と大体同じ締め切り時間で、`馬券投票で儲ける`のケースでの戦略をそのまま利用することができました。

- 優勝賞金100万円！！

## 買い目戦略
公営競技ベッティングAIとしてはシンプルな構成をとっているかと思います。
AI->各馬の予測確率(1着, 2着以内, 3着以内)
組み合わせの予測確率->Harvilleの公式を多少応用して計算。
以下が元のHarvilleの公式による勝率P(A)P(B)P(C)から三連単P(ABC)を求める式です。
```math
P(ABC) = P(A)*\frac{P(B)}{(1-P(A))}*\frac{P(C)}{1-P(A)-P(B)}
```

オッズ->直前にwebから取得
単体および組み合わせの予測確率とオッズを掛け合わせることで買い目の期待値が計算できます

確率・オッズどちらも誤差がなければ、この時点で理論上無限に試行することができれば期待値>1の買い目を買い続けるだけで収支100%は達成できるはずです。

ですが、１月あたりのレース数は概算
```math
288R = 12(1日あたりのレース数)*3(3場開催の場合)＊8(開催日数)
```
程度であるので、最低でも288レースである程度当たる程度の推定的中確率がある買い目を買うのが現実的です。
が、予選1,2終了現在。リスク承知でワンチャン狙う戦法で結果を出している参加者もいるようなのでそこは戦略次第です。

大会期間での的中の頻度と期待値を考慮して、買える買い目は全部買う戦略をとっているため
予選1,2での1R平均買い目点数が28.7点と参加者内1位になっていました。
制御に関する詳しい設定はここには書けませんが(気になる方は大会ホームページで買い目が公開されているので分析してみてください)、3連単が的中した場合払い戻しが大きくなるように設定しています。
## システム構成
学習環境は特筆することはないので予測環境について書くことにします。
ローカルのコンピューターリソースをずっと稼働さるわけには行かないのでGoogleCloud上にシステムを構築しています。
各モジュールはGoogleCloudFunctionsで作成し連携することで予測を実行します。
- データ
収集
netkeibaからスクレイピングで取得します。
予測確率モデルに必要なレースデータ
各データはGoogleCloudSQLに保存します
＊スクレイピングはサーバーに負荷をかけない紳士的な頻度で
- 予測確率推定
上記で作成したデータをGoogleCloudStorageに保存された予測モデルに入力し予測確率を作成します。
予測確率は一旦csvでGoogleCloudStorageに保存
- 買い目作成
上記で作成した予測確率と現在のオッズを比較し、ルールに基づいて買い目を作成し大会APIに登録します。
- 実行管理
GoogleCloudSchedulerにより1分ごとに実行され、
レース20分前にデータ作成
レース15分前に予測確率推定
レース5分前に買い目作成を実行します

![スクリーンショット 2023-12-06 16.42.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236273/e539daed-fa63-3724-d4f2-3b0be9da929c.png)

## さいごに
この大会が開催され他の競馬AI開発者の生の買い目を見ることで
買い目に対する考え方に思いのほか多様性があったことに気づき、また自分の戦略を深めることもできたと思っていて開催いただいているnetkeibaさんには感謝しています。

ついでに賞金欲しい！！
Latexでよく使う構文(備忘録)

## はじめに
Latexで図や箇条書きを使うときに毎回書き方を調べていたため、備忘録として雑に記事に残しておきます。

## 箇条書き
```
\begin{itemize}
  \item ...
  \item ...
\end{itemize}
```
参考: http://www.yamamo10.jp/yamamoto/comp/latex/make_doc/item/item.php

## 図の挿入
### 基本
#### プリアンブル
```
\usepackage[dvipdfmx]{graphicx}
```
#### 本体
```
\begin{figure}[h]
\centering
\includegraphics[keepaspectratio, scale = 1.0]
{ファイル名}
\caption{キャプション}
\label{ラベル名}
\end{figure}
```
ラベルは`\ref{ラベル名}`で本文中から参照できる。
参考: http://www.yamamo10.jp/yamamoto/comp/latex/make_doc/insert_fig/index.php#ADJUST

### テキストを回り込ませる
#### プリアンブル
```
\usepackage[dvipdfmx]{graphicx}
\usepackage{wrapfig}
```

#### 本体
```
\begin{wrapfigure}{r}{50mm}
  \begin{center}
    \includegraphics*[width=50mm]{ファイル名}
    \caption{キャプション}
    \label{ラベル}
  \end{center}
\end{wrapfigure}
```
画像を左に寄せたい場合は一行目のrをlにする。
参考: https://atatat.hatenablog.com/entry/cloud_latex10_wrapfig

## ソースコードの挿入
#### プリアンブル
```
\usepackage{listings}
```

#### 本体
```
\begin{lstlisting}[caption=...]
...
\end{lstlisting}
```
Pythonで「for文を使った繰り返し」の動作を確認してみた

# 概要

Pythonで「for文を使った繰り返し」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/for/index3.html

# 実装

以下のファイルを作成しました。
```sample.py
mylist = ["Orange", "Peach", "Lemon"]
for val in mylist:
    print(val)

print("End")

mylist = ["Orange", "Peach", "Lemon", "Apple"]
for val in mylist:
    print("value:" + val)

mydict = {"L":"Lemon", "O":"Orage", "G":"Grapes"}
for mykey, myvalue in mydict.items():
    print("key:" + mykey + ", value:" + myvalue)

count = 0
mylist = ["Orange", "Peach", "Lemon", "Apple"]
for val in mylist:
    print("value:" + val)
    count += 1
else:
    print("要素の数 = " + str(count))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
Orange
Peach
Lemon
End
value:Orange
value:Peach
value:Lemon
value:Apple
key:L, value:Lemon
key:O, value:Orage
key:G, value:Grapes
value:Orange
value:Peach
value:Lemon
value:Apple
要素の数 = 4
```

# まとめ

何かの役に立てばと。
【PHP】変数の条件判定を比較（if, isset, empty, is_null）

# はじめに

今回は、変数の条件判定を行う関数を比較し、まとめました。

※おことわり※
基本的に学習内容のアウトプットです。
初学者であるため、間違い等あればご指摘いただけますと嬉しいです。

# この記事の目的

メソッドの性質に関して理解が曖昧だったため、整理をしてアウトプットしようと思いました。

# この記事の対象者

- PHPを学習されている初学者の方
- issetやemptyの仕様に迷いがある方

# この記事の内容
1. isset
2. empty
3. is_null
4. メソッドの比較

# 1. isset

> 変数が宣言されていること、そしてnullとは異なることを検査する

https://www.php.net/manual/ja/function.isset

- 存在するかつ、null以外の値の場合true、それ以外はfalseを返す　※空はtrue

# 2. empty

> 変数が空であるかどうかを検査する

https://www.php.net/manual/en/function.empty.php

- 存在しないまたは、空, 0, "0", nullの値の場合true、それ以外はfalseを返す
- 変数が存在しない場合でも警告を出さない
- `!isset($var) || $var == false` と等しい

# 3. is_null

> 変数が null かどうか調べる

https://www.php.net/manual/ja/function.is-null

- nullの場合にtrue、それ以外の場合にfalseを返す

# 4. メソッドの比較

```php
$value_1 = 1;
var_dump($value_1 ? true : false);          // => true
var_dump(isset($value_1) ? true : false);   // => true
var_dump(empty($value_1) ? true : false);   // => false
var_dump(is_null($value_1) ? true : false); // => false

$value_2 = 0;
var_dump($value_2 ? true : false);          // => false
var_dump(isset($value_2) ? true : false);   // => true
var_dump(empty($value_2) ? true : false);   // => true
var_dump(is_null($value_2) ? true : false); // => false

$value_3 = "0";
var_dump($value_3 ? true : false);          // => false
var_dump(isset($value_3) ? true : false);   // => true
var_dump(empty($value_3) ? true : false);   // => true
var_dump(is_null($value_3) ? true : false); // => false

$value_4 = "";
var_dump($value_4 ? true : false);          // => false 
var_dump(isset($value_4) ? true : false);   // => true  
var_dump(empty($value_4) ? true : false);   // => true
var_dump(is_null($value_4) ? true : false); // => false 

$value_5 = null;
var_dump($value_5 ? true : false);          // => false 
var_dump(isset($value_5) ? true : false);   // => false  
var_dump(empty($value_5) ? true : false);   // => true
var_dump(is_null($value_5) ? true : false); // => true 

$value_6;
var_dump($value_6 ? true : false);          // => false 
var_dump(isset($value_6) ? true : false);   // => false  
var_dump(empty($value_6) ? true : false);   // => true
var_dump(is_null($value_6) ? true : false); // => true 

$array_1 = [];
var_dump($array_1 ? true : false);          // => false 
var_dump(isset($array_1) ? true : false);   // => true  
var_dump(empty($array_1) ? true : false);   // => true
var_dump(is_null($array_1) ? true : false); // => false 

$array_2 = [0];
var_dump($array_2 ? true : false);          // => true 
var_dump(isset($array_2) ? true : false);   // => true  
var_dump(empty($array_2) ? true : false);   // => false
var_dump(is_null($array_2) ? true : false); // => false
```
SwiftUI の dismiss() って「関数()」じゃなくて「オブジェクト()」だよね？

# はじめに
SwiftUI で多用されている Property Wrappers ですが、基本的に「なんか難しいことをやってくれてる」感じになってます。頻繁に利用される `@Environment` も、「こう書けばこう動く」という感じで何となく使っている人が多いと思います。

ところで、Property Wrapper そのものの機能とは関係ないですが、以下のコードの `@Environment` の `dismiss()` の部分はよく考えると不思議な構文ではないでしょうか。

```swift
// ビューを閉じるための DismissAction を取得
@Environment(\.dismiss) private var dismiss: DismissAction

...

// ビューを閉じる
dismiss() // <--- オブジェクト() という構文？？？
```

`dismiss` は `DismissAction` 型のオブジェクトなので、本来なら以下の形式でないと辻褄が合いませんよね。

```swift
dismiss.何かメソッド名() // <--- オブジェクト.メソッド名() という構文ならわかる
```

# 検証環境
- Xcode 15.0
- Swift 5.9

# callAsFunction メソッド
実は、これは `dismiss.何かメソッド名()` の省略形です。
具体的には `dismiss.callAsFunction()` です。

## callAsFunction の例
例として、単に「足し算をするためだけの構造体」を用意し、`callAsFunction` メソッドを実装して利用してみます。

```swift: callAsFunction の例
import Foundation

// 足し算をするためだけの構造体
struct AddAction {
    public func callAsFunction(_ number1: Int, with number2: Int) -> Int {
        return number1 + number2
    }
}

let add = AddAction()

// 以下は add.callAsFunction(10, with: 20) の省略形
let result1 = add(10, with: 20)
print(result1)

// もちろん、メソッド名を書いても動作する
let result2 = add.callAsFunction(50, with: 100)
print(result2)
```

上記のコードでは、`add` は `AddAction` 型のオブジェクトですが、`add(10, with: 20)` の形で実行できていることがわかります。

冒頭で紹介した `DismissAction` にも `callAsFunction` メソッドが定義されているため、`dismiss()` と記述できます。

## callAsFunction 関数の仕様
- クラス、構造体、列挙型に宣言する
- メソッド名は `callAsFunction`
- 引数の型と数、戻り値の型は自由
- `オブジェクト.callAsFunction(引数)`の形式で利用

## 注意点
`callAsFunction` というメソッド名は何らかのプロトコルで規定されているわけではないため、定義時にスペルミスをしてもエラーにはならない点に注意が必要です。
呼び出し側のコードを書いている時に、`オブジェクト(引数)` で呼べないので気づくこととなるでしょう。

# まとめ
`callAsFunction` を積極的に定義する機会は多くないと思います。
しかし、Swift（特に SwiftUI）では意外と使われていたりするので、仕組みは知っておくと良いでしょう。

以前に書いた記事 [SwiftUI でサイズクラスに対応する](https://qiita.com/aokiplayer/items/a91213b953c2a805626a) でも、軽く触れています。

作成したサンプルは、[GitHub: aokiplayer/swift-sandboxCallAsFunction.playground](https://github.com/aokiplayer/swift-sandbox/tree/master/CallAsFunction) に置きました。

この記事は、[私のブログ](https://yagamo-style.com/2023/12/04/call-as-function/) にも投稿しています。

# 参考
- [Methods with Special Names (The Swift Programming Language)](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations/#Methods-with-Special-Names)
- [callAsFunction() | DismissAction (Apple Developer Documentation)](https://developer.apple.com/documentation/swiftui/dismissaction/callasfunction())
【3分De解説】DockerでWindows/Mac用ソフトウェアは使えない

## 本記事の要約

* DockerはLinux OSの上で動く
* なのでWordやパワポといったWin/Mac用ソフトウェアは使えない
* Dockerコンテナはアプデせずどんどん捨てる

## 背景
こちらの[記事](https://qiita.com/Yuzaburo/items/0d04179bc7765f0d32a1)の続きです。

Dockerを使ってLaravelの環境構築をしようとしています。

しかしDockerが何かさっぱり分からないまま環境構築をするのもスッキリしないので、基本的理解を作ることにしました。

本記事の情報は[『仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん』](https://www.amazon.co.jp/%E4%BB%95%E7%B5%84%E3%81%BF%E3%81%A8%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B-Docker-Kubernetes%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E5%B0%8F%E7%AC%A0%E5%8E%9F%E7%A8%AE%E9%AB%98/dp/4839972745)を参考にしています。
<img width="50%" height = "50%" src="https://m.media-amazon.com/images/I/61jOLscxM3L._AC_UF894,1000_QL80_.jpg">

コメントや情報の訂正もお気軽にどうぞ！

## Dockerの仕組みについて
**DockerはLinux OSがないと動きません。**

MacやWindowsでDockerを使っている方がいるのは、Linux OSをマシンにインストールしているためです。

よって、WordやPowerPointといったWindows/Mac用のソフトウェアをDockerコンテナ上で動かすことはできないということです。

Linux OS上で動くという仕組み上、必然的に対応するのはLinux OS向けのソフトウェアになります。

## イメージとコンテナの関係について
Dockerコンテナにソフトウェアを隔離する際は、「Docker Hub」という公式レジストリを利用します。

ここではMySQLやApacheといったLinux OS用ソフトウェアのイメージ（型）が配布されています。

しかしこのイメージをそのままDockerで利用することはできません。

**イメージを使ってコンテナを作成することで、Docker上で使用することができるようになります。**

~~たこ焼き（コンテナ）を食べたいのに、たこ焼き機の型（イメージ）だけ渡されてもどうしようもないですよね。~~

## Dockerコンテナは使い捨て
コンテナ内のソフトウェアにアップデートの必要がある際、**Dockerではそのままコンテナを破棄して新しいコンテナを作ります。**

その理由は、一つのコンテナを保守するより新たにコンテナを入れた方が手間がかからないためです。

Dockerではイメージを使えば簡単に最新のソフトウェアを用意できます。

そしてデータもDockerが入った物理的マシンに保存しておけるので、たとえコンテナを破棄しても内部のデータに振り回されることがありません。

## Dockerのデメリットは？
メリットたくさんのDockerですが、当然デメリットも存在します。

その一つとして、**Dockerを入れている物理的マシンがクラッシュすると、中のすべてのコンテナも影響を受ける**点が挙げられます。

これは仮想化技術やクラウドでも同じですが、やはり「1マシン=1サーバ」の時よりも影響範囲が広くなってしまいます。

そして第二に、**DockerはLinux OSを前提とした技術なので、Linux OS用ソフトウェア以外は使用できない**ということです。

そのため冒頭でも触れたとおり、WordやPowerPointといったソフトウェアをコンテナ化することはできません。
Open 3D

# Open 3D
https://github.com/isl-org/Open3D/blob/master/examples/python/geometry/point_cloud_paint.py

http://www.open3d.org/docs/release/tutorial/geometry/pointcloud.html

https://qiita.com/n_chiba_/items/fc9605cde5c19a8c7dad
## Open3Dのインストール
https://qiita.com/kosei1515/items/6881d9dd571dff1d29a3

### トラブルシューティング
https://jp.easeus.com/data-recovery-solution/python-setup-py-egg-info-failed-with-error-code-1.html

* "illegal instruction (core dumped) "とか表示されたとき
     これはWindows上でvirtual boxを使って動かしているOS（私の場合はubuntu）にOpen3dをインストールした場合に発生するエラー．

    原因は，windowsでWSLとかの仮想環境を使うための機能（Hyper-V）がvirtual boxの機能を抑制しているせいなので，下記のサイトを参考にしながら，Hyper-Vを*オフ*にすればいい．

https://qiita.com/rdonster/items/466ce528706a3d822c51

## Open3Dの解説

https://www.google.com/search?q=open3d+point+cloud+%E4%BD%BF%E3%81%84%E6%96%B9&rlz=1C1FQRR_jaJP983JP983&sxsrf=APwXEdfr9iZFyAI0WZwTLm7iqx8C9QRW-Q%3A1681635898414&ei=Oro7ZKb9GMuL-Ab1wr7QCA&ved=0ahUKEwimgvfyha7-AhXLBd4KHXWhD4oQ4dUDCA8&uact=5&oq=open3d+point+cloud+%E4%BD%BF%E3%81%84%E6%96%B9&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAzIFCAAQogQyBQgAEKIEMgUIABCiBDIFCAAQogQyBQgAEKIEOgoIABBHENYEELADOgoIABCKBRCwAxBDOgcIABCKBRBDOggIABCABBDLAToFCAAQgAQ6CAgAEIoFEJECOgsIABCKBRCRAhCLAzoICAAQgAQQiwM6CAgAEIoFEIYDOgUIIRCgAToECCEQFToGCCEQChAqSgQIQRgAUIYGWLQWYN8YaAFwAXgAgAF1iAGoCJIBAzYuNZgBAKABAcgBCbgBAsABAQ&sclient=gws-wiz-serp


## rosインターフェース
<table>
    <thead>
    <tr>
      <th> 言語 </th> <th> ros interface </th> <th> 関連サイト </th>
    </tr>
  </thead>
  <tr>
    <td> python </td> 
    <td> <a href="https://github.com/karaage0703/open3d_ros/blob/master/util.py">https://github.com/karaage0703/open3d_ros/blob/master/util.py</a> </td>
    <td> <a href="https://karaage.hatenadiary.jp/entry/2018/03/12/073000">Open3D+ROS+Pythonで3次元画像処理を楽々プロトタイピング</a> </td> </td>
  </tr>
  <tr>
    <td> C/C++ </td> 
    <td> <a href="https://github.com/ros-perception/perception_open3d">https://github.com/ros-perception/perception_open3d</a> </td>
    <td> <a href="https://github.com/ntnu-arl/open3d_ros">githubページ</a> </td> </td>
  </tr>
</table>
PyWin32 の Outlook でフォルダ内のメールが処理できない問題を解決する

今回は PyWin32 の Outlook で、特定のフォルダ内にあるすべてのメールが処理できず、半分のメールしか処理できない問題を解決できた忘備録として記事を投稿します。

# 今回使用するコードと実行例
下書きボックスの中にある `python_drafts` に存在するメールをすべて削除済みアイテムボックスの中にある `python_deleted` に移動するというソースコードを想定します。

今回の特定のフォルダのメールをすべて移動させることを例に挙げておりますが、移動させることに限らず、フォルダ内のメールすべてに対して～～するという処理に対応します。

```Python: main.py
import win32com.client

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
draft = outlook.GetDefaultFolder(16) # 16: 下書き
deleted = outlook.GetDefaultFolder(3) # 3: 削除済みアイテム

draft_folders = draft.Folders
deleted_folders = deleted.Folders

def delete_drafts():
    Draft_Folder = draft.Folders("python_draft")
    Deleted_Folder = deleted.Folders("python_deleted")
    i = 1 # カウンタ
    for item in Draft_Folder.Items:
        print(f"のこり {len(Draft_Folder.Items)} 件: {i} 件目メール破棄しました")
        item.Move(Deleted_Folder)

if __name__ == "__main__":
    delete_drafts()
```

# 実行結果
```sh
$ python main.py 
のこり 3 件: 1 件目メール破棄しました
のこり 2 件: 2 件目メール破棄しました
```

実行前
![bad-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1652242/36a7f68a-1528-9a9b-eb4e-bfeb31232f67.png)

実行後
![bad-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1652242/58f89057-297b-b1a7-6fd6-2ab78a58b48b.png)

本来はメールが3件消えてほしいのですが、2件しか移動されず、どうしても1件残ってしまっています。

# 原因と対策
項目が頭から順次処理されることにより `Draft_Folder.Items`（フォルダ内のメールの集合）が減少するため、半分（奇数の場合は半分-1）のメールが残ってしまいます。そこで、For 文を逆順で回すことによって、`Draft_Folder.Items` を頭から処理するのではなく末尾から処理することにより、すべてのメールを削除することが可能になります。

# 解決したプログラムコード
逆順で処理する（Items コレクションの末尾から処理する）ことによって、特定のフォルダ内のすべてのメールに対して処理を行うことができました。
具体的には、`Draft_Folder.Items` を `reversed()` 関数を用いて `reversed(Draft_Folder.Items)` とすることによって逆順の動作を実現しました。

# 解決したソースコード
```Python: main.py
import win32com.client

outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
draft = outlook.GetDefaultFolder(16) # 16: 下書き
deleted = outlook.GetDefaultFolder(3) # 3: 削除済みアイテム

draft_folders = draft.Folders
deleted_folders = deleted.Folders

def delete_drafts():
    Draft_Folder = draft.Folders("python_draft")
    Deleted_Folder = deleted.Folders("python_deleted")
    i = 1 # カウンタ
    for item in reversed(Draft_Folder.Items): # ここで reversed 関数を使用する
        print(f"のこり {len(Draft_Folder.Items)} 件: {i} 件目メール破棄しました")
        item.Move(Deleted_Folder)

if __name__ == "__main__":
    delete_drafts()
```

# 実行結果
```sh
$ python main.py
のこり 3 件: 1 件目メール破棄しました
のこり 2 件: 2 件目メール破棄しました
のこり 1 件: 3 件目メール破棄しました
```
実行前
![bad-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1652242/36a7f68a-1528-9a9b-eb4e-bfeb31232f67.png)

実行後
![good-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1652242/58313357-fb31-1a4a-e29c-cddaf3a1d4f2.png)

きちんとすべてのメールが処理されています。

# 参考文献
https://stackoverflow.com/questions/72203459/python-move-all-outlook-emails-to-different-folder
パーティションを見てみる

## パーティション
HDD、SSDを内部の複数の独立した区画に分割。この一つ一つをパーティションと呼ぶ。
WindowsではCドライブ、Dドライブのようにドライブレター単位で分割。
Linuxでは`sda1`, `sda2`のように分割し、それぞれのパーティションが`usr`や`bin`など任意のディレクトリにマウントすることが一般的。`lsblk`パーティションとそのマウントポイントを確認できる。

```bash
$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda    254:0    0 59.6G  0 disk 
`-vda1 254:1    0 59.6G  0 part /etc/hosts
                                /etc/hostname
                                /etc/resolv.conf
```
プログラミング言語を選ぶ

どのプログラミング言語を学ぼう？？？

そこでプログラミング初めましてな人向けに，独断と偏見で各言語の違いを分類しておく．

# プログラミング言語とは？
人は言葉を介して意思や考えを共有するが，コンピュータは言葉を理解できない．コンピュータは電流のON/OFFで表される「0/1の数字の組み合わせ」のみを理解する．

しかし，人間がコンピュータに命令したいとき，毎回「0/1の数字を組み合わせて」命令書を記述するのは滅茶苦茶大変！（昔の人はやってたらしいけど....）

**そこで生まれたのがプログラミング言語である．**
プログラミング言語は比較的，人の言葉に近い形の文法構造を持っており，0/1より理解しやすい形をとる．

プログラミング言語で書かれたソースファイルをコンピュータの理解できる0/1で書かれた実行ファイルに変換することで，コンピュータに思い通りの動きをさせることが出来る．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3250323/0209d214-cff5-34fd-a4c9-926466281d17.png)

## プログラミング言語とできること（得意なこと）一覧
役割は☝で述べた通りだが，何をコンピュータにやらせるかによって言語ごとに得意なものが異なる．

| 得意なこと | プログラミング言語 |
|-----------|-------------------|
| ① Webサイトの構築 | HTML・CSS，PHP，Ruby，JavaScript， |
| ② アプリケーション開発| PHP，Ruby，Visual Basic，JavaScript，Python，Swift，C#，Kotlin，Java，C/C++，Objective-C |
| ③ 電子機器の制御 | Python，Go，C/C++ |
| ④ AI・機械学習の開発 | Python，R，Julia |

他にも様々な言語が生まれては消えるのを繰り返しているが，現時点でメジャーなものは以上の通り．

ここではさらに，ロボット開発においてメジャーな３つの言語，Python，C/C++，Matlabについて言及していく．

# ロボット3大?言語の比較

| 言語 | メリット | デメリット |
| ---- | ---- | ----- |
| **Python** | 最も単純な（英語に近い）文法構造を取るので，入門しやすい | 実際，ロボット制御などを行うときには，実行から実際に動くまでのタイムラグが大きい |
| **C/C++** | ロボット制御などの際に小さなタイムラグで実行可能 | 色々便利な分，感覚的に理解するのが難しい文法もある |
| **Matlab** | なぜか大学の先生は皆これを使う（計算などの拡張機能が充実しているから？） | 使用に必要なライセンスの料金が有料＆高額 |

以上をまとめると，**本当にプログラミング初めて！な人にはpythonが圧倒的におすすめ**．
pythonで基本的な文法を学んでから他の言語に切り替えれば，単語単語は似通っているので調べやすいし，覚えやすいし，理解しやすい．

また，ライブラリがたくさんあるので，機械学習など今流行りのものにも気軽に取り組める点もポイントが高い．


一方で，より難しい命令書を書くとなると，C/C++のほうが書きやすいことも.... だてに昔からずっと使われ続けた言語じゃない．

また，ロボット開発を目指すなら，センサによっては使える言語（対応言語）が限られていたりするので，そこも注意する必要がある．
コード生成AI簡易比較表

コード生成AIについて調べた備忘録です。詳細は公式ドキュメントをご参照ください。

| サービス名 | Amazon CodeWhisperer                               | GitHub Copilot                                                                          | Codey API                                                                             | Code Llama                                       | 
| ---------- | -------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------ | 
| 提供企業   | Amazon(AWS)                                        | GitHub、Microsoft                                                                       | Google Cloud                                                                          | Meta                                             | 
| 料金       | 無料, 19USD/月                                     | 10USD/月, 100USD/年                                                                     | 0.0005USD/1000文字                                                                    | 無料                                             | 
| 言語       | Java,JavaScript,Python                             | パブリックリポジトリ内多数の言語                                                        | C,Go,Java,PHP,Python,YAMLなど多岐                                                     | Python、C++、Java、PHP、Javascript、C#、Bashなど | 
| トークン数 | 記載なし                                           | 8192                                                                                    | 入力6122/出力1024                                                                     | 16000程度                                        | 
| データ保護 | 個人利用はコンテンツ改善のため保持(設定で回避可能) | データの学習利用なし                                                                    | 個別に設定可能                                                                        | 記述なし                                         | 
| 連携       | bash、VS コード内のターミナル、各種CLIなど         | Visual Studio Code、Visual Studio、Vim、Neovim、JetBrainsのIDE suite、Azure Data Studio | Google Cloud CLI、Kubernetes Resource Model（KRM）、Terraform                         | GitHub、HuggingFace                              | 
| URL        | https://aws.amazon.com/jp/codewhisperer/faqs/      | https://github.com/features/copilot/                                                    | https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview?hl=ja | https://github.com/facebookresearch/codellama    |