OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】Object.is()メソッドとは

# Object.is()メソッドとは
Object.is()メソッドは、厳密な等価性を比較するためのもので、引数を2つ受け取ります。具体的には、第一引数と第二引数を比較して、両方が同じ値と型であるかどうかを確認します。第一引数と第二引数が同じオブジェクトの場合にtrueを返します。

# ==演算子や===演算子との違い
1. 特殊なケースの扱い:
- == 演算子は、特殊なケースで型変換を行って比較を行います。例えば、0 == false は true を返します。
- === 演算子は、型変換を行わずに比較を行うため、型が異なる場合は常に false を返します。例えば、0 === false は false を返します。
- Object.is() メソッドは、特殊なケースを持ちません。つまり、型変換を行わずに厳密な等価性を比較します。

2\. NaN（非数値）の扱い:
- == 演算子では、NaN == NaN は false を返します。
- === 演算子でも同様に NaN === NaN は false を返します。
- Object.is() メソッドは、NaN 同士を比較する際に true を返します。

3\. -0と+0の扱い:
- == および === 演算子では、 -0 === +0 は true を返します。
- Object.is() メソッドでは、 -0 と +0 を区別し、Object.is(-0, +0) は false を返します。

# 使い方
```js
let a = 'foo';
let b = 'foo';
console.log(Object.is(a, b)); // true
```
現場で使えるRuby on Rails5速習実践ガイドを読んで

## はじめに
現場で使えるRuby on Rails5速習実践ガイドを読んだので、感想などをまとめてみました。

## 良かったところ
実際にアプリを作成しながら機能の実装についてしっかり解説してあるので、非常にわかりやすかったです。またチーム開発の流れも書いてあって、未経験の方は実務の流れがイメージしやすいので、とても良いと思いました。

## 学んだこと
#### MVC
Railsでは、アプリケーションの構造や名前付けを、M（モデル）、V（ビュー）、C（コントローラ）の3つの要素に従ってます。

**モデル**とは、データとデータに関わるビジネスロック（アプリケーション特有の処理）をオブジェクトとして実装したもです。データベースの保存や読み込みもモデルが担当する。

**ビュー**とは、ブラウザに表示する画面、HTMLなどのHTTPレスポンスの中身を実際に組み立てる部分です。必要に応じてコントローラからモデルのオブジェクトなどを受け取り、画面表示に利用します。

**コントローラ**は、ユーザーが操作するブラウザなどのクライアントからのリクエストを受け、適切なレスポンスを作成するための制御を行う部分です。

### マイグレーション
データベースのテーブル構造の変更の1つ1つを、Rubyのプログラムとして実現し、開発の沿って順番に実行することで最新のテーブル構造の状態にできるようにする。マイグレーションは、最新の状態から戻す機能も備えている

### リクエストパラメータ
Webアプリケーションでは、リクエストにデータを添えることができる。このデータを「リクエストパラメータ」と呼ぶ
リクエストパラメータの送り方は、HTTPの仕組みの上で、2通りに分かれます。

1. **POST**で送る。基本的にはHTMLのform要素をsubmitすることで送れる。
2. **GET**で送る。基本的にはURLの?以降に情報を含めることで送る。普通に？の付いたURLにブラウザからアクセスするほか、form要素のmethod属性にgetを指定して、form要素のsubmitを通じてそのようなリクエストを送ることもできる。

これらの2つの方式は送り方が違うため、本来は受け取り方も異なりますが、Railsは両者をなるべく区別しなくて済むようにしてくれます。具体的には、コントローラにおいてparamsというメソッドを利用することで、POSTかGETかに関係なく、送られてきたリクエストパラメータをHashのような感覚で取得できます。

#### モデルの検証
Railsでは、「モデルオブジェクト（レコード）をデータベースに登録、更新する前に検証を行い、エラーがあれば登録、更新をしないで差し戻す」という仕組みになっています。この仕組みに対応する登録、更新のためのメソッドが**save**です。

**save**メソッドは、データベースの登録、更新を行う前に自動的に検証を行い、検証エラーがあればfalseを返します。検証エラーがなければ、データベースの登録、更新を行なってtrueを返します。このとき、検証以外のエラーがあれば、例外を発生させます。

### ルーティング
「どのようなURLへどのようなHTTPメソッドでアクセスされたら、どのコントローラのどのアクションを呼び出したか」をconfig/routes.rbに定義します。アクセスを受けて適切なアクションへと案内する仕組みを、ルーティングと呼びます。

### Storong Parameters
コントローラでリクエストパラメータを受け取る際に、パラメータのどの属性を許可してどの属性を弾くのかを制御する機能です。

## 難しかったところ
Rails5の内容なので、実際に手を動かしながら進めるのはエラーで詰まるので、かなり大変だと感じました。

## 参考文献
[現場で使える RubyonRails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=7NL117JN69F3&keywords=Rails&qid=1642106965&sprefix=rails%2Caps%2C252&sr=8-6)
Railsでモデルに書いたメソッドをrails consoleで検証してみた

## この記事を書いた目的
Railsでコードを書く際にモデルにインタンスメソッドを定義をして、コントローラで呼び出すことがよく行われるということを学びました。少し調べてみると、このことは主にファットコントローラを避けることを目的として行われているようです。<br>ただ、初心者の私からすると「コントローラの流れすら追うのに苦労しているというのに、別の場所に定義したメソッドを呼び出すなんて、わけわかめ！」ということで、実際にコンソールを動かしてどういった動きをしているのか確かめてみました。
## 今回検証したコード
掲示板作成アプリ内のお気に入り登録ができる機能に関わる箇所です。該当のコントローラとモデル内のインスタンスメソッドは下記の通りです。

```ruby:bookmarks_controller.rb
 def create
    board = Board.find(params[:board_id])
    current_user.bookmark(board)
    #...
 end
```
```ruby:user.rb
def bookmark(board)
    bookmark_boards << board
end
```
- Userモデル内に作成したbookmarkの登録用メソッドを、bookmarksコンローラで呼び出すという流れです
## Bookmarkテーブル作成時のマイグレーションファイル
```ruby: XXXXXXX_create_bookmarks.rb
class CreateBookmarks < ActiveRecord::Migration[7.0]
  def change
    create_table :bookmarks do |t|
      t.references :user, null: false, foreign_key: true
      t.references :board, null: false, foreign_key: true

      t.timestamps
      t.index [:user_id, :board_id], unique: true
    end
  end
end
```
UserテーブルとBoardテーブルの中間テーブルです。また、同じユーザーが同じ投稿に対して2度ブックマーク登録を行うことのないよう、`user_id`と`board_id`にユニーク制約をかけることで、データベースレベルで一意性を保つようにしてあります。
## rails consoleの起動（Docker使用時）
```
$ docker compose run web bin/rails console
```
## RailsConsoleで流れを確認する
今回コンソールで検証するuser_id=1とboard_id=1の組み合わせでは、ブックマークが作成されていません。では、先ほどのコントローラー流れを1行ずつコンソールで確かめていきましょう。
### board = Board.find(params[:board_id])
```
irb(main):002:0> sample_board = Board.find_by(id: 1)
  Board Load (1.1ms)  SELECT `boards`.* FROM `boards` WHERE `boards`.`id` = 1 LIMIT 1
```
- Boardモデルからid=1のデータを取得し、sample_boardという変数に代入します
### current_user.bookmark(board)
```
irb(main):003:0> User.find_by(id: 1).bookmark(sample_board)
```
こちらで実行した内容としては下記の通りです。
- Userモデルからid=1のデータを取得します（コントローラではsorceryのメソッドcurrent_userで呼び出しています）
- 上のuserのデータに対して、引数sample_boardとってbookmarkメソッドを呼び出します

