OmniAICreator/Qiita-1.07M huggingface dataset:
javaのプロジェクト管理を学ぶ：そもそもビルドって何？

#java プロジェクト管理を学ぶ：そもそもビルドって何？

### 【超初心者向け】Maven超入門
https://qiita.com/tarosa0001/items/e5667cfa857529900216


### そもそも、ビルドとは

- ビルドとは、**「ソースコードに問題（バグ）がないか解析を行い、問題がなければ実行できる形のファイルに変換し、組み立てること」**

  - コンパイルとの違い：コンパイルはビルド作業の中に含まれる作業の1段階
  - コンパイル： プログラミング言語から機械が分かりやすい機械語に翻訳を行うことを指す。

- **ビルドの仕組みと流れ**
  - 1.各ソースコードの静的解析を行う。静的解析では、文法や構文の誤りを検出する（バグを見つける処理）
  - 2.プリプロセッサで前処理を行う。定数の数値への置き換えやコメントの削除、マクロ(複数の操作をまとめて呼び出せるようにする機能)の展開
  - 3.各ソースコードのコンパイルを行う。機械語に翻訳し、オブジェクトファイル(.o や.objなど)に変換する。
  - 4.各オブジェクトファイルとライブラリをリンクする。全ての部品をリンクすることで、最終的に「実行ファイル」が完成する。
 
![](2021-12-09-16-56-42.png)

---

### Mavenとは

- Mavenとは、プロジェクト（コードやリソースの集まり）をビルドしてアーティファクト（成果物）を得るためのツールです。
  - xmlを書くことで、機能：コンパイルの前後に依存するライブラリを自動でそろえる
  - ソースコードのコンパイルに加えて、コンパイルに必要なJARファイルを探したり・
  - ユニットテストを実行したり・
  - ビルドしたJARファイルを 公開したり

  - またMavenは「テストの前にコンパイル」「JARファイル作成の前にテスト」といった  **ビルド・ライフサイクル （作業の順番）**
  - 「依存元の前に依存先をビルド」といった 依存関係 をきちんと考えてビルドしてくれる

https://github.com/KengoTODA/what-is-maven/releases/download/v2021.11.09/what-is-maven.pdf


#### pom.xmlとは

Maven の設定は pom.xml という XML ファイルで記述する。
POM は、 Project Object Model の頭文字を取った略となっている。

Maven はビルド対象をプロジェクトという単位で管理する。
POM は、そのプロジェクトについての様々な設定を記述するためのファイルとなる。

★Mavenの優れている点は、依存関係の解決


---
```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...

  <dependencies>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.9</version>
    </dependency>
  </dependencies>
</project>
```

- ```<dependencies>``` の下の ```<dependency>```が、１つのアーティファクトを指している. 

- このように宣言すると、 Maven はプロジェクトをビルドするときに自動的に ```<dependencies>``` で宣言したアーティファクトをリモートリポジトリからダウンロードしてきてくれて、クラスパスに追加してくれる  => **ライブラリを手で落としてくる手間が省ける**

- さらに、リポジトリに格納されたアーティファクトには、それ自身の pom.xml も格納されている
もしプロジェクトで指定したアーティファクトの pom.xml に、さらに ```<dependencies>``` があった場合、 Maven はその依存アーティファクトも自動的にダウンロードしてくれる => **芋づる式にすべての依存関係を解決してくれる仕組み**

- Maven は、この仕組みのおかげで **依存ライブラリの管理が非常に楽** になった
  Maven の前身である Apache Ant は依存関係を手動で管理しなければならかったので、非常に辛かった
  この仕組みは、 Maven の後発である Gradle でも利用されている


https://qiita.com/opengl-8080/items/bb32732f9aa5cb3495d2#pom




### 参考にした記事一覧

   「ビルド」機能とは？仕組みやコンパイルとの違いを解説
https://proengineer.internous.co.jp/content/columnfeature/6308
Unity2018.4 Android対応その２


前回はjdk11を差し替えことで問題解決しました、今回はgradleを更新するの解決方法を紹介します。


facebook-loginやline-loginを依存する時は
Target APIはAPI LEVEL 31(Android12)を選択してビルドするとエラーが出ました。

```
An exception has occurred in the compiler (1.8.0-adoptopenjdk). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable$NameImpl)
```

### Gradleを6.1.1へアップデート


https://gradle.org/releases/

ここから6.1.1のバイナリをダウンロード。
zipを解凍

※ unity2018.4.24f1以前
/Applications/Unity/Hub/Editor/2018.4.22f1/PlaybackEngines/AndroidPlayer/Tools/gradle を置き換え。

※ unity2018.4.24f1以後
Preferences > External Tools > Android > Gradle Installed with Unity.でパスを指定します

UnityのPlayerSettingsのPublishing Settings/Build/Custom Gradle Template にチェックを入れる。mainTemplate.gradleを修正

```
buildscript {
    repositories {
        mavenCentral()
        google()
        jcenter()
    }
 
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.1'
**BUILD_SCRIPT_DEPS**}
}
```
Android SDK Build-Toolsは31をアンインストール、30.0.3をインストールします。

gradleOut.aab does not existのエラーが出てます

```
Android PostProcess task "Exporting project" took 269.852 ms
DisplayProgressbar: Building Gradle project
FileNotFoundException: Temp/gradleOut/build/outputs/bundle/release/gradleOut.aab does not exist
```



mainTemplate.gradleを修正

```
android {
    compileSdkVersion **APIVERSION**
    buildToolsVersion '**BUILDTOOLS**'
 
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
 
    defaultConfig {
        minSdkVersion **MINSDKVERSION**
        targetSdkVersion **TARGETSDKVERSION**
        applicationId '**APPLICATIONID**'
        ndk {
            abiFilters **ABIFILTERS**
        }
        versionCode **VERSIONCODE**
        versionName '**VERSIONNAME**'
        tasks.whenTaskAdded { task ->
            if (task.name.startsWith("bundle")) {
                def renameTaskName = "rename${task.name.capitalize()}Aab"
                def flavor = task.name.substring("bundle".length()).uncapitalize()
                tasks.create(renameTaskName, Copy) {
                    def path = "${buildDir}/outputs/bundle/${flavor}/"
                    from(path)
                    include "gradleOut-${flavor}.aab"
                    destinationDir file("${buildDir}/outputs/bundle/${flavor}/")
                    rename "gradleOut-${flavor}.aab", "gradleOut.aab"
                }
 
                task.finalizedBy(renameTaskName)
            }
        }
    }
```
遅延評価セグメントツリーのインデックス取得について

