OmniAICreator/Qiita-1.07M huggingface dataset:
誤嚥性肺炎にならないように

誤嚥性肺炎にならないように

誤嚥性肺炎の分析では、IEC HAZOPを用いることがある。　

HAZOPは、当初、化学プラント工場の電磁弁システムにおける、流量制御において、大きすぎる、小さすぎる、ない、早すぎる、遅すぎる、前、


# 安全分析　

安全（１９）医療システムをHAZOPで分析する

https://qiita.com/kaizen_nagoya/items/16fdc44da4fbb4f12d30


ちょけねこ　たんじょうびのおくりもの　

https://qiita.com/kaizen_nagoya/items/fc9675686c229f7a155e

効率的なHAZOPの進め方。仮説（187）

https://qiita.com/kaizen_nagoya/items/2b8eae196945b7976446


HAZOP資料整理

https://qiita.com/kaizen_nagoya/items/6dd3b903a324cc065ea6

図を使って分析・設計すればこんなに簡単。安全（１１）

https://qiita.com/kaizen_nagoya/items/6347eb55b2812d745549


HAZOPで図を用いる場合の機能

https://qiita.com/kaizen_nagoya/items/8f5d2c7bc2c60625e909

安全分析（HAZOP）の際の声かけ。安全（２０）

https://qiita.com/kaizen_nagoya/items/381649a6ea025ecba173


ちょけねこ　たんじょうびのおくりもの　はいふさきと　かつどう

https://qiita.com/kaizen_nagoya/items/0dced798518501d8ffba


＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　 20230３211
ver. 0.02 ありがとう追記 20230604
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
ディメンジョンの読み込み順についてのメモ

# 始まり
カスタムディメンジョンをMultiverseCore(以降mvc)で作成して、それらディメンジョン間を移動するためのプラグインを作成したのだが、どうにもうまく動作しない。

上手く動作しないというのは、mvc での設定が反映されていないディメンジョンに飛んでしまうというものだ。
(ディメンジョン名はmvc で作成した時と同じなのだが、ディメンジョンの環境設定だけが異なる)

# 原因
　テレポートをする際に、テレポート先のディメンジョンを読み込んでいないとディメンジョンのロードがかかり、タイムアウトで鯖から蹴られてしまう。
それを防ぐためにテレポートプラグインが起動する時点でWorldCreator を動かしてディメンジョンを読み込んでいた。
しかし、そのロード方法に問題があった。
WorldCreator#createWorld でディメンジョンをロードするといくつかのディメンジョン設定が無視されるようで、そのためにmvc で設定したものと異なる環境になってしまっていた。


> "If the world already exists, it will be loaded from disk and some options may be ignored."
>
> [Spigot JavaDoc WorldCreator#createWorld()](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/WorldCreator.html#createWorld())
>

# 対策
 mvc がカスタムディメンジョンをすべて読み込んだ後にテレポートプラグインを起動するようにすればよいので、plugin.yml の softDepend に Multiverse-Core を記載した。
本来は依存するプラグインなどを記載し、依存先よりも先に読み込まれないようにするための設定だと思われるが、単に起動のタイミングを前後させているだけなのでこのような使い方もできるようだ。
【AWS】ブログ構築でWebブラウザに表示されないときの対処法

<h1>はじめに</h1>
現在インフラエンジニアに未経験から転職。
知識のアウトプットを含めて記録。<br>
エラーをどこからみていけばいいのかわからなかったので原因の調査方法をまとめてみた。
<h1>構成図</h1>
マルチAZ構成にてWordPressの構築練習。
Route53,IGW(インターネットゲートウェイ),ALB,EC2,RDSを使用。
<a href>https://aws.amazon.com/jp/getting-started/hands-on/build-wordpress-website/</a>

<a href>https://hiyowa-na-engineer.com/how-to-wordpress-aws/</a>
↑こんな感じ。

<h1>状況</h1>
構築も終わり、実際にWebブラウザ上で表示させようとも<br>
【[このサイトに表示ができません]応答時間が長すぎます。】
というエラーが発生する。


<h1>対処手順</h1>
どこにエラーが発生しているのかというのを部分ごとに調査していく。
<br>
<br>
①Route53→ALBへの名前解決確認
SSH接続でローカルから作成したEC2に入る。
コマンドプロンプトにて
[nslookup　レコード名(自分で作成したドメイン名)]＝名前解決されているか確認
↓
・ドメイン名
・ALBのIPアドレス
が表示されれば問題なし。
<br>
<br>
②ALBのIP（宛先）を確認
AWSサービス上にて「EC2」→左サイドメニューにある「ネットワークインターフェイス」を表示。
「ネットワークインターフェイス」上にて、先ほどコマンドプロンプトで表示された「Adresses(IPアドレス)」をコピって検索かける。
→ネットワークインターフェイスが（今回の場合）ALBのセキュリティグループにて設定されていることを確認できればOK。
<br>
③ALB→EC２への疎通確認
EC２を確認。
「EC２」→ターゲットグループ→targets→対象のEC２が「healthy」ならOk。
<br>
④ALBのセキュリティグループ確認
↑結局自分はこれが問題でした。

<h1>さいごに</h1>
初心者にとってバグやらエラー起こった時、まず何からみればいいのってなりますが
自分的にはセキュリティグループの設定不備が多いですね、、、
ただ今回の調査で一通りの流れがつかめたのでよかったです。
Chat GPTに小説は書けるのか？

## 今は短編小説向き！
今回試した手法では、Chat GPTの文字数制限がネックになり長編小説を書くのは難しかった。
ただ、書き出しはそれっぽいので、あくまで素人が書く場合かもしれないが、短編を書いたり、プロットを作ってもらうには使える！

### 今回試した手法
・面白そうな小説の選択肢を聞く
・選択肢の中から興味あるものを選んでプロットを書いてもらう
・プロットから１話に該当する部分を抜き出して、文字数を指定しながら書いてもらう
※ 一番重要なのは、各ステップで気に食わなければケチをつけること。
　 問題点をしっかり指摘すると、修正して結果を返してくれる！

##### 面白そうな小説の選択肢を聞く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643239/0e34ab2d-ccde-908e-f076-86367f302ee4.png)

##### 選択肢の中から興味あるものを選んでプロットを書いてもらう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643239/8c6e7172-4e54-3a19-2b91-dbe7748eb375.png)

##### プロットから１話に該当する部分を抜き出して、文字数を指定しながら書いてもらう
試しに１話をお願いしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643239/7db1d95c-b8e8-a8c0-532e-22f2258a3f10.png)
小説としては唐突すぎて意味不明ですよね。
ちょっと文句を言ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643239/4ea13f81-f1fe-985b-2f78-02a0e6892718.png)
はい、ここから文字数を指定して１話を書いてもらいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643239/f23de234-b667-a3b0-075c-dcc6d88f0c21.png)
一見よさげですね。
これを読んでいって文句をつけたり一部を書き直してもらったり、
あるいは描写を増やせ、感情表現を入れろ！と編集者気分で指示していきましょう。


### 完成した小説
というわけで、例に出したものとは異なりますが同じ手法で出力したものを手直ししたサンプルがこちらです。（話の最後は衝撃的にしろ！読者をひきつけろ！みたいな精神論で調教しました）
https://ncode.syosetu.com/n8311ic/


### 問題点
・Chat GPTが長すぎる文章を解析できない
　→概要を書いて次を書いてもらおうとすると概要が生成されるなど融通がきかない
・１話はそれっぽかったけれども、上述の理由により２話以降はうまく生成することが難しく、
　手直しをしようとすると大変に手間。書いた文章のおかしさをChatGPTに評価させようとしても
　上述の制限のせいで難しい。
・プロットを守ってくれない上に、すぐに概要レベルの記載に変わってしまうので、
　小説の文体にするには何度も文句をつける必要が出てくる
医学論文を読む

通信の専門家です。　

博士論文は「端末間経路選択片方向遅延差測定方式」です。　

電子情報通信学会とIEEEの国際会議報告が中心になっています。　

主な学会活動は、情報処理学会、電子情報通信学会、IEEEです。　

情報処理学会、電子情報通信学会が参加する電気関係学会の東海支部で連盟の口頭発表を１００回近くしています。

# 学会発起人、世話人　

# 事例　

## カルタナー症候群　

## 膠原病　


### 皮膚筋炎　

医療、創薬 皮膚筋炎の発症メカニズム
https://www.ccb.osaka-u.ac.jp/wpccb_handle/wp-content/uploads/2022/03/FujimotoManabu2022JP.pdf

https://researchmap.jp/read0122743



####　transcriptional intermediary factor 1- γ (TIF1- γ)

Okiyama, N; Ichimura, Y; Shobo, M; Tanaka, R et al. Immune response to dermatomyositis-specific autoantigen, transcriptional intermediary
factor 1γ can result in experimental myositis. Ann Rheum Dis. 2021 Sep; 80(9): 1201-1208. doi: 10.1136/annrheumdis-2020-218661.


https://www.researchgate.net/publication/350594136_Immune_response_to_dermatomyositis-specific_autoantigen_transcriptional_intermediary_factor_1g_can_result_in_experimental_myositis

#### ncu
http://ncu-intern2.jp/group/rheumatology/research.html

難波 大夫
山邊徹
林　里音
# 参考資料　