ではコンソールの実行結果を見ていきます。
```
  User Load (1.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  TRANSACTION (0.4ms)  BEGIN
```
- Userモデルからid=1のデータを取得します
```
  Bookmark Exists? (0.4ms)  SELECT 1 AS one FROM `bookmarks` WHERE `bookmarks`.`user_id` = 1 AND `bookmarks`.`board_id` = 1 LIMIT 1
```
- 同じ`user_id`と`board_id`の組み合わせが既にBookmarkテーブルにないかを確認しています
```
  Bookmark Create (1.0ms)  INSERT INTO `bookmarks` (`user_id`, `board_id`, `created_at`, `updated_at`) VALUES (1, 1, '2024-03-31 11:40:52.618794', '2024-03-31 11:40:52.618794')
  TRANSACTION (1.2ms)  COMMIT  
```
- ここでbookmarkメソッドが呼び出されています
- <<演算子はhas_many関連付けで使用可能になるメソッドです
[4.3.1.2 collection<<(object, ...)](https://railsguides.jp/association_basics.html#has-many%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%82%8B%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89-collection-object)
[Array#<< (Ruby 3.3 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Array/i/=3c=3c.html)
- `bookmark_boards << board`は、`bookmarks.create!(board_id: board.id)`と同様の処理が行われるため、SQLでCREATE文が発行されます
- コミットすることでBookmarkテーブルにデータが保存されました
## まとめ
rails consoleで実際の流れを把握することで、コードに対する理解が深まったように感じました。まだまだ理解のできてない箇所があるので、誤っている点などあれば教えていただけると嬉しいです！

## 参考

https://zenn.dev/linkedge/articles/9e924c18e702d2
開発をスムーズに進めるための.gitignore設定ガイド

ソフトウェア開発において、`.gitignore`ファイルの適切な設定は重要です。このファイルによって、バージョン管理から除外すべきファイルやディレクトリを指定でき、不要なファイルがリポジトリに混入するのを防ぎます。特に、Go、Node.js、Python、Java、Ruby、C#などのプログラミング言語を使用している場合、言語特有の生成物や依存関係で生成されるファイルを無視する設定が必要になることがあります。本記事では、これらの言語における`.gitignore`の設定例と、それぞれの言語で無視すべき一般的なファイルについて解説します。

### Go（Golang）

Go言語では、ビルド時に生成される実行可能ファイルやテスト時に作成される一時ファイルを`.gitignore`に含めるべきです。また、`go.mod`や`go.sum`ファイルは依存関係の管理に使用されるため、これらは無視しないでください。

```
# 実行可能ファイル
*.exe
*.exe~
*.dll
*.so
*.dylib

# テスト関連
*.test
*.log

# 依存関係ツール
/vendor/
```

### Node.js

Node.js開発では、`node_modules`ディレクトリと環境設定ファイルが主な無視対象です。`node_modules`は、プロジェクトの依存関係を格納するディレクトリであり、これらは`npm install`を実行することで誰でも生成できるため、バージョン管理に含める必要はありません。

```
# 依存関係
/node_modules/
/npm-debug.log
/yarn-error.log

# 環境設定ファイル
.env
.env.local
```

### Python

Pythonプロジェクトでは、バイトコードコンパイルファイル、仮想環境ディレクトリ、設定ファイルが`.gitignore`の典型的な対象です。仮想環境は各開発者がローカルで設定するもので、プロジェクト共有には適しません。

```
# コンパイルされたバイトコード
__pycache__/
*.py[cod]
*$py.class

# 仮想環境
venv/
ENV/

# 設定ファイル
*.ini
*.cfg
*.config
```

### Java

Javaプロジェクトでは、ビルドプロセス中に生成されるクラスファイルやJARファイル、IDE固有の設定ファイルなどを無視する設定が一般的です。

```
# コンパイルされたクラスファイル
*.class

# パッケージングされたアーティファクト
*.jar
*.war
*.ear

# IDE設定ファイル
/.idea/
*.iml
*.eclipse
/project/
```

### Ruby

Ruby、特にRailsアプリケーション開発では、依存関係のファイル、ログファイル、一時ファイルなどを.gitignoreに含めることが推奨されます。

```
# 依存関係
/vendor/bundle

# SQLiteデータベース
*.sqlite3
*.sqlite3-journal

# ログと一時ファイル
/log/*
!/log/.keep
/tmp
```

### C#

C# (特に.NETプロジェクト) では、ビルドプロセス中に生成されるバイナリファイルや、IDEやOS固有のファイルを無視する設定が必要です。

```
# ビルド結果
[Bb]in/
[Oo]bj/
[Ll]ogs/
[Dd]ebug*/
[Rr]elease*/

# Visual Studio固有のファイル
.vs/
*.csproj.user
*.suo
*.user
*.userosscache
*.sln.docstates

# Windowsイメージファイル
Thumbs.db
ehthumbs.db
```

### まとめ

`.gitignore`の適切な設定は、開発プロセスをスムーズにし、不要なファイルの共有を防ぎます。上記の設定例を参考に、プロジェクト固有のニーズに合わせて`.gitignore`をカスタマイズすることが大切です。開発中に新たに無視すべきファイルが見つかった場合は、都度`.gitignore`を更新することを忘れないでください。
htmlのclass属性とid属性の違いについて

# はじめに
HTMLの「class属性」と「id属性」の違いについてまとめました。これらは要素を識別し、スタイルを適用したり、JavaScriptで操作したりするために使われます。この記事では、これらの属性がどのように機能し、どう使い分けるべきかの備忘です。

# class属性とは

* 同じクラス名を複数の要素に指定することができる
* 同じクラス名を持つ要素に対して、一括でスタイルを適用することが可能

# id属性とは
* id属性は、ページ内の要素を一意に識別するために使用される
* 同じid名を複数の要素に指定することはできない

# サンプルコード
```html
<!DOCTYPE html>
<html>
<head>
  <style>
    .red {
      color: red;
    }

    #blue {
      color: blue;
    }
  </style>
</head>
<body>
  <h1 class="red">This is a red heading.</h1>
  <p class="red">This is a red paragraph.</p>
  <p id="blue">This is a blue paragraph.</p>
</body>
</html>
```

# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759378/5dd60582-d1e7-7c3d-879f-28392f84a833.png)
SpringToolSuiteのフォント変更

# 概要

デフォルトフォントだと全角半角の区別がつきにくい文字があります。
タイプミスした時にすぐ分かるフォントにします。

# やり方

『Window』 ⇒ 『Preferences』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c117fa95-2734-9ea0-d101-19a0db285008.png)

『General』 ⇒ 『Appearance』 ⇒ 『Colors and Fonts』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/86d69c1d-d87e-0341-8337-b51deb431753.png)

フォントの設定箇所はちらばってるので検索すると楽。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8aff9915-d109-c659-300f-4cb7944f58e1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/301e9685-6185-480e-f23b-9d3c63893c07.png)

最後に『Apply』忘れずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c803595a-bff7-8292-9324-a714e70b84b4.png)


# 蛇足

https://qiita.com/waokitsune/items/dacb9688abfb0ac0e820

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
Spring Tool Suite Version: 4.20.1.RELEASE
子クラスにおけるOnSetActiveについて

## 発生している問題

親クラスに表示/非表示の処理を記述し、子クラスで表示/非表示が切り替わった際の処理を実装したい時、何も考えずに以下のように実装していました

### 親クラス
```
    public bool IsActive
    {
        get
        {
            return gameObject.activeSelf;
        }
        set
        {
            OnSetActive(value);
            gameObject.SetActive(value);
        }
    }

    protected virtual void OnSetActive(bool isActive)
    {
        if(isActive)
        {
            Debug.Log("表示");
        }
        else
        {
            Debug.Log("非表示");
        }
    }
```

### 子クラス
```
    // 表示/非表示が切り替わった
    protected override void OnSetActive(bool isActive)
    {
        if(isActive)
        {
            Debug.Log("表示された");
        }
        else
        {
            Debug.Log("非表示になった");
        }
    }
```
**子クラスの関数が読みづらい！**

OnSetActive()がoverrideされ、見ただけでは何の処理をしているのか分かりづらく、個人的に納得いきませんでした、、、

## 解決

問題となってるのは子クラスでの読みにくさなので、overrideする関数名を変更する
### 子クラス（修正後）
```
    // 表示時の初期化
    protected override void OnShowInit()
    {
        Debug.Log("表示された");
    }

    // 非表示時のリセット
    protected override void OnHideReset()
    {
        Debug.Log("非表示になった");
    }
```

個人的にはOnShow()ではなく、処理内容も簡潔に説明したOnShowInit()としたい
上記の子クラスに伴い、親クラスも修正する

### 親クラス（修正後）
```
    public bool IsActive
    {
        get
        {
            return gameObject.activeSelf;
        }
        set
        {
            if(value)
            {
                OnShowInit();
            }
            else
            {
                OnHideReset();
            }
            gameObject.SetActive(value);
        }
    }

    protected virtual void OnShowInit()
    {
        Debug.Log("表示");
    }

    protected virtual void OnHideReset()
    {
        Debug.Log("非表示");
    }
```

## まとめ
**親クラスにif分を追加し、関数を細分化することで読みやすくなった**

正直どっちでも動くし気にしない！という方もいると思いますが、参考になればと思います。
わずか2.7BのMoEモデル：Qwen1.5-MoEについて

先日、中国のAlibabaがQwen1.5というモデルのMoEバージョン：Qwen1.5-MoE-A2.7Bをリリースしました。
Qwen1.5-MoEはわずか2.7Bのサイズですが、7B程度モデルの性能を持っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/b2e51b04-4c33-563d-65fb-974f6d47e1d0.png)

このモデルは、MistralのMoEを改良し、エキスパートの数を調整しました。Mistralでは8x7Bで合計8個のエキスパートを使用していましたが、Qwenでは64個のエキスパートを採用しました。推論の際には、従来の2つのエキスパートではなく、4つのエキスパートを呼び出して処理を行います。

簡単に言えば、推論時には約7Bモデルの2倍のメモリを消費しますが、推論速度も1.74倍に向上しています。
（A100-80Gにおいて4000token/sの生成速度を達成しています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/2bdb4a2c-829c-66f2-7a27-a156cf1d083f.png)

ただし、必要なメモリ量も多くなっており、少なくとも28GBのメモリが必要です。


実際日本語の質問で少し試してみました。（Qwenは中国語と英語のモデルですが、日本語の学習データも十分に学習しているため、日本語の性能も悪くはないです。Qwen-72Bとかは普通の日本語70BLLM並みの精度を持っています）。


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/ad1e1604-4df9-669e-73e0-70fdbb8b96b1.png)


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/cd3051c7-b5c3-3c56-915b-0488056d992d.png)


回答の質としては一般的な7Bモデルのレベルですね。でも生成スピードは非常に速かったです。ほぼ一瞬でできました。


興味ある方：

https://qwenlm.github.io/blog/qwen-moe/

https://huggingface.co/Qwen/Qwen1.5-MoE-A2.7B-Chat
【衛星データ分析】関心ある領域（AOI）の作成方法

# AOIとは
衛星データや地理データ分析を行う際、AOIという用語を耳にすることがあります。

