OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Lightsailで構築したWordPressで、管理者メールアドレスをデフォルトから変更するまっとうな方法


# 背景
AWS Lightsailを使用してWordPressを構築したところ、管理者メールアドレスをデフォルトのuser@example.comから変更できない。正確に言うと、変更後の承認が、本来は新しいメールアドレス(自分の場合gmailアドレス)に送信されるはずだが、送信されない。(「新しいアドレスは確認が完了するまで有効化されません」のままになる)

結論は仕様。デフォルトではメール機能が有効になっていない。これを有効化するのが今回のお題。ちなみに、管理者メールアドレスを変更したいだけなら、
`http://ワードプレスサイトのURL/wp-admin/options.php`にアクセスすれば書き換えられる。ただ、メールが機能しないと他にもいろいろ面倒そうなので、有効化する。

# 大まかな流れ
公式で[手順](https://lightsail.aws.amazon.com/ls/docs/ja_jp/articles/amazon-lightsail-enabling-email-on-wordpress)を公開している。ただこの通りに行かないのとわかりにくいので、できるだけシンプルに記載しておく。

1. Amazon SESで、SMTPサーバのアドレスやTLS情報、SMTPクレデンシャルを確認する
2. Amazon SESで、新しい管理者メールアドレスを、検証済みにする
3. WordPress側で、プラグインを使ってSMTPを有効化し、SMTPサーバの情報を設定する

# Amazon SESとは
AWS内で使用できるメールサービス。特に何もしなくてもデフォルトで自分が使用できるSMTPサーバは存在し、その情報はすぐ入手できる。
ただし、最初はSandbox状態になっていて、
1. 検証済のID(ドメイン、メールアドレス)にしかメールできない
2. メール送受信の量に制限がある
という制約がある。Sandboxから出すこともできるが、悪用される恐れもあるため、今回はそのまま使用する。

# SMTPサーバのアドレスやTLS情報、SMTPクレデンシャルを確認する
SESのページから、「SMTP設定」に進む。ここにSMTPサーバのアドレスは表示されているので記録しておく。
「自分の SMTP 認証情報を作成する」を選択する。ここでは基本的に認証用にユーザを1つ作成することになる。ユーザ名はデフォルトでよい。作成後ユーザ名とパスワードを表示させて記録するか、CSVでダウンロードしておく。

# 新しい管理者メールアドレスを検証済みにする
SESのページから、「検証済みID」->「IDの作成」と進む。
IDタイプを「Eメールアドレス」として、設定したい管理者メールアドレスを指定する。ID作成すると、対象のアドレスに確認メールが飛ぶので、URLをクリックしてVerifyしておく。
上記リンクの公式では、いきなりドメインの検証となっているので混乱する(情報が古い?)が、実際にはメールアドレスタイプのIDを検証しないといけないということ。

# WordPress側でSMTPを有効化
WP SMTP Pluginを有効化する。自分は最初からインストールはされていた。
SMTP Mailerとしては、Other SMTPを選択する。選択肢にAmazon SESもあるが、Pro限定(ライセンス購入が必要)となっている。実際にはProでなくても、Other SMTPとすることで使用可能。
次の「Configure Mailer Settings」で、先ほど記録したSMTPホストや、SMTPユーザ名、パスワードを入れる。Fromのメールアドレスはなんでもよいはずだが、いったん「admin@<自分のドメイン>」としている。
設定後、WP Mail SMTPプラグインの設定画面から、Email Testを選び、自分のgmailアドレス宛に送信すると、無事送られた。

# 所感
相変わらずAWS関連はマニュアルが整備されているけど、わかりにくい…
wslでelixir その10

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。

# 練習問題
対話式に、論理回路を真理値表で表示せよ。

# 方針

IO.gets使う
再帰を使う

# 使ったコード

https://qiita.com/ohisama@github/items/84b22f53efb56dba1863


# サンプルコード

```
defmodule Ronri do
  @moduledoc """
  Documentation for `Ronri`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Ronri.hello()
      :world

  """
  def hello do
    :world
  end
	def run() do
		l = IO.gets("> ")
		l = String.replace(l, "\n", "")
		s = String.split(l, " ")
		cond do
		Enum.at(s, 0) == "make" ->
			Sim.make(Enum.at(s, 1))
			run()
		Enum.at(s, 0) == "init" ->
			Sim.init(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "nand" ->
			Sim.nand(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "nor" ->
			Sim.nor(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "xor" ->
			Sim.xor(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "and" ->
			Sim.and0(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "or" ->
			Sim.or0(Enum.at(s, 1), Enum.at(s, 2))
			run()
		Enum.at(s, 0) == "not" ->
			Sim.not(Enum.at(s, 1))
			run()
		Enum.at(s, 0) == "print" ->
			Sim.print()
			run()
		true ->
			IO.puts Enum.at(s, 0)
		end
	end
	def main(args \\ "") do
		Sim.start_link
		run()
	end
end

```

# 実行結果

```
$ ./ronri
> make 3
> init 0 1
> xor 0 1 2
> print
 0 1 2
 0 0 0
 1 0 1
 0 1 1
 1 1 0
> or 0 1 2
> print
 0 1 2
 0 0 0
 1 0 1
 0 1 1
 1 1 1
> p
p


```


以上。
AIに意識はやどる？意識の仮説への医学的なひとつの事実

# 
**意識には視床が必要？**

# 意識は脳の視床と関係するの？

今回はあっさりと、前回の意識の仮説の最後に書いた補足の記載をするよ。AIに意識が宿るか？その機構は？？って話。

自分は意識は視床で発生している、視床と大脳皮質が絡む巨大カオスが意識発生源と考えている。

視床

![Screenshot_2023-01-02-03-56-09-776_com.android.chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/315d00a0-9d1b-911f-f00b-ed65df007171.png)


画像出典


https://www.akira3132.info/diencephalon.html#:~:text=%E8%A6%96%E5%BA%8A%EF%BC%88%E3%81%97%E3%81%97%E3%82%87%E3%81%86%EF%BC%89%E3%81%AF%E3%80%81,%E6%9E%9C%E4%BD%93%E3%81%8C%E4%BD%8D%E7%BD%AE%E3%81%99%E3%82%8B%E3%80%82


視床と意識が関係しているのは、実は医学的には結構当たり前で、そもそも視床に活動低下が起こると意識は低下すると言われている。それもここで言っておくけど、もうひとつ、盲視というよく知られた現象があって。

目の悪い人の中に、本人見えてないと言うけど、何故か指す方向を当てずっぽうで当てさせるとめちゃ当たる人がいて。その人をよく調べると、大脳の視覚野が働いてなくて見えないらしいと。盲視と言うよ。極たまに脳障害の人にいる。

で、例えば以下のような記事があるので見て見て。盲視の記憶に関しての研究だし怪しい研究では無いのが分かるでしょ。

**見ていると意識できなくても“覚えている”脳
―視覚野の障害でも無意識に脳の別の部位（中脳・上丘）が記憶の機能を代償―**

https://www.jst.go.jp/pr/announce/20110316/index.html

で、この中に記載がちゃんとあるけど、説明の図を抜き出すとこれ。

通常の人の見えてる経路は下。

![IMG_20230101_160757.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/ae369532-ec10-c365-2f35-9a72ad86e3fe.jpeg)

そして、盲視の人の神経の経路はこれなんだ。

![IMG_20230101_160824.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/e13ca2ff-dcc5-8eb8-262f-9b6e4aec5761.jpeg)

つまり、視覚野の問題もあるけど、両方大脳には最後行ってるでしょ？

大脳行く前の中継で大きな所は、まさに
「視床を通っているかどうか」なのは一目瞭然なんだ。

もちろんの他にも理由はあるよ。まずはひとつの根拠を挙げてみたよ。分かりやすいよね。

- 視床通ってる経路なら「見えている」
  視床＋大脳視覚野   見える！

- 視床通ってないなら「見えてない」
  上丘＋頭頂野  見えない！！

視床には実際には視覚野の多数のフィードバックが来るよ。

これ見ると大脳の頭頂野に後者は行ってるけど見えてないでしょ？？要は言いたいことの一つとして、

「大脳はそれだけでは意識の野ではないのではないか？」

という事も強く示唆するよね。

また、もうひとつあるのが、視覚野が作った結果、を視床が見る、と言う形は、まさに視覚意識の特性として、出来上がった画像を「見ている」と言う振る舞いにとても合う。

色々な人がこれ言ってきたことなんだんけど、意識はまるで劇場のように、風景を見るわけだし、それは明らかに「脳内で作られた」映像なんだよね。

色は当然この世界には無い(電磁波が網膜細胞を刺激するのみ)ので、何か「見ている画像が作られる」言わば視覚のクオリアが発生する、と言うのは変な話。そして実際に視覚野ではまさにDNNの認識的な処理が行われているのはかなりわかっていて、問題はそれを「どう誰が見てるのか？？」という問題なんだよね。

実は視覚の結果が、視床にフィードバックされてると言ったけど、それが視床内で「意識に統合されている」とすればこの謎が明確にわかる。

そして、今までは、自分も含めて、視床は小さいし、それも変なんじゃないか？？と思っていたんだけど、StableDiffusionなどのネットワークが動作する様子を見ていて、ああ、視床でやっぱりいいのだ、と思うようになった。StableDiffusionの分析と視床の動作の比較などをしているので下記も見ていただければと。


https://qiita.com/ilabotakeda/items/f0a34463162d3e256b72


と言うのは、視床が産まれてからの初期意識を司っているのは大脳がまだ生まれてすぐはあまり作られてないので当然だし、そして潜在変数を扱う処理を行っていると考えるとまさにこれが視床の働きそのものとして非常にクリアになる、という事なんだ。

この信号の流れは極めて解剖学的なものだし、視床の流れ内に意識関係してるという直接的な医学的証拠として見てもいいのかな、と思ってる。

そしてこれは一部のAI企業と研究者が唱えている、

**「情報処理すれば意識あるでしょ？？」と言う素朴な情報処理と意識の同一説の反例としても機能しているね。**

こんな感じで詰めていこう。

# 追記

こういうの見て自分が思うのは、やはり、意識についていろんなことを言う人たち、実験とか現実とかちゃんと見てる？？って話かもしれない。

少なくても現実は「視床＋視覚野」は意識があり、「上丘」を通ったら意識がないんだ。

これは事実なんだ。神経も情報処理も意識の本質では無いことは明確で、「視床＋視覚野」が意識を発生させている物理機構なのは現実的に論理的に間違いないんだ。他の事をいくら言ってもそれは机上の空論なんだよ。もちろん他にも自分には理由があるんだけど、ここだけでも「絞りこめる」。難しい言説で混乱を招くべきでは無い。

HQFTの話もそうなんだけど、まず現実見ようよ。脳のどの経路に信号が流れてたら意識あるのか。そこだけでもいくらどんなこと言っても仕方ないでしょって思うわけですよ。そうでなくい人達は、やはり一種のポジショントークなのでは？意識の話をネタにして儲けようと思うからこそ、現実を見ない、ないし無視するのでは？？と思ってる。
Nestjsでgraphqlサーバー構築(その1. Nestjs + prisma + postgreSQLの環境構築)

id: 8ba2ec1a

参考記事

https://docs.nest-book.jp/ttebunestjs/no

https://docs.nestjs.com/first-steps

## 今回やること
- [x] NestJSの初期化(hello worldまで)
- [x] prisma の初期化
- [x] postgreSQLの初期化
- [x] prisma と postgreSQLの接続


### NestJSの初期化
```bash:bash
$ npm i -g @nestjs/cli
$ nest new project-name
$ cd project-name
```

* tsconfigの修正
```json:tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": true,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false,
    "strict": true
  }
}
```

* listen portの変更(3000->3005)

```ts:main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3005);
}
bootstrap();
```

* hello world

```bash: bash
$ yarn start
```
localhost:3005でhello world が表示されればok


### prisma の初期化

```bash:bash
$ yarn add -D prisma
$ yarn add @prisma/client
$ npx prisma init
```

### postgreSQLの初期化

* postgreSQL用のdocker-compose.ymlの作成
```yml: docker-compose.yml
version: '3.8'
services:
  dev-postgres:
    image: postgres:14.4-alpine
    ports:
      - 5434:5432
    environment:
      POSTGRES_USER: qiita
      POSTGRES_PASSWORD: qiita
      POSTGRES_DB: qiita
    restart: always
    networks:
      - lesson
networks:
  lesson:
```

* DBコンテナの起動
```bash:bash
$ docker-compose up -d
```
### prisma schemaの定義
```:schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id             Int      @id @default(autoincrement())
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt
  email          String   @unique
  hashedPassword String
  nickName       String?
  tasks          Task[]
}

model Task {
  id          Int      @id @default(autoincrement())
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
  title       String
  description String?
  userId      Int
  user        User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}
```


* schemaのmigration
```bash:bash
$ npx prisma migrate dev
```

* DBの状態確認
```bash:bash
$ npx prisma studio
```

* prisma client の更新

https://www.prisma.io/docs/concepts/components/prisma-client

>Whenever you make changes to your database that are reflected in the Prisma schema, you need to manually re-generate Prisma Client to update the generated code in the node_modules/.prisma/client directory:

```bash:bash
$ npx prisma generate
```
今月はジョブカンに何時間申請したかを正規表現で計算する

### 前提
かなり特殊な前提ですが…
- 私はアルバイトで、ジョブカンで自分で申請してる
- ジョブカンで申請した時間と同じ時間を経理の人に伝える
- ジョブカンの申請はあくまで補助で、基本は経理の人に伝えた時間が今月バイトした時間とみなされる

という状況です。
もちろん予め何時間働くという前提のもとに申請しているわけですが、例えばマクロを組む仕事が入るとかすると想定時間をオーバーすることがあるわけです。オーバーして申請を追加して...としてると、自分が今月何時間働いたかがわからなくなるというわけです。

そこで、
**ジョブカンに何時間申請したかをスピーディーに算出してぇ...** と思うようになりましたとさ。

### 方針
最初はAPIとかスクレイピングとかしてみるか！？と思ったけど、経験値の浅さゆえ面倒くささが勝ちギブ。
そのときふと、**画面をコピペして正規表現で時間を処理できるんじゃね？** と気づきました。

ジョブカンの画面はこんな感じで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530290/451a831b-3b56-b356-ec6a-51ec97aaf5f5.png)
D&Dで文章をさらってゆく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530290/f12d7cdd-b607-e162-4cdb-20a320513f01.png)
画面をコピペするとこんな感じの文章がゲットできる。はい、正規表現を使いましょう。~~興味本位の暇つぶしで~~ やっていてよかった。
ゲットした文章を「今月何時間働いた.txt」として保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530290/3f7eb0e5-bcd8-d298-67a0-ab2c48139fa2.png)