https://qiita.com/kaizen_nagoya/items/8710bfa1d9d6eebccdcf
generateのテーブル名は複数形

>Migrations Generator Conventions:
 Migrations should be:
    1. Camel cased or Snake cased
    2. start with an action (i.e. create, add, remove, etc)
    3. The name of the table should be the last word and it should be plural
    4. Column names should be snake cased and singular, followed by a colon “:” and data type (default is a string).


The name of the table should be the last word and it should be plural

テーブルの名前は最後の単語であるべきで、それは複数形であるべきだ
出典　DeepL


# 出典
https://medium.com/@decode2018/rails-generator-naming-conventions-c3f7df937033#:~:text=The%20name%20of%20the%20table%20should%20be%20the%20last%20word%20and%20it%20should%20be%20plural

テーブル名	users	先頭小文字・複数形
# 出典
https://qiita.com/gakkie/items/3afcd505c786364aa5fa

# 感想
2つの記事で同じことが書かれていたので複数形でいいのか。
何でだろうか
そういう仕様になっているからか。
とりあえず頑張ろう。
Ruby学んでみた。

# 注意
・C言語を学んでいるのでC言語とRubyを比較して理解を深めるかも。

# RubyでHello World
```ruby
# 一行でコメントアウト
puts "Hello World"
# コメントアウト

# 複数行でコメントアウト
=begin 
puts "Hello world"
puts "Hello Ruby"
puts "Hello omochi"
=end
// コメントアウトできない。
```
<b>メモ</b>
<b>Rubyで出力する命令メソッド（関数）は3種類ある。</b>
・print → 改行なし、改行をつける場合は\nを文末につける。
・puts → 改行あり。
・p → プリントデバック用に使う。

<b>使い方</b>
・putsと文字列の間には半角スペースが必要。
・シングルクォーテーションかダブルクォーテーションで文字列を囲む。


# Rubyで四則演算
```ruby
puts 1 + 1 # puts 1+1 でも ◎ 
puts 1 - 1
puts 1 * 1
puts 1 / 1
puts 1 % 1
```
<b>メモ</b>
・整数と演算子の間に半角スペースが無くても良い。
# Rubyで文字列の連結1
```ruby
puts "お" + "もち" 
puts 'お' + 'もち' 
```
<b>実行結果</b>
おもち
おもち

<b>メモ</b>
・シングルクォーテーションとダブルクォーテーションはどちらでもいい。
# Rubyで文字列の連結2
```ruby
puts "123" + "456"
puts "123 + 456"
```
<b>実行結果</b>
123456
123 + 456

# Rubyで変数1
・Rubyには変数の種類が4種類あるらしい
・ローカル変数
・インスタンス変数
・クラス変数
・グローバル変数
[Ruby 3.2 リファレンスマニュアル  変数と定数](https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html#:~:text=Ruby%20%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%A8%E5%AE%9A%E6%95%B0,%E3%81%8B%E3%81%AB%E5%8C%BA%E5%88%A5%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)

# Rubyで変数2
```ruby
food = "おもち"
puts food
```
<b>実行結果</b>
おもち

<b>memo</b>
・セミコロンいらないの不思議。どうやって文字が終了してるんだろう?
# Rubyで文字列の変数
```ruby
food = "おもち"
me = "食べたい"
sum = "3個"
puts food + me
puts sum + food + me
```
<b>実行結果</b>
おもち食べたい
3個おもち食べたい

# Rubyで変数展開
```Ruby
#  #{} これを使う
food = "おもち"
puts "私は毎日#{food}が食べたいです"

day = 2
puts "私は毎日#{day}個、#{food}を食べています。"

week = 7
omochiweek = day * week  
puts "私は1週間で#{food}を#{omochiweek}個、食べています。"
```
<b>実行結果</b>
私は毎日おもちが食べたいです
私は毎日2個、おもちを食べています。
私は1週間でおもちを14個、食べています。

<b>変数展開にできること</b>
・簡単に文字連結ができる。
・コードが読みやすくなる。 → 一目でどの変数がどこに使われているかわかる
・コードの書く量が減る。 → ダブルクォーテーションで囲んだ文字列の中に変数展開をすればその変数を使える。

# Rubyで式展開
・文字列の中の変数展開の中に式を書いても計算してくれる。
```Ruby
puts "The result of 1 + 2 is #{1 + 2}."
```
<b>実行結果</b>
The result of 1 + 2 is 3.

# Rubyで条件分岐
```Ruby
mochimuch = 5

if mochimuch > 2
    puts "おもちを食べすぎています。"
end
```
<b>実行結果</b>
おもちを食べすぎています。

# Rubyのメソッド（関数）
・randメソッド

https://docs.ruby-lang.org/ja/latest/method/Kernel/m/rand.html

# Rubyのデータ型
数値型:
整数(Integer)、浮動小数点数(Float)、有理数(Rational)、複素数(Complex)があります。

文字列型:
文字列(String)型があります。文字列はダブルクォート("")またはシングルクォート('')で囲みます。

配列型:
配列(Array)型があります。複数のオブジェクトを要素として持ちます。要素は0から始まる添字でアクセスできます。

ハッシュ型:
ハッシュ(Hash)型があります。キーと値のペアを持ちます。キーには文字列、シンボル、数値などを使用できます。

論理型:
真(True)または偽(False)を表す真偽値(Boolean)型があります。

シンボル型:
シンボル(Symbol)型があります。シンボルはコロン(:)で始まる文字列で、一意で不変です。

正規表現型:
正規表現(Regexp)型があります。パターンマッチングに使用されます。

nil型:
何もないことを表すnil型があります。何も値を持ちません。

ブロック型:
ブロック(Block)型があります。メソッド呼び出し時に付けられる処理の塊です。

ここは調べ中


# Rubyでfor文
```Ruby
for i in 1..3 
    puts "おもちが#{i}個"
end
puts "おもちの合計は#{i}個"
```
<b>実行結果</b>
おもちが1個
おもちが2個
おもちが3個
おもちの合計は3個

# Rubyで標準入力から値を受け取る

https://qiita.com/emioiso/items/a172971bf5be9b9d53ba

# Rubyでfor文

https://udemy.benesse.co.jp/development/system/ruby-each.html
DockerでPHP+PostgreSQLを使うとき用Tips

## この記事は
- とても初心者向けです
- Docker + PHP + PostgreSQLの構成を試したらハマり所が多かったのでメモを残しておく

## 例Dockerfile/docker-compose.yml
Dockerfile
```dockerfile
FROM "php:8.1.16-apache"

ENV COMPOSER_ALLOW_SUPERUSER=1
WORKDIR /var/www/html
COPY composer.json /var/www/html/
COPY composer.lock /var/www/html/
RUN apt-get update
RUN apt-get install zip unzip
ADD https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions && sync && \
    install-php-extensions pdo_pgsql
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
```

docker-compose.yml
```yml
version: "3"
services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php
    volumes:
      - ./app:/var/www/html
    ports:
      - 8080:80
    command: bash -c "composer install && docker-php-entrypoint apache2-foreground"
  pgsql:
    image: postgres:11.19-alpine
    container_name: pgsql
    volumes:
      - ./db/data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=root
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=root
    ports:
      - 5432:5432
```

### 解説
#### Dockerfile
**`RUN apt-get install zip unzip`**
- これがないとcomposerがそもそも開けない。元から入ってないのでインストールしておく

**`ADD` ~ `&& install-php-extensions pdo_pgsql`**
- PHPでPostgreSQLを使うための設定
- 通常のapt-getからインストールできる `php-pgsql` はDockerではうまくダウンロードできない
    - 参照：[I can't install php\-pgsql in container \- General Discussions \- Docker Community Forums](https://forums.docker.com/t/i-cant-install-php-pgsql-in-container/54667)
- そのため、apt-getを回避してドライバをインストールする策のひとつがこの方法

#### docker-compose.yml
**`command: bash -c "composer install && docker-php-entrypoint apache2-foreground"`**
- `composer install` をDockerfileの中でやっても意味がないと気づいた末のcommand
    - DockerfileのWorkdirの中でやると、結局そのディレクトリがマウントされて用意した `/vender` が上書き・不可視になってしまうので、autoloaderのエラーが起きてしまう
    - なのでここでディレクトリマウントしてからinstallすることで/venderがないエラーを回避
    - 毎回の起動にちょっと時間がかかってしまうのでもっと良いやり方はありそう
Java SE Bronze 資格取得までのロードマップ

## はじめに
Java Bronzeのロードマップをメモしておきます。

## 目次
1.スッキリわかるJava入門(書籍)
2.せかちゃん-世界一わかりやすい情報科チャンネル(YouTube)
3.Java プログラマ BronzeSE(書籍)

## 1.スッキリわかるJava入門
こちらの書籍は、Javaの基礎知識を初心者などがわかりやすいように、絵などを使って書かれている書籍になります。説明などもわかりやすくて、Java初心者の方にはオススメです。
まずは、こちらの書籍で基礎知識を固めます。

https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BJava%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1%E6%B8%85%E5%96%AC/dp/4295007803

## 2.せかちゃん-世界一わかりやすい情報科チャンネル(YouTube)
1の書籍だけでは理解が進めなかった方にはこちのYouTubeチャンネルをオススメします。
こちらのYouTubeチャンネルは、Javaなどに限らず、ITに関する様々な知識を学べるチャンネルです。Java Bronzeを取得するために見るべき動画はこちらになります。

▼入門講座１章：Javaの始め方
https://youtu.be/QeCX5-OmWW8
▼入門講座２章：Javaの基本文法
https://youtu.be/BBKVCkdqS8g
▼入門講座３章：オブジェクト指向－入門編－
https://youtu.be/dzy1ipa20Kk
▼入門講座４章：オブジェクト指向－応用編－
https://youtu.be/aecDJ0yN1oY

## 3.Java プログラマ BronzeSE(書籍)
こちらは、Javaの解説に加えて、Java Bronzeで出題される範囲に関する問題や、模試形式の問題が書かれている書籍になります。
実際に問題をやってみると、引っかけの問題なども結構あるので、試験を受ける前に問題慣れをしておく書籍にはピッタリかなと思います。

https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Bronze-SE-%E8%A9%A6%E9%A8%93%E7%95%AA%E5%8F%B71Z0-818/dp/479816206X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3FYMQXFYTQRV6&keywords=Java+%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E&qid=1677321289&s=books&sprefix=java+%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%2Cstripbooks%2C187&sr=1-1

## 最後に
以上の3つをしっかり学べば、Bronzeは取得できると思います。問題文をよく読んで、引っかけ問題に引っかからないようにしましょう。
Springでポートフォリオを作る　3-3.データ設計

# 前回まで
これまで機能設計と画面設計を行いました。

画面設計

https://qiita.com/Jackoguro/items/2bcaac1b13aa61131598

機能設計

https://qiita.com/Jackoguro/items/ccce8b0fd3d5ba44d8d8


# この記事の目的
これまで作成した画面設計と機能設計を元にして、データ設計を行います。

# データ設計の流れ
今回は以下の流れでデータ設計を行います。
1. データ構造を明確にする
　1. テーブルをマスタ・トランザクションに分ける
　1. テーブルの具体的な中身(データ構造)を決める
1. テーブル間の関係性を定義
　1. テーブル間の参照関係を整理する
　1. 参照関係を簡単なER図に書き起こす

## データ構造を明確にする
### テーブルをマスタ・トランザクションに分ける
最初はマスタとトランザクションにデータを分けます。

マスタテーブル：システムの運用上変更が頻繁にない基本的な情報が格納されたテーブル
トランザクションテーブル：システムの運用上、日々の記録が格納されたテーブル

:::note warn
下記画像にクエストマスタがマスターテーブル側で入っていますが、次回以降でトランザクションテーブル側に変更予定
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/5bf8e0a0-7873-3b03-4055-09341728ba92.png)

### テーブルの具体的な中身(データ構造)を決める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/f96c8c35-991b-e743-926b-7dfc2121176a.png)

今回テーブルの具体的な中身はGoogleスプレットシートで作成しました。

https://docs.google.com/spreadsheets/d/1xjiUk-_NbZkd69rD7czmMb-iGEqKhcq8XGfav-UnP-w/edit?usp=sharing

## テーブル間の関係性を定義
### テーブル間の参照関係を整理する
テーブル間の参照関係を赤：マスタ、青：トランザクションテーブルとして定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/1ec3ae43-f02c-ede9-68a9-c2905bf63e9b.png)