AOIとは、「Area of Interest」の略称であり、関心のある地域を指します。

GISや衛星データ分析において、AOIを指定することで、必要なデータのみを抽出したり、解析の対象地域を限定したりすることができます。

# AOIデータ（KMLファイル）の作成方法
AOIデータがある場合はそのままGoogle Earth EngineやQGISにインポートすればよいのですが、データがない場合は自分で作成する必要があります。

ここでは、地名（緯度・経度でも可能）からAOIデータを作成する方法をご紹介します。

まず、Google Mapでマイマップを表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493722/608d65d3-d37e-0870-0add-eb3273928a1e.png)

マイマップ上で、検索窓に村（地名）を入れて検索し、地図に表示させます。次にライン描写をクリックし、村の領域に沿ってポリゴンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493722/56d8bcc0-5a8e-f0e8-74db-60eda9fafc8f.png)

地図のタイトルの横にある右の点線をクリックして、KML/KMZにエクスポートをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493722/afa3e14d-4657-8902-3e49-3f242d614f32.png)

「地図全体」ではなく、「無題のレイヤ」（作成したポリゴン）を選択し、ダウンロードをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493722/2842d7e5-22fc-9848-66f9-bf748598628d.png)


これでKMLファイルとしてエクスポートできました。
QGIS上で分析する準備はこれで終了です。

# AOIデータ（シェープファイル）の作成方法
Google Earth EngineはKMLファイルに対応していないので、シェープファイルに変換する必要があります。

オンラインで無料の[Converter](https://products.aspose.app/gis/conversion/kml-to-shapefile)があったので、今回そちらを使用しました。

所定の場所に先ほどエクスポートしたKMLファイルをドロップしてシェープファイルに変換します。

試しにできあがったシェープファイルをQGISにインポート（ファイルをQGISの画面上にドロップ）すると、問題なく表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493722/72bcbef3-055f-ea60-4414-9f4ec22a4058.png)

# まとめ
- AOI（Area of Interest）とは、関心のある地域を指します。GISや衛星データ分析において、AOIを指定することで、必要なデータのみを抽出したり、解析の対象地域を限定したりすることができます。
- AOIデータはGoogle Mapで作成できます。その際には、地名や緯度・経度が必要です。
- Google Earth EngineはKMLファイルに対応していません。そのため、Google Mapで作成したKMLファイルをシェープファイルに変換する必要があります。
- 変換には無料オンラインサイトが利用できます。

# おわりに
この手順がお役に立てば幸いです。

無料サイトが利用できない場合、QGISでもKMLファイルからシェープファイルにエクスポートすることが可能です。

不明な点やより効率的な方法があれば、ぜひコメントください。
Unityでは音が鳴るのにAppleVisionPro実機だと音が鳴らないんですが！？

# Unityでは音が鳴るのにAppleVisionPro実機だと音が鳴らないんですが！？

visionOS用のアプリを開発をしていたのですが、先日VisionPro実機で音が鳴らない現象に遭遇しました！
しかも厄介なことに、音が鳴るアプリと鳴らないアプリがあるんです。（複数のアプリを開発してました）
解決に3日くらいかかったので、忘れないうちにメモを残します。


# シーンの状態

シーンの構成は以下のようにしていました。

- シーン内にAudioSource を設置している
- `Play On Awake` をONにしており、シーン起動時に音が鳴るようにしている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/0508a828-78c6-4e01-bb94-6a8d155b565e.png)


# 症状

症状としてはこんな感じです。

- UnityEditorでは音がなるが、AppleVisionPro実機では音が鳴らない
- ただし、アプリ起動中にControl Centerを開くと鳴る

録画したので、以下をご覧ください！

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">VisionProで自作アプリを起動すると、一瞬だけBGMが鳴ってすぐに消えるという現象に遭遇しました！<br>しかもControl Centerを開くと、何故かBGMの続きが鳴るという謎挙動です<br><br>同じ症状に悩む人がいるかもなので、録画を残しておきます！<br>解決方法は引用元Postに載せてます！<a href="https://t.co/v7frblQwF1">https://t.co/v7frblQwF1</a> <a href="https://t.co/YdrmgVvQhC">pic.twitter.com/YdrmgVvQhC</a></p>&mdash; segur(せぎゅ)@ARエンジニア (@segur_vita) <a href="https://twitter.com/segur_vita/status/1775524749428535579?ref_src=twsrc%5Etfw">April 3, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この症状が発生するアプリと、発生しないアプリがあるという状況です。


# 調べたこと

最初は `Play On Awake` がよくないのかと思い、C#から `Play` を明示的に実行したりしましたが、解決しませんでした。

仕方なく、Unityプロジェクトを再構築したり、Xcodeをクリーンビルドしたり、いろいろ試しましたが解決しませんでした。

症状が発生するアプリとしないアプリで何が違うのか？設定画面をにらめっこしましたが、決定的な違いは見つけられませんでした…

そんな中、似たような症状がないか調査したところ、以下のページを見つけました！

- https://discussions.unity.com/t/no-audio-is-heard-by-the-player-during-gameplay/328641

まさしく同じ症状です！


# 原因

以下の2つに別々のファイルを指定していたことが原因でした！

- Project SettingsのVolume Window Config
- シーンのVolume Window Config

## 実際に起きていたこと

- アプリが起動した直後は、Project SettingsのVolume Window Configを読み込まれる
  - その際、AudioSourceが音を鳴らそうとする
- その直後にシーン内のVolume Cameraが読み込まれ、そこに設定されている別のVolume Window Configが読み込まれる
  - その際、BoundedやUnboundedの設定が変わってしまうと、AudioSourceの音が消えてしまう（理由は不明）


# 解決方法

以下の2つに同じファイルを設定したら、AudioSourceが鳴るようになります！

- Project SettingsのVolume Window Config
- シーンのVolume Window Config

設定箇所は以下の通りです。

## Project SettingsのVolume Window Config

`Project Settings > PolySpatial > Default Volume Camera Window Config` にファイルを設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/9734c140-3a34-990e-9309-c7765624cdf5.png)


## シーンのVolume Window Config

シーン内に設置した `VolumeCamera` の `Volume Window Config` にファイルを設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/5c4d9312-f38d-b293-b390-0e1e69d0990a.png)


# さいごに

本記事作成にあたり、以下のページを参考にさせていただきました。ありがとうございました。

- https://discussions.unity.com/t/no-audio-is-heard-by-the-player-during-gameplay/328641

また、原因調査中にいろいろと助言してくれたみなさま、大変励みになりました！ありがとうございました！
docker-composeを使ったredmineの導入方法

# はじめに
はじめに、docker-composeをつかってredmineを導入したい時がありますよね！！！そんな時の参考にして欲しいです。。。

# ファイル構成
docker-composeを用いてredmineを構築する。ボリュームの永続化などをこなうので、最終的なファイル構成について紹介する。
```
|-docker-compose.yml
    |-/redmine
        |-files
        |-plugins
    |-/mysql
        |-/data
    |-/dockerfiles
        |-redmine.Dockerfile
        |-mysql.Dockerfile
```

簡単に説明しておくと、docker-compose.ymlからredmine, mysqlに関するdockerfileを参照する。redmineディレクトリ、mysqlディレクトリは各コンテナで永続化するためのホスト側のディレクトリである。

# docker-compose.yml
以下にdocker-compose.ymlを示す。
```
version: '3'
services: 
  redmine:
    build:
      context: .
      dockerfile: dockerfiles/redmine.Dockerfile
    ports:
      - 8080:3000
    volumes:
      - ./redmine/files:/usr/src/redmine/files
      - ./redmine/plugins:/usr/src/redmine/plugins
    
  db:
    build:
      context: .
      dockerfile: dockerfiles/mysql.Dockerfile
    volumes:
      - ./mysql/data:/var/lib/mysql 
```

* contextではカレントディレクトリの指定を行う。（docker-compose.ymlが存在する位置）
* filesディレクトリはredmineに添付された画像などのファイルを格納する
* pluginsはredmineのプラグインを格納する

# dockerfile
以下にredmineコンテナに関するdockerfileを示す。
```
FROM redmine

RUN apt update && apt install vim -y

ENV REDMINE_DB_MYSQL= db¥
    REDMINE_DB_PASSWORD= redmine_pass¥
    REDMINE_DB_DATABASE= redmine¥
    REDMINE_DB_USERNAME= redmine_user¥
    REDMINE_SECRET_KEY_BASE= supersecretkey
```

* 通常バージョンの指定がない時には最新バージョンが選択される。

以下にmysqlコンテナに関するdockerfileを示す。
```
FROM: mysql:8.0

ENV: MYSQL_ROOT_PASSWORD= root_password¥
     MYSQL_DATABASE= redmine¥
     MYSQL_USER= redmine_user¥
     MYSQL_PASSWORD= redmine_pass
```

# コンテナのビルド
では、docker-compose.ymlファイルが存在する階層をカレントディレクトリに設定して以下コマンドを実行
```
docker-compose up -d -build
```

# 確認
ブラウザで http://ip:8080 と指定して以下のようになればOK

![スクリーンショット 2024-04-03 22.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693671/15464da4-1eff-d30c-4e90-a0d20b29b7db.png)
5GCoreのシーケンスを勉強しよう

# 背景
5GCのシーケンスそろそろ学んでみようと思いました。