# はじめに
Atcoderの典型90問の[遅延評価セグメントツリーの実装](https://github.com/ryusuke920/kyopro_educational_90_python/blob/main/solve_python/029.py)のgindex (特に補数操作) が分からなかったので考えてみた。
元問題: [Long Bricks](https://atcoder.jp/contests/typical90/tasks/typical90_ac)

# 躓いた部分
```.py
# https://github.com/ryusuke920/kyopro_educational_90_python/blob/main/solve_python/029.py
# l34 ~ l48
    def gindex(self, l, r):
        l += self.num
        r += self.num
        lm = l >> (l & -l).bit_length()
        rm = r >> (r & -r).bit_length()
        while l < r:
            if l <= lm:
                yield l
            if r <= rm:
                yield r
            r >>= 1
            l >>= 1
        while l:
            yield l
            l >>= 1
```
セグメントツリーを知らない僕はこのインデックス取得関数の意味が分からなかった。セグメントツリーについて調べてみたところ ([Segment Tree のお勉強(2)](https://maspypy.com/segment-tree-%E3%81%AE%E3%81%8A%E5%8B%89%E5%BC%B72)) 、どうやら底辺のクエリを指定した時に、対応する上方の区間を出力するイテレータとして機能しているようであった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321042/66157fa3-d6d8-f8a3-bd7d-223473dd1304.png)

コードでは、区間[l, r)とし、上図のピンク色のブロックを順に出力するための関数であると考えられる。以下、コードの上からレビューする。

# 1. lm = l >> (l & -l).bit_length() について
rm = r >> (r & -r).bit_length() も同様。そもそも、x & -x は何を表しているのだろうか？[2の補数とは？2の補数の計算方法と表現範囲をわかりやすく解説！1の補数との違いは？](https://agency-star.co.jp/column/2-complement) によると、x & -x は、xを２進数で表したものと、そのビットを反転させて、1を足したもののビット積である。以下4ビットの場合の例を挙げる。

- 例 x = 1 の時
<br>xは0001、-xは負の数なので4ビット目は1。3ビット目を1に2ビット目を1に、1ビット目を0に反転させて1110。これに1を加えて、1111。各ビット位が共に1である部分に着目して、x & -xは0001。よって、10進数に戻すと x & -x = 1

同様に

- x = 2 の時
<br>xは0010, -xは1110, x & -x は0010。よって、x & -x = 2。
- x = 3 の時
<br>xは0011, -xは1101, x & -x は0001。よって、x & -x = 1。
- x = 4 の時
<br>xは0100, -xは1100, x & -x は0100。よって、x & -x = 4。
- x = 5 の時
<br>xは0011, -xは1101, x & -x は0001。よって、x & -x = 1。
- x = 6 の時
<br>xは0110, -xは1010, x & -x は0010。よって、x & -x = 2。
- x = 7 の時
<br>xは0111, -xは1001, x & -x は0001。よって、x & -x = 1。
- x = 8 の時
<br>xは0100, -xは1100, x & -x は0100。よって、x & -x = 8。

***ビットの反転操作により、0と1の値が反転してしまうが、その後に1が加わるため、繰り上がりが起こり、反転前と同じ位で1になるような場所が生まれる。一般化すると、ある数 x をビット表記をした時に、右側から数えて初めて1になるような位が右からN番目の位であるとする。これを反転させた時、N番目の数は0となり、N番目より右側は1が連続し、N番目より左側は各位反転された数が連続する。これに1を加えると、繰り上がりが発生しN番目より右側は0となり、N番目は1となりここで繰り上がりが止まる。したがって、元の数のビットと比較するとN番目の位の数のみが共に1となる。よって、x & -x = 2 ^ (N-1) である。***
「ビット表記をした時に、右側から数えて初めて1になるような位が右からN番目の位である」ような数は、10進数において、[奇数]× 2^(N-1) の形で表せられる数である。x & -x = 2 ^ (N-1) より、x & -x は x を奇数と2の累乗数で因数分解した時の2の累乗数を表している。
再びlm = l >> (l & -l).bit_length()に戻って考える。(l & -l).bit_length() はl & -l のビット長、つまり上の説明で言うところのN-1である。N-1 だけ l のビットを右にシフト (>>) するということは、2^(N-1)で割ることと同義であり、lm は[奇数]× 2^(N-1)と因数分解したときの[奇数]を表している。言い換えると l を2で割っていって最初たどり着く奇数である。

# 2. while l < r:及びwhile l:
yieldというのはreturn同様返り値の出力であるが、yieldはイテレータとして働き、呼び出され代入をする度にwhile文が回転し新しい値を出力する。if l <= lm: という条件により、無駄な出力を防いでいる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321042/66157fa3-d6d8-f8a3-bd7d-223473dd1304.png)
上図のように、左側に (l) については奇数を、右側 (r) については、偶数を出力しなくてはならないはずである (l:45,23,3 r:38,18,8)。これについては、イテレータを受け取った後に -1 など処理することで帳尻を合わせている。

# 最後に
これからも遅延セグ木について詰まったら記事に追加していく。
リアルタイムの会話も倍速で聞きたい

この記事は [クソアプリアドベントカレンダー2](https://qiita.com/advent-calendar/2021/kuso-app) の5日目の記事です。これを書いている今は実は12/9なのですが、現時点で枠がまだ空いていて、衝動的につくりたいクソアプリを思いついたので急遽参加させていただきました。

ちなみに先日はこんなクソアプリで参加させていただきました。

https://qiita.com/shu223/items/9bf0f24058665ec2fc6e

## もはや「リアル」は遅い

Podcastなどの音声コンテンツでは1.5xや2.0xでの倍速再生が普通で、たまに間違って1.0xで再生すると「あれ、Miyagawaさん今日は眠いのかな？」などと感じてしまったりするのはあるあるかと思います。YouTubeではそもそもジェットカットなんて用語もあるぐらい「間」を極限まで減らす編集が好まれる上に、やはり倍速再生している人が多い印象です。最近ではついにはNetflixでも倍速再生が可能となり、映画やドラマも倍速で鑑賞する時代になってきました。

一方で、リアルタイムの勉強会やパネルディスカッション、Zoomでの会議中に、等速で行われる会話の遅さにやきもきしたことはないでしょうか。

もはや我々には**リアルは遅すぎる**のです。

## 「倍速マイク」というiOSアプリをつくった

### しくみ

- AirPodsとかのノイズキャンセリングイヤホンを装着して使う（実際の話し声が直接聴こえてしまわないように）
- iPhoneのマイクから入力された音から、**無音区間やノイズといった人の声「以外」の音を除外しつつ**バッファリング `（※）`
- ある程度たまったら倍速再生する



`（※）` ごめんなさい、今回のクソアプリでは時間の都合でこの無音区間除去までは実装できませんでした🙇🏻‍♂️

ただ同等の処理（無音区間やノイズといった人の声「以外」の音を除外）を弊アプリ「Chopper」では**実装済み**なので、フィジビリティ的には問題ありません。

https://twitter.com/shu223/status/1440276985075290120

https://twitter.com/shu223/status/1440281660243673092



### 実装のポイント

- 録音は `AVAudioEngine` を利用

https://note.com/shu223/n/n229dedcb581c

- 録音しつつ再生もするので、`AVAudioSession` で `playAndRecord` カテゴリーをセット。`allowBluetooth` も忘れずに。

```swift
try! AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: .allowBluetooth)
```

- 倍速再生中も音を録音できるよう、ダブルバッファ化

  - バッファ1を倍速再生中、バッファ2に録音

  - バッファ2を倍速再生中、バッファ1に録音

- 発話区間の判定にはSound AnalysisのSound Classificationを利用する
  - `speech`に分類された区間だけをバッファに`write`する

https://zenn.dev/shu223/articles/soundanalysis-builtin

- 無音区間の判定には `vDSP` を利用する

https://note.com/shu223/n/nc65fbc626a3b



## 使ってみた所感

すみません、デモ動画はないしUIも何もないのでスクショも意味ないし録音された音声ファイルもただの音声だしで何もお見せできるものがないのですが、本当につくって一応人と会話してみました。（ちょうど近くにいた[@ku_suke](https://twitter.com/ku_suke)氏に相手になってもらった）

「ある程度たまったら倍速再生」の挙動としては今は `10秒` たまるごとに `2x` で再生するようにしました。



作る前から想像していたことですが、まぁ会話では実用的では**ない**です。

再生と再生の間が結局手持ち無沙汰になるし、キャッチボールにならないし。



ただ、完全に非実用的なクソアプリかというと、実用的な場面も**ある**とは思います。

**自分が一方的に聞く立場（反応する必要がない）**場面では、バッファリングする時間をかなり大きめにして、無音区間や非発話区間をがっつりカットすれば、かなり時短になり、十分実用的だと思われます。
CIDR表記で書かれたIPをネットワークアドレスに変更するpythonプログラム

```python
import ipaddress
import os
current_dir = os.getcwd()
read_file_name = '/NWアドレスに変更前.txt' 
output_file_name = '/NWアドレスに変更後.txt'

read_file = current_dir + read_file_name
output_file = current_dir + output_file_name

before_ip_list = []
after_ip_list = []
with open(read_file, mode='r') as f:
    before_ip_list = f.readlines()

for ip in before_ip_list:
    ip = ipaddress.ip_interface(ip.replace('\n', ''))
    after_ip_list.append(ip.network)


with open(output_file, mode='w') as f:
    for ip in after_ip_list:
        f.write(str(ip))
        f.write('\n')
```
##使い方
本pythonプログラムと同じフォルダに以下２つのファイルを作成し、プログラムを実行
NWアドレスに変更前.txtとNWアドレスに変更後.txt

##使用例
```:NWアドレスに変更前
192.168.0.155/24
192.168.0.155/25
192.168.0.155/26
192.168.0.155/27
192.168.0.155/28
192.168.0.155/29
```

```:NWアドレスに変更後.txt
192.168.0.0/24
192.168.0.128/25
192.168.0.128/26
192.168.0.128/27
192.168.0.144/28
192.168.0.152/29
```
さくらインターネットのVPSにRockyLinux 8をインストールする（2021/12頃）

# はじめに
2021年12月時点での、さくらインターネットのVPSにRockyLinux 8サーバーを構築する手順の備忘録。初期OSとしてRockyLinux 8は選択できないのでOS再インストールが必要となる（このため再インストール時にストレージを全部削除する手順が必要になる）。

# 手順
1. VPSサーバーを作成　※すぐ壊すのでOSは何でも可
2. サーバー作成後、サーバー管理画面でサーバーを選択して「OS再インストール」―「カスタムOS」―「RockyLinux8」を選択して「内容確認」―「OS再インストール」－「VNCコンソールを起動」
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/d80184a4-cbe6-4d21-c941-676468b5b738.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/4f2e75e6-ebf9-c360-4d9e-ceffd1c3e2bd.png)
<br>※このOS再インストール時に何度かに一回エラーが出てインストールが進まないことがあったので、その場合は電源操作で強制停止した後、（少し待ってから）もう一度OS再インストールを実行する
3. VNCコンソールを表示し、INSTALLATION SUMMARY画面が表示されたら以下の順で順次設定し、すべて終えたらBegin Installationをクリック![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/7483de7f-5893-761e-4939-e6baa2947513.png)

|大項目|項目名|設定内容|
|---|---|---|
|SYSTEM|Installation Destination|1. Custom にチェックをいれて左上の Done![03-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/59c21714-c12a-e175-dece-0d1a84671c2d.png)<br>2. インストールしたOSとUnknownのパーティションをすべて削除（領域を選択して－をクリック![03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/21f871d0-9738-0774-209c-f78a83fa98cb.png)<br>3. New mount～でStandard Partitionを選択し、Click here to～をクリック![03-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/69a7e648-c415-13bc-ad34-3db7ca18e536.png)<br>4. 必要があればパーティション変更（筆者は/homeを削除してすべて/に変更した）![03-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/55ebfed6-92eb-4045-dc04-6eaf54f2a069.png)<br>5. Done－Accept Changes![03-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/72b69630-ca8c-d343-15cc-8a36466d197f.png)|
|SYSTEM|Network & Host Name|必要ならホスト名を適当に変更|
|SOFTWARE|Software Selection|左はMinimal Install、右はDevelopment Toolsをチェック（必要ならその他もチェック）してDone![03-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/48bd6eeb-dffe-ecea-860f-b597ec95c3f8.png)|
|LOCALIZATION|Language Support|左は日本語、右はチェックしてDone![03-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/5319faf0-08db-8d05-8911-e6e8db3b4b89.png)|
|USER SETTINGS|Root Password|適切なパスワードを設定してDone![03-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75240/60bc4e38-547f-984b-75f1-710e1ab9f17c.png)|
【Harmoware-VIS】組込みの移動データフォーマットを使用せず外部データで再生する方法

#Harmoware-VIS とは

https://qiita.com/ucl_Harmoware_VIS/items/e861e0f651ffde647b6a

#組込みの移動データフォーマットを使用せず外部データで再生する方法

##処理イメージ
<img width="1648" src="https://img.esa.io/uploads/production/attachments/8212/2021/09/16/31805/ce3b1a08-e8ab-4ac1-88e7-5b6c0fbc22e8.png">

##各インターフェース

###setTimeBegin
Harmoware-VIS既存の関数です。処理開始日時（[`timeBegin`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#timebegin-number)）をUNIX時間（秒）で設定します。

###setTimeLength
Harmoware-VIS既存の関数です。処理時間長（[`timeLength`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#timelength-number)）を秒数で設定します。

###setExtractedDataFunc
Harmoware-VIS新規の関数です。任意表示データ生成処理（[`getExtractedDataFunc`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#getextracteddatafunc-function)）をHarmoware-VISに登録（オーバライド）します。
登録されるとフレーム毎のデータ作成時にオーバライドされた当該関数がコールされます。

**任意表示データ生成処理（[`getExtractedDataFunc`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#getextracteddatafunc-function)）の書式**

```javascript
<P>(nextprops: P) => any
```

戻り値：任意のデータ
そのまま、Harmoware-VIS 内にて [`ExtractedData`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#extracteddata-any) に格納されます。

引数：nextprops
Harmoware-VISのルートプロパティ及びアプリでルートに追加したプロパティです。
但し、内容は次のフレームデータを作成するための内容に変更されています。（[`settime`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#settime-number)など）

コード例

```javascript
//アプリのルートクラス
class App extends Container {
  constructor(props) {
    super(props);
    //任意表示データ生成処理に登録
    this.props.actions.setExtractedDataFunc(this.getExtractedDataFunc.bind(this));
    ・・・
  }
  ・・・
  //Harmoware-VISにオーバライドする関数
  getExtractedDataFunc(props){
    const {settime} = props; //経過時間の抽出
    return getExtractedData(settime); //経過時間に対応する表示データを抽出する内部処理など
  }
  ・・・
  render() {
    const { actions, viewport, ExtractedData } = this.props;
    const { GridCellLayerData } = ExtractedData;
    return (
    <div>
        <div className="harmovis_area">
          <HarmoVisLayers
            viewport={viewport} actions={actions}
            mapboxApiAccessToken={MAPBOX_TOKEN}
            layers={[
              GridCellLayerData && (GridCellLayerData.length > 0) ?
                return new GridCellLayer({
                  id: 'GridCellLayer-ExtractedData',
                  data: GridCellLayerData, //データをレイヤーに渡す
                }):null
            ]}
          />
       </div>
    </div>
  );
}

・・・

//外部データの取得処理
getExternaldataLoad(){
  const { actions } = this.props;
  ・・・ // 外部のデータをreaddataに取得する処理
  const {Externaldata, startTime, endTime} = readdata;
  // Externaldataは後で抽出できるように保存
  actions.setTimeBegin(startTime); //処理開始日時設定
  actions.setTimeLength(endTime - startTime) //処理時間長設定
  ・・・
}
```

[`timeBegin`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#timebegin-number)や[`timeLength`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#timelength-number)は外部データロード時でなくてもOK
双方を設定したと同時に再生が開始します。
再生処理中に変更することも可能なので外部データに追加があったタイミングで処理時間長を延長するなども可能
仕事ができるいいやつ

こんにちは。エンジニア未経験で株式会社Catallaxyに入社しました。断捨離の凡才です。凡才というより才能が皆無です。片付けも断捨離もできませんが整理収納アドバイザー２級を持っています。

さて、今日は、Catallaxyの採用基準である「仕事ができるいいやつ」について書きたいと思います。

「仕事ができる」

と言うと、その定義は人によって様々かと思いますが、Catallaxyのエンジニアには相手の立場や気持ちを想像して発言できる人が多いです。

働く上での人間関係は、非常に心地いいものだと自信を持って言えます。

VS CODEを開いていると、

「〇〇さん、すみません。質問してもいいですか」「は〜い、どうぞ〜」

と、パソコンから今日も誰かの声がします。

タブを切り替え[Gather](https://www.gather.town/)（バーチャルオフィス空間で会話ができるツールを使ってコミュニケーションツール）にいくと、エンジニアが解決できないエラーの質問を他のメンバーにしているようです。

「画面共有します〜」「ここのエラーなのですが、、、、」

といったように会話が始まり、聞きたいことがあれば、メンバーにすぐに質問することができます。

![スクリーンショット 2021-12-08 20.03.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/3d6c6602-9a31-086a-b9b2-c046ac8da016.png)


デスク周りにはスノーモービルが登場し、机の上には脳みそのホルマリン漬けが。そしてもうすぐクリスマスだと言うのにハロウィンのカボチャまで置いてあります。私の断捨離の才能が皆無なことは、関係ないはずです。

見た目がピクセルっぽいので、私はGatherをドラクエと勝手に呼んでいます。

Gather上で闘ったり、魔王を倒したりはできませんが、踊ったり、❤️を飛ばしたり、クラッカーを人に向かって噴射したりすることはできます。

「社員一人一人が主人公となり、エンジニアリングを武器に「未来の製造業をつくる」という壮大な冒険物語をRPGする」

という意味では共通だと思うのでご愛嬌をお願いします。

話が逸れましたが、誰か困っている人がいると、リアルオフィスでみんなで集まって仕事をしているように、他のエンジニアが寄ってたかって誰かの疑問を解決するために奮闘してくれます。

私はこの現象を、仲間と共にエラー倒すダンジョンと密かに呼んでいます。

MTG中や集中したい時などは、離席中マークをつけて、誰も話しかけないでという合図もできるので、一人でもくもくと作業をしたい時も安心です。

最初は、他のメンバーに質問することに対して、気負いしてしまうこともあったのですが、Catallaxyのメンバーは

「最初はわからないことだらけだと思うので、たくさん質問してください。みんな最初は何もわからなかったので大丈夫です。やっていくうちに慣れていくので心配しないでください」

そんなスタンスで受け入れてくれる人たちばかりです。そういったメンバーの寛容さが、まだやったことない言語にも、挑戦してみようという気持ちを後押ししてくれます。

（自分はまだまだ助けてもらう場面ばかりですが）相手の気持ちや状況、技量などを理解、想像して、接してくれるメンバーに、本当に感謝しています。

Catallaxyは「仕事ができるいいやつ」の集まりなのです。

そんなCatallaxyで、「未来の製造業をつくる」という冒険物語の主人公、もしくは仲間になりたいという方は、お気軽に話を聞きに来てください。断捨離が苦手な方でも大丈夫です。
ミルククラウン解析（その５，妥当性確認）

#概要
オープンCAEシンポジウム2021のオープンCAEコンテスト2021に応募したミルククラウン解析の解析結果をコンテストが終了したので、順次公開します。
#妥当性確認
（その２）で書きそびれましたが、解析モデルは以下の論文の条件に近くなるように設定されています。
解析結果の妥当性確認も以下の論文に記載されている方法で行いました。
M. Rieber and A. Frohn, Int. J. Heat Fluid Flow, 20 (1999) 455-461.
##ミルククラウン半径の評価
（その１）で紹介したアニメーションの断面図を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784513/13694051-3c3c-4627-0b83-a697ef41afbb.png)
ミルククラウン半径の理論的漸近解は次式で表されます。
$$ \frac{r_{l,b}}{D}=kT^{1/2} $$
$$ k=[\frac{2A}{UD}]^{1/2} $$
$$ T=t\frac{U}{D} $$
$$ A=\int_{0}^{L_x}\bar{u}(x)dx $$
$$ \bar{u}(x)=\frac{\int_{0}^{h}\alpha(x,y=0,z)u(x,y=0,z)dz}{\int_{0}^{h}\alpha(x,y=0,z)dz} $$

ここで、

|変数|単位|説明|
|:-:|:-:|:-:|
|$D$|$m$|液滴直径|
|$U$|$m/s$|液滴初速|
|$r_{l,b}$|$m$|初期水位でのミルククラウン半径|
|$k$|-|無次元定数|
|$t$|$sec$|解析時間|
|$T$|-|無次元時間（液滴が床に衝突する時刻で0と定義）|
|$L_x$|$m$|解析モデルのx方向長さ|
|$h$|$m$|床面の初期水位|

無次元定数$k$を次式に変更すると、改善した近似解となります。

$$ k=[\frac{6h}{D}]^{-1/4} $$

ミルククラウン断面図から読み取ったデータを分析すると、理論的漸近解、改善した近似解および単回帰曲線の無次元定数$k$および無次元時間$T$の乗数$n$は次のようになります。

|解|$k$|$n$|
|:-:|:-:|:-:|
|理論的漸近解|1.047|1/2|
|改善した近似解|1.095|1/2|
|単回帰曲線|0.9656|0.4887|
単回帰曲線が理論的漸近解・改善した近似解と同様に、時間の平方根に依存することが確認できました。
プロット図は次のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784513/6bf34dc1-d025-8ef9-6bc4-e795515fcbca.png)

##リム上の突起の数の推定
リム上の突起の数は次式で表されます。
$$ n=\frac{2\pi r_{l,r}}{\lambda_{max}}=\frac{2\pi}{9.0147}\frac{r_{l,r}}{r_{rim}} $$
Reileigh不安定生は次式で表されます。
$$ \lambda_{max}=9.0147r_{rim} $$
ミルククラウン断面積は次式で表されます。
$$ S(z)=\int\alpha(x,y,z)dxdy=\pi\frac{r_{l,r}}{D}\frac{r_{rim}}{D} $$

ここで、

|変数|単位|説明|
|:-:|:-:|:-:|
|$r_{l,r}$|$m$|ミルククラウン半径（断面図から読み取り）|
|$r_{rim}$|$m$|リム半径（$S(z)$より算出）|


T=1.72(t=00085(s))での例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784513/780d8fb7-14ea-f1e4-7d10-b1059bf910c3.png)
論文では、どの高さでのミルククラウン半径を用いるのか明記されていませんでした。
統一した基準で計測する必要があると考え、高さはミルククラウン外周で最もくびれているところと定義しました。

$r_{l,r}$の単回帰曲線は次のようになりました。
$$ \frac{r_{l,r}}{D}=1.0514T^{0.4759} $$
プロット図は次の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784513/8345fa92-4be7-4573-0c02-210e256b81a4.png)

$r_{rim}$の単回帰曲線は次のようになりました。
$$ \frac{r_{rim}}{D}=0.0296T^{0.3792} $$
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1784513/591eec7c-9749-8da3-da84-37121a5dc56d.png)

以上より、リム上の突起の数$n$は次式で表されます。
$$ n=24.75T^{0.0967} $$

この計算式の$n$の値と、アニメーションデータでカウントした突起の数の比較表は次の通りです。

|$T$|0.915|1.72|2.52|3.54|
|:-:|:-:|:-:|:-:|:-:|
|計算式の$n$|24|26|27|28|
|アニメーションデータでカウントした数|16|20|28|28|

リム上の突起の数がT=3.54に28個で一致しました。

#まとめ
全体的に論文に近い結果が得られたと思います。
[py2rb] math.factorial

# はじめに
移植やってます
# math.factorial (Python)
```python
_precalc_fact = np.log([math.factorial(n) for n in range(20)])
```
`math.factorial(n)` は、nの`階乗`です。
# inject (Ruby)
```ruby
(1..n).inject(1, :*)
```
@scivola さんの記事を [【Ruby のまずいコード】階乗](https://qiita.com/scivola/items/cc09eaa800623f69e955) ~~コピペ~~参照させていただきました。
`AtCoder`を始めとする競技プログラミングで活用できそうですね。

```ruby
_precalc_fact = np.log((0...20).map{ |m| (1..m).inject(1, :*) })
```
# メモ
+ Python の math.factorial を学習した
+ 道のりは遠そう
背景画像がherokuにデプロイすると表示されなくなる

### 事象

オリジナルアプリを作成していて、ローカル環境での動作も問題ないのでherokuにデプロイ。
background-imageを使用して背景画像を設定しており、ローカル環境では表示されるのに
本番環境では表示されないという事象が発生。

```CSS
background-image: url('assets/4558407_s.jpg');
```

表示されないのにはAsset Pipelineという仕組みが関係している。
app/assets以下に画像やjs、cssなどのファイルを格納しており、これらを「高速に」
「キャッシュに悪用されないように」本番環境に反映させるのがAsset Pipelineの役割。

格納してあるファイルには名前がついており、アップデートしてくとファイル名は以前と
変化はしていないが、中身は更新されているということになる。
それによりキャッシュによって更新済みのものでなく、更新前の同じファイル名のものが
読み込まれるという事態を防ぐ仕組みを「dijest」と言う。

具体的には、app/assets以下に配置されたファイルが、コードが更新されるごとに
ファイル名にユニークな拡張子がつけられる様になる。

さらに、デプロイされると、app/assets以下のファイルは全てpublic/assetsに
上記のdigest付きになって移動される。

 シンプルにファイル名が変わっているためurl指定では読み込むことができない。


### 解決方法

```CSS
background-image: image-url('4558407_s.jpg');
```
と言う記述に変更する。
railsが指定するimage-urlメソッドを使用することで、デプロイ時にapp/assetsから
public/assetsにファイルが移動する際自動的にファイルにdijestを付与してくれるように
なる。

しかし、なぜかimage-urlメソッドで読み込まない。

ファイル名をcssからscssに変更することで解決。
scssはcssを拡張して書きやすく、見やすくしたスタイルシートのこと。

scssでは使用できてcssでは使用できないメソッドもあると言うことを理解した。
MVCモデルとは

# MVCモデルとは
***MVCモデル***は、GUIを持つWebアプリケーションなどのソフトウェア設計モデルの1つ。
MVCは、```Model```、```View```、```Controller```の頭文字を取ったものである。
この***３つの役割ごとにプログラムを分割して記述する設計手法***。

## Model
アプリケーションのビジネスロジックを担当。
主にデータベース操作に関わる処理を行う。

## View
画面表示、ユーザーからの入力や出力を担当。
 ```Controller```から受け取ったデータをWebブラウザに表示するためのHTMLを作成するなど。

## Controller
　```Model```と```View```間でのデータのやり取りなどの橋渡しを担当。

## MVCモデルのメリット
MVCモデルは、```Model```・```View```・```Controller```と役割が明確に決められていることで以下のようなメリットが得られる。
・高い保守性
・再利用性が高まる
・分担開発が行いやすい
【Harmoware-VIS】停留所アイコンを複数レイヤーで表示

#Harmoware-VIS とは

https://qiita.com/ucl_Harmoware_VIS/items/e861e0f651ffde647b6a

#停留所アイコンを複数レイヤーで表示

Harmoware-VIS で停留所等を表示する [`DepotsLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#depotslayer) は、Harmoware-VISで停留所データが複数管理できないため、重複させることが出来ません。
その問題を解決するため、一つの停留所データ内で停留所の type を識別することで、 [`DepotsLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#depotslayer) 内で複数のアイコンレイヤーを重ねることが出来ます。

停留所データ（[`depotsBase`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#depotsbase-object-array)）の type 定義の例

```json
[ //停留所データの配列
    {"type": "station", //この停留所のtypeをstationと定義
        "position": [・・・・・・] //停留所位置データ
    },
    {"type": "busstop", //この停留所のtypeをbusstopと定義
        "position": [・・・・・・] //停留所位置データ
    },
]
```

[`DepotsLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#depotslayer) のコード例

```javascript
new DepotsLayer({
    depotsData,
    iconDesignations:[ //ここでtype毎に使用するレイヤーを指定する。
        {type:'station', layer:'SimpleMesh'},
        {type:'busstop', layer:'Scatterplot'},],
})
```

上の例ではtype毎のレイヤー指定のみですが、色やサイズ、３Ｄアイコンデータなどもtype毎にプロパティ設定できます。

詳細は[`DepotsLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#depotslayer)の `iconDesignations` のリファレンスを参照してください。

typeの設定をしていないオブジェクトは [`DepotsLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#depotslayer) 全体へのプロパティ設定値を適用します。
エンジニアになろうとしたきっかけ

年齢：29歳
エンジニア歴：1年半
使用言語：Javascript、PHP
コーディングや技術とは特に関係ありませんが、エンジニアになろうとしたきっかけ等を綴っていこうと思います。

###前職
私は元々「これがしたい！」と言ったものがなく、そんな状態で前職・前々職と営業事務をしていました。
当然コーディングのコも知らない、それどころか「いやいや文系だし絶対わからないわ」と敬遠さえしていました。全員が同じとは言いませんが、営業事務なんてそんなものでしょう。
一番最初の前々職。そもそも「PCを触るのは苦手」とさえ思っていました。ExcelなんてSUMが使えれば上等くらいの職場です。オートフィル？　「どうやって使うのか知らないけどなんかすごい機能だ！」くらいの認識で当時使えた試しもありません。
「事務ならExcelくらい使えて当然」とは思いますが、最低限さえ知っておけばなんとかなってしまう環境でした。
毎月ものすごく四苦八苦しながら表を作っていた覚えがあります。この時「苦手だから」で終わらせず、もう少し理解しようとしていればマシになったのではと思う時もありますが、たらればを言ったところで仕方ありません。

最初の職場を離れた後、職業訓練でOfficeを勉強しました。初級だったので本当に触りだけですが、これのおかげで苦手意識は払拭されたのだと思います。
これを踏まえた上での2社目ですが、困ったことにほぼアナログでした。「事務仕事をやる上でPCを十全に使って仕事をしたい」と言ったはずなのに実際は前の職場よりもPCを触っている時間が少なかった気がします。字が汚い、作業が遅い私にはこれがかなり苦痛でした。
なので、徹底的に「楽をする」事にリソースを割く事にしました。楽をすると言ってもサボるのではなく、今自分が担当している仕事をとにかく効率的にできるよう根本から変えていく方向で。イレギュラーが起こると焦って非効率的な事をしようとするので、そんな隙間を作らないくらい簡単に。誰が見てもわかるように。Excelの便利さを思い知りました。果てはVBAにも手を出してみたりと、とにかく業務の簡略化に努めました。
……今はその職場を離れていますが、そんな努力の結晶がしっかり使われている事を祈るばかりです。
そうして、ここに来てようやく自分のモチベーションとなる根本を理解しました。

**「無駄な事はしたくない」**

いや、そんなネガティブなモチベーションあるか？自分でも驚きました。とは言え前職はそれで頑張ったのだから事実です。上述でも書きましたが、別にサボりたいとかそんな意味ではなく。誰だって5分でできる事を１時間かけてしたくないじゃないですか。それだけです。それから次の転職活動はIT系の会社に舵を切りました。ただ、この時点ではやはりスキルがないので事務中心です。
いくつか面接を受けた中、面接官が一言。
**「君、SEの方が向いてるんじゃない？」**
完全に目から鱗でした。
よくよく考えると「SEは文系だし無理……」とか言いながら既にマクロ通り越してVBAにまで手を出しているのですから、全くできない筈がないんですよね。
面接官からすれば体の良い断り文句というのは重々に理解できるのですが、私の中ではこれが強く残っています。
人生何で変わるかわかりませんね。こんな一言で未経験者がいきなりこの世界に飛び込もうとするのですから。


###今
それからスクールへ行って今に至ります。
今でもたまに思い出すのが前職で使用していたシステムです。あらゆる部署に対応していたわけではなく、当然システムと実際の業務が合わない部署もあるわけで。そんな部署がデータを大量に印刷し、その中からアナログで項目のチェックをしていた記憶があります。システム自体が悪いのではなく、その会社の業務形態にあっていなかったのだと思います。
それを元に今実際作る側になって、初めてやりたいことを認識できました。
事務等の業務を行う時、基本的に思考停止自体が悪いとは考えていません。問題はその思考停止の中で如何に無駄を省くかで、私は今その中で一番無駄を省ける、「今までやってたから当たり前」を根本から修正できる立ち位置にいるわけで。
少しでも「作業が楽になった」と言ってもらえるような、そんな仕事がしたいと思っています。
クリスマスイブなのでハートをパーティクルで作りましょう！

<h1>はじめに</h1>
皆さん！こんにちは！
1年は早いもので、気づけばもうクリスマスイブです！
クリスマスにちなんで今回はハート型にパーティクルを展開するコードをメモ程度に残しておこうと思います！

<h1>注意</h1>
筆者は時代の流行に追いついていないので**PocketMine-MP3**を基準にしてこの記事を書いております。
ここに乗ってるコードを使用する際は、PocketMine-MP4の記述方法に変更してから実装してください。
それとこの時期はExplosionクラスも用意したほうがいいかも！

<h1>数式</h1>
ハートに描画する数式は以下のとおりです。
筆者は数学が死ぬほど嫌いなのでネットで探したりそれを[scratch](https://scratch.mit.edu/)で試したりしてます。

```
x+size*sin(rad)^3*2
y+2+(size*cos(rad)-cos(rad)^4)*2
```

<h1>実装</h1>
実際にプラグインで実装してみます。

```php
for ($i=0; $i<360; $i+=10) {
    $pos = new Vector3($x+1*sin(deg2rad($i))**3*2, $y+2+(1*cos(deg2rad($i))-cos(deg2rad($i))**4)*2, $z);
    $level->addParticle(new HeartParticle($pos));
}
```

<h1>Generatorを使う方法</h1>
上記の方法だと一瞬でハートが出来てしまいます。
これだと折角のクリスマスイヴの雰囲気も台無しです。
せっかくなら下記の動画のようにロマンチックに演出してみましょう！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">あたらしいぷらぐいんのえいぞう <a href="https://t.co/5FKA7oQT8F">pic.twitter.com/5FKA7oQT8F</a></p>&mdash; Yurisi (@Dev_yrs) <a href="https://twitter.com/Dev_yrs/status/1262189516850204673?ref_src=twsrc%5Etfw">May 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ゆっくり1つずつパーティクルを出すにはSchedulerとGeneratorを利用します

```php:Main.php
$func = function (int $x, int $y, int $z, Level $level) {
    for ($i=0; $i<360; $i+=10) {
        yield;
        $level->addParticle(new HeartParticle(new Vector3($x+1*sin(deg2rad($i))**3*2, $y+2+(1*cos(deg2rad($i))-cos(deg2rad($i))**4)*2, $z)));
    }
};
$this->getScheduler()->scheduleRepeatingTask(new HeartTask($func($player->getX(), $player->getY(), $player->getZ(), $player->getLevel())), 1);
```

```php:EventGenerater.php
use pocketmine\scheduler\Task;

class EventGenerater extends Task {

    private $generator;

    public function __construct(\Generator $generator) {
        $this->generator = $generator;
    }

    public function onRun(int $currentTick) {
        if ($this->generator->valid()) {
            $this->generator->next();
        } else {
            $this->getHandler()->cancel();
        }
    }
}
```

これでゆっくり出るようになったはずです！
<h1>おわりに</h1>
これでクリスマスイブにMinecraft内でロマンチックを演出することが出来ます！
ぜひ恋人同士なんかとMinecraftをする際に使ってみてください！
<br />
<br />
私はロマンチックと縁がありませんので明日のゆこさんの記事を推しています。
【Harmoware-VIS】移動体データに移動体以外のデータを設定

#Harmoware-VIS とは

https://qiita.com/ucl_Harmoware_VIS/items/e861e0f651ffde647b6a

#移動体データに移動体以外のデータを設定

Harmoware-VIS では移動体データ（[`movesbase`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#movesbase-object-array)）より、時間経過に沿った移動をシミュレーションしますが、移動処理対象としないが時間経過によって表示を更新するためのデータを設定することが出来ます。

利用用途はいろいろありますが、例えば３Ｄポリゴンを時間経過でレイヤー表示することで、ビルがどんどん増えていく表現とか、建築進捗の表現とか、２Ⅾ範囲を時間経過でレイヤー表示することで、地区ごとの電力消費量の変化とか、何かの影響が時間経過により拡散する様子を表現したり出来ると思います。

```json-doc
[ //移動体データの配列
    //移動処理対象のデータ
    {"operation": [ //移動経路データ配列
            {"elapsedtime": 99999,
            "position": [999.9999, 999.9999, 999.9999], //positionが定義されると移動処理対象
            ・・・ //その他の情報
            },・・・
        ]
    },
    {"operation": [ //移動経路データ配列
            {"elapsedtime": 99999, //必須
            "polygon": [[999.9999, 999.9999, 999.9999],
                        [999.9999, 999.9999, 999.9999],
                        [999.9999, 999.9999, 999.9999], ・・・ ],
            ・・・ //positionが定義されないと移動処理対象外
            },・・・
        ]
    },・・・・・・
]
```

Harmoware-VIS のプロパティに含まれる [`movedData`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#moveddata-object-array) には、シミュレーション中の時間における移動対象データと移動対象外のデータが抽出されています。
[`MovesLayer`](https://qiita.com/ucl_Harmoware_VIS/items/cc65d90488d2f0d66ae1#moveslayer) は position が含まれない [`movedData`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#moveddata-object-array) は無視しますので、 [`movedData`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#moveddata-object-array) より position 以外で必要なデータを抽出してレイヤーで表示してください。

以下に移動体データへ polygon を追加した場合のコードのサンプルを示します。（細かい部分は省略）

```javascript
  render() {
    const { movedData } = this.props;
    const polygonData = movedData.filter((x:any)=>x.polygon);
    return (
      <div>
          <HarmoVisLayers
              ・・・ //省略
            layers={
              new MovesLayer({ //こちらは移動処理対象のデータを表示
                movedData,
                ・・・ //省略
              }),
              polygonData.length > 0  ?
              new PolygonLayer({ //PolygonLayerはdeck.glの提供レイヤー
                id: 'PolygonLayer',
                data: polygonData, //movedDataから抽出したデータ
                getPolygon: (x: any) => x.polygon,
                getFillColor: (x: any) => x.color || [255,255,255,255],
                getElevation: (x: any) => x.elevation || 1,
              }):null
            )}
          />
      </div>
    );
  }
```
raspberry pi（raspbain)にpyenvを導入しようとして躓いた件

Raspberrypi3 にpyenvを導入しようとして、インストール記事を参考にして躓いたため、メモとして記事に残します。

## 現象

pyenvをglobalに適用しても

```
:$ pyenv global 3.10.1
```

結果として、適用できていない。


```
:$ python -V
Python 3.7.3
```

## 原因・解決策

pathが認識されていないため。

~/.bashrc
あるいは
~/.bash_profile
に記述する以下の部分を修正します。

＜変更前＞

```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

＜変更後＞

```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
```

### インストール方法の参考記事

参考:[Raspberry PiにpyenvをインストールしてPythonをバージョン管理](https://qiita.com/hoshi621/items/c8b82ab42564256df884)
【WSL】WSL2環境のUbuntu18.04にHerokuCLIをインストールする

# 経緯
開発に使用しているWSL2環境のUbuntu18.04で、HerokuCLIを使用したくなったため、
公式の手順に沿ってインストールを行おうとしたが、うまく動作しなかった。
その解決策を記録します。

## 試したこと

[ここ](https://devcenter.heroku.com/articles/heroku-cli#download-and-install)に記載されているインストール方法では、インストール出来なかった。

```bash
# snapに対応していなくて失敗
$ sudo snap install --classic heroku

# こっちも試す
$ curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
～～～省略
Error: node is not installed.
```

## 解決した方法

```bash
# Nodejsがないらしいのでインストール
$ sudo apt install nodejs

# 再度HerokuCLIのインストールを再度試す
$ curl https://cli-assets.heroku.com/install-ubuntu.sh | sh

# インストールできたか確認
$ heroku --version
heroku/7.59.1 linux-x64 node-v8.10.0
```

# おわりに
Nodejsがないとダメなんて公式に書いてあったっけ?
ひとまず無事動いたので良かった。
Azureに登録したクレジットカードと、Microsoftアカウントのクレジットカードの関係のメモ

#きっかけ
無料アカウント期間が終わって支払いが発生したので、どのカードで払うんだっけ？
↓
あ、Microsoftアカウントか。
↓
あれ？カード２つあるぞ、消そう
消せない。。Azureと連携してるかも？っていうメッセージが。。。

#やったこと
##Azureのカード情報を削除
下記を参照。
Microsoftアカウントにも登録されている不要なカードがもう一枚登録されていたので、既定の支払い情報を支払いたいカードに「置き換え」して、不要な方のカード情報を削除。


https://docs.microsoft.com/ja-jp/azure/cost-management-billing/manage/change-credit-card

##Microsoftアカウントのカード情報を削除

あっさり削除できました。

##ちなみに

AzurePortalでクレジットカード追加　→　Microsoftアカウントにも追加
という流れだけど、
Microsoftアカウントにクレジットカード追加　→　AzurePortalにも追加
にはならない模様
Railsで依存関係にあるテーブルを削除する方法

# はじめに
テーブル関係を削除してスッキリさせようと思ったところ、関連付けのおかげで少し手間取ったので記事にまとめます。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [テーブルを削除する](#Chapter1)
1. [依存関係がある場合](#Chapter2)
1. [依存関係がある場合のテーブルを削除してみる](#Chapter3)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# テーブルを削除する

テーブルを削除するときの手順として私は以下のように行います。

① モデル削除
 ``rails destroy model モデル名`` 


② 削除用のマイグレーションファイルを作成
``rails generate migration 自分でつけるmigrationファイルの名前``

③ drop_tableで削除したいテーブル名を書く
　作成したmigrationファイルに記載

```rb
class 自分で作成したファイルの名前が入る < ActiveRecord::Migration[6.0]
  def change
    drop_table :hoges   # hogesテーブルを削除する場合
  end
end

```
　
④ migrateを実行して削除

``rails db:migratre``

<a id="#Chapter2"></a>
# 依存関係がある場合

いつもなら最初の方法で問題がないはずなのですが、依存関係がある場合だと下記のようなエラーが出ます。

```

DROP TABLE products;

NOTICE:  constraint orders_product_no_fkey on table orders depends on table products
ERROR:  cannot drop table products because other objects depend on it
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

```
公式サイトによると

>データベース構造全体の整合性を保つため、PostgreSQLは、他のオブジェクトと依存関係にあるオブジェクトの削除を許可しません。 例えば、項5.3.5で作成したproductsテーブルを削除しようとしても、ordersテーブルがこのテーブルに依存しているので、以下のようなエラーメッセージが現れます。

つまり**関連付けを行なっているためdrop_tableを実行できない**という事ですね。
その後の文章では次のように続きます。

>エラーメッセージには役に立つヒントが含まれています。 以下のようにすると、依存する全てのオブジェクトを1つずつ削除する手間を省けます。
DROP TABLE products CASCADE;
これで全ての依存オブジェクトが削除されます。 この場合、ordersテーブルは削除されずに外部キー制約のみが削除されます。

なるほど！ ``DROP TABLE products CASCADE;``を使用すればいいか！早速やってみよう！

<a id="#Chapter3"></a>
# 依存関係がある場合のテーブルを削除してみる

Railsでは``rails db``または　``rails dbconsole``でSQLを操作できるようになるので早速やってみます。パスワードを求められるので自身で設定したパスワードで入ってください

① ``rails db``を実行

② ``DROP TABLE 削除したテーブル名 CASCADE;``を実行

以上でなんとか削除できました！よかった！

<a id="#reference"></a>
# 参考文献
- [PostgreSQL公式](https://www.postgresql.jp/document/8.0/html/ddl-depend.html)
PowerVC 2.0.2 設定 ~ リモート・バックアップ・ノードの登録 ~ 

##### はじめに

PowerVC 2.0.2 では、PowerVC管理ノードとは異なるサーバーをリモート・バックアップ・ノードとして登録し、イメージ・インポート、エクスポートをリモート・バックアップ・ノードですることが可能です。
リモート・バックアップ・ノードを使用することで、PowerVC 管理ノードがバックアップで必要なリソースを使用しなくて良いというパフォーマンス面での利点があります。

参考：

https://www.ibm.com/docs/ja/powervc/2.0.2?topic=images-registering-backup-node

---

##### 環境

PowerVC 2.0.2 (RHEL8.4 ppc64le on PowerSystems S824)
リモート・バックアップ・ノード (RHEL8.4 ppc64le on PowerSystems S824)
　=> PowerVC で NPIV 接続でデプロした仮想マシンを使用

---
##### バックアップ・ノードの登録

GUI deログインし、"Storages" - "Backup nodes" に移動します。

![スクリーンショット 2021-12-04 20.39.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/af666783-5208-c0e7-c589-3795545ef8cd.png)

"Add node" を押し対象のノードの登録設定を行います。

![スクリーンショット 2021-12-04 20.40.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/3fb3237f-525f-0c73-4f5c-ac590c92d41f.png)


Add を押したのち、リモート・バックアップ・ノードに PowerVC バックアップ・ノード用のモジュール(cinder サービス など) が導入されるため時間がかかります。

8分程度経過後 GUI 上で追加が確認できました。

GUI には出てこないのでどのように進捗しているかがわかりにくいですが、"/var/log/cinder/api.log" (リモート・バックアップ・ノード)、"/opt/ibm/powervc/log/powervc_install_<timestamp>.log"(PowerVC管理ノード) で確認できます。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/71cfa73e-4c28-0d9a-54c4-6078224c014c.png)



まだ Pending 状態です。
Network Connection が正常化すると、Health OK となります。(~15分くらい。環境による)

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/cbf36edd-04eb-aa1a-40c3-d69d7bb2883e.png)


正常状態になりました。


＊注意

・yum repository を設定しておくことが必要です。
・PowerVC 管理ノードがPowerVCサービスで使用するネットワークとリモート・バックアップ・ノード として登録するIPアドレスは同じネットワークである必要があります。


----

##### イメージ・エクスポートの試行

既存のイメージをエクスポートを実行し、ovaファイルを作成します。
AIX7200-05-03 イメージを選択しています。

![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/ad0f5068-5d96-5fe2-e58b-8552cd302dc6.png)

ovaファイルの名前を任意に記載し、対象のバックアップ・ノードを選択します。
COS へのアップロードもオプショナルで可能です。

Export を押し、実行します。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/1657e6d2-35bd-3484-f91b-5384a3650e28.png)

"Backup nodes" の Image backups に対象のイメージファイルがリストされました。

![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/1fa82cd7-53b1-a87c-9d4b-0e7600b3c376.png)


サーバー上でも、testova.ova　ファイルが作成されていることが確認できました。

```
# pwd
/var/opt/ibm/powervc
# ls -l
total 0
drwxr-xr-x 2 cinder cinder  6 Dec  9 15:58 image-backups
drwxr-xr-x 2 cinder cinder 27 Dec  9 16:03 image-ovas

# cd image-ovas/
# ls -l
total 8062568
-rw-r--r-- 1 cinder cinder 8256067716 Dec  9 16:03 testova.ova
```




以上です。
【Harmoware-VIS】アプリ起動時に表示する地図の位置や視点の設定

#Harmoware-VIS とは

https://qiita.com/ucl_Harmoware_VIS/items/e861e0f651ffde647b6a

#アプリ起動時に表示する地図の位置や視点の設定

Harmoware-VISのデフォルトでの地図の初期表示は

```console
longitude: 136.906428,
latitude: 35.181453,
```

となっています。
これは名古屋市役所の位置です。

これをカスタマイズするには、アプリのルートクラスのマウント時に[`setViewport`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#viewport-object)で視点を設定してください。

```javascript
class App extends Container {

  componentDidMount(){
    super.componentDidMount();
    this.props.actions.setViewport({longitude:139.692074,latitude:35.689806});

  } ... }
```
誰でも簡単、SymbolでオンチェーンNFTを実現する手立て

Symbol でも NFT を作ってみたいんですが、実装はできるだけシンプルにしたい！何か良い方法はないものでしょうか。


３年前の[書き出し](https://qiita.com/tkskysk/items/adfb779bd64202a5d546)を、現代ナイズしました。
NIS1で既に行われているのだから、Symbolノードでやらないってほうが不自然でしょう。

ということで、かねてよりやりたそうな顔をしていた有識者 [たべさら](https://twitter.com/taberu_salad_jp)に声をかけて全面的に協力してもらうことにしました。企画立案から、実装までお付き合いいただけるようで感謝しかありません。

# 何する
Symbol NFTをもっと身近に。

https://twitter.com/TrendStream/status/1465633947136630784?s=20

要するに私がしたいことはトレストさんがすべて言ってくれています。

乾坤一擲の絵をNFTするのもいいですが、スマホで撮った日常の写真がNFTになる、それをSymbolが担うのはいかがですか。という提案です。

ということで、皆さんの手元にある、スマホでNFTをSymbolで実現するにはどうすればいいか、を考えてみました。

# 設計してみた
フルオンチェーンのNFT　軽く実装を考えてみたら、びっくりするほど簡単に出来そうでした。正直何も難しいことはありません、誰でも作れます。少なくともSymbolにおいては。

ざっとフローを書き出してみます。

1. 画像をエンコードする
1. それらをトランザクションのメッセージに詰め込む、その際にアグリゲートトランザクションを用いることでトランザクションの内容をまとめる
1. 作成したアグリゲートトランザクションを秘密鍵を放棄したアカウントに送る
1. 新規でモザイクを発行する
1. 発行したモザイクのメタデータに、放棄したアカウントのアドレスを書き込む

以上です。あれ、もしかしてUI/UX拘って作ったとしても５営くらいで出来たりしない…？

下にそれぞれ補足します。

## 1 画像をエンコードする

テキスト形式でデータを扱う場合には一般的なエンコード形式である `Base64` を用います。
先人の知恵に感謝。

## 2 アグリゲートトランザクションに内容をまとめる
仕様は適当に策定予定ですが、要するにPlainMessageに先ほどエンコードしたBase64形式の画像データをぶち込みます。そしてそれらをアグリゲートトランザクションにまとめます。
オンチェーンNFTでアグリゲートトランザクションを使う利点は２つほど。

- トランザクションの順番の担保
- すべて成功するか、すべて成功しないか、のどちらかしかない

という点です。



## 3 秘密鍵を放棄したアカウントにトランザクションを実際に送る
秘密鍵を放棄したアカウントに先ほど作成したアグリゲートトランザクションを送ります。
こちらのアカウントのアドレスがデータを持つことになるので `データアドレス` と呼ばれるものになります。
オンチェーン上のデータを保有している大事なアカウントです。
Txを飛ばしたりしないように秘密鍵を放棄します。

## 4,5 モザイクの発行
先ほど作ったデータアドレスのアドレス情報をメタデータに書き込んだモザイクを作成します。
期限や総発行量、初期供給量は用途に合わせて生成します。当然、ユニークなものにしたければ無期限、発行供給はともに１というものになるでしょう。

# アプリと組み合わせる
さて、ここまででNFTは完成しました。

早速アプリを作っていきましょう。
とはいえ、今クライアント側にはSDKがないのでFlutterで両OSゼロから作るのは億劫…。ということでTxの作成はサーバーサイドにぶん投げましょう。

整理します。
クライアント側に要求するのは以下です。

- 画像データの送信
- アグリゲートトランザクションに署名
- モザイク作成トランザクションに署名
- 画像表示（デコード）
- Symbolアカウントの管理
- 使いたくなるUI/UX(一番大事）

一方でサーバーサイド側に要求するのは以下です。
- 画像の受け取り
- Base64形式でエンコード
- アドレスの作成、秘密鍵の放棄
- アグリゲートトランザクションの作成
- モザイク作成トランザクションの作成

これだけです。サーバーサイドにDBすら持つ必要がありません。
Symbolアカウントの管理をせずに秘密鍵をベタ打ちするような仕様にすればストアにすら上げられそう。

# 作る
ということでそのうち一緒に作っていきます。
なんかハッカソンが行われるようなのでそれに合わせて作れればいいな。
それまでに誰かが作ってくれても全然いいです。僕たちのほうがいいモノ作るので、ぜひ争いましょう。

フルオンチェーンNFTを作るのは簡単です。
それをしたうえで何をするか、をもっと考えたほうが建設的ですね。
500 OOPS: SSL: cannot load RSA certificate でvsftpdが起動しない

### これは何
証明書発行の形式がvsftpd様に合わなかったようで、変えたらエラー回避できた話です。
エラー解決からだいぶ日が経ってしまったので、忘れてしまっている部分もあり、概要だけ書きます。

### 構成図

![スクリーンショット 2021-12-09 15.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740345/e1bbaa82-0bf2-fa22-8504-a41068cfa586.png)

### 事象
```
$ sudo openssl genrsa -aes256 2048 > vsftpd.key
Generating RSA private key, 2048 bit long modulus
.................+++
.........................+++
Enter pass phrase:
Verifying - Enter pass phrase:

$ sudo openssl req -new -key vsftpd.key -x509 -days 365 -out vsftpd.pem
Enter pass phrase for vsftpd.key:

$ mv vsftpd.key vsftpd.key.bak

$ sudo openssl rsa -in vsftpd.key.bak -out vsftpd.key
Enter pass phrase for vsftpd.key.bak:
writing RSA key

$ sudo chown root:root vsftpd.pem vsftpd.key
```
で証明書を発行。

これをvsftpdで使用するように設定して、再起動したところ、表題のエラー。

### 解決策
以下参考に、証明書発行の形式を変えたところ、うまくいった。
https://askubuntu.com/questions/412070/vsftpd-will-not-start-with-ssl-enabled

```
openssl req -x509 -nodes -days 720 -newkey rsa:2048 -keyout /etc/vsftpd/vsftpd.key -out /etc/vsftpd/vsftpd.pem
```

なお、なぜうまくいったかはまだ判明できていない。
そのうち時間ができたらこの辺勉強したい。

### 参考
https://askubuntu.com/questions/412070/vsftpd-will-not-start-with-ssl-enabled

参考にさせていただきました。ありがとうございます。
issueのコメントの記法のススメとコミュニケーション

#この記事について
サービスの保守・運用を担当している者が日々のissueの解決策とエンジニアと非エンジニア間でのコミュニケーションの際に気をつけるべき点を書かせていただきました。

#issueのコメント
担当業務でgithubのissueに毎日触れているので、多くのissueを如何に正確にcloseへ導くかの手法を列挙いたします。
1.**コメントは具体的に「〇〇の△△を□□に変更」のように書くべし**
2.**コメントは再現可能なものにするべし**

この２つに尽きるかと思います。
1に関しては、当たり前の中の当たり前ですが誰がいつどんな時にみてもわかりやすいコメントにしておくことで、変更履歴も追うことができますし、その修正に至った経緯も把握することができます。これにより、チーム内での認識のズレなども解消できたり、そもそもの作業者の思考が間違っている場合に修正が可能です。

2に関しては、過去にcloseになったissueから解決方法を探ることができるので、同じエラーの場合はその当時の対処法を試すことで速やかにcloseすることができます。

#####実際のコメント例
**画像①↓**
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2306339/6e8d8a52-6584-c457-9032-679b0ff03665.png)
**画像②↓**
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2306339/58ef76c8-5992-cc2e-97ee-77550a6dea85.png)

上記の画像は実際のissueの画面です。
画像①と画像②を比較したときに差は歴然かと思います。(※すごく極端な例です)

issueのコメントは最早、自問自答の場だと思っており、思考のプロセスを保存する場所です。
細かい情報を残すことで未来の自分を助けることにもつながる且つ、マネジメントをする側もされる側にも進捗や理解度を提示することができるので、できるだけ具体的なコメントを心掛けると良いかと思います。


#エンジニアと非エンジニア間でのコミュニケーション
社内やお客様からの問い合わせも担当しているが、どうしてもシステム内部の詳細なデータに関わることとなると我々から開発チームにヘルプを要請します。
筆者の失敗談を交えて書きたいと思います。

**失敗談(※実際の問い合わせとは異なります。あくまで例です。)**

営業担当者）〇〇社から「差し替えをお願いした画像が表示されていないようなので原因を調査してほしい」というお問い合わせが来ているので対応を御願いします！

筆者）調査・・・調査・・・調査・・・???
データ上は存在するのに、サイト上には表示さ・れ・な・い?なぜ?
開発チームに依頼しよう！

筆者）開発チームさーん！
〇〇の企業のサイトの新しい画像が表示されないのですが何故ですか??(・∀・)

**はい！アウトです！！！**
言うまでもなくここから無駄なコミュニケーションがこの先続いたわけです。。。

開発チームへの依頼時に、、、
・**現時点で起きている事象**
・**自分が調査した内容と結果**
・**調査時に使用したデータ**
これらを共有していれば半分で済んだコミュニケーションが2倍の工数を生むことになってしまったのです。

分かりきったことですが、問い合わせる際には気をつけるべきことは、**△△をした結果□□になり、その際に使用したデータは××ですと伝えるべきです。**

問い合わせ対応がひと段落した後に、開発チームの方からすごく優しい文面でご指摘をいただきました。。。
久々にやらかしてしまい反省しております。

今では、テンプレート的に思い出して使っています。

#最後に
書いた内容はエンジニアとして、社会人として当たり前なことですが、昨今のコロナ禍の影響で
リモートワークでの業務に従事している人はIT業界に関わらず増加したかと思います。

対面でのコミュニケーションが難しい環境だからこそ、今一度、見直す必要があると感じました。
【Harmoware-VIS】マップ移動時にFlyToエフェクトの使い方

#Harmoware-VIS とは

https://qiita.com/ucl_Harmoware_VIS/items/e861e0f651ffde647b6a

#マップ移動時にFlyToエフェクトの使い方

視点移動をエフェクトしたい場合は`actions.setViewport`の引数の[`viewport`](https://qiita.com/ucl_Harmoware_VIS/items/ea97c5e0e112a3d0ecca#viewport-object)に`transitionDuration`を追加し、時間（ミリ秒）を設定委してください。

```javascript
this.props.actions.setViewport({...changeview,
transitionDuration: 9999});
```

`transitionDuration`のタイプは`number`です。
`number`の単位はミリ秒で、移動にかける時間を指定します。

**移動エフェクトのタイプも変更可能です。**
既定は「[LinearInterpolator](https://github.com/visgl/deck.gl/blob/master/docs/api-reference/core/linear-interpolator.md)」で目的ポイントまで最短経路での移動のエフェクトです。
もうひとつは「[FlyToInterpolator](https://github.com/visgl/deck.gl/blob/master/docs/api-reference/core/fly-to-interpolator.md)」で目的ポイントまで弧を描く経路での移動のエフェクトです。
詳細は各クラスのリファレンスを参照してください。

```javascript
this.props.actions.setViewport({...changeview,
transitionDuration: 9999,
transitionInterpolator:new FlyToInterpolator()});
```
QAエンジニアに必要な素養を挙げてみる

わたくし、QA職について10年近く経つ者です。
たくさんの若者とお仕事をしてきましたが、QAとしてのキャリアの伸ばし方がわからず、戸惑っている人をそれなりに見てきました。

QAとしての成長ルート(「年収の上げ方」と言っても良いかも)は、ある程度、筋道があると思ってまして、キャリアに迷う若者の参考になればと思い、アドベントカレンダーに投稿するのでした。

## 5つのスキル
QAスキルを伸ばすなら、下記のスキルを習得する必要があると思います。下記1～5、順不同で習得しても良いですが、1から順番に習得していくと、無理なくステップアップできる気がします。

1.ドメイン知識
2.ソフトウェアテスト
3.開発知識
4.リーダシップ
5.マネジメント

## ドメイン知識
ざっくりいえば、「 サービスに対する知識」です。

ソフトウェアテストという仕事は、ユーザと同じだけのサービス知識(=ドメイン知識)さえあれば、そこそこ仕事ができます(QAという仕事の間口の広さの理由でもあります)。QA未経験の方は、まずはドメイン知識を覚えると良いでしょう。

サービスそのものに詳しくなったり、類似サービスや業界のことに詳しくなると、業務の質や速度で、他の人と差をつけることができると思います。


* 伸ばし方
    * サービスを隅々まで触る
    * 類似のサービスを触る
    * ゲームであれば攻略サイトなどを見る
    * バグチケットを読み漁る


## ソフトウェアテスト
「QAの先人が積み上げてきたノウハウ」と言い換えても良いでしょう。 より効率よく、より柔軟に、より高度に業務を行うためには、ソフトウェアテストの知識が必要です。

* 伸ばし方
    * インプットを行う(本を読む、セミナーに参加する、勉強会に参加する)
    * アウトプットを行う(ドクベに書く、ブログに書く、セミナーで登壇する、など)
    * 資格勉強をする(JSTQBとか)



## 開発知識
ゲームなりWebサービスなりが、どのように作られているかを知ることです。エンジニア、プランナー、ディレクター、デザイナーが、どんな技術やツールを使って、どんなフローで、どのような成果物を作っているのかを知ることは、上流からのQAを行う上で必要な知識となるでしょう。

ざっくり知っておくだけで良くて、できる必要はありません。

* 伸ばし方
    * 他セクションのスタッフの話を聞く
    * 他セクションの社内ドキュメントを読んでみる
    * 本とか動画でインプットする(開発知識ならドットインストールとか)
    * 趣味でプログラムやデザインをやってみる


## リーダシップ
ここで言うリーダシップとは、「良いと思ったことは、臆せず実行に移せる資質」のことです(※「強引さ」や「わがまま」とは違います)。要は受け身じゃないってことですね。

QAは必ず集団の中で作業をします(QA一人でコンテンツを生み出すことは不可能)。集団の中の一員として、良い結果を出すためには、リーダシップは不可欠です。


## マネジメント
QAリードの立場になると、複数人のQAスタッフを率いて、チームで成果を出さねばなりません。
しかし、人をなんとなく一箇所に集めても、力は発揮されないのが常なので、「集団」を「チーム」にする取り組みが必要となるでしょう。

仮にリードの立場じゃなくても、リードの目線を知っておくと、良い動きが出来ると思います。


## おめでとうございます！
1～5を習得したあなたは、晴れてQAエンジニアの __スタートライン__ に立ちました。

ゴールだと思いきや、ここがスタートラインです。1~5はあくまでQAエンジニアとしての基礎知識です。医者で言えば、医師免許を取ったばかりの状況で、専門的な強みが無い状況。ここから、得意分野を選んで伸ばし、強みを発揮しましょう！

それでは！
防音室の中にいてもインターホンに気づけるようにしたこと

「[PONOS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ponos)」12日目の記事です。
昨日は[@caramel_cafe](https://qiita.com/caramel_cafe)さんの記事でした。
# 防音室の困りごと
最近自宅に防音室を置き始めました。
いつでもお隣さんを気にせず音を出せるので大変良いものなのですが、困ったこともあります。
それが**『インターホンに気づけない』**ことです。
家にいたのに不在票が放り込まれたり、「時間指定配達がいつ来るかわからないから今は防音室に入るのはやめよう」みたいなことが発生していました。

# 電子工作？めんどくせぇ！SwitchBotを使ってなんとかしよう！！
今回はこの問題を既に家に設置していたSwitchBotを利用して解決してみました。
以下の製品を使います。

* [SwitchBot 人感センサー](https://www.amazon.co.jp/dp/B094W18WZM)
* [SwitchBot スマートプラグ](https://www.amazon.co.jp/dp/B07TVSGJT4)

これらのものを使ってインターホンに気づける仕組みを考えました。

1. インターホンが鳴って画面が付く
2. 画面が付いた明るさで人感センサーの明度センサーが反応する
3. スマートプラグと連携して防音室の電源を落とす
4. 防音室の電気が消えるのでインターホンに気づく

というわけで設置した様子がこちらです。
![PXL_20211209_060251608.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356727/0155d9c2-b0bc-9c3b-8c4a-fffe15f39260.jpeg)
見た目は気にしないことにしました。

あとは明るくなったときに電源を消すようなシーンを作成すれば準備完了です！
![Screenshot_20211209-154153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356727/576af9e0-82b7-b181-3088-9bf15e412abc.png)

# 実際に運用した結果
インターホンがなったあと1,2秒のラグはありますが防音室の電源を落とすことに成功しました🎉
これからはインターホンを聞き逃すことがなくなりそうで良かったです。

明日は[@iixd_pog](https://qiita.com/iixd_pog)さんの記事です。お楽しみに！！
[py2rb] getattr

# はじめに
移植やってます
# getattr (Python)
```python
class a:
    def pg(self):
        print("print getattr")

getattr(a(), "pg")()
```
インスタンスメソッドを呼び出しています。

```python
def _accession(self, key):
    return getattr(key, 'accession', None)
```
これは、引数が３つですね。
# respond_to? (Ruby)
```ruby
class A
  def accession
    "A"
  end
end

class B; end

a = A.new
b = B.new

puts a.respond_to?(:accession) ? a.accession : nil
puts b.respond_to?(:accession) ? b.accession : nil
```
@Nabetani さんの [コメント](https://qiita.com/superrino130/items/e48404e48995014c6c1d#comment-053d6ed575a1ee75ad62) を活用させていただきました。
# メモ
+ Python の getattr を学習した
+ 道のりは遠そう