https://www.figma.com/file/H7EbP2Z2hbHfkSLgtay1Uy/%E3%83%87%E3%83%BC%E3%82%BF%E8%A8%AD%E8%A8%88?node-id=1%3A2&t=4itH8H1EU2Nf3mTD-1

### 参照関係を簡単なER図に書き起こす
最後に参照関係をER図に書き起こします。今回ER図はhttps://www.diagrams.net/ を使用して作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/29cc54de-313b-57df-125e-52a31551ab01.png)

https://drive.google.com/file/d/1DJJOgWMffSVQy2eSP7UN25qRTGHs92vM/view?usp=sharing

# 最後に
今回で基本設計は一通り終了しましました。
しかし、所々設計が甘い部分が見つかったため、もう一周基本設計を行いクオリティーを高めます。
箱入り娘パズルを探索で解いてみた

## 箱入り娘パズルとは
みなさんはスライドパズルの一種、箱入り娘はご存じでしょうか
![](https://upload.wikimedia.org/wikipedia/ja/0/0c/Hakoiri.JPG)画像はwikipediaより。[(引用　画像の作者名Adan　パズル「箱入り娘」。 2005/7/13,Adanさんによる撮影)](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Hakoiri.JPG#filelinks)

箱入り娘とは、駒を空いている位置にスライドさせて移動させることによって、娘と呼ばれる２×２の一番大きな駒を、枠の下部の切れ目に移動させることを目的としたパズルです。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/ccc7c112-98cd-6265-e7be-9b0a1e1cfc9b.png)




簡単そうに見えますが自分でやってみるとめちゃくちゃむずかしいです。
もしやってみたい方は、千葉市科学館で売っており、体験コーナーもあって遊べるのでぜひ。通販でも手に入ります。
（通販だと箱入り娘ではなくて箱入り曹操でした。箱入り曹操…？）

今回はこの箱入り娘をPythonで解いていこうと思います。
[コードはこちら(githubページに飛びます）](https://github.com/mimic-asy/hakoiri_musume)


## どうやって解くか
今回は幅優先探索によって初期位置から娘を目的の位置に届けるクリアまでの経路を求めます。

## 箱入り娘をPython上で再現する
箱入り娘の盤面は、多重配列np.arrayを用いて再現しました。
それぞれの駒を指定しやすいように、父、母、娘...等の名前をつけました。これらの駒を並べて盤面を再現しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/7f538cdb-ebb4-6b44-826e-ed173178d5d9.png)


箱入り娘パズルでは、同じような形の駒が複数あるので全体としての形状は変わらず、駒の名前だけが違うパターンが多く存在します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/594fec84-2e2b-bbbc-de91-0760f1ad2947.png)
しかし探索する際には名前を区別する必要はなく、全体の形のみを比較したいため、比較を行う際には駒を形状ごとに数字へ変換しました
するとこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/fd25314c-f0b0-2022-dbe4-dff838203885.png)
全体の形のみを比較することができるようになるため、変換する前よりも効率的に探索を行えるようになりました。


## クリアまでの経路の求め方

幅優先探索を行って新規に盤面を発見した際に、新規に発見された盤面とその一つ前の盤面を対応づけます。これを探索の各ステップで行うことで全ての盤面同士につながりができ、つながりを逆に辿ることでどの盤面からでも初期位置まで戻ることができます。これを利用してクリアとなる盤面から初期盤面までの経路を求めています。

## 実行結果

総盤面数と、クリアまでの経路が出ました、経路は下図のようになっております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092001/bd48f20d-6d50-4783-4bf6-d84f277fd1fe.png)

初期位置から116手でクリアへ辿り着くことができました。

## まとめ

・箱入り娘を幅優先探索で解いてみた結果、11６手で解けることが判明しました。
・箱入り娘が取れる盤面の総数は25955個でした。

## 書いてみて得られたこと
・深さ優先探索も同時に実装したので幅優先探索との特性の違いを知ることができました。
・最初は、np.arrayのまま全ての処理を行なっていました。とても遅かったので盤面を文字列で表現して処理を行なったところ倍以上の速度になったので、型ごとの速さの違いを体験する良い機会となりました。
・ちゃんと動いていると思っていたものでもテストコードを書くと色々バグが出てきて、テストコードをちゃんと書かなければという意識が芽生えました。


## 最後に
アルバイトを募集しています。
twitterのDMやリプライでお声がけください。
https://twitter.com/Not_rinrikan
ubuntu に新しいユーザを追加しssh接続（メモ・記録）

# ubuntu に　新しいユーザを追加　（root権限なし）

# ユーザーの追加

```shell
    useradd <任意の名前>
    passwd <任意の名前>
```

### sudoを使いたい場合

現在ログインしているユーザーがsudo権限を持っていることを確認します。

```bash
    sudo -l
```

sudoグループにユーザーを追加します。

```shell
    sudo usermod -aG sudo ＜ユーザー名>
```

変更を反映するために、ログアウトして再度ログインします。

```shell
    logout
```

再度sudo権限を確認します。

```shell
    sudo -l
```

## homeディレクトリを作成

```shell
    mkdir /home/<任意の名前>
```

## .sshディレクトリを作成

```shell
    mkdir /home/<任意の名前>/.ssh
```

## authorized_keysを作成

```shell
    touch /home/<任意の名前>/.ssh/authorized_keys
```

## パーミッションを変更

```shell
    chmod 700 /home/<任意の名前>/.ssh
    chmod 600 /home/<任意の名前>/.ssh/authorized_keys
```

## ユーザーの所有者を変更

```shell
    chown -R <任意の名前>:<任意の名前> /home/<任意の名前>/.ssh
```

## ssh接続するクライアントの端末で鍵を作成

### 初めて.sshディレクトリを作成する場合

```shell
    mkdir ~/.ssh
    chmod 700 ~/.ssh
    ssh-keygen -t rsa
```

### すでに.sshディレクトリがある場合

```shell
    ssh-keygen -t rsa
```

## 作成した鍵をサーバーに送信


パスう
```shell
    ssh-copy-id -i ~/.ssh/id_rsa.pub <任意の名前>@<サーバーのIPアドレス>
```