# 参考文献
[1] [free5GCのSignallingをend-to-endで解析してみた Muneaki ogawa](https://omni-jp.github.io/events/002/)
[2] [5Gモバイルネットワーク入門 CN/TN編 川上 雄也](https://www.nic.ad.jp/ja/materials/iw/2022/proceedings/c12/c12-kawakami.pdf)
[3] [相互接続のための技術的手引 Go5G](https://go5g.go.jp/sitemanager/wp-content/uploads/2023/04/%E3%80%90%E6%89%8B%E5%BC%95%E3%80%91%E7%9B%B8%E4%BA%92%E6%8E%A5%E7%B6%9A.pdf)
[4](5Gコアネットワーク勉強メモ　kuro227){https://qiita.com/kuro227/items/bf2e63a16355ecec5257}
[5](5Gネットワークスライシングの概要 daisuke tanaka)[https://qiita.com/disk_tnk/items/40753046c5a0411c7e76]
[6][5gs-call-flow] (https://github.com/nickel0/5gs-call-flow)
[7][教養としての5GC(free5gc+UERANSIMで学ぶ5Gコアネットワーク) wzm](https://qiita.com/wzm/items/e3eb73835005ed7e8702)
# パラメータ
[3] に整合が必要とされるパラメータがあります。
| パラメータ | 概要         | 備考         |
|:-----------|:------------|:------------|
| IPアドレス  | 各種NF      |          |
| PLMN       | 事業者識別番号  | とりあえず日本だと440xx、441xx |
| TAI, TAC   | 5GCで管理する位置情報（エリア＝複数セルの塊）  |        |
| SST       | スライスのサービスタイプ     | まずはSST:1 eMBB=スマホを考える |
| SD        | 同一SST内でスライス識別  | とりあえず0でいいか？  |
| OPc値      | 端末認証用    |        |
| K,Ki    | 端末認証用     |      |
| APN     | Access POint name     |  P-GWの外側のNW名    |
| AMF     | 非アクセス層？     | TS 33.102 の AnnexHを見るとよいらしい？    |
|CK, IK生成アルゴリズム |SIM化d－の認証に用いられるアルゴリズム | |
|秘匿・インテグリティアルゴリズム|zルゴリズム|

# コールフロー
[6]を見ていく
## HTTP/2のでコード
　分析　Decode as(Ctrl+Shift+U) TCP 8000 > HTTP2

## 有効化したプロトコル
iOS / iPadOSでIchigoJam BASICを扱う方法

本記事は画像などがまだ添付されていません。
後の更新で追加予定です。

# 対象デバイス
:::note info
問題なく動く機種
- iOS 14以降
- iPadOS 14以降
:::

:::note warn
動くであろうデバイス
UTM v3.2.4以前を利用してください。
- iOS 11~13
- iPadOS 13
:::

# 動作確認環境
- iPhone SE 2020 
    - iOS 16.1.1
- iPad Pro 11" 2020
    - iPadOS 16.2


# 概要
IchigoJam BASICはLPC1114向けに書かれており、一般的なコンピュータ上で簡単に動くものではない。しかし、派生形が複数存在し、`IchigoJam rpi`を筆頭に`IchigoJam web`や`IchigoJam for pc`が存在する。

今回は、x86系コンピュータ上にIchigoJam BASICを起動させることができる`IchigoJam for pc`のディスクイメージを利用し、iPhone上でBASICを起動してみようと思う。

ここまで読むと、iPhone上でx86を動かすということに矛盾を覚える方がいるはずだ。
今回は、IchigoJam for pcディスクイメージを起動するのにUTMというiPhone上でQemuを実行し仮想マシンを構築するアプリケーションを利用する。IchigoJam for pcはiPhone上でエミュレーションするにも十分軽量なので問題なく動く。

# UTM導入
UTMはいわゆる野良アプリで、執筆時点ではサイドロードする必要がある。

UTMの導入に関しては各自で調べてほしい。
というのも、iOSのバージョンによって操作や手法が大きく異なるのだ。

大まかに案内すると、

### 脱獄済み？
- はい
    - Cydia,dpkg,Sileoなどからインストール
- いいえ
    - 次の選択へ

### 自分がTrollStoreに対応しているか
https://ios.cfw.guide/installing-trollstore/

このサイトで自分の環境がTrollStoreに対応しているか調べる
対応している場合は、上記サイトに従いTrollStoreを導入する。

### TrollStoreに対応していた場合
- M1 / M2デバイス
    - TrollStore経由でUTM-HV.ipaをインストール
- iPhone / iPad (Aシリーズ)
    - TrollStore経由でUTM.ipaをインストール

### TrollStoreに非対応の場合
AltStoreを利用しサイドロード
7日毎の再署名と起動時PCに接続しAltJITを有効化する必要がある。

といった具合だ。
見ての通り非常にややこしいので、作業は割愛する。
JITに対応していることだけは確認してほしい。

# UTM導入後

### ISOファイルの用意
https://fukuno.jig.jp/1256

上記ページからzipをダウンロードして解凍
`ichigojam.img`を用意する。

### 仮想マシンの作成
1. UTMを開く
2. 仮想マシンを新規作成
3. [エミュレート]を選択
4. [その他]を選択
5. ISO起動をスキップ : オン 続ける
6. [ハードウェア]の設定
    - [アーキテクチャ] : i386(x86)
    - [システム] : そのまま
    - [メモリ] : 16MB
    - [CPU] : そのまま
7. [ストレージ]の画面はそのまま「続ける」
8. [共有ディレクトリ]の画面はそのまま「続ける」
9. 概要が表示されたら保存をタップ
10. 作成した仮想マシンを編集 (トップ画面で仮想マシンを長押し→編集)
    - [情報]
        - [名前] : IchigoJam など分かりやすい名前に変更
    - [QEMU]
        - UEFI起動 : オフ
        - RNGデバイス : オフ
        - PS/2コントローラーを強制 : オン
    - [USB]
        - 対応USB : 無効
    - [共有]
        - クリップボード共有を有効にする : オフ
    - [ネットワーク]
        - 項目をスワイプし削除
    - [サウンド]
        - 項目をスワイプし削除
    - IDEドライブ
        - 既存のドライブをスワイプしディスクイメージごと削除
    - `+`からデバイスを追加
        - ドライブを読み込む
        - ダウンロードしたISOを選択
    - [IDEドライブ]
        - イメージの種類 : ディスクイメージ
        - インターフェイス : フロッピー
    - 保存をタップ

これで起動準備は完了
再生アイコンをタップしIchigoJam BASICが立ち上がれば完成

お疲れさまでした。

IchigoJam BASICの設定に関する質問であればコメントにどうぞ。
UTMの導入は本質ではないので受けられません。

# 参考記事
https://kana-yaz.hatenablog.jp/entry/2016/01/02/161854

https://kana-yaz.hatenablog.jp/entry/2016/01/05/012141
Java

本日からJavaの勉強を開始します！

Rubyは勉強したことがあり、まだまだ始まったばかりなのにRubyって簡潔( ´∀｀ )
みんなが言っていたの納得....笑

ソースコートの外側部分をとりあえず覚えるのを目標に！！（英語苦手）
https://gyazo.com/518addad6664d20c3f419cd3f3dad0e8
この形を覚えるぞ！
省略できるものもあるみたいだけど初心者は入力するのみだ

class名とファイル名が同じこと。
勉強すると日付とか入れたくなるけど気を付けるぞ
これはどの言語でも同じなんだろうけどわかりやすく！意識するぞ( ｀ー´)ノ

コンパイルをしてエラーがでるけど、まだまだ最初だからかなRubyよりはわかりやすいと感じた！
（調子のりすぎかな...笑）

次は変数宣言！
【解決】vxe-tableをCDNで利用するサンプルがちょっと不親切で手間取った

高機能なVueのテーブルコンポーネント`vxe-table`をCDNで使いたかったのですが、サンプルが良く分からず。。
あれこれ試して動いたので結果を記録します。

vxe-table
---------

https://github.com/x-extends/vxe-table/blob/4c4723b8a2063c31fe751283fd789a0bf6edb08b/README.en.md#cdn

CDNで使いたいなら、以下のように書きましょう、とあります。

```html
<!-- Style -->
<link rel="stylesheet" href="https://unpkg.com/vxe-table@next/lib/style.css">
<!-- Script -->
<script src="https://unpkg.com/xe-utils"></script>
<script src="https://unpkg.com/vxe-table@next"></script>
```

ん、その後はどう書けばよいのかしら？
コンポーネントが登録できていないのは分かるんだけど、オブジェクトの名前が分かりません。

```
vue.global.js:1622 [Vue warn]: Failed to resolve component: vxe-table-column
vue.global.js:1622 [Vue warn]: Failed to resolve component: vxe-table
```

結果
----

グローバルスコープに定義されていた`VXETable`の中身を眺めながら試した結果、テーブルが表示できた結果が以下です。

```html
<!-- Style -->
<link rel="stylesheet" href="https://unpkg.com/vxe-table@next/lib/style.css">
<!-- Script -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/xe-utils"></script>
<script src="https://unpkg.com/vxe-table@next"></script>

<!-- Root Component -->
<div id="app">
    <div>
        <!-- vxe-tableコンポーネントにtableDataをバインドする -->
        <vxe-table :data="tableData">
            <!-- 各カラムをvxe-table-columnで定義する -->
            <!-- type="seq"で行番号を表示する -->
            <vxe-table-column type="seq" title="Seq" width="60"></vxe-table-column>
            <!-- tableDataのkey名をfieldとして指定する -->
            <vxe-table-column field="name" title="Name"></vxe-table-column>
            <vxe-table-column field="sex" title="Sex"></vxe-table-column>
            <vxe-table-column field="address" title="Address"></vxe-table-column>
        </vxe-table>
    </div>
</div>

<script>
    // vxe-tableにバインドされるデータ
    const tableData = [
        { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', address: 'Shenzhen' },
        { id: 10002, name: 'Test2', role: 'Test', sex: 'Man', address: 'Guangzhou' },
        { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', address: 'Shanghai' }
    ];

    const { createApp } = Vue;
    const app = createApp({
        data(){
            return { tableData }
        },
    });
    app.component('vxe-table', VXETable.Table);
    app.component('vxe-table-column', VXETable.Column);
    app.mount('#app');
</script>
```


参考
----

https://qiita.com/Nag729/items/c7df9e24136477a56264
文字型を分割（split）したらオヨヨとなったお話

# お！っと思ったところ
空の文字数と、空の文字数をスプリットするとlenで長さを取ると違う値になる。
当たり前だけど気付かなかった。

# きっかけ
ある設備とシリアル通信してたんです。ま、シリアル通信も詳しくはないけど。
その設備から帰ってきた値（文字型）で困ったお話。

# 環境
今回は関係ないかな

# 起きたこと
正常時は今感じのデータ
```python
text = 'aaa bbb 123 ccc'
```


異常時はこんな感じが起きます。他のパターンも起きます
```python
text = ''
```

正常時のパターンを考えて、半角スペースでスプリットしようとしたんですよ。
```python
splited_text = len(text.split(' ')
```


そしたらデスよ
```python
text1 = 'aaa bbb 123 ccc'
splited_text1 = text1.split(' ')
print(len(splited_text1))

text2 = ''
splited_text2 = text2.split(' ')
print(len(splited_text2))
```

この出力ってどうなるかわかります？
`text1`は想像つきますけど、`text2`は想像外でした。
なんと
```
4
1
```

ん？**1？**

len(text2)は０だよ？
文字数０デスよ？
確認してみました。
```python
print(splited_text1)
print(splited_text2)
```
```
['aaa', 'bbb', '123', 'ccc']
['']
```

まじか！`['']`だと？
文字数０からスプリットすると要素が一つできちゃうんですね。

以上、ハマった落とし穴でした。
Qiitaに書いとけば2度とやらないでしょう。笑
エンジニアになりたいなって思ったら

こんにちは、Crane＆I　藤島です。
私は24歳になった年の12月、ITエンジニアの道を進むことになりました。
当時、ITバブル時代で、様々な企業が未経験を対象に採用を始めていた時代。
自分も例にもれず、「時代はITだろ！」という気持ちで、エンジニアという仕事もよくわからない中、企業の扉を叩いたことを覚えています。

今日は、未経験からのキャリアチェンジとして
「エンジニアになりたいな」、「エンジニアってどんな仕事だろう？」
と、考えている方に「こんな方はエンジニア業務に適性があるかも！？」という点を、
私の独断と偏見で、ちょっと書いてみたいと思います。

なお、エンジニアというカテゴリには、沢山の職種があります。
〇〇エンジニアにとっては～。という話は一旦置いておいて、もっと手前の「エンジニア」自体に焦点を当ててみました！


# エンジニア業務に適合する特徴５選（完全なる独断と偏見です）

**①横文字に抵抗がない**
英語単元が苦手な方、安心してください。
私も英語は出来ません。声高らかに言うことではありませんが笑
（出来たほうが明らかに職位の幅は広がりますので、これから学習することはお勧めです！）
しかし、エンジニアの世界は単語、略称、造語含め、横文字パラダイス。
特に大文字三文字が大好き。その大文字も英単語の集まりです。
SSH（Secure Shell）だとか、WBS（Work Breakdown Structure）だとか。
最初はほんと何言ってるかわかんないので、その意味を調べるところから始まります。
これが死ぬほど苦痛だと、結構苦しいかもしれません。


**②本（文章）を読むことが苦痛ではない**
エンジニア業務における、最初のステップは技術書やマニュアルとお友達になることです。
技術力を積み重ねていくのがエンジニアですが、大抵その技術力は知識のインプットから始まります。
知識はいわずもがな、いろいろな文章から仕入れていくわけなのですが・・・
語弊を恐れずに言うならば、それらは、殆どが「わかりづらく、面白くない文章」です。（知らないからね）
ストーリー性がある物語や、自身の背景に照らし合わせる自己啓発本などですらも
読むことが苦痛な方は、これも結構苦労すると思われます。


**③料理を作るときなど、レシピを一通り眺めてから作業に取り掛かる**
例えば、料理をしようかな。と思って、１から１０までの手順があったとき
１から並行して自分の行動をリンクさせますか？
それとも１０まで一度眺めてからもう一度折り返して１の作業を行いますか？
エンジニアの仕事は、後者の行動に利があります。
これからやる作業の「全体像をつかむ」ことで、一つ一つの作業に余裕を生むことが出来るのです。
もし、あまり意識されてなかったら、これからいろいろな手順で試してみてください！


**④知らない言葉を聞いたとき、スマホやPCで調べる癖がついている**
先輩やお客様、上司がお話されているとき、知らない言葉を話していることが沢山あります。
未経験からエンジニア職に就くと、周りはみんな「宇宙人」です。
つまり、周りの人は「宇宙語」を喋っているわけなのですが、エンジニア的な成長をするためには
その「宇宙語」をストックし、調べて翻訳し、知識としてインプットすることがとても重要です。
つまり、「宇宙語」を理解し、自らが「宇宙人」になっていくことを、どれだけ早めることが出来るのかが勝負なのだと、私は思います。


**⑤わからない知識や場面に遭遇した時、楽しいと思える**
エンジニアの世界は、上記に書いたように「宇宙語」の巣窟です。
１５年以上この業務に就き続けてきた私でも未だにそう感じます。
上記に書いた。①～③は、未経験からこの業界に入ってきた当初、私が持っていない特徴でした。
それでもここまで至ることが出来たのは、わからない知識や技術にぶつかった時に
「よっしゃ！わからないこと出てきた！これでまた成長できる！」という、
マゾヒストさながらの知的好奇心が支えてくれたんだなと感じます。
（会社で壁にぶつかった私が、「全然わかんない！楽しい！」と言っていたのを、「藤島って変態・・・」とヒソヒソされていたのは良い思い出）


# エンジニアって楽しい業務！
殆どのエンジニアがぶつかる「技術の壁」。
これを乗り越えられるか否かが、まさにエンジニア業務に適合するか否かなのではないかなと感じます。
この一山を超えた方は、世界が広がり、沢山の技術習得を苦痛なく取り入れられるのではないでしょうか。
最初はつらかった資格勉強も、自身のスキルになってしまえば、大変有益だし面白いと感じるようになりました。

如何でしたでしょうか。
どれか一つに当てはまれば、きっとそれを基準に、ほかの特徴にも手を出せることと思います。
是非、ご自身と会話をしてみて、ここは自信を持てるぞ！という部分を探してみてくださいね。

ITエンジニアに興味をもって下さる人がどんどん増えたら嬉しいです。
datetime、timeモジュール



## はじめに
datetime、timeモジュールに関しての備忘録。

## 🦁<INS>**結論**</INS>🦁
現在の日時をさまざま場面で活用するために
datetimeモジュール、timeモジュールを使う。
%m: 月を2桁の数字（例：01、12）
%d: 日を2桁の数字（例：01、31）
%H: 24時間制の時を2桁の数字（例：00、23）
%M: 分を2桁の数字で表します（例：00、59）

:::note info
押さえておくべき点
* datetimeモジュールは日付だけ、時間だけ、またはその両方を扱うことができる。
* timeモジュールは主にUNIXタイムスタンプの取得や変換に使われる。
* 現在の日時の取得するメソッドは「datetime.now()」
* UNIXタイムスタンプはtime.time()にて現在のUNIXタイムスタンプを取得できる
* strftime()メソッドを使って、日付や時間を特定の形式の文字列に変換できる。
* datetimeオブジェクト同士の差を計算できる。
:::  
***

:::note warn
利用シーン
* ログ（loggerなど）にタイムスタンプを入れる
* スクショの名前にタイムスタンプを入れる
* ユーザーのアクションの時のタイムスタンプを入れる
:::  
***

:::note alert
注意点
*  strftime()やstrptime()を使う際、フォーマット文字列を間違えるとエラーが発生する。
:::  

***

## <INS>**コード一覧**</INS>

## <INS>**現在の日時**</INS>

```py
from datetime import datetime

# 現在の日時を取得して表示
now = datetime.now()
print("現在の日時:", now.strftime("%Y年%m月%d日 %H時%M分%S秒"))
```

## <INS>**UNIXタイムスタンプ**</INS>

```py
# UNIXタイムスタンプを取得して表示
timestamp = time.time()
print("現在のUNIXタイムスタンプ:", timestamp)
```


## <INS>**処理時間の計測**</INS>

```py
from datetime import datetime

# 処理開始前の時刻を記録
start_time = datetime.now()

# 処理 (ここでは時間のかかる処理をシミュレートするためにsleepを使用)
time.sleep(2)  # 2秒間待機

# 処理終了後の時刻を記録
end_time = datetime.now()

# 処理にかかった時間を計算
elapsed_time = end_time - start_time

print(f"処理にかかった時間: {elapsed_time}秒")
```

## まとめ✍️
タイムスタンプを正しく理解して、さまざまな場面で活用する。
CISCOのIOSを誤って消してしまった場合の復旧手順

# はじめに
実務で使う機会は少ないと思いますが、CISCOの機器でIOSを誤って消してしまった場合の復旧手順について、備忘録として記載します。
# 前提
・復旧用のIOSファイルがPCに用意してあること
・PCとCISCO機がコンソールケーブルで接続されていること
・teratarmを使った手順になりますので、teratarmがPCにインストールされていること
# 手順
 ①CISCO機側の設定
 　CISCO機側で以下のコマンドを入力します
```
 　xmodem "対象のIOS".bin
```
   　例）rommon 1 >xmodem c3620-i-mz.122-16.bin
※IOSが入っていない状態ではプロンプトが「rommon」になります

コマンドを入力すると作業を続行するか確認されますので「y」を入力しエンターを押下します。

②TeraTarm側の設定
　TeraTarmを起動し、新しい接続で「シリアル」を選択し「OK」を押下します
 　メニューの「ファイル」→「転送」→「XMODEM」→「送信」を選択し
　対象のIOSファイルを選択し「開く」を押せば転送が開始されます
<img width="500" alt="画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/2c8b1e04-22fd-9f16-ea57-4439feb35a91.png">

IOSの転送が完了するとCISCO機の再起動が始まります。
再起動時に「would you like to enter the initial configuration dialog？yes/no」と聞かれますので「n」を入力しエンターを押します。
  
しばらくログが流れますので、ログが止まったらエンターを押下します。
プロンプトが「Router」となったら「show version」 コマンドを入力し、System image file が転送したファイルと 同じであることを確認してください。

 # まとめ #
 上記の手順は使わずに済むのが一番ですが、本手順が誰かの助けになれば幸いです。
 ルーターとスイッチでは復旧手順が異なりますので、スイッチのIOS復旧の際は以下のサイトも参照ください。
 
 https://www.infraexpert.com/study/ciscoios14.html
画像をレトロPCっぽく加工する

![base.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487997/d8cdb13b-1b91-bc5e-ae09-5c2d7c3b5827.png)

下記のURLの内容で画像を加工しました。
[レトロPCゲームみたいな写真が撮りたい](https://dailyportalz.jp/kiji/retro_PC_game-mitaina-shashin)

1. [Imagemagick](https://imagemagick.org/script/download.php)をインストール
1. 以下の画像を"palette.png"という名前で変換予定の画像と同じディレクトリに保存。
    ![palette.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487997/6f5b32e9-c9f4-0daa-35d5-2c184dd20da5.png)
この画像は透明部分も追加されているため、透過処理が不要な場合はURL先の画像を保存するか透過部分を削除してください
1. コマンドプロンプトを起動する
1. 変換予定の画像のディレクトリに移動する
`cd 変換予定の画像のディレクトリ`
1. 変換する
`magick convert -resize 画像サイズ +sigmoidal-contrast 8,50% -modulate 100,200,100 -ordered-dither 4x4,8,8,8 +dither -map palette.png  変換予定の画像名 出力する画像名`

例：`magick convert -resize 1270x720 +sigmoidal-contrast 8,50% -modulate 100,200,100 -ordered-dither 4x4,8,8,8 +dither -map palette.png  input.png output.png`

同じディレクトリに出力されます。
変換予定の画像に透過部分があっても、透過して出力されます。
【2024年04月版】Proxmox で LXCのマイグレーション【初心者向け】

# はじめに

Proxmox　で LXC(Linux Container) をマイグレーションするメモ。

MacbookPro M3 + UTM で環境構築していますが、x86-64でも手順は変わりません。

# 環境

- Proxmox8.1 x 3台
- CephFS構築済み
- AlpineのLXC起動済み

:::note info
- Proxmoxのインストールは、[【2024年04月版】Apple silicon (M1/M2/M3) de Proxmox【Proxmox on UTM】](https://qiita.com/nouernet/items/c7b116fe332fc9ed93aa)等を参考にしてください
- ProxmoxのCluster構築は、[【2024年04月版】Proxmox で Cluster構築【初心者向け】](https://qiita.com/nouernet/items/33e35409527b1c83df97)等を参考にしてください
- ProxmoxのCeph/CephFS構築は、[【2024年04月版】Proxmox で Ceph/CephFS構築【初心者向け】](https://qiita.com/nouernet/items/120c5d8c8b96f881f077)等を参考にしてください
- ProxmoxのLCX実行は、[【2024年04月版】Mac で Proxmox で LXC【初心者向け】](https://qiita.com/nouernet/items/9ba7fe51ddb8101dae91)等を参考にしてください
:::

:::note warn
- この記事ではオフィシャルでないProxmox-Portを、MacbookPro14 M3（AppliSelicon上） + UTM で稼働させています
- [Proxmox-Port Wiki LXC](https://github.com/jiangcuo/Proxmox-Port/wiki/lxc) を元に動かしています
:::

# LXCのマイグレーション

ノードをまたいでマイグレーションを行います。ここではLXCはpve2で実行されており、マイグレーションが実行されることでpve3に移動します。

当初の状況は以下です。マイグレーションを行うLXCを選択し「Migrate」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/58b0e5ff-2d04-b06a-de6b-eaca6f49ebe4.png)

「Target node」に移動先のノードを選択し「Migrate」を押下します。ここでは`pve3`を選択しています。「Mode」は`Restart Mode`のみで必ずLXCの再起動が発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/ca1f8f86-b08e-6caf-3e78-f6858dea615a.png)

「TASK OK」となれば、マイグレーション完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/eca02293-0933-d637-8125-1816634de16c.png)

新しいノードでLXCの動作を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/85f3816a-1f9d-20bd-2685-e88fb11128b2.png)

# さいごに

かんたんでしたね。

# 関連リンク

- [UTM](https://mac.getutm.app/)
- [Proxmox](https://www.proxmox.com/en/)
- [Proxmox-Port](https://github.com/jiangcuo/Proxmox-Port)
- [Proxmox-Port Wiki](https://github.com/jiangcuo/Proxmox-Port/wiki)
- [【2024年04月版】Apple silicon (M1/M2/M3) de Proxmox【Proxmox on UTM】](https://qiita.com/nouernet/items/c7b116fe332fc9ed93aa)
- [【2024年04月版】MacでProxmoxのインストールUSBを作成【diskutil, dd】](https://qiita.com/nouernet/items/273fdce0e77f0b2528bd)
- [【2024年04月版】Proxmoxのストレージタイプ【iSCSI, LVM, NFS, Ceph, GlusterFS】](https://qiita.com/nouernet/items/9115d497fd62930bbfcb)
- [【2024年04月版】Proxmox で Cluster構築【初心者向け】](https://qiita.com/nouernet/items/33e35409527b1c83df97)
- [【2024年04月版】Proxmox で Ceph/CephFS構築【初心者向け】](https://qiita.com/nouernet/items/120c5d8c8b96f881f077)
- [【2024年04月版】Mac で Proxmox で LXC【初心者向け】](https://qiita.com/nouernet/items/9ba7fe51ddb8101dae91)
PowerShellのバージョンによるEncodingの違い

目新しい情報ではないですが、ハマったのでメモ。

## 問題
次のPowershellスクリプト、それぞれどのようなエンコーディングでファイル出力されるでしょうか。

```powershell
"あいうえお" | out-file "unspecified.txt"
"あいうえお" | out-file "default.txt" -Encoding default
"あいうえお" | out-file "unicode.txt" -Encoding unicode
"あいうえお" | out-file "utf8.txt" -Encoding UTF8
"あいうえお" | out-file "utf8bom.txt" -Encoding utf8BOM
"あいうえお" | out-file "utf8nobom.txt" -Encoding utf8NoBOM

$shiftjis = [Text.Encoding]::GetEncoding("Shift-JIS")
"あいうえお" | out-file "shiftjis.txt" -Encoding $shiftjis
```


# 解答
powershellのエンコーディング周りはv6で破壊的変更があり、WindowsにプリインストールのPowershell(v5)と最新のPowershell(v6+)で動作が違います。

参考：
https://learn.microsoft.com/ja-jp/previous-versions/powershell/scripting/whats-new/what-s-new-in-powershell-core-60?view=powershell-6

|Encodingの指定|Windows Powershell|Powershell|
|--|--|--|
|なし|UTF-16LE|UTF-8|
|Default|ANSI(Shift-JIS)|UTF-8|
|unicode|UTF-16LE|UTF-16LE|
|UTF8|UTF-8-BOM|UTF-8|
|utf8BOM|エラー(非対応)|UTF-8-BOM|
|utf8NoBom|エラー(非対応)|UTF-8|
|shift-jis|エラー(非対応)|Shift-JIS|

## 出力別逆引き
|出力したいEncoding|Windows Powershell|Powershell|
|--|--|--|
|UTF-8|不可能(※)|UTF8|
|UTF-8-bom|UTF8|utf8BOM|
|shift-jis|default|[Text.Encoding]::GetEncoding("Shift-JIS")|
|UTF-16LE|unicode|unicode|

(※)Encodingの指定だけでは不可能だが、工夫次第で可能([参考リンク](https://qiita.com/SAITO_Keita/items/120e1286727fb680a699))

なお、v6以降であれば、shift-jisに限らず[Text.Encoding]が扱えるエンコーディングはすべて扱えます。

## まとめ

未指定と`default`で挙動が違ったり、UTF-16LEの指定が`unicode`だったりと、クセが多いです。ちなみに使うことはないと思いますが、UTF-16BEは`BigEndianUnicode`です…。

Powershellは最近のWindowsなら標準で使えるので、ちょっとしたスクリプトを書くのにも便利ですが、手元のPowershellで動作確認したのに、他の環境に持っていったら動かない、みたいなバグを踏みがちです。chatGPTに書いてもらったコードをそのまま使う場合などは特に気をつけましょう……(一敗)

にしても、どの文字コードで出力するにしても、両方で動く書き方がないんだけど。どうなってんだ。UTF16で扱えってか。
クリギング①：バリオグラム

## はじめに
前回はクリギングの大まかな流れについて書きました。

https://qiita.com/watlab/items/7bac35355c19ac977156

今回はクリギングをやるにあたって、等方性・異方性の確認から共分散関数の設定までを書いていきたいと思います。

## 使用するデータ
ChatGPTに作成させた標高データを用います。簡単のため行列形式にしました。LLM、すごく便利ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740696/035f0b53-166d-ae6e-634b-93ff93a82c01.png)

このデータから500点をサンプリングします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740696/deac107c-aea5-5924-7dbe-e5430cd229fe.png)

このサンプリングデータから欠損箇所を補完する問題について考えます。

## 等方性・異方性の確認
例えばある二次元以上の空間がある場合、どの方向によっても観測値同士の相関性が変わらないことを等方性と言います。対して方向によって観測値同士の相関性が変わってしまう時、これを異方性と言います。例として、水の広がり方を挙げてみます。水をプールに入れるとき、水平方向には均等に広がります。しかし、垂直方向では下方向に水が溜まり、上方向に水が広がることはありません。このことから、水平方向のみの二次元空間を考える場合は等方性になりますが、水平方向+垂直方向の三次元空間を考える場合は異方性になります。異方性があるときは別々にバリオグラム雲を作成する必要があります。今回は等方性を考えます。

## バリオグラム雲と経験バリオグラム
バリオグラム雲とは、バリオグラムを縦軸に、観測値同士のユーグリッド距離を横軸に置いた散布図です。ここで、バリオグラムは以下で定義されます。

~~~math
\gamma_{i,j}=\frac{1}{2}{(z_i-z_j)^2}
~~~

ここで、$y$は目的変数です。今回は標高データを使用しているため、目的変数は標高にあたります。
一次元のみで考える場合や、等方性の場合は素直なユーグリッド距離でいいのですが、異方性の場合、方向別にバリオグラム雲を作る必要があります。サンプリングデータからバリオグラム雲を作成すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740696/3fa44cbe-4aad-b083-d3a1-c15fa9fe2ccb.png)

$h$は、各観測データ間のユークリッド距離です。
経験バリオグラムは、バリオグラム雲の分布をグルーピングして、期待値のプロットとして単純化することです。こうすることによって、視覚的に関係がわかりやすい散布図になります。作成したバリオグラム雲から経験バリオグラムを求めると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740696/874c4773-4cdb-c79f-e7c0-5438328633ce.png)


この経験バリオグラムは、距離$h$のグルーピング幅を5としています。

## 理論バリオグラム
理論バリオグラムは、目的変数をバリオグラム、説明変数をデータ間との距離で表したモデルです。理論バリオグラムのモデルは、球形モデル、指数モデル、ガウスモデルなど様々です。

### 球形モデル
~~~math
\gamma(h)=b+(c-b)\bigg[\frac{2}{3}\frac{h}{a}-\frac{1}{2}\bigg(\frac{h}{a}\bigg)^3\bigg];h>a
~~~
~~~math
\gamma=c;h\leqq{a}
~~~
### 指数モデル
~~~math
\gamma(h)=b+(c-b)\bigg[1-\exp\bigg(-\frac{h}{a}\bigg)\bigg]
~~~
### ガウスモデル
~~~math
\gamma(h)=b+(c-b)\bigg[1-\exp\bigg\{-\bigg(\frac{h}{a}\bigg)^2\bigg\}\bigg]
~~~

ここで、$a$はレンジ、$b$はナゲット、$c$はシルという名前を持つハイパーパラメータです。

色々な理論バリオグラムから、どのモデルにするかは先ほどの経験バリオグラムとの二乗誤差で決定します。理論バリオグラムにはハイパーパラメータがありますが、こちらも経験バリオグラムとの最小二乗法で決定します(厳密には凸最適化となります)。今回はガウスモデルを用いて、経験バリオグラムからハイパーパラメータを決定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740696/c9ac1073-bbc6-52c4-bbba-d4c7998c32d6.png)

レンジは12.6、ナゲットは11.6、シルは336.8です。

## 共分散関数の設定
理論バリオグラム$\gamma(\infty)$がある値で収束するとき、共分散関数と理論バリオグラムには以下の関係があります。

~~~math
\gamma(h)=C(0)-C(h)
~~~
~~~math
C(0)=\gamma(\infty)
~~~

ここで、$C$は共分散関数です。この式の意味は、理論バリオグラムと対をなすものが共分散関数、ということになります。今回はガウスモデルを使用したので、以下のようになります。
~~~math
C(h)=(c-b)\bigg[\exp\bigg\{-\bigg(\frac{h}{a}\bigg)^2\bigg\}\bigg]
~~~
先程求めたハイパーパラメータの値を代入すると、
~~~math
C(h)=325.2\bigg[\exp\bigg\{-\bigg(\frac{h}{12.6}\bigg)^2\bigg\}\bigg]
~~~
以上で共分散関数を求めることができました。

## さいごに
今回はバリオグラムから共分散関数を求めるやり方について説明しました。お気づきの方もいらっしゃるとは思いますが、実はバリオグラムのガウスモデルはGPRでいうところのガウスカーネルと密接に関係したものになっています。違う分野で進歩はしつつも、このような巡り合わせがあるのは面白いですよね。異方性のときどうするかが書けなかったので、おいおい別の記事で書きたいと思います。次回は単純クリギングです。

https://qiita.com/watlab/items/f6078807842aae95ab06

### 参考文献
コロナ社、阪田義隆、クリギング入門
Elixirの基礎中の基礎

# 本レッスンのゴール
Elixirのみならず、プログラムの基本中の基本を理解し、プログラミングのベースを確立する

## iexとは何か？
iexとは、Elixirに用意されているREPL環境(Read-Eval-Print Loop)を提供するアプリケーションのことです。

REPLとは、Read(読む)、Eval(評価)、Print(印刷)、Loop(繰り返す)を意味し、つまり、利用者が入力欄にキーボードなどから式や文を一行入力すると、即座に解釈・実行して結果を返し、再び入力可能になるもののことを指します。

ElixirはこのREPL環境がiexに予め搭載されているので、iexを起動することで入力した式をその場で、実行確認できると言ったメリットがあります。このような機能はElixir特有ではなく、さまざまな言語に搭載されているということを覚えておきましょう。

iexの起動
それでは、iexを起動し様々な機能やプログラムに触れていきましょう。

## オートコンプリート
オートコンプリートとは、各モジュールに用意された関数を、モジュール名に続けてドットを入力し、Tabキーを押すことで、そのモジュールで関数で使える関数を表示してくれる機能です。

## Elixir基本文法
### 整数型(integer)
```
iex> 1
iex> 2
iex> 3
```

### 浮動小数点型(float)
```
iex> 1.0
iex> 2.0
iex> 3.0
```

### 四則演算(加算、減算)
```
iex> 2 + 2
iex> 4 * 5
iex> 30 / 2
```

### 関数を使った計算
Elixirには、予め用意されている関数があります。それらを使って計算を行なっていきましょう。
```
iex> div(20, 2)
```

Elixirには余りを求める演算子が用意されていない代わりにrem関数が用意されています。
```
iex> rem(5, 3)
```

### 論理演算真偽値
```
iex> true
iex> false
iex> true == false
```

### アトム
アトムとは、自身の名前がそのまま値になっている定数
```
iex> :a
iex> :b
iex> :japan
```

### 文字列
文字列とは、ダブルコーテーション("")で囲った値がテキストデータとして認識されます。空白なども1文字として、扱われます。
```
iex> "1"
iex> "tokyo"
iex> "toukyo taro"
```

### リスト
リスト(List)とは、0個以上の集合を表現するデータ構造です。[]で囲います。リストは、連結リストと呼ばれ、複数のデータ要素が順番に連結して並んでいます。
そのため、基本的にリスト先頭への要素の追加はリスト末尾への要素の追加より高速に行うことができます。
```
iex> [1, 2, 3]
iex> ["a", :b, 4]
```

リストの先頭に要素を追加してみましょう。リストに要素を追加する方法は++を使います。
```
iex> [5] ++ ["a", :b, 4]
```
### タプル
タプル(tuple)とは、リストと同じように複数の値を内包できるデータ構造です。{}を用いて記述します。リストと同様に、複数の型を含むことができます。
タプルは各要素がメモリ上に隣接して格納されるため、タプルの長さを得るのは高速ですが修正を行うのが高コストになります。
```
iex> {1, 2, 3}
iex> {true, :atom, 5}
```

リスト同様に、タプルへの要素追加を実行してみましょう。
```
iex> {1} ++ {true, :atom, 5}
```
自分の周り5人の平均が自分理論は正しいのか

# はじめに

おはようございます。Watanabe Jin(@Sicut_study)です。
今回は「自分の周りの5人の平均が自分」ということについて書いていこうと思います。
実際に私がエンジニアをしていて感じたこともまとめていきます。

# 毎朝5分で読める

朝5分で読めるシリーズは平日7時にエンジニアの方に気づきが与えられるような記事を投稿しています。

よければ@Sicut_studyのフォローを宜しくおねがいします！

また**スタエフ**でも毎朝6時58分にお話をしているので、耳で学習したい方はこちらもお願いします！

音声を5分聞いて学ぶことも可能です👇

https://stand.fm/episodes/6604e4ad13be25d210c8b9ce

# 自分の周り理論は正しいのか？

<font color="red">**結論、私は正しいと思っています**</font>

ではなぜ自分の周り5人の平均が自分になっていくのかを説明していきます。

もしあなたが何かプログラミングの勉強を始めようと、休日を使うようになったとします。
もちろん周りの友達はプログラミングなどやったことはありません。

気づいたらプログラミングに熱中していて、ある程度技術が身についたとします。すると、いままでの友達としていた会話が合わなくなってくる瞬間が訪れます。

もっとプログラミングをやるような人たちと交流していこうとTwitterを始めるかも知れません。

**人は成長し始めるといままでの環境では合わなくなり、別の環境を望むようになってきます**

つまり周りの5人を変更するようになってくるわけです。

よく起きるコンビ芸人が売れたらコンビ芸人の顔が知られている方が解散を切り出すなどはこういうことから起きていると思っています。

# エンジニアは成長するとやめる

エンジニアは転職が多い職業です。
もちろん給料を上げるために転職をするというのもありますが、私が見てきたのは「技術力を上げるために転職する」という理由です。

実は私も同じ体験をしました。

>新卒で入社した企業は、入社したての頃の私にとっては先輩全員が最強のエンジニアに見えていました。しかし、プログラミングに熱中していた私はプライベートでもコードを書くようになり、気づいたら会社にはすごいと思える人がかなり少なくなっていました。
すると気づきます。周りはみんな自分のようにプライベートで勉強しているわけではなくて、あまり成長意欲がない。この環境にいても自分はあまり成長しない気がする。
そう思って転職をして、今では更に技術力がある環境でお仕事ができています。

これもまさに**自分の周りを転職を使って変えている瞬間**だと思います。

# 今の環境で周りと話が合うなら成長していない

この理論で行くと、年末などで地元に返って友達と話したときに**話が合う**と自分は1年間成長していないなと思ってしまいます (地元が東京なら話は別)

また、会社の人と話があって楽しいというレベルだとまだまだ成長する余地があると考えます。

話が合わなくなると疎遠になってしまって悲しく感じるかも知れませんが、あなたの人生はあなたのものなので**それはそれでよい**と思っています。

前の友達や会社とは疎遠にはなりますが、次の環境できっと新しい仲間が見つかります。

# 離婚との意外な関係性

ここからは、私が実際に聞いて面白いなと思った話を共有します。

**どちらかが成長意欲がある状態だと離婚につながりやすい**

というものがあります。
パートナーのうちどちらかが成長意欲があって、どちらかが成長意欲がなくなってしまったというパターンになると起きるみたいです。

成長意欲がある同士結ばれるので、そのような人たちの中では時間経過と共によく起きる問題らしいです。

# おわりに

常に自分の周りをアップデートし続けられるように色々頑張りたいところです。
目に見えて成長がわかるのも面白いポイントだなと思いましたので紹介しました。

ここまで読んでいただけた方は**いいね**と**ストック**よろしくお願いします。
@Sicut_study を**フォロー**いただけるととてもうれしく思います。

https://qiita.com/Sicut_study

また明日の記事でお会いしましょう！

![jisou-banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/217ea52d-8130-3266-0619-990fa968408a.png)

# おすすめ記事

https://qiita.com/Sicut_study/items/71b866d8f064699cb57b

https://qiita.com/Sicut_study/items/2318952ecfdddefd384c

https://qiita.com/Sicut_study/items/96c5f6eb794dbf808750

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp

# About Me

Webエンジニア転身して1年間本気で勉強
転職ドラフトで高額オファーを複数獲得
そこでの経験からアウトプットやマインドセットの発信に強みがある
エンジニアをやりながら、起業に挑戦中
アイデア作りやパブリックスピーキングを得意としてる

■ Twitter
https://twitter.com/Sicut_study
■ stand.fm
https://stand.fm/channels/65db27e353b400abe28ec29a
■ Youtube
https://www.youtube.com/channel/UCBFrGAJhPuuaoLwUIHBILsA

■ プログラミングコーチングJISOU
https://projisou.jp
■ 体験で学ぶ！JISOU
https://experience-learn.connpass.com/
■ 登壇依頼などご依頼はこちらから
himaria.jin.watanabe@gmail.com
array_spliceとarray_slice

## はじめに

名前が似ていて混乱するので整理用に

## array_splice
配列に対し要素を追加/置換/削除する

```
array_splice(array &$array, int $offset [, ?int $length[, mixed $replacement]]) :array
```
&$array : 操作対象の配列
＄offset : 要素の抽出開始位置
＄length : 取り出す要素数
＄replacement : 削除箇所に挿入する配列（単一の場合は文字列でも可）



```php:array_splice.php
$data = ['高江', '青木', '片渕', '和田', '花田', '佐藤'];

print_r(array_splice($data, 2, 3, ['日尾', '掛谷', '薄井'])); //['片渕', '和田', '花田']
print_r($data); //['高江', '青木', '日尾', '掛谷', '薄井', '佐藤']

print_r(array_splice($data, -3, -2, ['長田', '杉山'])); //['掛谷']
print_r($data); //['高江', '青木', '日尾', '長田', '杉山', '薄井', '佐藤']

print_r(array_splice($data, 3)); //['長田', '杉山', '薄井', '佐藤']
print_r($data); //['高江', '青木', '日尾']

print_r(array_splice($data, 1, 0, ['山田', '矢吹'])); //[]
print_r($data); //['高江', '山田', '矢吹', '青木', '日尾']

```

## array_slice
配列から特定の要素を取り出す（スライスする)

```
array_slice(array $array, int $offset [, ?int $length[, bool $preserve_keys = false]]) :array
```
$array : 任意の配列
＄offset : 抽出開始位置
＄length : 取り出す要素数
＄preserve_keys : 取得した要素のキーを維持するか

```php:array_splice.php
$data = ['高江', '青木', '片渕', '和田', '花田', '佐藤'];

print_r(array_slice($data, 2, 3)); //[0 => '片渕', 1 => '和田', 2 => '花田']

print_r(array_slice($data, 2, 3, true)); //[2 => '片渕', 3 => '和田', 4 => '花田']

print_r(array_slice($data, 4)); //[0 => '花田', 1 => '佐藤']

print_r(array_slice($data, -4, -3)); //[0 => '片渕']

```
Streamlit × MediaPipeでHandPoseEstimationのWebアプリを簡単デプロイ

# はじめに
手の姿勢推定に興味があるので、ひとまず簡単なモデルを動かしたいと思いました。
また、Streamlitを一度使ってみたいと思っていたので、手の姿勢推定とPythonのWebアプリを組み合わせて制作物を作ろうと思いました。

## Streamlitとは
**Streamlit**とはPythonによる主にデータ可視化・データ分析向けのWebアプリケーションフレームワークです。
マークダウンを使用してページを作成できたり，デプロイも簡単なのが特徴です。デプロイしなくともちょっと可視化したいときなどにもおすすめです。
ぜひ「**Streamlit**」で調べてみてください

## MediaPipeとは
**MediaPipe**とはGoogleが開発した機械学習や画像認識を行うフレームワークで、物体検出，顔検出，姿勢推定などの様々なタスクに対応しています。
Pythonなどで無料で簡単に使用できます。また解説記事も豊富にあるので「**MediaPipe**」で調べてみてください

# 制作物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/e8cfeb2b-b724-f60c-73c1-14df0c2064cd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/9a085d78-633d-f1b1-7d92-9f4b86159105.png)


Webアプリ

https://hand-pose-estimation.streamlit.app/



Repository

https://github.com/ryhara/Streamlit-handpose

# 実装
それぞれ以下のサイトを参考にしてほとんど貼り付けただけです。
表示や、パラメータ調整は自身で工夫しました。

## MediaPipe

https://developers.google.com/mediapipe/solutions/vision/hand_landmarker

https://www.youtube.com/watch?app=desktop&v=vQZ4IvB07ec


## Streamlit
https://zenn.dev/whitphx/articles/streamlit-realtime-cv-app

# デプロイ
以下の記事を参考にしました。Githubにpushするだけなので簡単です。

気をつける点は必要なライブラリをrequirements.txtに書いておくことと， Pythonのバージョンを最初に指定するくらいです。

https://qiita.com/kagami_t/items/c54702e271d729948e24


デプロイ後にopencv周りでエラーが出ていたら以下のサイトを参考にすると良いです。

- [[Streamlit sharing] Importerror: libgl.so.1: cannot open shared object file: no such file or directory opencv error - ☁️ Community Cloud - Streamlit](https://discuss.streamlit.io/t/streamlit-sharing-importerror-libgl-so-1-cannot-open-shared-object-file-no-such-file-or-directory-opencv-error/12367/36)

- [ImportError libGL.so.1 cannot open shared object file No such file or directory - Streamlit Docs](https://docs.streamlit.io/knowledge-base/dependencies/libgl)

# 最後に
PythonとMediaPipeは少しだけ触ったことがありましたが、1時間ちょっとで作れたと思うので、是非参考にしてみてください。