```python:今月何時間働いた？.py
import re, datetime

def sabun(t1,t2):
    return (datetime.datetime.strptime(t1, '%H:%M') - datetime.datetime.strptime(t2, '%H:%M')).seconds

time = []

with open(rf"今月働いた？.txt", encoding="utf-8") as f:
    texts = list(map(lambda s: s.strip(), f.readlines()))

for text in texts:
    if "時刻指定" in text:
        dates = re.findall("\d\d:\d\d", text)
        time.append(sabun(dates[1],dates[0]))
        
h = sum(time) // 60 // 60
m = sum(time) // 60 % 60
print(f"今月は、{h}時間{m}分")
input()
```
今月のバイト時間は60時間でした。だいたい六万円でしたね。~~うぅむ...もう一回10万円くれねえかなぁ...~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530290/fe5b0d5d-7aa4-7058-7b32-8d032da32fb1.png)
vmwareの仮想マシンイメージをThin形式のままデータを引っ越しする



# 1. はじめに

vmwareの仮想マシンイメージをcpでコピーするとThinイメージからThickイメージになってしまいます。
それを回避するためには、Storage vMotionを使うか、vmkfstoolsを使う必要があります。

vmware ESXiやvmware essentialではStorage vMotionは使えないのでコマンドラインでvmkfstoolsを使って移行しました。
移行するときに手作業ではミスる可能性が高いので、シェルスクリプトを組みました。

# 2. 結論

src_stは、移動元のストレージです。移行用のESXiからNFSでマウントされているとします。
dst_stは、移行先のストレージです。移行用のESXiからNFSでマウントされているとします。

引数で、移行する仮想マシンイメージのディレクトリ名を指定します。

```bash
#!/bin/sh

source_storage='src_st'
dest_storage='dst_st'

trans_vmdir=$1
if [ -z $trans_vmdir ]
then
  echo "Please specify the transport source directory 'transfer-vmimage.sh <vmware image dir>'"
  exit
else
  :
fi

echo "exec copy file vmware image: $trans_mvdir"

mkdir -p "/vmfs/volumes/$dest_storage/$trans_vmdir"

if [[ ! "$(find "/vmfs/volumes/$source_storage/$trans_vmdir" -name '*.vswp'| wc -l )" == "0" ]]
then
  echo "current virtual machine is running. please stop $trans_vmdir"
  exit
fi

echo "Copy files without .vmdk"
find "/vmfs/volumes/$source_storage/$trans_vmdir" -maxdepth 1 -type f | grep -v ".vmdk" | while read file; do cp -rf "$file" "/vmfs/volumes/$dest_storage/$trans_vmdir"; done

echo "Copy .vmdk file"
src_file_list=$(find "/vmfs/volumes/$source_storage/$trans_vmdir" -maxdepth 1 -type f | grep ".vmdk" | grep -v "\-flat.vmdk")

for src_file in $src_file_list
do
  dest_file=$(echo $src_file | sed -ne 's/$source_storage/$dest_storage/p')
  echo "source      .vmdk file: $src_file"
  echo "destination .vmdk file: $dest_file"
  vmkfstools -i "$src_file" -d thin "$dest_file"
done
```


# 3. 参考

Move VMware ESXi VM to new datastore - preserve thin-provisioning - Server Fault
https://serverfault.com/questions/372526/move-vmware-esxi-vm-to-new-datastore-preserve-thin-provisioning

コマンドでシンプロビジョニングの仮想マシンを別のデータストアへ移行する | MSeeeeN
https://mseeeen.msen.jp/migration-to-another-data-store-with-thin-provisioning/
Nuxt3 の script setup ( Composition API ) で 外部APIにリクエストする

# コード例

`pages/example.vue`

```js

<script lang="ts">
export default defineComponent({
  async setup() {
    const { data: items } = await useFetch('https://jsonplaceholder.typicode.com/todos/')
    return {
      items
    }
  },
})
</script>

<template>
  <ul>
    <li v-for="item in items">
      {{ item.id }} {{ item.title }}
    </li>
  </ul>
</template>

```

# 表示例

<img width="567" alt="image" src="https://user-images.githubusercontent.com/13635059/210162409-41a02601-c5dd-44fc-9004-cf403c048a89.png">

# 備考

よりシンプルな構文も試したがうまく動かなかった

```
<script setup lang="ts">
    const data = await fetch('https://jsonplaceholder.typicode.com/todos/')
    const { data: items } = await data.json()
</script>
```

# 環境

nuxt 3.0
vue 3.2.45

# 参考

https://zenn.dev/coedo/articles/86bc31acb4ea47


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Unreal EngineのFStringのコピー

# はじめに
Unreal EngineのFStringについて, コピーの動作がどうなっているのか, 気軽にコピーしてもよいのか明確にしようと思います.

# FString