## configに設定を書く

```shell
    vim ~/.ssh/config
```

```shell
    Host <任意の名前>
        HostName <サーバーのIPアドレス>
        User <任意の名前>
        Port 22
        IdentityFile ~/.ssh/id_rsa
```

vimを保存し終了する方法は、以下の手順です。

・ノーマルモード（コマンドモード）に移行する。
    もし現在編集モード（インサートモード）にいる場合は、エスケープキーを押してノーマルモードに戻る。
    コマンドモードで「:」を入力する。
・「wq」と入力する。
    「w」は保存（write）、「q」は終了（quit）の意味。
・Enterキーを押す。
    これでvimが保存され、終了されます。

## sshd_configを編集

```shell
    vim /etc/ssh/sshd_config
```

以下の行があればコメントアウトします。

```shell
    #AuthorizedKeysFile /.ssh/authorized_keys
```

新しい Match ブロックを作成して、それぞれのユーザの公開鍵を指定する AuthorizedKeysFile ディレクティブを追加します。

```shell
    Match User root
    AuthorizedKeysFile ~/.ssh/authorized_keys

    Match User <任意の名前>
    AuthorizedKeysFile /home/<任意の名前>/.ssh/authorized_keys
```

## sshdを再起動

これで、指定されたユーザごとに異なる authorized_keys ファイルが使用されるようになります。

```shell
    systemctl restart sshd
```

## ssh接続するクライアントの端末からログイン

```shell
    ssh <任意の名前>@<サーバーのIPアドレス>
```

または

```shell
    ssh <configに設定を書くで設定したHOSTの名前>
```


## 接続した時にターミナルでコマンドが打てない場合

```shell
    exec bash -l
```

### 次回以降自動で立ち上がる設定

```shell
    touch /home/<任意の名前>/.bashrc
    echo "exec bash -l" >> ~/.bashrc
```

chshコマンドを使用して、新しいログインシェルを指定します。

```shell
    chsh -s /bin/bash <任意の名前>
```
sudoが必要な場合がある。
[環境変数] os.environ.get()を使用しねえ！！Pydanticを使用した環境変数の取得方法！！


## 早速みていきましょう！
1. .envファイルやAWSのパラメータストアから環境変数を取得し、アプリケーションのコンテナを立ち上げる
1. コンテナ内で取得した環境変数を設定クラスに記述
1. 設定クラスをインスタンス化することで利用可能

```.env
DEBUG=1
TEST=hoge
```

```example.py
from pydantic import BaseSettings

class VariableSettings(BaseSettings):
    """
    環境変数を取得する設定クラス
    """
    DEBUG: bool
    TEST: str
    AAA: str = "BBB"
  
settings = VariableSettings()
print(settings.DEBUG) # True
print(settings.TEST) # hoge
print(settings.AAA) # BBB
```
# load_dotenv()で取得せず、このやり方にするメリット
1. 環境変数の型を指定できる
1. settings.py内でどんな環境変数が使用されているか一目でわかる
1. タイポしていると読み込み時にエラーになるので分かりやすい
1. 何度も同じ文字列を書く必要がない
1. 編集する箇所が限定されている(エディタの機能でリネームしやすい)