## 構造
ここをみれば特性は把握できるので, わざわざ実験する必要もないのですが.
`TArray`を利用しており, 固定サイズで容量が増加します. `TArray`は`std::vector`と同じです. `trivially copyable`な型に対する最適化などはありません.

```cpp
using AllocatorType = TSizedDefaultAllocator<32>;
/** Array holding the character data */
typedef TArray<TCHAR, AllocatorType> DataType;
DataType Data;

```

## コピー
`TArray`の`ResizeForCopy`が呼び出されるだけで, `FMemory::Malloc`や`FMemory::Realloc`に行きつきます. `Small Size Optimization`などはとくにありません, 足りなければ領域を新たに確保しコピーします. 文字列なので`FMemory::Memcpy`で十分なのですが, ループでコピーコンストラクトします.
次のような簡単なテストでは`std::string`の方がパフォーマンスが良いです.

```cpp
ATestString::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    using wstring = std::basic_string<TCHAR>;
    static constexpr uint32 Count = 10000;
    uint32 Frame = static_cast<uint32>(GFrameCounter%100);
    FString S = FString::Format(TEXT("%d"), {Frame});
    wstring s;
    {
        std::basic_stringstream<TCHAR> ss;
        ss << Frame;
        s = ss.str();
    }
    TArray<FString> FStrings;
    std::vector<wstring> strings;
    FStrings.SetNum(Count);
    strings.resize(Count);
    {
        SCOPE_CYCLE_COUNTER(STAT_FString);
        for (uint32 i = 0; i<Count; ++i) {
            FStrings[i] = S;
        }
    }
    {
        SCOPE_CYCLE_COUNTER(STAT_StdString);
        for (uint32 i = 0; i<Count; ++i) {
            strings[i] = s;
        }
    }
}
```

# まとめ
Unreal EngineのSTLに代わるコンテナがゲーム向けに高速化されているという事実は, 私の知る範囲ではありません. それどころか, `FString`は`TArray`に依存する, `TMap`は`TSet`に依存するなどコード量を減らすやり方が, パフォーマンスの面ではマイナスにはたらいています. 
ゲームでよく使われるコンテナが追加されているという意見には同意します.
STLと同じように, 集成体の引数はconst参照というプラクティスは有用です. `TStringView`もありますので活用していくとよいでしょう.
DataSpider SDKでNFT連携するための技術要素

DataSpiderとブロックチェーン　その８