# 参考
[pydanticで設定ファイルのバリデーションをする](https://zenn.dev/nkoguchi_dev/articles/a77c9391b72e9b#basesettings%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
北陽電機公式のROS 2ノード urg_node2 でURGを動かす

# はじめに

北陽電機の2DLiDARを使えるROS2パッケージとしてurg_nodeがあるが、公式からurg_node2というROS2パッケージが出ている。
今回はこれを使ってUSBタイプのURG-04LXを動かしてみた。

https://github.com/Hokuyo-aut/urg_node2

以前書いたurg_nodeの記事

https://qiita.com/porizou1/items/b3cc26eb0cf168412dbc


# 環境

OS:ubuntu22.04LTS
ROS 2 : Humble

使用したLiDAR URG-04LX

# Install 

READMEの通り


```bash
cd ros2_ws/src/
git clone --recursive https://github.com/Hokuyo-aut/urg_node2.git
rosdep update
rosdep install -i --from-paths urg_node2
cd ../
colcon build --symlink-install --packages-select urg_node2 
```


# launchファイル編集

USB接続のURGを使う場合launch/urg_node2.launch.py​​を以下のように変更する。(デフォルトはparams_ether)

```python:urg_node2.launch
def generate_launch_description():

    # パラメータファイルのパス設定
    config_file_path = os.path.join(
        get_package_share_directory('urg_node2'),
        'config',
        'params_serial.yaml'
    )
```


# 実行

以下でros2ノードの実行　※/dev/ttyACM0にLiDARがつながっているとする

```bash
sudo chmod 777 /dev/ttyACM0
ros2 launch urg_node2 urg_node2.launch.py
```

```
[INFO] [launch]: All log files can be found below /home/porizou/.ros/log/2023-03-11-11-12-15-148865-porizou-RM7C-R35T-3253
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [urg_node2_node-1]: process started with pid [3265]
[urg_node2_node-1] [INFO] [1678500735.912239365] [urg_node2]: Connected to a serial device with single scan. Hardware ID: H1510839
```



## rviz2 でLaserScanを見る

rviz2起動

```bash
rviz2
```

Fixed Frame をlaserに設定
左下のAddボタンをクリック
一覧からLaserScanを選択してOKをクリック
Topicに/scanを入力

![rviz_screenshot_2023_03_11-02_58_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/6562f599-a6bf-e873-073a-27aa5c01d245.png)


点群がrvuz2に表示されればOK


### node の終了

Lifecycleの機能で終了できる

```bash
ros2 lifecycle set /urg_node2 shutdown
```



# おわりに

公式のROS2パッケージだけあってLifecycleに対応していたり、多機能なので
今後ROS2で北陽電機の2DLiDARを使う場合はこちらのパッケージを使うのがよいだろう。





# 参考


https://www.hokuyo-aut.co.jp/topics/detail.php?id=212

https://sourceforge.net/p/urgnetwork/wiki/urg_node2/
Subversionを利用したWordPress公式プラグインの公開方法

## はじめに
WordPressの公式サイトにプラグイン公開を申請して承認されると、Subversion（Gitに似ているが運用方法は異なる）のリポジトリURLが送られてきます。
自作のWordPressプラグインを公開しようとした際に避けては通れないSubversion（バージョン管理システム（以下VCS）について、今回はここに残していきたいと思います！
この記事では初めてプラグインを公開する場合の手順を書いていきますが、プラグインを更新する際の手順は[こちら](https://qiita.com/shun_shiratori/items/f70bf4b627033a952986)の記事を参考にしていただければと思います。

## 手順

1. ターミナルからインストール
2. ディレクトリをローカル環境に作成
3. ディレクトリに移動
4. リポジトリのチェックアウト
5. クローンファイルにプラグインファイルの挿入
6. リポジトリの追加準備
7. リポジトリにコミット

詳しく見ていきましょう。


### 1.ターミナルからインストール
まずはSubversionをインストールしていきます。
ターミナルを開き、下記コードにてインストールしていきます。
```
$ brew install subversion
```
*Macの場合


### 2.ディレクトリをローカル環境に作成
ローカル環境に、Subversion用の任意のディレクトリを作成します。（今回はmy-plugins-svnという名前にします）
```
$ mkdir my-plugins-svn
```
ここで正しく生成されたか確認してみると良いでしょう。
「アプリケーション」や「ダウンロード」ファイルがあるディレクトリに下記のようにファイルが生成されていれば問題ございません
![スクリーンショット 2023-03-17 20.23.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690898/8d714941-be66-783f-624a-a0078afaa35d.png)


### 3.ディレクトリに移動
下記のコードで先ほど作成したディレクトリに移動していきます。
```
cd my-plugins-svn
```
*「my-plugins」に申請したプラグインのディレクトリの名前を入れてください


### 4.リポジトリのチェックアウト（ローカルにクローン）
Subversionのリポジトリからローカル環境（使用中のPC）にクローンを落とし込みます。

```
$ svn co https://plugins.svn.wordpress.org/my-plugins/
```
すると４つのファイルが落ちてきます。
```
A    my-plugins_svn/assets
A    my-plugins-name_svn/branches
A    my-plugins-name_svn/tags
A    my-plugins-name_svn/trunk
Checked out revision 000000.
```
ファイルの種類

##### assets：アイキャッチ画像を格納
アイキャッチ画像などの画像ファイルなどを格納するためのファイルです

##### trunk：プラグインファイルを格納
こちらのファイルに登録申請時のプラグインファイルを入れることになります。

##### tags：バージョン管理ファイルを格納
バージョン更新時などに使用しますが、後述します。

### 5.クローンファイルに作成したプラグインファイルの追加

落ちてきたクローンファイルに下記の要件にてファイルを入れてください。

###### アイキャッチ画像の種類と名前
プラグインページの画像は「banner-772×250.jpg」、「banner1544x500.jpg」
アイコンは「icon-128×128.jpg」、「icon-256×256.jpg」

### 6.リポジトリの追加準備（コミットの前段階）
ファイルへの追加が完了したら、addしていきます
```
svn add trunk/*
```
そうすると下記のようになります
```
A         trunk/css
A         trunk/css/style.css
A         trunk/images
A  (bin)  trunk/images/no-image.png
A         trunk/includes
A         trunk/languages
A         trunk/readme.txt
A  (bin)  trunk/screenshot-1.png
A  (bin)  trunk/screenshot-2.png
A         trunk/uninstall.php
```

### 7.リポジトリに追加(commit)
下記のコードを入力し、リポジトリに追加させてください。
```
$ svn commit -m "First commit"
```
この際、”First commit”の部分は、のちにどんな変更などをしたか判別できるように、必ず記入しましょう。

#### 初めてのコミットの場合
初めてのコミットの場合は、下記のパスワードの入力が求められます。

まずPCのパスワードを記入
```
Password for 'username':
```
次にwordpress.orgのアカウントのユーザー名を記入
```
Authentication realm: <https://plugins.svn.wordpress.org:443> Use your WordPress.org login
Username:
```
その後にwordpress.orgのアカウントのパスワードを記入
```
Password for 'username':
```
ここで一旦公開はされましたので公式ページにて、自身のプラグインを検索してみてください！
https://ja.wordpress.org/plugins/

#### バージョン管理
tagsにtrunkをコピーしておくことも忘れないで行いましょう。
こちらはバージョンを管理していく上で必要になってきます。
```
svn cp trunk tags/1.0.0
```
/trunkを/tag/1.0.0にコピーするという意味のコードを記入しましたが、まだローカル上でのコピーなので、これをコミットしていきます
```
$ svn commit -m "Tag　1.0.0"
```


## 最後に
今回は初めて自作プラグインを公開していくための手順を書きましたが今後更新などをしていく上での手順は[こちら](https://qiita.com/shun_shiratori/items/f70bf4b627033a952986)の記事を参考にしてみてください。
teratermを使って公開鍵認証でSSH接続するときに"認証に失敗しました"と出たときの対処法

久しぶりに自前サーバーを構築するときにハマったのでメモ


https://qiita.com/sakamotosan/items/d65a73d7d59eea451c54

基本的に上記に書いてある通りです。
ssh鍵形式がRSAだとなぜか認証しなくて、**公開鍵暗号の生成にECDSAを使用する**と接続できます
なんでやねん。

どこにも書いてなかったのでメモ
【AWS SAA】①受験当日まで曖昧だったもの~CloudWatch~

#はじめに
先月全くの未経験からSAAに合格した自分が研修中に教えてもらえたことの備忘録的なものです。

＃対象
未経験からAWS SAA(ソリューションアーキテクト)を受験される方、勉強中の方に向けて。

＃勉強前イメージ
CloudWatchとCloudWatch logs,CloudWatchAgentって何が違うの・・・？
そもそもCloudWatch自体はなにするの。
同じサービスなの？区別がつかない、、、。

＃図でまとめてみた
![スクリーンショット 2023-03-11 093504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249635/1850ec0e-381c-5f75-f021-3cccafddcf56.png)

ざっくりと分けると
・CloudWatch
→「CloudWatch Alarm,Logs,Metrics..などサービスを包括してるよ」

・CloudWatch Logs
→「僕は標準メトリクスでCPU使用率とディスクI/O、ネットワーク利用量、死活監視といった基本的なデータの取得が可能だよ！...ただもっと詳しく知りたいなら【カスタムメトリクス】使ってね！」

・CloudWatchAgent
→「自分をEC2にインストールしたらCloudWatch Logsでもっと詳しくみれるよ！【カスタムメトリクス】といって標準メトリクスでは見れない詳細な部分もみれるよ！」

といった感じ。
ざっくりと書いてるのでもっとしっかり言うとなると異なる部分はでてきますが、今回の目的は【AWS SAA】合格が目的。
なので正直未経験の方はこのくらいの理解でいいと思います。

＃勉強後イメージ
CloudWatchってLogsやらAlarmやらあってじゃあCloudwatch自体は何するんだい？と思っていたけど
複合体がCloudWatchなんですね。
カスタムメトリクス使うには、EC2にCloudWatch Agentをインストールして使用するものですね。
実務となるとCloudWatch自体操作の幅が広く、もっと勉強が必要なので引き続き理解深める。
DatabricksからBigQueryへの接続設定

# DatabricksからBigqueryへの接続

Databricks(spark)ではさまざまなConnectorを用意しており、sparkで生成したDataFrameを簡単にBigQueryに書き込む OR BigQueryからtableの読み込みを行うことができます。

手順としては簡単で
- BigQuery Strorage APIの有効化
- Service Accountの作成
- temporary gcs bucketの作成

ということで簡単に行うことができます。

https://docs.databricks.com/external-data/bigquery.html#google-bigquery

が、Databricks側のClusterに設定するSpark Configが毎回つまづくので備忘録として
残しておきたいと思います。

## Spark Configの設定

必要なSpark Configは下記の通りです。

```bash
credentials <base64-keys>

spark.hadoop.google.cloud.auth.service.account.enable true
spark.hadoop.fs.gs.auth.service.account.email <client_email>
spark.hadoop.fs.gs.project.id <project_id>
spark.hadoop.fs.gs.auth.service.account.private.key <private_key>
spark.hadoop.fs.gs.auth.service.account.private.key.id <private_key_id>
```

https://docs.databricks.com/external-data/bigquery.html#step-2-set-up-databricks

:::note warn
警告
本来は、secretに入れてSpark Configから読み出すのがpracticeですが、わかりやすさ優先のためsecretを使いません。
:::


ポイントはcredentailsの箇所で、service  accountで作成したkeyをDownloadした際に
service account名などが入った"project名-xxxxxxxxxxxxxx.json"があると思うのですが
このファイルに対して

```bash
base64 projectname-XXXXXX.json
```

で、base64コマンドでエンコードして出力された値をcredentialの箇所に貼り付けます。

もう一箇所はprivate keyの箇所で、↑でDownloadしたjsonの中のprivate keyを貼り付けるのですが、そのまま貼り付けると読み込みに失敗するので、ダブルコーテーションを外すとうまく読み込めます。

あとの項目はそのまま貼り付けでOKですが、私はダブルコートありなしで区別するのが面倒なので、ダブルコートは全て外しています。(前にダブルコートをつけた時にうまくいかなかった記憶がありますので、、、

# まとめ
Databricksでpipelineを生成してデータマートとしてBigqueryに書き込む構成パターンは結構あるので、設定の参考になれば幸いです。
M1 MacBookAirでDockerを使ったRailsの環境構築

以前も似たような記事を書いたのですが情報の鮮度が落ちているので、アップデートした部分も含めての解説になります。

docker-docsという公式の情報集で"rails"と検索したところGitHubのクイックスタートを見つけたのでそれを参考にして進めます。

https://github.com/docker/awesome-compose/tree/master/official-documentation-samples/rails/

これの通りに進めるだけです。

私なりの手順も一応共有
①ディレクトリを作成（sample_appとか好きな名前でいいです）
②ディレクトリの中に以下5つのファイルを作成
* Dockerfile
* Gemfile
* Gemfile.lock
* entrypoint.sh
* docker-compose.yml

①②の手順ですが以下のコマンドをターミナルに入力するとできます。
~~~
mkdir sample_app && touch myapp/{Dockerfile,Gemfile,Gemfile.lock,entrypoint.sh,docker-compose.yml}
~~~

③それぞれのファイルに必要な情報をコピペ（公式のGitHubに載っているものをコピペしました）

④公式GitHubを見ながらdockerコマンドをターミナルに入力していく

⑤localhost:3000にrailsのページが表示されたらOK

# 感想
調べるとやり方を解説するサイトはたくさんあるんですけど、公式の安心感に勝る物はないなと感じました。
Dockerコマンドは数分かかるのもあるので本当に動いているのか心配になりました。
Googleデジタルマーケティング＆Eコマース：タイトルリンクとスペニット

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

# タイトルリンクとスペニット

検索エンジンに検索クエリを入力すると、多くの検索エンジンの結果ページ（SERPs）に多数の結果が表示されることになります。ほとんどの検索エンジンは、同じような結果構造を持っています。結果には通常、スニペット（検索結果の説明または要約部分）の上に太字のタイトルリンク（Webページにリンクしている検索結果のタイトル）が表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/81788326-4a7c-b794-c5e8-b22f5a4f917d.png" width="７00">

Googleは、ページのWebページタイトル要素と、そのメタディスクリプションまたはページの可視テキストの関連する部分のいずれかに基づいて、これらの結果を自動的に生成します。Webページのタイトル要素は、ユーザーと検索エンジンにそのページのトピックを提供します。メタディスクリプションは、そのページが何についてのページであるかの概要を検索エンジンに提供します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/10529f87-fd5e-68d7-e486-b707c4321fde.png" width="７00">

# タイトルリンクとスペニットのベストプラクティス

### <font color="MediumBlue">タイトルリンクに影響を与える</font>

タイトルリンクは、ユーザーに検索結果の内容とその検索結果に関連する理由をすばやく伝えることができます。タイトルリンクは、ユーザーがどの結果をクリックするかを決定するための主要な情報であることがよくあります。

Googleは、WebページのコンテンツとWeb上に表示されるそのページへの参照の両方からタイトルリンクを生成します。Googleはこれらのタイトルリンクを自動的に決定しますが、以下のベストプラクティスに従うことで、タイトルリンクに影響を与え、その効果を高めることができます。

#### Do:

- タイトル要素で各ページの内容を的確に表現する。
- 説明的でありながら簡潔なタイトルをつける。
- 自然に読めるタイトルにする。
- 各ページに独自のタイトルを設定する。
- 各ページのメインヘッドラインは、視覚的な重みを持たせ、目立たせる。

#### Don't:

- ページのコンテンツと関係のないテキストをタイトル要素に使用する。
- 「ホーム」「無題」「新しいページ1」など、デフォルトのテキストや曖昧なテキストをタイトルに使用する。
- サイト内のすべてのページのタイトルには、単一のタイトルを使用する。
- タイトルが長すぎたり、語弊があったりする。
- 繰り返しのテキストや定型的なテキストを使用する。
- タイトルに不要なキーワードや過剰なキーワードを詰め込む。

### <font color="MediumBlue">質の高いメタディスクリプションを作成し、スニペットを制御する</font>

Googleは、検索結果にスニペットを生成するために、Webページのメタディスクリプションを使用することがあります。メタディスクリプションは、特定のページが何について書かれているかを短く要約することで、ユーザーに情報を提供し、興味を持たせるものです。メタディスクリプションは、そのページがまさに探しているものであるとユーザーに確信させるのに役立ちます。以下のベストプラクティスに従って、効果的なメタディスクリプションを記述してください。

#### Do:

- ページの内容を正確に要約する。
- そのページがユーザーにとって有益かどうか、関連性があるかどうかを判断するために必要な情報をすべて含める。
- サイト内の各ページに独自の説明文を作成する。

#### Don't:

- ページのコンテンツと関係のないメタディスクリプションを書く。
- "これはウェブページです"、"女性服についてのページ "などの一般的な説明を使用する。
- 説明文にキーワードを詰め込みすぎる。
- ウェブページの内容を丸ごとコピーして、meta descriptionタグに貼り付ける。
- サイトのすべてのページで単一のメタディスクリプションを使用する。
Nx でカラー画像の黒背景を透過する

## はじめに

Discord の「elixir と見習い錬金術師」サーバーにて、 @SF-28 さんから質問がりました

https://qiita.com/nako_sleep_9h/items/9b6b9b70084cf5998f2d

> カラー画像の黒背景を透過する処理についてです。
> とりあえず以下コードで処理自体は実現出来たんですが、あまりスマートじゃないなと・・・
> EvisionやNxでこのあたり上手く扱う方法をご存知の方いらっしゃいませんか？
>
> ```
> bgr_img
> |> Evision.Mat.to_nx()
> |> Nx.to_list()
> |> Enum.map(fn x ->
>   Enum.map(x, fn
>     [0, 0, 0] -> [0, 0, 0, 0]
>     y -> y ++ [255]
>   end)
> end)
> |> Nx.tensor(type: :u8)
> |> Evision.Mat.from_nx_2d()
> ```

というわけで記事に答えを書きます

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/evision/transparent_black.livemd

## 実行環境

Livebook を使います

https://livebook.dev/

- Elixir: 1.14.2
- Livebook: 0.8.1

## セットアップ

必要なモジュールをインストールします

```elixir
Mix.install([
  {:evision, "~> 0.1"},
  {:kino, "~> 0.8"},
  {:nx, "~> 0.5"}
])
```

- [evision](https://github.com/cocoa-xu/evision): 画像処理
- [kino](https://github.com/livebook-dev/kino): Livebook の UI/UX
- [nx](https://github.com/elixir-nx/nx): 行列演算

## 画像の準備

今回は以下の画像を使います

![bg_black.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/4ee4c34a-39b1-d7cb-838a-efa7ab1980d7.png)

piyopiyo.ex のキャラクターを殻から出しています

https://piyopiyoex.connpass.com/

以下のコードを実行するとアップロード用のウィジェットが表示されます

```elixir
img_input = Kino.Input.image("IMAGE", format: :png)
```

![画像アップロード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e1cd3add-74d7-a5e0-4c58-4106a36341fe.png)

ドラッグ&ドロップ等で画像を選択し、アップロードします

![画像アップロード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/02e15a7c-08af-7560-01c6-e30bfc6db2cf.png)

画像を Nx で扱えるテンソルに変換します

`Evision.imdecode` でバイナリデータを evision (OpenCV) の行列データに変換します

`Evision.Mat.to_nx` で evision の行列データを Nx のテンソルに変換します

evision で読み込んだ画像は RGB ではなく BGR の順に色データが並んでいるので `bgr_img` にしています

`Kino.Image.new` に画像のテンソルを渡すと、Livebook 上に画像として表示してくれます

```elixir
bgr_img =
  img_input
  |> Kino.Input.read()
  |> then(& &1.data)
  |> Evision.imdecode(Evision.Constant.cv_IMREAD_COLOR)
  |> Evision.Mat.to_nx(Nx.BinaryBackend)

Kino.Image.new(bgr_img)
```

![bg_black.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/4ee4c34a-39b1-d7cb-838a-efa7ab1980d7.png)

## 背景透過

BGR に A （アルファ）チャネルを付けると透過画像になります

A が 0 のとき完全な透明、 A が 255 のときは完全な不透明です


```elixir
alpha =
  bgr_img
  |> Nx.reduce_max(axes: [2])
  |> Nx.greater(0)
  |> Nx.multiply(255)
  |> Nx.new_axis(2)

bgra_img =
  [bgr_img, alpha]
  |> Nx.concatenate(axis: 2)

Kino.Image.new(bgra_img)
```

![bg_clear.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6979bb11-fd2d-845f-d1e0-38cea9f60e9b.png)


`Nx.reduce_max(axes: [2])` により、画像内の各ピクセルについて BGR の最大を計算します

黒は `[0, 0, 0]` なので最大が 0 で、それ以外の色は 0 より大きくなります

`Nx.greater(0)` で、最大が 0 より大きければ 1　、 そうでなければ 0 にします

これによって黒のピクセルは 0 、 それ以外のピクセルは 1 になります

`Nx.multiply(255)` で各ピクセルの値を 255 倍にします

黒は 0 （透明）、それ以外は 255 （不透明）になります

`Nx.new_axis(2)` でテンソルの形を `{<横ピクセル数>, <縦ピクセル数>}` から `{<横ピクセル数>, <縦ピクセル数>, 1}` に変形します

後で BGR とくっつけるためです

`Nx.concatenate(axis: 2)` で BGR に A をくっつけます

## まとめ

`Enum.map` などで処理するよりも、 Nx の行列演算の方が圧倒的に速いので、可能な限り行列演算するようにしましょう
Googleデジタルマーケティング＆Eコマース：モバイルフレンドリーなWebサイト

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

# モバイルフレンドリーなWebサイト

モバイルフレンドリーとは、スマートフォンでも機能するWebサイトにすることです。多くの国で、スマートフォンの普及台数はパソコンの普及台数を上回っています。モバイルフレンドリーなWebサイトを持つことは、オンラインプレゼンスを確立する上で重要な要素になっています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/39f4d895-0b9c-01ff-8c0d-56b3771c9871.png" width="600">

Webサイトがモバイルフレンドリーでない場合、モバイル端末での閲覧や利用が困難になることがあります。モバイルフレンドリーでないサイトでは、ユーザーがコンテンツを読むためにピンチやズームをする必要があります。ユーザーはこれにイライラします。イライラすると、ユーザーはWebサイトを放棄してしまうかもしれません。

モバイルフレンドリーなサイトであれば、スマートフォンでも読みやすく、すぐに使えるようになります。これにより、モバイルデバイスからサイトを訪問した際に、訪問者が良い体験をすることができます。

:::note info
Wixのような多くのウェブサイトテーマやビルダーは、コンテンツを取り込んで自動的にモバイルフレンドリーにすることができます。
:::

# モバイルフレンドリーなWebサイトを構築するための知っておくべきこと

### <font color="MediumBlue">お客様が使いやすいようにする</font>

お客様の目的を考えましょう。

- 彼らはあなたのブログ記事で楽しませてもらいたいのでしょうか？
- あなたのレストランの住所を知りたいのでしょうか？
- 商品のレビューを読みたいのでしょうか？

その目的を達成しやすいように、Webサイトをデザインしましょう。そのために、カスタマージャーニーのステップの概要を説明します。モバイル端末でこれらのステップを簡単に踏んで、旅を達成できるようにします。

下の例では、あるお客様がランプを購入しようとしています。
- まず、購入したいランプを検索し、Webサイトをクリックします。
- 次に、ランプの中から好きなものを選びます。
- そして、目的の照明器具を購入します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/dfd6fc75-80ae-b687-b783-2dbf978dcb7f.png" width="600">

モバイルユーザーがいかに簡単に共通の作業を行えるかで、Webサイトの有効性を評価しましょう。

- どの程度簡単に完了できましたか？

インターフェイスの一貫性を重視し、すべてのプラットフォームで統一されたエクスペリエンスを実現しましょう。

### <font color="MediumBlue">レスポンシブWebデザインを採用する</font>

レスポンシブWebデザインとは、ユーザーがデスクトップコンピューター、タブレット、携帯電話のいずれを利用していても、同じコードを使用しているWebサイトのことを指します。画面サイズに応じて表示が調整されます。

Googleは、他のデザインパターンよりもレスポンシブWebデザインを使用することを推奨しています。レスポンシブWebデザインの利点は、モバイル用とデスクトップ用の2つのバージョンを用意する必要がなく、1つのバージョンのみを維持すればよいことです。

# 初心者が避けるべき失敗例トップ3

### <font color="Darkcyan">モバイルの顧客を忘れている</font>

優れたモバイルサイトは、訪問者のタスクを完了するのに役立つものであることを忘れないでください。モバイル向けサイトを作ることだけに集中して、完全な機能を提供することを忘れてはいけません。スマートフォンでは問題なく表示されても、パソコンで見るのと同じように機能しなければ、ユーザーの妨げになる可能性があります。

また、パソコンを使わずスマートフォンで作業をする人のために、モバイルフォーマットや機能を充実させることも必要です。

### <font color="Darkcyan">モバイルサイトを別ドメインで実装する</font>

モバイル用のURLを個別に作成すると、サイトの維持・更新に必要な作業量が大幅に増加します。また、技術的な問題が発生する可能性もあります。

レスポンシブWebデザインを使用すれば、Webサイトの管理を簡素化できます。このデザインでは、デスクトップとモバイルのWebサイトを同じURLで提供します。

### <font color="Darkcyan">インスピレーションを求めるより、単独で作業する</font>

モバイルフレンドリーなWebサイト作りを始める前に、競合他社など同業他社のサイトを見て、インスピレーションやベストプラクティスを探しましょう。彼らのWebサイトで役に立つ機能、役立たない機能から学びましょう。

# モバイルフレンドリーテスト

[Googleのモバイルフレンドリーテスト][mobile]は、Googlebotを使ってお客様のWebサイトを取得し、モバイルフレンドリーかどうかを判断します。そうでない場合、結果には、スマートフォンでアクセスしたときにページに影響を与える可能性のある問題が記述されます。

お客様に悪影響を与えないよう、Webサイト上でこれらの問題を解決することがベストプラクティスです。

[mobile]: https://search.google.com/test/mobile-friendly
[Node.js]ExpressのサーバーログにリクエストIDを出力する

AsyncLocalStorageを使ってExpressのサーバーログにリクエストIDを出力する方法を紹介します。

https://nodejs.org/api/async_context.html#class-asynclocalstorage

AsyncLocalStorageは他言語のTLS（thread local storage, スレッド局所記憶）のような機能を提供し、リクエストごとにデータを保管してくれます。


```js:asyncLocalStorage.ts
const { AsyncLocalStorage } = require('async_hooks');

export const asyncLocalStorage = new AsyncLocalStorage();
```
### ミドルウェアでrequestIdをセット
```js:index.ts
import Express from 'express';
import { v4 as uuid } from 'uuid';
import { asyncLocalStorage } from './asyncLocalStorage';

export const app = Express();

app.use((req, res, next) => {
  asyncLocalStorage.run(new Map(), () => {
    asyncLocalStorage.getStore().set('requestId', uuid());

    next();
  });
});
```
### requestIdをログに出力
```js:logger.ts
import { asyncLocalStorage } from './asyncLocalStorage';

export default class Logger {
  public static info = (): void => {
    console.log(JSON.stringify({
      requestId: Logger.requestId()
    }));
  };

  private static requestId = () => {
    return asyncLocalStorage.getStore().get('requestId');
  };
}
```
Googleデジタルマーケティング＆Eコマース：Webサイト内画像のベストプラクティス

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/84e33f4e-81cb-98a6-4546-f2ec06fd8b8b.png" width="800">

# Webサイト内画像の最適化

検索エンジンは、インターネット上の情報を視覚的に発見する方法として、画像を利用しています。また、画像は、顧客があなたの製品やサービスを視覚的に理解する方法でもあります。Googleの[SERPsに表示される画像][serps]について説明したのを覚えていますか？その画像は、ほとんどがWebサイトから取得したものです。そう、Webサイトにアップロードした画像をGoogleイメージの結果に表示させることは可能なのです。

[serps]: https://qiita.com/mapami/items/7eac72ea70b79473020b

これらの推奨事項は、検索エンジンだけでなく、ユーザーのためのものであることがおわかりいただけると思います。ユーザーを満足させると、検索エンジンはその満足度を認識し、あなたのWebサイトや画像、コンテンツを表示することが多いのです。Webサイトに画像をアップロードするのは簡単な作業に思えるかもしれませんが、ユーザーと検索エンジンの両方にフレンドリーであるためには、いくつかの考慮すべき要素があります。

### <font color="MediumBlue">素晴らしいユーザエクスペリエンスを作り出す</font>

- ビジュアルコンテンツがページのトピックに関連していることを確認します。画像は、そのページにオリジナルの価値を付加する場所にのみ表示します。
- 可能な限り、画像はページ内の目立つ場所に、関連するテキストの近くに配置しましょう。最も重要な画像は、ページの最上部付近に配置することも検討します。
- 画像はデバイスフレンドリーであることも重要です。つまり、パソコン、タブレット、モバイルで適切に読み込まれるようにすることです。モバイルでは画像がリサイズされることがあります。切れていませんか、それともパソコンと同じように見えていますか？


### <font color="MediumBlue">素晴らしいユーザエクスペリエンスを作り出す</font>

- Googleイメージに表示するためにWebサイトから画像を取得する場合、Googleは自動的にタイトルを生成し、写真を説明するためにそれを切り取ります。この際、説明的なページタイトルを作成することで、これを支援することができます。
- 写真にキャプションを付けることも検討すべきです。これは、Googleが写真の中で何が起こっているかを理解するのに役立ちます。
- ファイル名は、画像の主題に関する手がかりをGoogleに与えることができます。
    - 例えば、"my-new-grey-kitten.jpg "は、"IMG0023.jpg "よりも説明的な名前です。

### <font color="MediumBlue">説明的なaltテキストを使用する</font>

- altテキストは、画像を説明するテキストです。スクリーンリーダーを使用している人や低帯域幅の接続を持つ人など、Webページ上の画像を見ることができない人のためのアクセシビリティを向上させます。Googleは、altテキストをコンピュータビジョンのアルゴリズムやページのコンテンツと一緒に使用して、画像の主題を理解します。altテキストを記述する際は、キーワードを適切に使用し、有益で情報量の多いコンテンツを作成することに重点を置いてください。
- altテキストは、ページ内容の文脈に沿ったものである必要があります。
- altテキストにキーワードを詰め込むことは避けるべきです。ユーザーエクスペリエンスが低下し、Google検索にスパムサイトとして認識される可能性があります。子犬の写真のaltテキストにキーワードスタッフィングがある例を見てみましょう。
    - キーワードスタッフィングされたaltテキストは、"puppy dog baby dog pups doggies litter retriever Labrador Dalmatian terrier cheap dog food puppy food." のように表示されます。
    - より明確なaltテキストの例としては、"Dalmatian puppy playing fetch. "が挙げられるでしょう。

### <font color="MediumBlue">速度を最適化する</font>

画像は、ページ全体のサイズを大きく左右することが多く、ページの読み込みが遅くなることがあります。ウェブサイトに画像をアップロードする場合、通常、オリジナルの画像はアップロードしません。画像の品質を落とさずに、Webサイトに適したサイズにリサイズする必要があります。

画像がWebサイトの読み込み速度を遅くしているかどうかを判断するには、「[Page Speed Insights](https://pagespeed.web.dev/)」というGoogleが提供する無料のツールを使用します。
- このツールは、Webページを分析し、その読み込み時間に関する情報を提供します。
- また、どの画像の読み込みに時間がかかっているかなど、読み込み時間を短縮するための提案も行っています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5ef642b0-131a-b9d9-4e05-fce71957c87b.png" width="700">
（PHP）文字列内で変数や配列の値を使う方法をまとめた


とりあえず結果だけ教えろな方は[こちら](#結果)

## 変数
```php
$money = '金';

echo '同情するなら$moneyをくれ';  // ① 
// 同情するなら$moneyをくれ

echo '同情するなら' . $money . 'をくれ'; // ② 文字列結合演算子 .
// 同情するなら金をくれ

echo '同情するなら{$money}をくれ'; // ③ 
// 同情するなら{$money}をくれ

echo "同情するなら$moneyをくれ"; // ④ 
// エラー

echo "同情するなら$money をくれ"; // ⑤ 
// 同情するなら金 をくれ

echo "同情するなら{$money}をくれ"; // ⑥ ダブルクォーテーション "" + 波括弧{}
// 同情するなら金をくれ
```
正確に表示されているのは

② 文字列結合演算子 . で文字列と変数を連結
⑥ ダブルクォーテーション「"」で括った文字列の中に、波括弧{}で括った変数名を埋め込む

場合のみ。

なお、⑤でも表示できるが、どこまでが変数名か明確にするために半角空白でスペースを作っているので、echoで文字列を表示すると不自然な空白が生まれてしまっている。


## 配列（キー名なし）
```php
$money = ['金'];

echo '同情するなら$money[0]をくれ';  // ① 
// 同情するなら$money[0]をくれ

echo '同情するなら' . $money[0] . 'をくれ'; // ② 文字列結合演算子 .
// 同情するなら金をくれ

echo '同情するなら{$money[0]}をくれ'; // ③ 
// 同情するなら{$money[0]}をくれ

echo "同情するなら$money[0]をくれ"; // ④ ダブルクォーテーション
// 同情するなら金をくれ

echo "同情するなら$money[0] をくれ"; // ⑤ 
// 同情するなら金 をくれ

echo "同情するなら{$money[0]}をくれ"; // ⑥ ダブルクォーテーション "" + 波括弧{}
// 同情するなら金をくれ
```

変数同様②⑥はOK。

変数との違いは、④の場合、配列はうまく表示される。
閉じ角括弧 ] が配列添字の終端を表すため（以下[マニュアル](https://www.php.net/manual/ja/language.types.string) から抜粋）
> 同様に、配列添字とオブジェクトのプロパティをパースすることも可能です。 配列添字の場合、閉じ角括弧 (]) は添字の終りを意味します。 シンプルな変数の場合と同じ規則が、オブジェクトのプロパティに対しても適用されます。

## 配列（キー名あり）
```php
$arr = ['money' => '金'];

echo '同情するなら$arr['money']をくれ'; // ① 
// エラー

echo '同情するなら' . $arr['money'] . 'をくれ'; // ② 文字列結合演算子 .
// 同情するなら金をくれ

echo '同情するなら{$arr['money']}をくれ'; // ③ 
// エラー

echo "同情するなら$arr['money']をくれ"; // ④ 
// エラー

echo "同情するなら$arr['money'] をくれ"; // ⑤ 
// エラー

echo "同情するなら{$arr['money']}をくれ"; // ⑥ ダブルクォーテーション "" + 波括弧{}
// 同情するなら金をくれ
```

キー名なしの場合と異なり、④がエラーになる。

実は文字列内で、キー名を指定して配列の要素にアクセスする場合、 'キー名' のシングルクォーテーションを除く必要がある

```php
echo "同情するなら$arr[money]をくれ"; // ④' シングルクォーテーション「'」を削除
// 同情するなら金をくれ
```

これで④が正しく表示される。

##  結果
文字列内で変数や配列の値を使いたい場合は以下のとおり
```php
// 変数
$money = '金';
echo '同情するなら' . $money . 'をくれ'; // 文字列結合演算子 .
echo "同情するなら{$money}をくれ";  //  ダブルクォーテーション "" + 波括弧{}

// 配列 キーなし
$money = ['金'];
echo '同情するなら' . $money[0] . 'をくれ';  // 文字列結合演算子 .
echo "同情するなら$money[0]をくれ"; // ダブルクォーテーション
echo "同情するなら{$money[0]}をくれ"; //  ダブルクォーテーション "" + 波括弧{}

// 配列 キーあり
$arr = ['money' => '金'];
echo '同情するなら' . $arr['money'] . 'をくれ';  // 文字列結合演算子 .
echo "同情するなら{$arr['money']}をくれ";  //  ダブルクォーテーション "" + 波括弧{}
echo "同情するなら$arr[money]をくれ"; // キー名のシングルクォーテーション「'」を削除

// 出力結果（全て）
// 同情するなら金をくれ
```

結論として

- 文字列結合演算子 .
- ダブルクォーテーション "" + 波括弧{}

の二つなら、どの場合でも変数と配列を正しく展開できるので、どちらかを使えばよい！

なお、シングルクォーテーションの方が処理速度早いとか、ダブルクォーテーションに変数展開した方がコードが読みやすいとかそれぞれメリデリありますが、今回はその辺触れません。

## 参考
- 結合演算子「 . 」
[文字列演算子](https://www.php.net/manual/ja/language.operators.string.php)

- ダブルクォート＋波括弧記法
[二重引用符](https://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax.double)
[複雑な (波括弧) 構文](https://www.php.net/manual/ja/language.types.string.php#language.types.string.parsing.complex)
PHPでmimetypeを取得する方法

- PHPでmimetypeについて調べました
- 方法は複数ありますが、finfoを使った取得方法がデファクトのようです

# [finfo](https://www.php.net/manual/ja/class.finfo.php)(ローカルパス)

- ローカルパスに存在するファイルのmimetypeを取得出来る

```php
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($url);
```

- 注意点
    - リモートファイルは取得できない(エラーとなる)
    - 設定でfinfoを有効化する必要がある

# [finfo_buffer](https://www.php.net/manual/ja/function.finfo-buffer.php)(バイナリ)

- バイナリデータからmimetypeを取得する方法
- 上述の`finfo→file()`だとリモートファイルの情報を取得することは出来ないので、事前にリモートファイルをダウンロードしておき、`finfo_buffer`で取得できる

```php
$finfo  = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_buffer($finfo, $binary);
finfo_close($finfo);
```

# [get_headers](https://www.php.net/manual/ja/function.get-headers.php)

- HTTP リクエストに対するレスポンス内で サーバーによって送出されたヘッダの配列を返す
- 第2引数のassociativeをtrueにすることで、レスポンスがパースされ、配列のキーをセットしてくれる(逆にfalseだと数値添字で参照しなければならない)

```php
$header = get_headers($url, true);
$mimeType = $header['Content-Type'];
```

- 返り値は以下のようになる

```php
Array
(
    [0] => HTTP/1.1 200 OK
    [Date] => Sat, 29 May 2004 12:28:14 GMT
    [Server] => Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
    [ETag] => "3f80f-1b6-3e1cb03b"
    [Accept-Ranges] => bytes
    [Content-Length] => 438
    [Connection] => close
    [Content-Type] => text/html
)
```

- 注意点
    - リモートファイルの情報を取得するには、php.iniでallow_url_fopenが有効化されている必要がある

# [getimagesize](https://www.php.net/manual/ja/function.getimagesize.php)

- 関数名から察せる通り、ファイルが画像だと分かっている場合に有効な手段

```php
$imageInfo = getimagesize($url);
$mimeType = $imageInfo['mime'];
```

- 注意点
    - リモートファイルの情報を取得するには、php.iniでallow_url_fopenが有効化されている必要がある

# 最後に

- mime_content_type関数を使った方法もありますが、使って良いのか分からない(過去に非推奨になっていたり、廃止になりかけたり..)ので今回は触れませんでした
- mime_content_typeは避けるべきなのか、使っても良いのかご存知の方がいれば教えて下さい…
Python演習問題＿0【　条件分岐練習問題①　】_解答

【問題1】：文字列を入力として受け取り、その文字列が回文（「しんぶんし」・「トマト」のように上から読んでも、下から読んでも意味が同じもののこと）かどうかを判定するプログラムを書いてください。

```
text = input("文字列を入力してください：")

# 文字列を反転させたものが元の文字列と同じであれば回文
if text == text[::-1]:
    print("回文です。")
else:
    print("回文ではありません。")
```
【問題2】：0~100までの整数値をランダムに生成し、その数値が80以上であれば "優"、60以上80未満であれば "良"、それ以外であれば "可" と出力するプログラムを書いてください。
【例】：生成された数値が90の場合、"優"と出力します。

```
import random

num = random.randint(0, 100)

if num >= 80:
    print("優")
elif num >= 60:
    print("良")
else:
    print("可")
```
Python演習問題＿0【　条件分岐練習問題①　】

# 条件分岐 #
## 練習 ##

```
【問題1】：文字列を入力として受け取り、その文字列が回文（「しんぶんし」・「トマト」のように上から読んでも、下から読んでも意味が同じもののこと）かどうかを判定するプログラムを書いてください。
```

```
【問題2】：0~100までの整数値をランダムに生成し、その数値が80以上であれば "優"、60以上80未満であれば "良"、それ以外であれば "可" と出力するプログラムを書いてください。
【例】：生成された数値が90の場合、"優"と出力します。
AIで医療用画像分類 皮膚がんを分類する【AI活用事例／プログラミング不要】

# 医療分野でAIを活用する

医療分野にもAIは活用できます。
患部の写真やレントゲン画像など、人間では見分けられない特徴をつかむこともできます。
AIというと難しそうなイメージがあるかもしれませんが、**プログラミングなしでもAIを使って医療画像分類をおこなうことはできます。**

# 皮膚がんの分類
今回は、皮膚がんの画像と、がんではないできものの画像をAIに分類させます。

### データを用意する
Kaggleに上がっていた公共データを使います。

皮膚がん画像↓
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/7ecda29a-12bb-5fa1-956e-f1e547dbed20.jpeg width=200>
非皮膚がん画像↓
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5e8b5af3-9dbb-8ce4-5f53-48611464b733.jpeg width=200>

それぞれ１００枚ずつ程度のデータセットです。

### CreateMLを使う
AppleのAIツールCreateMLを使います。
皮膚がんのフォルダと非皮膚がんのフォルダにそれぞれ画像を入れ、Training Dataとして設定します。

![スクリーンショット 2023-03-11 8.49.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/7715e3e0-87be-198f-37cd-777f357ebc26.png)

▶︎Trainボタンを押すとAIのトレーニングが始まり、１０秒ほどで終了します。

![スクリーンショット 2023-03-11 8.52.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b02b4f09-c7ce-04f0-05c0-0c4310ca185e.png)

トレーニングしたAIに未知の画像を分類させてみます。
![スクリーンショット 2023-03-11 8.54.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/1b41d998-62ed-babd-be68-5f091de0fe11.png)

このように、プログラミングなしでも画像分類ができることがわかりました。
医療やさまざまなビジネスにもっと普及すると良いですね。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)