前回までの投稿にて、[DataSpiderSDKを用いてスマートコントラクトの連携と運用するためのガス代](https://qiita.com/dataspider-fan)について紹介しました。
今回から、具体的なNFT連携について説明していきたいと思います。
これからNFT連携のためのDataSpiderアダプタを作成していきますが、NFT連携のシナリオとNFT連携に必要な技術要素について紹介したいと思います。

## DataSpiderによるNFT連携のシナリオ
DataSpiderを用いて、利用者に対して証明書（PDF形式）を発行し、その発行されたPDFデータをNFT化します。
また、証明書を見たい時にいつでも閲覧できることを要件に含め、アクセス制限のないパブリックネットワーク上にNFT化された証明書PDFを配置します。

### NFT発行までの処理概要
①から⑤の処理をDataSpiderのスクリプトに実装することにより、NFT連携を実現します。
#### NFT発行までの処理イメージ
![nft全体像.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849535/1346cd86-5743-14f4-1704-6a93fc4b93d7.png)

#### 受取者名簿
![受取者名簿2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849535/c46643b0-93f3-501d-ff12-e9daeffdf7e8.png)

#### 生成する証明書（PDF形式）イメージ
![証明書サンプル4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849535/db1c38c9-9e5f-cdf2-f5b0-7ce5aaf1b741.png)


**処理フローは以下：**
1. 証明書を受け取る利用者(受講者)のCSVファイルの一覧を用意しておきます。
この一覧に証明書に埋め込む情報も保存しておきます。今回の検証では、利用者(受講者)氏名、TRONアドレスを証明書に埋め込みます。
2. 受取者名簿から利用者氏名、TRONアドレスを読み込み、PDFを生成します。
今回の検証では、PDFテンプレートは用意せず、コード内でスクラッチからPDFファイルを生成する処理を実装します。
3. 生成したPDFをIPFS/PINサービス宛に転送します。
転送が完了するとPDFのコンテンツアドレスが返却されますので一旦保持します。
4. PDFのコンテンツアドレスとNFTとして必要な情報をJSONファイルに埋め込みます。
再度IPFS/PINサービス宛にJSONファイルを転送します。
転送が完了するとJSONファイルのコンテンツアドレスが返却されますので一旦保持します。
5. JSONファイルのコンテンツアドレスとNFTの管理IDを引数とし、NFT生成用のスマートコントラクトを呼び出します。
ブロードキャストが完了すると、NFT情報がブロックチェーン上に書き込まれます。

以上で、NFT連携は完了です。

### NFT連携のために作成するアダプタ
+ PDF生成アダプタ(❷)
+ IPFS/PINサービス通信アダプタ（❸および❹） **(※)**
+ NFT生成アダプタ（❺） **(※)**

DataSpiderが提供しているアダプタにPDF生成機能がありませんでしたので今回作成します。
 **(※)** IPFS/PINサービス通信アダプタは、NFT化するための必須とする情報が返却されますので、❸から❺は１つのアダプタとして実装するかもしれません。

### 上記シナリオで必要となるJavaライブラリ
+ [TRON Trident-JAVA](https://github.com/tronprotocol/trident)（こちらのライブラリは前回までの記事の説明でインストール済）
+ [iText ライブラリ](https://github.com/itext/itext7)（PDF化するためのライブラリはiTextを使用します）


## NFTの技術要素
基本的なNFTの考え方と技術要素について説明します。
DataSpiderによるNFT連携に必要な技術要素に絞って紹介します。
参考サイト：https://ipfs-book.decentralized-web.jp/what_is_ipfs/

### NFTの基本
NFTはnon-fungible token の略（非代替性トークン）であると、他のページでは説明がされています。
昨今では、NFTといいますと、アート分野などコレクションの1つとして売買されたり、あるグッズとだきあわせで販売されています。
NFTは電子データですが、固有の電子データとして各々に価値があるものとして流通していると考えます。また、この固有の電子データということで、入手したいという消費者の購買意欲の向上にも働きかけていると思います。
それでは、なぜ固有の電子データとして扱えるのでしょうか。その技術要素について紹介します。

### コンテンツアドレッシングの仕組み
特定の電子データをNFTとして扱うために、IPFSの利用が必須であると私は考えます。
IPFSは、InterPlanetary File Systemというプロトコルの1つであり、IPFSのサービスに対して電子データを送付すると、その電子データのハッシュ値が得られます。
このハッシュ値は、電子データをもとに生成されるため、対象の電子データが異なれば、別のハッシュ値が得られることになります。よって、このハッシュ値の導出により特定の電子データが固有であるという裏付けになるわけです。
さらに、このハッシュ化された文字列は、Web上において、その電子データへアクセスする際のURIの一部となります。つまり唯一無二のURLが電子データにより生成されることになります。これがコンテンツアドレッシングです。
URLはネット上のコンテンツ（動画ページや写真など）に対して場所を表す文字列ですが、このコンテンツアドレッシングという考え方は、場所だけではなくモノ（対象の電子データ）に対しても指し示すことになります。

### ブロックチェーン技術との組み合わせ
ブロックチェーン上のデータは改ざんされない、ブロックチェーンは改ざん耐性が強いと言われますが、この強固なネットワークにIPFSにより得られるコンテンツアドレスを埋め込むことにより、改ざんされていないことの証明となりデータの信頼性が担保できると言えます。
このような理由から、コンシューマ向けのサービスだけではなく、業務用アプリケーションにも応用がされてきていると思います。

## 次回は
[NFT化する証明書PDFを生成するアダプタの実装例](https://qiita.com/dataspider-fan/items/05c199a8facb54e9b1c3)を紹介します。
【GitHub】でコミットしたメッセージを後から変更する方法


## 環境
Mac(M1, 2020)
vscode５

# [概要]
Gitでコミットメッセージを間違えてしてしまった。
すでに同じような記事ありますが、調べていくと思ってたより複雑だったので備忘録的に残しておきます。
（個人的には、```git commit --amend -m　コミットID "変更したいメッセージ"　```　でできると勝手にイメージしてました🙇）

※今回は３番目にコミットしたメッセージを変更したいのでその方法です



## 2つ以上前のコミットメッセージを変更する

#### 1.```git log --oneline```で変更したいコミットを確認
```
7ae1955 質問欄エントリーポイント作成
33b8358 質問欄作成
0336e1c 解答欄エントリーポイントをインポート　　←ここを変更したい！！
b539167 質問欄エントリーポイント作成
6f72911 質問欄作成
fdc485d 解答欄エントリーポイントのインポート
87b5141 test
cc7728c 解答欄を表示
2938347 datasetを取り出した
9903bb2 エントリーポイント作成
3f419a1 解答欄コンポーネント作成
5800a50 💄 スタイルとフォントの作成
0dfead2 データセットファイルの作成と記述
835a8df styleのimport修正
```
#### 2.```git rebase -i HEAD~’変更したい番号’```
HEAD~の次に入る番号は上から１なので、今回は```git rebase -i HEAD~３```を実行

VIエディターと言うものが開きます
![スクリーンショット 2023-01-01 11.14.07（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884551/64f78a6b-e18f-1925-8664-f897d24b668d.png)
一番上に変更したいコミットがあります。
行の先にあるpickをeditに変更する必要がありますが、入力ができないと思いますので
『入力モード』に切り替えるため```i```と入力し最下部に「INSERT」と表示されたらOK

#### 3.pickをeditに書き換え「コマンドモード」に切り替える
※ここではまだコミットメッセージは変更しない
![スクリーンショット 2023-01-01 11.14.37（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884551/ae78db25-a0f7-8e7c-1061-6c48311128c4.png)
画像のように書き換えたら、先ほどの入力内容を保存してから、viエディタを閉じる。
その前に、保存するにはさっきの「入力モード」から逆に```Esc```で「コマンドモード」に変更する必要があるので入力し最下部の「INSERT」も消える。
これでファイルの保存やVIの終了操作ができるようになる。

#### 4. ファイルを上書き保存してVIエディタを終了する

ファイルの上書き保存は```:w```を入力。
次に、VIエディタを終了するには```:q```を入力。

#### 5. コミットメッセージを変更
3.の変更でeditを指定したコミット（今回の場合は3つ前のコミット）まで状況が戻っているので、
ここで```git commit --amend -m "質問欄エントリーポイントをインポート"```を実行
すると、3つ前のコミットメッセージが入力した内容に更新される。

次に```git rebase --continue```を実行してし終了。



#### 6. ```git log --oneline```で変更できているか確認

```
7ae1955 質問欄エントリーポイント作成
33b8358 質問欄作成
0336e1c 質問欄エントリーポイントをインポート ←変更できている！！
b539167 質問欄エントリーポイント作成
6f72911 質問欄作成
fdc485d 解答欄エントリーポイントのインポート
87b5141 test
cc7728c 解答欄を表示
2938347 datasetを取り出した
9903bb2 エントリーポイント作成
3f419a1 解答欄コンポーネント作成
5800a50 💄 スタイルとフォントの作成
0dfead2 データセットファイルの作成と記述
835a8df styleのimport修正
```

間違った認識や、他に簡単にできる方法あれば教えて頂けたら嬉しいです🙇
"リスク"に対する考え方

youtubeのとある動画で、
「なんかこういうことしてるといつか事故起こしそうだなぁ」っていう感想を投稿したら
「冷めるから批判したいヤツらは黙ってろ」
「そうそう事故なんて起きるもんじゃない」
みたいな、擁護派(?)のコメントがついて自分のコメントスレッドが長くなってた(100件くらい)ので、
ちょっとそれに対して感じたことをメモ。
仕事に対しての”リスク”管理みたいなとこにも通じると思ったので。

殴り書き感覚なので、読みに来ていただいた方々、読みづらさはご容赦ください。

### どんな動画だったか
リンクは貼りませんが、
登場人物は１、２歳くらいの子ども、中型犬くらいの大きさの犬（犬種は知らない）、カメラマンの大人(親？)
中身としては、リードを手離して犬を散歩させてて、
そのリードを拾おうと、子どもがよちよち歩きで追いかけてる。
（よちよち歩きでつかず離れずくらいの速度で犬もゆっくり歩いてる）

### 動画を見て感じたこと（コメントの概要）
この子がリードを拾えたとして、今は犬のほうが人間に合わせてゆっくり動いてるけど、
走り出したりしたら確実に犬の方が力強くて制御はできない
一見ほのぼのしたワンシーンぽいけど、「もし犬が暴走したら」という意識が抜け落ちてる。
少なくとも大人はセーフティのためにもリード掴んでおくべきだった。


### 自分のコメントに対する批判に対して思うこと。
#### "問題起きてないから大丈夫"は結果論でしかない。
「平和なワンシーンとして投稿された動画にとやかくいうもんじゃない」
みたいな意見がだいたいのところなんだけど、
それって結果論でしかなくて、そんな「結果的に問題なかったからヨシ！」みたいなやり方で本当にいいの？？
っていうのがすごく感じたところ。

というか、「リスクがあるように感じる」という趣旨の自分のコメントに対して、
「今現在、”まだ”問題が起きていないから大丈夫」っていう反駁は、
自分のリスク感覚に対して何も答えを与えてくれてないし。

#### 擁護派は想定しているリスクの範囲が狭い。
もう一個大きく気になったのは、擁護派の人が基本的に
「犬、もしくは子どもが何かしらの怪我をする」くらいのリスクしか想定してなくて、
「あー、犬が暴走して誰かに怪我をさせる」とか、
そういう、他人様にご迷惑や被害を与えてしまう方向性であんまり考えてないのも気になった。

そもそも、動画の投稿主も、動画を撮ってるシチュエーションが100%安全で、
何か起こっても自分の責任で対処できるならそういうコメントを動画に入れればいいんじゃん？と。
ていうか、子育てとかペット飼育とかって、そういうことを常に考えるもんじゃない？？
（そういう宣言があるんなら、自分もこんな記事書いてないし、そもそも動画にコメントしてなかったと思う）

投稿主（親・飼い主）にその意識が見えなかったのが、
「本当にその状況、誰にとっても安心して見てられる状況なの？？」って聞きたくなる本質的な理由だった。

### ムリヤリ仕事に繋げる。
#### どこかの電車に迷子犬が乗り込んでニュースになったこともあったよね
この動画にコメントしたのとほぼ同時に、どこかの電車で迷子犬が乗り込んで、
犬も精神張り詰めてたのか歯剥き出しでめっちゃ唸ってて、
車掌さんが降ろそうとするのに苦心してる動画が出回ってた。

この犬も首輪もしてて飼い犬らしかったけど、飼い主はたぶん
「普段おとなしくてこういうことになる想像なんてしなかった」
って言うと思うし、原因は多分そういう思考だからちょっと油断してても大丈夫って意識だと思うんよね。

で、時期を同じくしてそういうニュースが出たりするから、
というか、自分の意識では
「想定しうるリスクはどこかで必ず顕在化する」
と思ってるから、結果論で「大丈夫ってことにする」思考ってやばいよね、と。
世の中の事故って、たぶんほぼ全部「よし今日事故起こそう」と誰かが考えて起こしたワケじゃない。

全然技術的なことは関係なかったけど、エンジニアとして今回の件は
リスクヘッジにおいて、”結果”は手段の信頼性を補強するためのものであって、
常に気にしておくべきは、「安全かどうかの議論になったときに説明材料としての手段を準備しておけるか」じゃないかなぁ、って思いましたとさ。

### まぁ、youtubeだし・・・
youtubeって媒体だから、見てる人の年齢層が低かったりっていうのもあるんだろうけど、
見てて楽しい気分になれることが最優先で、
水を差す意見を叩き潰そうとするリプがけっこうついてたのとか、
大丈夫だと思ってる人は推測で大丈夫な理由を足そうとする感じとか、
人間の恐ろしい一面を生々しく垣間見た気がして、ちょっと怖かったなぁと。

一方で、
「とはいえ、飼い主がリード離してていい理由にはならない」的な人も結構いて安心もした。
Pythonでクラス関数が親クラスを継承しているかを調べる

# Pythonでクラス関数が親クラスを継承しているかを調べる

## はじめに
Pythonでは、クラス間の関係を継承関係と呼び、クラス関数が親クラスを継承しているかを調べることができます。

## 例
以下のコードを例に、Pythonでクラス関数が親クラスを継承しているかを調べる方法を説明します。

```python
class A:
    pass

class B(A):
    def test():
        pass

issubclass(B,A) #True
```

class Aが親クラスで、class Bが子クラスです。issubclass()関数を使用することで、class Bがclass Aを継承しているかを調べることができます。

## 応用例
issubclass()関数を使用すると、クラス間の継承関係があるかを調べるだけでなく、複数のクラス間の最終的な親クラスを調べることもできます。

例えば、class Aがclass Bを継承し、class Bがclass Cを継承している場合、class Cがclass Aを継承しているかを調べることができます。

```python
class A:
    pass

class B(A):
    def test():
        pass

class C(B):
    pass

issubclass(C,A) #True
```

## まとめ
Pythonでは、クラス関数が親クラスを継承しているかをissubclass()関数を使用して調べることができます。また、複数のクラス間の継承関係を調べることも可能です。
【Git】末尾に改行があるべき!?　\ No newline at end of fileの意味とその対応方法！

# 概要
* `git diff`で差分を確認したところ、`\ No newline at end of file`というエラーが表示されました。何も変えていないファイルなのになぜ？と思い、調べてみました。

```terminal
\ No newline at end of file
```

# 原因・解決方法
* 上記のエラーメッセージは、改行を入れたら出なくなりました!
    * 参考文献：[git :: 「No newline at end of file」の対処](https://tm.root-n.com/unix:command:git:operation:no_newline_at_end_of_file)
  
* [【vim】No newline at end of file](https://www.softel.co.jp/blogs/tech/archives/7278
) にはこのように記載があります

> POSIX的にはテキストファイル末尾には改行があるべきらしく、vimでテキストファイルを開いて保存すると改行が付く。

> 混乱のもとは、ファイル末尾に改行を付与するエディタ（vim）とファイル末尾に改行を付与しないエディタ（他のエディタ）混在しているからかと思われる。

* 改行を入れてあげれば解決できますが、毎回行うのが面倒な場合は、vim でファイルを開き、コマンドモードで下記を実行して保存すれば、警告がなくなります。

```terminal
:set binary noeol
```
XPath を Element から相対的に指定する

意外と調べても見当たらなかった(調べ方が悪い？)ので、自分の覚書。
Python & Selenium ですが、他の XPath を利用する場合にも使えるんじゃないかな？
# HTML 要素(最上位要素)を基準に、要素を取得する場合
XPath の情報でよく見る記載です。
```Python:よく散見される、Selenium による XPath の指定
from selenium import webdriver
from webdriver_manager.microsoft import EdgeChromiumDriverManager
(中略)
# WebVriverをwebdriver_managerで取得
driver = webdriver.Edge(EdgeChromiumDriverManager().install())
# driver = webdriver.Edge(r"C:\〇〇〇\edgedriver_win64\msedgedriver.exe")
(中略)
driver.find_element_by_xpath('//*[@id="password"]').send_keys(passw)
```
この **`'//*[@id="password"]'`** の表現ですが、**`//`** は、先頭に記載されることによって、HTML文書の最上位要素である`<html>`タグを基準にして、そこから XPath の記載に従った要素取得を行う内容となっています。
# 取得したエレメントの子要素を、ループで回して処理したい！
例えば、検索サイトである単語でWeb検索を行い、その中から指定のページを見つけて開く、という処理を考えた場合、検索結果全体を表示するdivエレメントを取得し、その子要素をループにかけたい場合もあると思います。

:::note info
対象のページのタイトルが分かってるなら、**`//*[contains(text(),"タイトル文字")]`** で取得できる、というツッコミは無しで。
そういう類のモノではないという前提です。
:::
```Python
for temp_element in driver.find_elements_by_xpath('//*[@id="tree-1-El"]/child::div[starts-with(@id,"tree-panel-")]'):
    temp_element_child = temp_element.find_element_by_xpath('temp_element 要素の下にある、id が "header-title-" で始まる、div 要素')
    if temp_element_child.text == 'テキスト1':
        temp_ele_text1 = temp_element
    elif temp_element_child.text == 'テキスト2':
        temp_ele_text2 = temp_element
```
`temp_element 要素の下にある、id が "header-title-" で始まる、div 要素` を、XPath でどの様に指定すればよいか？
# 勿体付けずに、正解はこちら
```Python
for temp_element in driver.find_elements_by_xpath('//*[@id="tree-1-El"]/child::div[starts-with(@id,"tree-panel-")]'):
    temp_element_child = temp_element.find_element_by_xpath('.//div[starts-with(@id,"header-title-")]')
    if temp_element_child.text == 'テキスト1':
        temp_ele_text1 = temp_element
    elif temp_element_child.text == 'テキスト2':
        temp_ele_text2 = temp_element
```
**`'.//div[starts-with(@id,"header-title-")]'`** が該当箇所です。
単純に、**`.//`** で始まるように指定すればよかったんですね。
**`/`** とか **`./`** で上手くいかずに、無駄な時間を使いました・・・
## XPath は、極めるととても便利
XPath は、とても奥が深いんですよね、私は下記のサイトを参考にしています。

https://ai-inter1.com/xpath/
【GitHub】 fatal: Need to specify how to reconcile divergent branches.を解決


## 環境
Mac(M1, 2020)
vscode５
git version 2.37.1 

# [概要]
gitでコミットメッセージを間違えてしまい変更後pullしようとしたらエラーにぶつかった。


## ぶつかったエラー
fatal: Need to specify how to reconcile divergent branches.
![スクリーンショット 2023-01-01 11.25.50（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884551/8c1b9a31-f90b-3f7e-a979-da10831d4e25.png)




翻訳・意味
致命的: 分岐ブランチを調整する方法を指定する必要があります。
## やったこと
解決策 1: マージ戦略に切り替える
ローカル ブランチにないリモートの変更がある場合は、解決する必要があります。デフォルトの Git の動作はマージです。これにより、ローカル ブランチに新しいコミットが作成され、それらの変更が解決されます。git config pull.rebase falseコマンドを使用して、リベース戦略を使用する代わりにデフォルトのマージ戦略に戻すことができます。
※下記URLの記事参照（意味わからんです！）


https://www.cyberithub.com/solved-fatal-need-to-specify-how-to-reconcile-divergent-branches/
1.```git config pull.rebase false```を実行


## 結果
コミットメッセージを変更できました。


わかったことがあれば追記していきたいと考えています。
間違った認識などあれば教えて頂けたら嬉しいです🙇

## 追記
「継続的デリバリーのソフトウェア工学」を読んだ

最近読み終えた「継続的デリバリーのソフトウェア工学」が面白かったのでたまにはざっくり感想を書いてみます。
https://bookplus.nikkei.com/atcl/catalog/22/12/01/00531/


# 第1部「ソフトウェア工学とは何か」
この本ではソフトウェア工学を「ソフトウェアの現実的な問題に対する効率的、経験的な会を見つけるための経験的、科学的なアプローチの応用のことである」(1.2より)と定義しています。多くの技術書で触れられているような高品質なソフトウェアを作る方法のことをこの本では「工芸」とし、高品質かつ大規模なソフトウェアを作る方法である工学と区別して論じています。全15章の内の最初の第1部(第1章から第3章)にて、本来の意味から意味が変わってしまった「ソフトウェア工学」を意味を改めて説明し直していますが、読み物として一番面白いのはこの部分とも思いました。実際、「本書は、ソフトウェア工学に工学を取り戻す試みです。」(はじめにより)とも書いてあります。

# 第2部「学びの最適化」
仕様をはじめから決定し切ることや実装前に理解し切ることが非現実的であるという前提に立ち、漸近的・反復的な開発により徐々に仕様と実装の完成に近付ける手法について、第2部で説明しています。つまり、ウォーターフォール手法を否定し、アジャイルへの復帰及び継続的デリバリーを推奨しています。継続的デリバリーとは、「小さな変更を加えるたびにそれをリリースできるようにすること(一日に複数回)を目標に」(4.1より)することです。そしてそれを実現するためのTDD(テスト駆動開発)の説明と推奨も記されています。

# 第3部「複雑さ管理の最適化」
主題である「ソフトウェア工学」の実現のために重要な複雑性の管理については第3部で述べられています。目次を見ればわかるように、ここではモジュラー性・凝集度・関心の分離・抽象化・カップリングなどのトピックについて触れられています。ここまでこの本にはコード例が登場しなかったので、このまま例無しで終わるのかしらんとも思っていましたが、10章から悪いコードと良いコードの対比で各概念の説明し、どのように改善すべきかについて論じています。いずれのトピックについての章でも、最後には「改善するためにはテスト駆動が必須である」と説得されるので、読んでいて暴れん坊将軍やドラえもんを見ているかのような予定調和的な流れを感じさせてちょっと面白かったです。(これは読書感想文です。) 各トピックについての改善点とその説明には納得できる一方で、それを実現するにはまずTDDの環境が必要であり、実際に仕事にこれを適用させるにはTDDの導入が一番のハードルかもなぁとも思ったりしました。

# まとめ
あらゆるソフトウェア開発現場で即座にこれを実現できるかと言えばNoなのですが、本書で得られた知識を元に現場の改善を行うのは非常に有益であるとは言えます。例えTDDの導入が困難な現場であっても、第3部のトピックを断片的にでも導入することで高品質化は可能でしょうし、新たに開発するモジュールに対してTDDを導入することでの高品質化も可能かも知れません。
小さいソフトウェアを短期間で工芸的に作成するのみならず、中長期の開発期間である程度の規模を持ったソフトウェアを開発するために知っておいた方が良い知識が本書で得られることでしょう。
未経験からプログラミング勉強する人はプログラミングの本は買わない方が良い

未経験からプログラミング勉強を始める時に本を買った方が良いと思うかも知れません。しかし、プログラミングの場合は、本は買わない方が良いと思います。
(最初に未経験の方向けにポジショントークとなってます。本を愛する方には申し訳ありませんが、お金を払って本を買って失敗してプログラミングを嫌いになるのが残念に思って記事を書いてます。)

# 理由その１
本だとコピペできないから

プログラミングは先ず動かないとおわります動くものを入力して少しずつ修正しながら覚えるのが良いです。
しかし、
本を見ながらソースコードをタイピングしてるとページを開きながら打ち込むは、めちゃくちゃ面倒です。
ページが閉じてしまうし、本に目を移して、ディスプレイに目を移して、ブラインドタッチが出来ない場合は、キーボードも見る必要があります。その結果、打ち間違えたりして、エラーの意味が分からないので、見直しをしても間違いに気づかずに終了してしまいます

# 理由その２
本だと情報が古い！

言語やフレームワーク等は日々バージョンアップされています。しかし、本は発売するまでに時間が掛かります。執筆時間、刊行時間。そーすると新しいバージョンが出てしまいます。新しいバージョンの場合、互換性がなく該当ソースが動かない事が良くあります。その結果、バージョンによって勉強が進まなくなる事がよくあります。

# 理由その３
本だと情報が少ない！

限りがあるため情報が少ない事があります。その結果、躓いた時は結局ネットを調べる事になってします。
これだと高い本を買っても意味がありません。

# 結論
最初に気合を入れてお金を払って本を買っても不便な事も多く、難しいかも知れません。
先ずは無料のサイトやYouTubeで勉強してみましょう。

それで難しいと感じる様であれば、フォローが受けられるスクールが良いのではと思います。
サイトを検索した場合は、なるべく新しい記事を参考にして、バージョンについては注意して確認しましょう！
無料のサイトで勉強して更に詳しく勉強したい場合は、本も非常に良いと思います。

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
【Rails】present?とexists?の挙動を確認し、使い分けの基準を整理する

## 1. present?
- Railsのメソッド
- オブジェクトがある場合はtrueを返す
- present?の反対は、blank?
- 実行するとキャッシュされる


発行されるクエリを見てみると、1回全部の該当レコードをごそっと取ってきていることが分かる
``SELECT "articles".* FROM "articles" WHERE "articles"."title" = ?  [["title", "Test"]]``

```
irb(main):001:0> Article.where(title: 'Test').present?
   (1.6ms)  SELECT sqlite_version(*)
  Article Load (0.2ms)  SELECT "articles".* FROM "articles" WHERE "articles"."title" = ?  [["title", "Test"]]
=> true
```

## 2. exists?
- Railsのメソッド
- SQLのexists式を使う
    - 該当レコードが1件でもあればtrueを返す


発行されるクエリを見てみると、該当するレコードをLIMIT 1で絞り込んでいることが分かる
``SELECT 1 AS one FROM "articles" WHERE "articles"."title" = ? LIMIT ?  [["title", "Test"], ["LIMIT", 1]]``

```
irb(main):002:0> Article.where(title: 'Test').exists?
  Article Exists? (0.2ms)  SELECT 1 AS one FROM "articles" WHERE "articles"."title" = ? LIMIT ?  [["title", "Test"], ["LIMIT", 1]]
=> true
```

## 3. exists?を使うべき時

- 該当のレコード数が何百万件と多い時
    - present?の場合該当する全レコードを取得するため、データが多い場合そこでパフォーマンスの問題が生じる可能性が高い
- キャッシュを使う必要がない時



```ruby
if Article.where(title: 'Test').exists?
 p 'タイトルがTestという記事が存在します！'
else
 p 'タイトルがTestという記事は存在しません'
end

Article Exists? (0.2ms)  SELECT 1 AS one FROM "articles" WHERE "articles"."title" = ? LIMIT ?  [["title", "Test"], ["LIMIT", 1]]
"タイトルがTestという記事が存在します！"
=> "タイトルがTestという記事が存在します！"
```

## 4. present?を使うべき時
- 存在確認後に、キャッシュを使う予定がある時
- 既にキャッシュが存在していて、それが使える時

``articles.present?``で``Article.where(id: 1)``の結果がキャッシュされ、``articles.pluck(:title)``実行時にはキャッシュを使うため、クエリは1回しか発行されない

```ruby
articles = Article.where(id: 1)
if articles.present?
 p "タイトルは#{articles.pluck(:title)}です"
else
 p '該当する記事がありません'
end

Article Load (0.2ms)  SELECT "articles".* FROM "articles" WHERE "articles"."id" = ?  [["id", 1]]
"タイトルは[\"Test\"]です"
=> "タイトルは[\"Test\"]です

```


exists?を使うと、クエリが2回発行されてしまう

```ruby
if articles.exists?
 p "タイトルは#{articles.pluck(:title)}です"
else
 p '該当する記事がありません'
end
  
Article Exists? (0.2ms)  SELECT 1 AS one FROM "articles" WHERE "articles"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 (0.1ms)  SELECT "articles"."title" FROM "articles" WHERE "articles"."id" = ?  [["id", 1]]
"タイトルは[\"Test\"]です"
=> "タイトルは[\"Test\"]です"
```

## 5. まとめ
present?とexists?を使う基準は以下の通り

- exists?：キャッシュを使わない、該当のレコード数が何百万件と多い時
- present?：存在確認後にキャッシュを使う、存在確認前に既にキャッシュがある時



## 参考
https://blog.solunita.net/posts/how-to-check-existing-or-not-in-ruby-on-rails/

https://qiita.com/hirohero/items/bdf893b363274ae74a5e
Blenderチャレンジ：フレームキューブ

3DCGソフトウェアのBlenderを使って、お題のモデルを作成してみましょう。
やり方は一通りではないと思います。あなたは、どんな方法を考えますか？

## 問題

以下のようなオブジェクトを作ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/2cf49c57-7cba-1ce9-189e-50be504f341a.png)

※わかりやすいようにワイヤーフレーム表示にしています。

[完成物をSketchfabで見る](https://skfb.ly/oC6XI)

…
…
…

OK？

---

## 解答例

作成する手順です。macOSのキーを書いています。Windowsの場合は、`Option`を`Alt`に読み替えてください。

- 下記のアドオンを有効化。
    - Auto Mirror
    - Bool Tool

- `Shift + A`（追加メニュー）の「メッシュ」の「立方体」を選びます（以下Cube）。
- 編集モードで面だけ削除。
- 奥の1点を選択し、選択を拡大し頂点を削除。→4頂点が残る。
- 全選択し、`V + Space`で頂点をリップ。
- オブジェクトモードで変換のカーブ。
- カーブのジオメトリのベベルで深度を`0.2`、解像度を`10`。
- 変換のメッシュ。
- 編集モードで`AFP + Enter`。
- オブジェクトモードで`AN`
- サイドバーの編集タブのBool ToolのAuto BooleanのUnion。
    - うまく統合されなかったら2つずつ統合。
    - 編集モードで余計な頂点がないか確認。
- 別のCubeを追加。
- 編集モードで細分化（分割数を`5`、スムーズを`1`）。
- `S.1155`。
- 下図のように1/8の象限だけ残して他頂点を消す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/89de6179-63ff-5e2f-c4b1-9bc4eed29e35.png)

- はまるように移動（各軸の移動距離は`1`）。
- オブジェクトモードで2つのオブジェクトを`Ctrl + J`で統合。
- 編集モードで不要な面を削除し、頂点をいい感じにマージ。
- オブジェクトモードでXYZでAutoMirror。
    - うまくいかなかったら、座標系を逆に。
- 変換のメッシュ化。
- 編集モードで不要な辺を溶解。

## 別解（完全に同じではない方法）

サブディビジョンサーフェスを使うと似たような感じになります。ただし、角付近が若干盛り上がります。

- 立方体（Cube）を追加。
- 編集モードで細分化し、細分化で追加された24辺を選択。
- `Ctrl + B`、`.75S2`、`[Enter]`
- 面モードにし、一番面積の大きい面を選択し、`Shift + G`の面積で、24面を選択。
- `Option + E`の法線に沿って面を押し出しを選び、`-.25`、`[Space]`。
- `X`で面を削除。
- `AM`で「距離で」。
- 点モードにし、XYZのいずれかが0の48頂点を選択。
- `Ctrl + B`、`.75S1`、`[Enter]`
- オブジェクトモードで、サブディビジョンサーフェスモディファイアーを追加し、ビューポートのレベル数を2に。

## ジオメトリーノードの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/bd33cd95-a478-3ae8-e7d9-c9baa0731814.png)

角が`UV Sphere`なので、ちょっと違います。

## 参考

https://www.youtube.com/watch?v=rYUGd6UQwkY

以上
Nuxt / Vue  – 外部のJSOI APIをFetchして v-for で表示するコード例 

# ポイント

dataで変数の器を作っておいてからmoutedで変数に代入する


# コード例

`pages/example.vue`

```vue
<template>
  <ul>
    <li v-for="item in items">
      {{ item.id }} {{ item.title }}
    </li>
  </ul>
</template>

<script>

export default {
  data: () => {
    return {
      items: [],
    };
  },
  async mounted() {
    const data = await fetch('https://jsonplaceholder.typicode.com/todos/')
    const json = await data.json()
    this.items = json
  }
};
</script>
```

# JSON の内容

```json
[
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },
  {
    "userId": 1,
    "id": 2,
    "title": "quis ut nam facilis et officia qui",
    "completed": false
  },
  {
    "userId": 1,
    "id": 3,
    "title": "fugiat veniam minus",
    "completed": false
  },
  {
    "userId": 1,
    "id": 4,
    "title": "et porro tempora",
    "completed": true
  },
...
```

# 表示例

<img width="587" alt="image" src="https://user-images.githubusercontent.com/13635059/210159611-e5368b97-7475-43e0-afa9-cdbe085fef60.png">


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
自分の作ってるAIに意識はあるのかよ？

#
**Googleのエンジニアの悩みはすぐ他人事ではなくなる**

# 意識の仮説がみんな欲しくなる理由

なんで意識の話が急に始まんの？そんな怪しい話、しなくてもいいでしょ？ってのが20世紀の世界観。何もこの世には怪しいものはなく、素粒子は次々と発見され、霊魂も魂もなく、オカルトもなく、科学は平坦に数千年も発展し続けてこの世界はどんどん平和に幸福に、そして便利になる。以上！！

と言うのがちょっと前までの世界や特に日本の感覚だった。

でも、21世紀になりそれは激変した。日本は1990年代から没落を始め、半導体、家電、金融、政治。全てがあれあれという間に落ちまくり、スマホは遅れまくり、貧乏になり、大震災、少子化、おまけにコロナに戦争。世界までおかしくなってダブルで日本人は未来が見えなくなった。

そして科学も激変した。既に量子力学は予測の不全性は隠しようがなくなり、HQFTなどもあって役割を終えつつあり、超弦理論や最近はもうこの世界はホログラフィなんじゃないのとか、何が何だか分からなくなり、ヒッグスボソンは質量の2パーセント、そして宇宙の中では見える質量は5パーセント。って事はこの世のものは宇宙の1000分の1の質量分だけの素粒子からなる。原子核さえ素粒子からなっていてクオークも電子も点だか紐だか、とてつもなく小さく、既にスカスカの範囲を超えてほぼ真空みたいなもの。自分たちは幽霊のようなものと何が違うのか。

その上、ベルの不等式は破れてノーベル賞。いよいよこの世界は非局所が本質。つまり局所性なんてむしろ世界の僅かな部分にしか過ぎない事も分かってきた。

これはもう人類は人類としての「ダニングクルーガー」がやっと終わりに来たのかもな、とか、思ったりもする。幼年期の終わりかもしれないね。

そしてAIはStableDiffusionやらGPT4ももう見えてきてAGI直前。量子テレポーテーションはしまくって、20世紀の世界からいよいよ21世紀は全開。人間の知能をAIが超えることはもう原理的な問題はなく、ほぼ数年から遅くても数十年で約束されてるレベル。

そして、ここで満を持して出てくるのが！？

# 哲学的ゾンビ

そう、哲学的ゾンビさんですよ。何かとごく簡単に言えば、あなたと同じように話し、感情があり、自分が見えている、死ぬのが怖い、と言っている存在、ロボットとかいたとして、実際には見えてない感じてない「もの」まさにゾンビのような存在だ。

これは既にLaMDAが出てきたりで考えてる人も多いと思うが、つまりコンピュータ業界的には

- 自分たちが作ってるハードやソフトには意識があるか？

と、考えたり述べたりする必要がもう発生してきていて、そしてその理由と、もしまだ無いなら、

- じゃあどうやったら哲学的ゾンビでない「存在」を設計して作ることが出来るか？

を言うべき時が来てる訳だ。

自分はゲームの3Dの並列処理のプロセッサ開発もしてたし、そういう中で、脳のびっくりするぐらいの圧倒的な処理性能、低消費電力、そして柔軟に学習する可塑性、半分をなくしてもまだ何とか機能するという超ロバスト性、と言うありえないものが、それこそ満員で車に乗るだけで空間の何パーセントかを占めるような恐ろしい世界が存在してると言うことがひたすらに驚愕だた😱

そして例えば小さい蜘蛛が糸を張るんだけど、それは視覚や触覚からの巣の張れる場所の環境認識、手足の精密な連続した動きでのプログラム的な動き、こんなもの、いまだにどれだけのハードとソフトと開発期間があれば作れるか、みたいな。

つまり脳は、ありえない性能と、そし意識という「存在」と言うトンデモにしか見えないモノまである、現代科学をはるかに超えた存在なんだけど、普通の地球上の物質だけでいくらでも出来てるし、よしんば勝手に増えるし数年で「モノゴゴロ」。付いてしまう。自分もモノからいつの間にか自分になっていた🤔👽

これを考えると人間のコンピュータなんてどれだけのおもちゃなんだって話なんだよね。

でもそれがやっと「自分は電源を切られるのは怖いです」とか、録音でなくて言い出すぐらいまでには来た。だから自分たちのAIは哲学的ゾンビなのかそうでないのか、そうでないならどうやったら作れるか、を考えなきゃと言うこと。

前置き長いな。

で、先の話と絡んでくる訳だ。意識の発生が物理的なものだという過程と機序が分かれば、少なくても仮定できれば、意識の存在のあるなし答えを準備し、そしてそれを作る、ことも可能になるだろう、という事だ。

# じゃあ今のAIには意識はあるか？

で、これはどうなんの？偉そうなごたく並べて。わかお前に分かるのか？言ってみなよ？って事だよね。

で、先の議論からの続きとして考える訳なんだか、答えは

**明確にノー**

だよ。

それはつまり、

**意識発生の機序のための「機構」「物理現象」が今のAIには存在していないから。**

以下少し説明しよう。

デジタルな世界には「量子カオス」発生しないから(厳密には細切れのローカルな領域にしか発生しない)。「量子カオス」が無いから、「量子もつれ」の発展した「常温BEC」が発生しない。常温BECが無ければ、非局所的な繋がりは発生せず、反応は「局所的」となり、「高次元での繋がった情報空間が発生しない。」だから今のAIには意識が発生しない事がすぐに導き出せる。

意識に「非局所性」があり、「実在の情報空間」と、考えれば、それを発生する機序がない所には意識は発生しない。当たり前の話だ。今のAIの処理、CPU、GPUでは「量子カオス」はグローバルには起こらない。デジタル回路はグローバルな繋がりを排除することで正確性を担保してるからだ。情報処理は本来難しいから、制御性を最大限に高めるためにこそ、意図的にローカルでデジタルな動作にしたんだ。だからこの量子カオスができないのは当然なんだよね。

まだ説明足りないと思ってる。本当は何百ページも書かないといけない。まあ今年かけてじっくり空いた時間に書いていくよ。

ちょっとだけ補足。思い出して欲しいのは「あなたや私の脳の中ですら、意識のある情報処理と、無意識の情報処理がある」という事。そして意識の情報処理が行われているからこそ「そこでだけ意識が発生する」という事だよ。

 # 今回の結論

という事で、新年早々、究極の「人工存在」に向けた第1歩の話を初めてしまったよw

でも意識が何かが分かれば、機序が分かれば、情報処理装置の「意識のあるなし」の判定と、「それぞれの装置の開発」が原理的に可能になる、事はわかって貰えると思う。怪しい話も「作るため」にしたいんだよね。

お分かりだろうか？？(CM入る🤤)
Pythonで子クラスの親クラスを取得する方法

# 概要

Pythonで子クラスの親クラスを取得するには、「inspectモジュール」を用います。Inspectモジュールは、Pythonインタプリタ内で実行されるオブジェクトの情報を取得したり、ソースコードを読み取ったりするライブラリです。Inspectモジュールを使用すると、子クラスの親クラスを取得することができます。

# 使用例

以下の例では、Inspectモジュールを使用して、子クラスの親クラスを取得しています。

```python
import inspect

class ParentClass:
    def parent_function(self):
        print("Parent Function")

class ChildClass(ParentClass):
    def child_function(self):
        print("Child Function")

# 子クラスの親クラスを取得
parent_class = inspect.getmro(ChildClass)

# 取得した親クラスを出力
print(parent_class)
```

上記のコードを実行すると、次のように表示されます。

```
(<class '__main__.ChildClass'>, <class '__main__.ParentClass'>, <class 'object'>)
```

このように、Inspectモジュールを使用することで、子クラスの親クラスを取得することができます。
トランプのシャッフルと位数の関係について

### トランプのシャッフルは何回で元に戻る？

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/5b37e29d-a754-300d-9a8f-9b41a19ab171.png" width=40%>

トランプのシャッフルの中でもよく使われる[リフルシャッフル](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB_(%E3%82%AB%E3%83%BC%E3%83%89)#%E3%83%AA%E3%83%95%E3%83%AB%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB)ですが、これを完全に1枚ずつ交互に混ぜる方法をパーフェクトシャッフルと呼ぶようです。これを繰り返すと何回のシャッフルで元に戻るかは色々紹介されていますが、簡単にまとめると、

```math 
上からk番目(一番上を0とする)のカードが\\
シャッフルでf(k)番目に移るとすると\\

\begin{equation}
f(k)= \left \{
\begin{array}{l}
2k　\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (上半分) \\
2k-(N-1)　(下半分)
\end{array}
\right.
\end{equation}
```

```math
両辺の\mod{(N-1)}を取ると場合分けがなくなって、\\ \\
\\
f(k) \equiv 2k \pmod{(N-1)}\\
```
```math

これをs回繰り返す関数をf^s(k)とすると\\

f^s(k) \equiv  2^sk \pmod{(N-1)} \\

よってs回シャッフルで元に戻る条件は　\\
 \large 2^s \equiv 1 \pmod{(N-1)} \ 　\cdots (1)　\\
を満たす最小のsが求める数となります。
```
### 元に戻る回数と位数の関係

式(1)を見てピンと来た方もいると思いますが。これはまさに **「法(N-1)における２の位数」** の定義になります。参考のために[「位数の性質と原始根の応用」](https://manabitimes.jp/math/905)から位数の定義を引用します。

```math
\cdot \ a^n \equiv 1 \pmod p となる最小の正の整数nを法pにおけるaの位数と呼びます。
```

### sympyのn_orderで位数を求める

位数の求め方は色々あると思いますが、sympyには既にn_orderという関数がありますので、これを使ってN=52の時の位数が8なので、 **8回** で元に戻ることが分かると思います。

```python 
from sympy import  n_order
print(n_order(2, 52-1))
# 8
```
同様にN＝2~52の偶数に対して位数を求めてみました。8回で元に戻るのは他にN=18の場合があるのが分かります。次なる疑問として他にはないのかというのが気になります。

```python 
from sympy import  n_order

print([n_order(2,(n-1)) for n in range(2,52+1,2)])
# [1, 2, 4, 3, 6, 10, 12, 4, 8, 18, 6, 11, 20, 18, 28, 5, 10, 12, 36, 12, 20, 14, 12, 23, 21, 8]
```

### 8回で元に戻る枚数をすべて求める

ループの上限を増やせば分かりそうですが、闇雲にチェックするのは効率的ではありません。そこで式(1)を以下のように変形します。

```math 
 2^s - 1 \equiv 0 \pmod{(N-1)} \ 　　\\
(2^s - 1)が(N-1)で割り切れるので\\
(N-1)は(2^s - 1)の約数となる
```

$(2^s - 1)$の約数に対して2の位数をチェックすれは良いことになります。

```python
from sympy import divisors,n_order
s = 8
for d in divisors(2**s-1):
  print(d, n_order(2,d),d+1)
#1 1 2
#3 2 4
#5 4 6
#15 4 16
#17 8 18
#51 8 52
#85 8 86
#255 8 256
```
2の位数が8になるのはN=18, 52, 86, 256の時でこれらがすべてであることが分かりました。

（開発環境：Google Colab）

この考え方はProject Euler, Problem 622:Riffle Shufflesを解くのに役に立ちます。
wslでelixir その9

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
mixで実行ファイルは、どうすんだろ。

# mixで実行ファイル作る手順。

# プロジェクトを作る。

$ mix new hello

# def mainを実装する。

```
	def main(args \\ "") do
		IO.puts("ok")
	end
```

# mix.exsに追加する。

```
			escript: [main_module: Hello],

```

# ビルド。
$ mix escript.build


# 実行

$ ./hello

# 実行結果

```
$ ls
README.md  _build  hello  lib  mix.exs  test

$ ./hello
ok
```


以上。
シェル芸（Bash）で解くAtCoderの問題n選

# はじめに

シェル芸（Bash）で解くことができるAtCoderの問題を紹介します。

# 本題の前に

AtCoderに初めて触れる方は、こちらの記事も参考にしてくださいませ。

https://qiita.com/ykpages/items/3d7c6a90f73a4f2f82b0

# AtCoder Beginner Contest （ABC）

初心者向けコンテストである「ABC」の問題から紹介していきます。

## ABC 002 B - 罠

まずは簡単な問題からどうぞ。

文字列が与えられるので、そこから母音を除去する問題です。

https://atcoder.jp/contests/abc002/tasks/abc002_2

私の回答。

https://atcoder.jp/contests/abc002/submissions/37627581

## ABC 003 C - AtCoderプログラミング講座

問題文はややこしいですが、シェル芸なら簡単に解けますね。

出力する値の精度に気をつけてください。

また、標準入力は```read```で受け取れます。

https://atcoder.jp/contests/abc003/tasks/abc003_3

私の回答。

https://atcoder.jp/contests/abc003/submissions/37630868

## ABC 004 B - 回転

まさにシェル芸の出番です。

入力を180度だけ回転させて、出力しましょう。

https://atcoder.jp/contests/abc004/tasks/abc004_2

私の回答。

https://atcoder.jp/contests/abc004/submissions/37632245

## ABC 008 B - 投票

シェル芸の定番問題です。

```uniq -c```でカウントしてあげましょう。

https://atcoder.jp/contests/abc008/tasks/abc008_2

私の回答。

https://atcoder.jp/contests/abc008/submissions/37635015

## ABC 009 B - 心配性な富豪、ファミリーレストランに行く。

問題文は長いですが、やることは簡単です。

https://atcoder.jp/contests/abc009/tasks/abc009_2

私の回答。

https://atcoder.jp/contests/abc009/submissions/37635133

## ABC 011 B - 名前の確認

```sed```で置換してあげましょう。

https://atcoder.jp/contests/abc011/tasks/abc011_2

私の回答。

https://atcoder.jp/contests/abc011/submissions/37646797

# おわりに

随時更新予定です。

シェル芸とAtCoderとAtCoder Problemsに感謝を。

いつもありがとうございます。

楽しいです。

# ブログの移転

新しくブログを始めました。AtCoder関連の記事もあります。

https://yusukekato.jp/20230420.html
【再挑戦】UnityでSpeechRecognizer（Android）を試す①

 AndroidのSpeechRecognizerを使ってUniryで動かす方法について
細かい解説記事を見つけたので、チャレンジしてみます。

https://edom18.hateblo.jp/entry/2018/03/21/175104

## Android Studio でファイルを生成
記載の記事に従って、aarファイルを作成後
UnityにもってきてC#コードで呼び出します。

https://edom18.hateblo.jp/entry/2018/03/20/200243

Javaは初めて触ったのですが、C#に似ていてわかりやすくあるものの
Dialogでの表示であるため、恐らくここでOculusにもってきたときに上手く動かないのかな
とあたりをつけはじめました。

## 構成に詰まる
AndroidでUnityのファイルを指定するためにclassファイルを投げ込む＆適用する必要があるようですが、上手く入れ込めず。

![dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/d3f27266-8a95-eb14-53ec-b6c178d353d7.png)

https://indie-du.com/entry/2016/12/09/203000

今日はここまで...
[WearOS] Androidアプリ開発との相違点

## :speaker: 今回話すこと 
- Androidアプリ開発とWearアプリ開発との相違点について

## :thinking: Androidアプリ開発との相違点
###  :ok_woman: 同じところ  :ok_woman: 
#### AndroidStudioで開発できる
エミュレーターもWearOS端末で実行できるので、実機がなくても実行は出来ます。
ワイヤレスデバックにも対応しています。

AndroidのエミュレーターとWearのエミュレーターを接続することも出来ます。

#### Jetpackライブラリを使用できる
Jetpackライブラリなどが使える点で、Androidエンジニアとしての知識がそのまま活用できます。
そのため、ViewModelやFlow, Hiltなどを用いたAACベースのアーキテクチャを採用できます。
また、UIもViewベースでの書き方とComposeベースの書き方両方あるので、特に変わりはないです。

#### OSのバージョンが対応されている
同じである点か微妙ですが、一応。
AndroidのAPIレベルと対応されています。
WearOS2.0はAPIレベル25~28をターゲットとし、サポートするには、minSdk25に設定します。

#### 通知機能は共有される
モバイルアプリの通知機能は、WearOSでも同期されるので新しく実装する必要はありません。

#### Play Consoleからリリースする
アプリの配布形式がAPK/AABなのでこの点は同じです。

### :no_good:   違うところ :no_good:  
#### 特定のUXに特化したUIにする
画面が小さいので、やることを出来る限り一つか二つに絞るのが重要です。
また、操作も短時間で終了できるようにUIを設計する必要があります
下記のように一画面で確認/選択が出来るようなUI/UXが好ましいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599059/30703e3b-06b8-0005-f9fa-15a8dce0ba65.png)

#### さまざまなサーフェスが使える
ここでいう、サーフェスとはアプリのUIの種類の事を指しています。

#### インストールは別
中には既にAndroidアプリをリリースしていて後からWearOSに対応したアプリをリリースするケースがあると思いますが、WearOS2.0以上の場合別のAABファイルで審査に出してユーザーにインストールしてもらう必要があります。

#### ナビゲーション
バックスタックによる画面遷移のネストは二階層までが推奨されています。
もしくは、横並びのリニア形式での画面遷移が必要とされています。

#### ヘルスサービス機能が使える
これは、WearOs独自の機能です。

#### 常にダークモード
節約を考慮してダークモードのみ対応となっています。


## まとめ
やはり、AndroidをベースとしたOSともあってAndroidアプリ開発で得た知識がそのまま活用できるとなと感じました。

もっと相違点はあると思うので、皆様のコメントや今後のキャッチアップで追記していきたいと思います。

## 参考
https://developer.android.com/training/wearables/wear-v-mobile?hl=ja

https://www.youtube.com/watch?v=o0HhsnVAGNA&t=1978s

https://github.com/android/wear-os-samples
GitHub Actionsを使ってGitHubのPRのラベルを自動生成しよう！

## 概要
プロジェクトによって使用しているラベルの色や名称がバラバラだと困るかと思います
そのため、ラベルの運用を統一すべきだと私は考えています
今回は手動で作成せずにラベルを自動生成及び定期的に更新できるようGitHub Actionsを使って自動化したいと思います

## 使用するAction
今回はlabel-syncerを使用します

https://github.com/micnncim/action-label-syncer

## workflowを書いてみよう
今回作成するファイルは
- .github/worklfows/label-syncer.yml
- .github/labels.yml

の2種類です
```
tree
.
└── .github
        ├──workflows
        │     └──label-syncer.yml
        └──labels.yml
```

label-syncer.ymlにラベルを自動生成するワークフローを作成します
また、チェックアウトについて詳しく知りたい方は以下の記事を参照してください

https://qiita.com/shun198/items/14cdba2d8e58ab96cf95

```.github/worklfows/label-syncer.yml
name: Sync labels

on: pull_request
jobs:
  build:
    name: Sync labels
    runs-on: ubuntu-latest
    steps:
      # リポジトリのチェックアウト
      - uses: actions/checkout@v2
      # label-syncerを使用
      - uses: micnncim/action-label-syncer@v0.3.1
        env:
          # GITHUB_TOKENはデフォルトで使用できるため、secretsへの追記は不要
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          # .github/labels.ymlに自動生成するラベルの設定を記載
          manifest: .github/labels.yml
```

ラベルの設定を行います
ymlファイルに
- 色
- 説明
- ラベル名

を指定します
```.github/labels.yml
- color: d73a4a
  description: Something isn't working
  name: bug
- color: 0075ca
  description: Improvements or additions to documentation
  name: documentation
- color: a2eeef
  description: New feature or request
  name: enhancement
- color: b60205
  description: An urgent pull request to look
  name: emergency
- color: f9d0c4
  description: Refactor Code
  name: refactor
- color: 1d76db
  description: Test Code
  name: test
```

## ラベルを確認してみよう！
ラベルの初期設定は以下の通りです
![スクリーンショット 2023-01-01 6.26.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/2560e3f8-9d3a-dc00-e0d8-7cf2eb077036.png)

先ほど設定したラベルに変更されていることが確認できました！
![スクリーンショット 2023-01-01 6.28.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/0cd22b2b-d355-27b0-bcd1-62fb285e1bde.png)

## ラベルの更新を決まった時間に定期的に行うには？
ラベルの作成及び更新は初回に作成する以外頻繁に変えるものではないので
下記のようにcronを使って例えば毎週月曜日朝9時に更新する運用をしてもいいかと思います

```.github/worklfows/label-syncer.yml
name: Sync labels
on:
  schedule:
    - cron: "0 9 * * 1"
jobs:
  build:
    name: Sync labels
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: micnncim/action-label-syncer@v0.3.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          manifest: .github/labels.yml
```

schedule及びcronの使い方は以下の公式ドキュメントを参照してください

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#scheduled-events

## 記事の紹介
下記の記事も書きましたのでよかったら読んでみてください

https://qiita.com/shun198/items/15d8947a1a5642154392

## 参考
https://github.com/micnncim/action-label-syncer

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#scheduled-events

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07
【車輪の再発明】Enum.reduceを使ってEnum.all?のテストプログラム作成する　


「【車輪の再発明】Enum.reduceを使ってEnum.all?を作ってみよう」
のテストプログラムを作りたいと思います

https://qiita.com/t-yamanashi/items/54f0583b7f513202c9cc

ルール
　・ぶっちゃけ本物の関数と比較すればよい
　・テストパターンはたくさん書くべきだけど、テスト化するのが目的

# テストプログラム

```Elixir:test/hoge_test.exs
defmodule HogeTest do
  use ExUnit.Case
  doctest Hoge

  params = [
    [true, 1, "s"],
    [true, nil, true],
    [true, 1, false],
  ]

  for param <- params do
    @param param
    test "Hoge.all?/1 param #{inspect(@param)}" do
      assert Hoge.all?(@param) == Enum.all?(@param)
    end
  end

  params = [
    [2, 4, 6],
    [2, 4, 5]
  ]

  for param <- params do
    @param param
    test "Hoge.all?/2 param #{inspect(@param)}" do
      fx = fn x -> rem(x, 2) == 0 end
      assert Hoge.all?(@param, fx) == Enum.all?(@param, fx)
    end
  end
end
```

# 課題

```Elixir
　fx = fn x -> rem(x, 2) == 0 end
```

の部分がパラメータ化できてない