OmniAICreator/Qiita-1.07M huggingface dataset:
docker-compose buildで You must use Bundler 2 or greater with this lockfile.エラーが出る

docker-compose buildをしたときにエラーが発生したため備忘録として残しておきます。
ググってみてもよくある解決策で解決しなかった人のためになれば幸いです。

```ruby:Dockerfile
FROM ruby:2.5.1

RUN apt-get update -qq && \
  apt-get install -y build-essential \
  nodejs\
  mariadb-server\
  mariadb-client

WORKDIR /portfolio

COPY Gemfile /portfolio//Gemfile
COPY Gemfile.lock /portfolio//Gemfile.lock


RUN gem install bundler
RUN bundle install 

RUN mkdir -p tmp/sockets
```

この状態でdocker-compose buidを実行すると以下のエラーが発生。

```
 => ERROR [7/8] RUN bundle install                                                                                                                                                                            0.4s 
------                                                                                                                                                                                                             
 > [7/8] RUN bundle install:
#9 0.430 You must use Bundler 2 or greater with this lockfile.
------
executor failed running [/bin/sh -c bundle install]: exit code: 20
ERROR: Service 'app' failed to build : Build failed
```
ググってみると

https://qiita.com/___fff_/items/8b62633b59d7d72e6719

こちらのサイトがヒットしたが自分の場合はGemfile.lockで既にbundlerのバージョンは2以上であることが判明。

# 原因
このサイトは自分は当てはまらないと考えよくコードを眺めていると...
Gemfile.lockのrubyのバージョンとDockerfileの実装しているrubyのコードが違うことが発覚。

```ruby:Gemfile.lock
RUBY VERSION
   ruby 2.7.3p183
```

# 解決策
DockerfileのrubyのバージョンとGemfileのrubyのバージョンを統一した。
その後、docker-compose buildを実行したら違うエラーが発生。

```
E: Package 'mysql-client' has no installation candidate
ERROR: Service 'web' failed to build: The command '/bin/sh -c apt-get update -qq && apt-get install -y build-essential libpq-dev   mysql-client  nodejs returned a non-zero code: 100
```

https://qiita.com/aseanchild1400/items/d3580366054fee3d2703

こちらの記事によると

# 原因
mysql-client は、 mariadb-client に統合されていることが原因らしい。

# 解決策
Dockerfile内のmysql-client を、 mariadb-clientに変更
これらの編集により無事docker-compose buildを実行することができました。おしまい。
Apache Supersetをdocker-composeを使って立ててみる。

# Apache Supersetをdocker-composeを使って立ててみる。

## 初めに

* Apache　SupersetはRedashなどと同じBIツールの一つ。
* オープンソースなので無料で利用できる。
    * <https://superset.apache.org/>

## docker-compose

```yaml
version: '3.7'
services:
  superset:
    image: apache/superset:2.0.0
    container_name: superset
    ports:
      - "8088:8088"
```

## 初期化Script

* docker-composeでsupersetを起動させた後、行う初期化。

```bash
#!/bin/bash
CONTAINER_NAME='superset'

docker exec -it ${CONTAINER_NAME} superset db upgrade

docker exec -it ${CONTAINER_NAME} superset fab create-admin \
    --username admin \
    --firstname admin \
    --lastname user \
    --email admin@fab.org \
    --password admin

docker exec -it ${CONTAINER_NAME} superset load-examples

docker exec -it ${CONTAINER_NAME} superset init
```

## 動作確認

* ログインできることを確認する。 
* <http://127.0.0.1:8088/>
【Oracle】表ごとのセグメントサイズ合計(表、LOB、索引)を出力する【SQL*Plus】

`dba_segments`は`segment_name`でしか表名・LOB名など指定できないため、表ごと・LOBごとでサイズを見ることになります。
仕様上、「1つの表にかかわる全体のセグメントサイズ」を見積もりたいときちょっと面倒なので、スクリプト作りました。
`union all`でくっつけて`sum`するゴリ押しです。

不要なら`dba_indexes`削除。
`group by`の前か各`select`文に`where OWNER(TABLE_NAME) = '~~~'`指定。
```
--table,index,lob

select OWNER,TABLE_NAME,sum(M_BYTES) from (
select t.OWNER,t.TABLE_NAME,s.BYTES/1024/1024 M_BYTES
from dba_tables t
inner join dba_segments s on
s.SEGMENT_TYPE in ('TABLE','TABLE PARTITION') and
t.OWNER = s.OWNER and
t.TABLE_NAME = s.SEGMENT_NAME
union all
select i.OWNER,i.TABLE_NAME,s.BYTES/1024/1024 M_BYTES
from dba_indexes i
inner join dba_segments s on
s.SEGMENT_TYPE in ('INDEX','LOBINDEX','INDEX PARTITION') and
i.OWNER = s.OWNER and
i.INDEX_NAME = s.SEGMENT_NAME
union all
select l.OWNER,l.TABLE_NAME,s.BYTES/1024/1024 M_BYTES
from dba_lobs l
inner join dba_segments s on
s.SEGMENT_TYPE in ('LOBSEGMENT','LOB PARTITION') and
l.OWNER = s.OWNER and
l.SEGMENT_NAME = s.SEGMENT_NAME)
group by OWNER,TABLE_NAME
order by 1,2,3;
```
MPI.jlつかったコードをバッチジョブで計算すると並列性能が出ない

# 状況
MPI.jlを使って，MPIで並列化したJuliaのコード。普通は以下のように実行すると思います。

```bash
mpiexec -n 10 julia main.jl
```

main.jlがMPI.jl使って並列化したコード。今回はMPIにIntel MPIを使いました。

これが17秒程度で実行できたとします。これをOpenPBSでジョブスケジューリングしている環境で計算を流します。お金がないので，管理ノードと計算ノード兼用のマシンで実行しました。

バッチ処理用のシェルは以下の感じ

```bash:exec.sh
#!/bin/bash
#PBS -q default
#PBS -l nodes=1:ncpus=10
#PBS -j oe             

cd $PBS_O_WORKDIR

# Intel MPIのためのパス設定
source /opt/intel/oneapi/setvars.sh

mpirun -n 10 julia main.jl
```

OpenPBSなので，以下のコマンドでジョブ投入。

```bash
qsub exec.sh
```

普通，コンソールからの実行時間と大差ない時間で終了することを期待しますが， **実行時間がなんと43秒。** 倍以上増加。計算規模を大きくすると，10倍程度の差が出ました。

# 現状の対策
Intel MPIの設定が悪いのかとか環境変数が読み込めてないのかとか，OpenPBSのバージョンが悪いのかとか色々考えました。

ちなみにOSはRockylinux 8.5で微妙に新しいので，Torqueが入らなかったりして，OpenPBSを入れました。OpenPBSの入れ直しも何度かやりましたが，改善せず。

今日たどりついた対策は以下。シェルファイルを以下のようにします。

```bash:execR.sh
#!/bin/bash
#PBS -q default

#PBS -j oe             

cd $PBS_O_WORKDIR

# Intel MPIのためのパス設定
source /opt/intel/oneapi/setvars.sh

mpirun -n 10 julia main.jl
```

nodes=1:ncpus=10の設定を削除しました。こうするとコンソールから直接実行したときと同程度の時間で実行できます。なぜこれでいいのかはよくわかってません。

qstatで状況確認すると，コア数指定してないので，1コアだけ使用しているように見えますが，psコマンドでみると，10並列で計算していることが確認できました。

問題は，ジョブスケジューリング上は1コアしか使ってないようになっていますが，実際は10コアつかってるので，他のジョブが入ってくると，性能が落ちる可能性が高いことです。１つのコアで複数ジョブの計算を行う可能性が高いため。

1ノード専有して，使用するコア数を指定しない計算とかだと問題ないですが，研究室の共有クラスタマシンとかだと問題になりそう。

シェルファイルで専有するコア数を決めると，MPI.jlの処理とかちあって，性能が落ちているのだろうと想像しますが，よくわかりません。
正規表現の先読み/後読み(Look-Ahead/Look-Behind)のカッコをどっちに付けるかがやっとわかった。

# 結論
重要なのはマッチ部分。(goodbye)
で、先読み/後読みのカッコの部分が、マッチ部分のどちらに付ければいいのか、毎回わからなくなっていた。
テキストの順方向に対して、どちら側を見ているかで、カッコを付ける場所が判明する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/f855cea1-931b-b8b1-fb71-02475f79e514.png)
C言語の開発環境をDockerで作る with VisualStudioCode

# リポジトリ
このリポジトリでは下記手順に加えて自動化バッチファイルも作成してあります。パスを変えて使用してください。

https://github.com/sumeshi96/c-env

# 環境
・Windows11 21H2（ローカルOS）
・Ubuntu 22.10(コンテナ)
・Docker Desktop 20.10.14
・VisualStudioCode 1.70.0

# 構想
Dockerfile+docker-compose.ymlでコンテナを構築する。
構築したコンテナにローカルOSのVSCodeからアタッチする。

# ファイル構成
```
c-env
├── .devcontaienr
│   └── devcontainer.json
├── src(ここにソースファイルを置く)
├── docker-compose.yml
└── Dockerfile
```
# コンテナ構築
## Dockerfile
C言語開発環境に最低限必要なのは、build-essentialとgdbだけなのでそれ以外はお好みで。
```dockerfile:Dockerfile
FROM ubuntu:22.10

#コンテナにsudo権限を持つユーザを作成
ARG DOCKER_UID=1000
ARG DOCKER_USER=docker
ARG DOCKER_PASSWORD=docker
RUN useradd -m -s /bin/bash --uid ${DOCKER_UID} --groups sudo ${DOCKER_USER} \
    && echo ${DOCKER_USER}:${DOCKER_PASSWORD} | chpasswd
USER ${DOKCER_USER}

#コンテナ構築時に実行
RUN apt-get update && \
    apt-get install -y git build-essential cmake clang nano gdb
```

## docker-compose.yml
ローカルOSのsrcフォルダをコンテナのc-devフォルダにマウントします。
```yaml:docker-compose.yml
version: '3'
services:
  dev:
    build: .
    container_name: c-env
    volumes:
      - ./src:/c-dev
    tty: true
    user: "1000:1000"
```
上記２つのファイルを使用してコンテナを構築します。
任意のシェルでdocker-compose.ymlがあるファイル（ここではc-env）に移動し、下記コマンドを実行します。
```
docker-compose up
```
処理が終了すればコンテナの構築は終了です。

# コンテナにローカルOSのVSCodeでアタッチ
ここからはローカルOSのVSCodeでの操作になります。
VSCodeの拡張機能である「Remote -Containers」を使用してコンテナにアタッチします。
「Remote -Containers」をインストールすると左にリモートエクスプローラのアイコンが表示されるのでクリックし遷移します。
Dev Containersに先程作成したコンテナがあるのでフォルダのマークをクリックするとコンテナへアタッチできます。

# 動作テスト
hello.cを作成する。
```c:hello.c
include <stdio.h>

int main(void){
    printf("Hello,World!");
    return 0;
}
```
ターミナルでgccコマンドを実行
```bash:bash
gcc -o heloo hello.c
```
helloというファイルが作成されればコンパイル成功。
ターミナルで
```bash:bash
./hello
```
を実行して、ターミナルに「Hello,World!」と表示されれば実行成功です。

これで開発環境の構築は終了です。
Slackで人を褒めている人を褒める、やっさしーいSlack botを作る

# Slack botでやさしいせかいを作りたい！
Slackアプリ制作記事の3本目になります。ちょっと短めです。
前回の記事もぜひ読んでみてください。

https://qiita.com/KojoBarbie/items/1341eb4e75ce81e68368

## 作ろうと思った理由
Slack botくんがたまに「あなただけに表示されています」みたいなメッセージを投稿してくれるのはSlackユーザーだったら心当たりあるかなと思うのですが、それを自分の作っているSlackアプリでできないかなと思ってずっと調べていました。たまたまやり方を見つけることができたので共有がてらその機能を作ったアプリを作ってみました。

## 完成のイメージ
下の画像のように、誰かがほめる投稿をすると、botくんが反応して「すごい！」とか言ってくれます。やさしいせかい。
![スクリーンショット 2022-08-09 180152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671694/0e2bb719-cdf0-42f4-2579-b8147bfd8e1e.png)

## 作ってみる！
下記の記事で作成したアプリをそのまま流用します。この記事から読んでいただいている人はこちらも読んでみてください。

https://qiita.com/KojoBarbie/items/7897db9d5e8ba3dc935d

### 1. Glitchのコードを編集する
glitchに次のようなコードを追加してみてください。追加する場所は一番最後の(async () => {みたいな行よりも前です。

```index.js
// ()の中身を変えればほかの語にも反応するようになる
app.message(/^(ナイス|すごい|神).*/, async ({ message, client }) => {
  console.log(message);
  
  const user = message.user;
  const channel = message.channel;
  
  // その人にしか見えないメッセージを投稿
  await client.chat.postEphemeral({
    text: `<@${user}>さん、ほかの人をほめててえらい！！`,
    channel: message.channel,
    user: user
  });
});

```

chat.postEphemeralで「あなただけに表示されています」の投稿を実現することができています。
↓↓参考

https://api.slack.com/methods/chat.postEphemeral

これまでに投稿した2本の記事以上にSlackアプリの権限を追加する必要はありません。「chat:write」・「message.channels」だけあれば十分だと思います。

### 2. テストしてみる
今回は「ナイス」「神」「すごい」などの言葉に反応するようになっています。早速打ってみましょう。
![スクリーンショット 2022-08-09 180600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671694/8b311601-d212-8188-c807-000ed395b441.png)
無事想定通りに動きましたね。

## 今後やってみたいこと
当初は真逆の「悪い言葉を使っているユーザーに対して、その言葉を伏字に編集して怒る」という機能を考えていたのですが、ユーザーが投稿したメッセージをbotが編集するやり方が見つからず断念しました。
自分のメッセージの編集ならできるんだけど…他人のメッセージを編集するメソッド、ないのかなあ…？そのあたりももう少し調査してみたいと思います。
Docker-composeでnode.jsのUDP通信をテスト。

# はじめに
　世の中には自分の良く使うプログラム言語をローカル環境に入れたくないという人がいるものです(自分)。そのくせしてサーバーの方で環境を整えるのもめんどうという人もまたいます。でもでも、それでも、プログラムの挙動がどうなるのか自分自身で確かめたい。そんな人のためのDocker-compose環境を共有します。
　因みに…一番大事なことの気もしますが…テストするのはタイトル通りUDP通信です。Docker コンテナ同士を内部ネットワークで繋いでUDP通信しています。

# GitHubからクローン

```
git clone https://github.com/DogKingFun/U_AandB.git
```

　予めGitHubに用意しておいたリポジトリからデータを持ってきます。中のAとBのディレクトリにあるnode.jsのプログラムを書き替えてもらえれば十分なテストが可能だと思います。

# Docker-compose

```
docker-compose up
```

　2022/08/09日のバージョンでは、以下のようなログが流れます。

```
Recreating UDP_A ... 
Recreating UDP_A ... done
Attaching to UDP_B, UDP_A
UDP_A | 172.19.0.2:8001 - {"c":1}
UDP_B | 172.19.0.3:8000 - {"c":1}
UDP_B | { c: 1 }
UDP_A | 172.19.0.2:8001 - {"c":2}
UDP_B | 172.19.0.3:8000 - {"c":2}
UDP_B | { c: 2 }
UDP_A | 172.19.0.2:8001 - {"c":3}
UDP_B | 172.19.0.3:8000 - {"c":3}
UDP_B | { c: 3 }
UDP_A | 172.19.0.2:8001 - {"c":4}
UDP_B | 172.19.0.3:8000 - {"c":4}
UDP_B | { c: 4 }
UDP_A | 172.19.0.2:8001 - {"c":5}
UDP_B | 172.19.0.3:8000 - {"c":5}
UDP_B | { c: 5 }
UDP_A | 172.19.0.2:8001 - {"c":6}
UDP_B | 172.19.0.3:8000 - {"c":6}
UDP_B | { c: 6 }
UDP_A | 172.19.0.2:8001 - {"c":7}
UDP_B | 172.19.0.3:8000 - {"c":7}
UDP_B | { c: 7 }
UDP_A | 172.19.0.2:8001 - {"c":8}
UDP_B | 172.19.0.3:8000 - {"c":8}
UDP_B | { c: 8 }
UDP_A | 172.19.0.2:8001 - {"c":9}
UDP_B | 172.19.0.3:8000 - {"c":9}
UDP_B | { c: 9 }
UDP_A | 172.19.0.2:8001 - {"c":10}
UDP_B | 172.19.0.3:8000 - {"c":10}
UDP_B | { c: 10 }
```

# 終わりに
　Docker-composeって便利だなーとGitHubって便利だなーと思いながら使ってますが、何だか使い方が間違えている気がしてなりません。…間違えてたら恥ずかしいな(*ﾉωﾉ)
homebrewでtomcatのインストール

## 概要
homebrewでtomcatをインストール

## やってみる

```
brew install tomcat
```

インストール先
```
/usr/local/Cellar/tomcat/10.0.23
```

## 起動と停止
以下のコマンドで起動と停止が可能
```
brew services start tomcat
brew services stop tomcat
```
Salesforceを毎日異なる環境の設定をしている人におすすめ～Salesforce環境ごとに個性を出す方法

こんにちは。
Salesforceを管理するシステム管理者は、本番環境はもちろんのこと、Sandbox環境を複数開発している場合もあるかと思います。


また、Salesforce業務を生業にする人は複数のお客様のSalesforce環境にログインしているかと思います。


そのさい起こるのが「どの環境に今ログインしているのか？」という問題が発生すると思います。




特にSandboxと本番環境では同じような環境なので
・本番環境で設定していると思ったらSandbox環境だと思った
・Sandbox環境で設定していると思ったら本番環境だと思った

ということが起こってしますかと思います。

では、このような問題が起こらないにはどうすればいいでしょうか

私なりに３つの設定を考えました


### 1.アプリケーションの画像を変更する

アプリケーションの画像を変えると、常に左上に画像の表示がされるので環境ごとに個性を出せます
![2022-08-05 23_18_46-アプリケーションマネージャ _ Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c933a40d-fa50-131a-0cdb-f992ec831dd9.png)
![営業０２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/adb82607-81cd-2803-1418-920eb7e748d4.png)

### 2.ユーザの画像を変更する
ユーザの画像を変えると、常に左上に画像の表示がされるので環境ごとに個性を出せます
ユーザアイコンはLightning環境であれば常に右上に表示されるので、環境ごとのユーザアイコンを変えればどの環境か確認しやすいです
![ユーザ右上.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/59a930d6-c77a-88d8-330a-0477d52fb931.png)


### ３.テーマおよびブランド設定を変更する

テーマおよびブランド設定を変更すると見え方が大きく変えることができます

例えばデフォルトのブランド「稲津リッジ」だとこのように通常と大きく見え方が変わりますね
![テーマおよびブランド設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d27d56d7-3d77-a5f9-7366-a61928dcb6f6.png)

カスタムを作成したらだいぶ変わりますね（さすがにここまで変わると目がつらくなりますね。。）
![カスタム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8d50c9a2-c2f6-2133-72f9-26dbd6d3265b.png)



テーマで注意する点は全ユーザに影響が与えられてしまうことです。
もしも１ユーザでも見え方を変えたくない　という環境ではテーマをいじることをおすすめしません。

今回の内容は動画でも解説しています

https://www.youtube.com/watch?v=32A_1s9viMY

<iframe width="560" height="315" src="https://www.youtube.com/embed/32A_1s9viMY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
[Android]高速に何度も画面遷移する際にクラッシュする[Unable to add window]

# エラー内容
繰り返し画面の遷移を行っている際に時々アプリのクラッシュが起こっていた。
エラー内容は下部。
```
android.view.WindowManager$BadTokenException: Unable to add window"
```

# 解決方法
調べたところContextの拡張関数でAlertDialogを作成していた場面でエラーが起きていた。
ダイアログ生成時に呼び出し元のContextが終了していると起きるらしく、そのため繰り返し高速に画面遷移を行っていた場合に起きていた。

なので作成した拡張関数内で
```kotlin
fun Context.function(){
    if(this is Activity){
        if (this.isDestroyed || this.isFinishing) {
            return
        }
    }
}
```
としてやれば修正された。
速度改善のためRailsコードをGoで書き直して、FFIを使ってみた


railsのコードをgolangに書き直したら、10倍早くなりました
===================================

ffiでgoを呼び出すようにすると早くなるという記事を見たので、

実際に使用してみたら、本当に10倍ほど早くなりました。


## ディレクトリ構成
今回はrailsなのでlib配下にffiディレクトリを用意して、その中にソースコードをおきました。

+ /app
    + /models
        + test.rb
+ /lib
    + /ffi
        + sample.rb
        + .directory-list.md
        + /src
            + sample.go      
            + /model
                + data.go
        + /bin
            + sample.so



## 事前準備

ffiのgemを入れておく
```
gem install ffi
```

go.mod ファイル作成
```
cd lib/ffi/src 
go mod init ffi/src
```
上記を実行すると、下記のようなgo.modファイルが作れられます。

これがないと、各ファイルを呼び出せなくてエラーになりました。
```
module ffi/src

go 1.17

```


## ruby側

sample.rb
```
require "ffi"

class Ffi::Sample

  extend FFI::Library
  ffi_lib File.dirname(__FILE__) + '/bin/sample.so'

  # golangとの接続用
  attach_function :sampleCalc, [:string], :string

end

```

test.rb
```
class Test 
  def execute
        
      test_data = []
      test_data << {
        X: 1,
        Y: 2,
        Comment: "abc"
      }

      test_data << {
        X: 2,
        Y: 3,
        Comment: "efg"
      }
        

      ret = Ffi::PathFind.sampleCalc test_data.to_json
      ret= JSON.parse(ret, :symbolize_names => true)

  end
end
```

## go側

data.go      
```
package model


type Sample struct {
  X int
  Y int
  Comment string
}
```

sample.go      
```
package main

import (
  "C"
  "fmt"
  "encoding/json"
  "ffi/src/model"
  "log"
)



//export sampleCalc
func sampleCalc(sampleJson *C.char) *C.char {

  // jsonをstructに入れる
  sm := []model.Sample{}
  err := json.Unmarshal([]byte(C.GoString(sm)), &sm)
  if err != nil {
      log.Fatalf("gridinfo json parse error : %s\n", err)
  }

       　　　　　　　　　:
       　　　　　　　　　:
      処理を書いていく
      　　　　　　　　　 :
       　　　　　　　　　:

  // structをjson形式に変換
  resultJSON, err := json.Marshal(sm)
  if err != nil {
      log.Fatalf("result json encode error : %s\n", err)
  }

  return C.CString(string(resultJSON)) 

}

```

//export sampleCalc
を記述しないと呼び出しができないようです。

exportの前にスペースが入ってもダメです。

### goをbuildする
goのファイルをビルドします。
```
go build -buildmode=c-shared -o ../bin/sample.so sample.go
```

これでgolangのプログラムrubyから呼び出すことができるようになりました。






### まとめ
今回はハッシュの配列(go側では構造体の配列)を渡す必要があり、

方法が不明だったため、json形式に変換してから受け渡しするようにしました。

もし方法があれば教えていただきたいです。

goでの開発が初めてだったので、調べながらコードを書いたので、

もしかしたらもっと良い方法があるのかも。。

とはいえ、速度は10倍近く速くなったのでよかったです。



### 参考
・[RailsコードをGoで書き直して、FFIを使ってRailsからGoの関数を実行させて実行時間を5%以下に短縮させた](https://cluex-developers.hateblo.jp/entry/2018/06/27/172950)

・[RubyからGoの関数をつかう → はやい](https://qiita.com/achm/items/679b3f3af2cf377f0f02)

・[Go and Ruby-FFI](https://c7.se/go-and-ruby-ffi/)
MacにReact Nativeの開発環境を構築する方法

MacOS に React Native の Android アプリを開発する環境の構築方法を紹介いたします。

# 概要

案件で React Native の Android アプリを開発する環境が必要となったため、メモ用として記事にしました。   
この記事では MacOS 12.4のM1チップ, Android Studio Chipmunk 2021.2.1 を使用しております。  
また、コマンドライン引数に与えるユーザー名は適宜読み替えてください。

# 1. Homebrew のインストール

[Homebrew](https://brew.sh/index_ja) とは macOS 用のパッケージマネージャーのことで、  
今回は Watchman、JDK のインストールで使用します。  
下記のコマンドを実行して Homebrew をインストールします。

```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

# 2. Node.js のインストール

[Node.js](https://nodejs.org/ja/) は JavaScript の実行環境の 1 つです。  
2022年8月1日時点での推奨バージョンは v16.16.0 で、Node.js のパッケージ管理ツールである npm も一緒にインストールされます。  
下記のコマンドを実行して Node.js をインストールします。

```
$ nodebrew install-binary v16.16.0
```

# ※3. Watchman のインストール

[Watchman](https://facebook.github.io/watchman/) はファイルの変更時にアクションを設定することができます。  
今回はソースコードを編集した場合に、ビルドを行うようにするため Watchman を使用します。  
下記のコマンドを実行して Watchman をインストールします。  
**※ Watchman のインストールは React Native の環境構築において必須ではありません。**

```
$ brew install watchman
```

# 4. React Native CLI のインストール

[React Native CLI](https://github.com/react-native-community/cli) は React Native でアプリ開発するためのパッケージです。  
下記のコマンドを実行して React Native CLI をインストールします。

```
$ npm install -g react-native-cli
```

# 5. JDK のインストール

React Native で Android アプリを開発するためには [JDK(Java Development Kit](https://www.oracle.com/java/technologies/downloads/) をインストールする必要があります。  
下記のコマンドを実行して JDK をインストールします。

```
$ brew tap AdoptOpenJDK/openjdk
$ brew install adoptopenjdk/openjdk/adoptopenjdk8 --cask
```

# 6. Android Studio インストール

React Native で Android アプリを開発するためには [Android Studio](https://developer.android.com/studio) をインストールする必要があります。

下記のリンクから Android Studio をダウンロードします。
https://developer.android.com/studio  
インストール過程で、SDK Components Setup 画面が表示されます。  
その際は、Performance(Intel® HAXM) と Android Virtual Device を選択し、Next ボタンを押してインストールを進めます。

## SDK 設定

Android Studio の Preferences を開き、Appearance & Behavior > System Setting > Android SDK の順でタブを開くと、下記画面が表示されます。

![Android SDK](https://gyazo.com/60230d28ee4ff3feaa2761b873847604.jpg "Android SDK")

右下の Show Pacakge Details を選択します。  
そして、リストの中から下記内容を選択します。

- Android SDK Platform 28
- Intel x86 Atom System Image
- Google APIs Intel x86 Atom System Image
- Google APIs Intel x86 Atom_64 System Image

全て選択したら、OK ボタンを押して次の画面に移動します。

# 7. 環境変数設定

環境変数の設定として、 ~/.zshrc ファイルに下記の内容を追加します。

```
export ANDROID_HOME=/Users/"ユーザー名"/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
```

# まとめ
今回は MacOS に React Native の Android アプリを開発する環境を構築する方法を紹介いたしました。  
環境構築自体は難しくないのですが、インストール数が多いため環境構築に時間を要しました。  
また、案件の引き継ぎも兼ねてQiitaの記事にしたことで、マークダウン記法の勉強にもなりました。  
この記事が React Native で Android アプリを開発する方の手助けになれば幸いです。
【Reray】ローカルサーバーでLINE Botの動作確認をする

Rerayで簡単に無料で試せるLINE Botの動作確認方法を紹介します。

# はじめに
近年LINEのユーザー数が増加する一方で、LINEを使用したマーケティングを行う企業が増えてきております。
そのマーケティング手法の1つとしてLINE Botの活用が注目されています。

LINE BotはLINEプラットフォームを通して呼び出されます。そのためLINE BotはLINEプラットフォームから見えるところに存在する必要があります。
つまりインターネットからアクセス可能なところにLINE Botを配置しなければならないのですが、グローバルなネットワーク上に配置するとなるとAWSなどのクラウドサービスやVPSなどのレンタルサーバーなどと契約が必要となり、動作確認や検証をするためだけにも料金が発生してしまいます。

Rerayを使用することで、無料で簡単にローカルで開発中のLINE Botをインターネット上に公開し、動作検証やテストをすることができます。

# 公式サイト
[https://reray.net](https://reray.net)

# 仕組み
![structure_linebot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711406/d5a7e6cc-a600-9e3f-d3c4-ffb0d8bb1674.png)

# Rerayのセットアップ
過去記事で紹介していますので参照ください。非常に簡単です。

https://qiita.com/Reray/items/c58429c301068e1cdda5

# LINE側の設定例
LINE Developersの「Messaging API設定」を開いて、
「Webhook設定」の「Webhook URL」に「https://subsub.reray.net/callback」を入力します。
※「/callback」がLINE Botを呼び出す際のパスとして設定しています。
![webhook_linebot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711406/9843cd52-a56b-3723-6543-75da1103ecbf.png)

Webhook URLを入力して「検証」ボタンを押して、成功が表示されたらOKです。
![webhook_ok_linebot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711406/32edf471-b415-952d-6396-9c5839e16049.png)

Webhook以外の設定はこちら
[https://developers.line.biz/ja/docs/messaging-api/getting-started/](https://developers.line.biz/ja/docs/messaging-api/getting-started/)

以上でローカルで実行中のLINE BotをLINEアプリから呼び出すことができます。
aws-cliとjupyterでAWSサービスのセットアップ

システムセットアップを簡単にするための全ての設定

# 環境
・MacBook Pro
・macOS Mnterey 12.5
・Apple M1 Max

## 1.AWS/IAM
AWSのIAMから、今回のjupyterでアクセスできる権限を持ったIAMユーザーを作成し、アクセスキーとシークレットアクセスキーを入手する。
そのキーの取り扱いには十分に注意する。

## 2.local/仮想環境の作成
仮想環境で実行するのがおすすめ。
Miniforge3+condaで作成しているので、　`conda acrivate hoge` という形で環境に入る。

### モジュールのインストール
`pip install awscli`

## 3.cliの設定
`aws configure --profile hoge`
AWS Access Key ID [None]: `{アクセスキー(各自)}`
AWS Secret Access Key [None]: `{シークレットアクセスキー(各自)}`
Default region name [None]: `{us-west-2（←オレゴン）} OR {ap-northeast-1}`
Default output format [None]: `json`

## 4.cli設定の確認
### IAMのユーザー一覧出力
```terminal
aws iam list-users
```

### 現在のcliプロファイルを出力
```terminal
aws configure list
```

### 指定のプロファイルを出力
```terminal
aws configure list --profile hoge
```

### プロファイルの変更
```
# デフォルト変更
export AWS_DEFAULT_PROFILE=hoge

# 確認
aws configure list
```


### 設定一覧

```terminal
# キーの確認
cat ~/.aws/credentials

# リージョンの確認
cat ~/.aws/config
```
WinMergeで左右キーを押すとマージされるのが困る時はマージモードを解除

# やり方

下記で切り替え可。
この設定はWinMergeの終了後も引き継がれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1e46c6d0-13ee-4ad8-7eb8-9b567cda7b55.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1865
WinMerge Version 2.16.20.1 Japanese + jp-1 ×64
データベース障害管理

データが壊れると困る。
そんな時に```バックアップ```をとってデータベースの内容を別ファイルにコピーして保管する。
バックアップと次のバックアップ間に更新されるとデータの内容は保護されていない。
なので更新された情報を記録するものがある。
それが```ジャーナル```だ。

ジャーナルは更新前と更新後の状態の２つに分けられる。
更新前を```更新前ジャーナル```
更新後を```更新後ジャーナル```と言う。

このジャーナルを保存することによってデータベースの更新履歴を管理する。

これらのファイルを使って```ロールバック```,```ロールフォワード```などの障害回復処理を行う。(この処理で元の状態に戻す)

# コミットとロールバック
データベースは、トランザクション単位で更新処理を管理する。
トランザクション(一連の処理)が問題なく完了できた時に最後にその更新を確定することでデータペースへと更新内容を反映させる。
これを```コミット```と言う。

トランザクションが完了しなかった場合は```コミットは行われない```。
トランザクションのどこかの処理に障害が発生するとデータの整合性が取れなくなってしまうからだ。
こうなってしまうと元の状態に戻してやらなくてはならない。
こう言う時に```更新前ジャーナル```を使う。
更新前ジャーナルを使うとトランザクション開始直前の状態に戻る。

このようにトランザクション前の状態に戻す作業を```ロールバック```と言う。

# 分散データベースと２層コミット
データベースを扱うサーバーは必ず一つではない。
物理的に分かれているデータベースのを見かけ上に一つのデータベースとして扱えるようにしたシステムがある。
それが```分散データベースシステム```だ。

分散していると一部のデータベースだけ更新されていなかったりすること(データの整合性が取れていない）が発生する可能性がある。
そんな時にコミットできるかどうかを各データベースに確認を取る。
```確認が取れたら```書くデータベースに```コミットする（反映する)```。
またはやり直す時はロールバックを行う。

この確認をとってコミットやロールバックを行う方式を```２層コミット```と言う。

# データベースを復旧させるロールフォワード
トランザクションの処理中ではなく、ディスク障害などで突然データベースが故障してしまう場合がある。
そう言う時はバックアップファイルからデータを復元するできる。
しかし
最新のバックアップファイルからの更新情報は欠如したままだ。
この欠如した更新情報は```更新後ジャーナル```から取得してデータベースを障害発生直前までの状態に復旧させる。
この更新後ジャーナルを使ってバックアップ後の更新情報も加えて復旧することを```ロールフォワード```と言う。

# 問題を解いた時に気づいたこと
## ログファイルとは？
* ジャーナルとは、ファイルシステムへの変更や通信記録などの変更を記録すること、または、その変更履歴情報のことである。```「ログファイル」や「ジャーナルファイル」などともと呼ばれる```こともある。
出典 https://www.sophia-it.com/content/%E3%82%B8%E3%83%A3%E3%83%BC%E3%83%8A%E3%83%AB

* ジャーナルもログも情報技術（ＩＴ）用語であり、```どちらもほぼ同じ意味```で使用し、専ら、コンピュータなどの機器が不具合を起こした際に使用する履歴情報のことである。ジャーナルは、```半自動的に記録したその情報により復旧が可能```なデータベースであり、ログは、起動中、自動的に一定の形式で```時系列に記録している情報のことで、それを見ることで何が起きたかを知る```ことができる。
出典 http://koredekaiketu-chigai.lance5.net/z024.html

大体はログファイルとジャーナルファイルも同じ意味として捉えられているのか。

## ダンプファイルとは？
* 拡張子が```「.dmp」```
* データとかを、```そのままの形で出力すること```(```未加工```、人間が見えるように加工をしていない）
* ファイルの型によっては```人間が読むことはできない```。
出典 https://wa3.i-3-i.info/word14682.html

* コンピュータの```メインメモリ（RAM）やレジスタなどのある瞬間```の内容を、ストレージ（外部記憶装置）上の```ファイルに丸ごと写し取った```もの。
* オペレーティングシステム（OS）やアプリケーションソフトが異常終了した際、原因特定の手がかりになるように```最後の瞬間のメモリやレジスタの内容を記録```したダンプファイルが作成されることがある。```「メモリダンプ」（memory dump）「クラッシュダンプ」（crash dump）```などとも呼ばれる。
* ```データベース管理システム（DBMS）```では、バックアップやシステムの移転などのために```ある瞬間のデータベースの内容を丸ごと複製したファイル```をダンプファイルという。
* 機材の故障などでデータが失われた際に、ダンプファイルからデータベースを（ファイル作成時点の状態に）復元することができる。機材の更新などの際にも、```古いシステムで取ったダンプファイルを新しいシステムでリストアすることで円滑にデータベースを移転```することができる。
出典 https://e-words.jp/w/%E3%83%80%E3%83%B3%E3%83%97%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.html#:~:text=%E3%83%80%E3%83%B3%E3%83%97%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A8%E3%81%AF%E3%80%81%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF,%E3%81%AB%E4%B8%B8%E3%81%94%E3%81%A8%E5%86%99%E3%81%97%E5%8F%96%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE%E3%80%82
postされたファイル(画像やExcelファイル等)をDBに登録

# postされたファイルをDBに登録
## ①request.filesで取得したファイルをbyte型に変換する。
```Python:qiita.py
f = request.files['filename'].stream
file = bytes(f)
```
## ②pandasのDataFrameを利用し、DBに登録する。
pandasとsqlalchemyはインストールしておく。
```batch
$ pip install pandas
$ pip install sqlalchemy
```
DB登録までのソース。
```Python:qiita.py
import pandas as pd
from sqlalchemy import create_engine

#接続文字列 user、passwd、localhost、databaseをそれぞれ今回の対象に入れ替える。
engine = create_engine('mysql://user:passwd@localhost/database?charset=utf8')
#DataFrameにファイルを格納
#この時 if_exists がappendだとinsertされる
#tablenameを入れたいテーブルに入れ替える
#かっこがないとインデックスのエラーが出るので、必ず使うこと→{'file':[file]}
df = pd.DataFrame({'file':[file]})
#データ更新部分
df.to_sql(
           name = 'tablename',
           con = engine,
           if_exists='append', 
           index = False,
           chunksize = 10000,
           method = "multi",
          )
```

※ファイルを格納するデータ型は、Blob型に。

insert文に直接「%s」でファイルをバイト変換したを組み込み、実行してみたが書き方が間違っているといわれ
色々試してみたが正解が見つけられなかった。
なので、pandasを使ってみたが個人的にはSQL文を直書きしたい人間なので微妙な感じ。
まだPythonを触れて、一週間前後なのでもしかしたら見つかるかもしれない。

Part2(https://qiita.com/v4ns/items/18df62d59a4cb6c6d843)
Active Recordについて

# Active Recordとは
簡潔に言うと、SQLをRubyに翻訳したもの。
MVCのM（モデル）がデータベースのデータを扱う際、本来であればSQL文でクエリを発行するが、RailsにはActive Recordのお陰で、Rubyでデータベースを操作することができる。
また、SQLではDBシステムによって互換性があるが、Active Recordでは、DBシステムの種類に関わらず、同じ記法が使えるのもメリットの一つ。

# CRUD処理でよく使うメソッド
自身が現在CRUD処理の実装を復習しているので、Create（作成）、Read（参照）、Update（更新）、Delete（削除）の流れでよく使うメソッドをまとめていきます。

# Create(生成)でよく使うメソッド
```ruby
@user = User.new(name: "山田", age: 22)
# userモデルのインスタンスの作成　DBには保存されない

@user.save
# 上記のnewで作成したインスタンスをDBに保存

@user.create(name: "山田", age: 22)
# インスタンスを作成し、DBに保存までまとめて行う
```

# Read(参照)でよく使うメソッド
参照メソッドはかなりあるので、自身があまり使い慣れてないものを中心にまとめます。
```ruby
@users = User.order(created_at: :asc)
# userの作成日時が古い順（昇順）で取得　:descで新しい順（降順）

@user = User.find(2)
# id が 2 のレコードを取得

@user = User.find_by(name: "山田")
# nameカラムで　山田　と一致するものの一番若いレコードを取得

@user = User.where(age: 22)
# ageカラムで　２２　と一致する全てのレコードを取得

@user = User.where.not(age: 20)
# ageカラムで　２０　ではない全てのレコードを取得

```

# Update(更新)でよく使うメソッド
```ruby
@user.update
# findメソッド等で取得したデータを更新
```

# Delete(削除)でよく使うメソッド
```ruby
@user.destroy
# findメソッド等で取得したデータを削除
```







参考：
[【初心者向け】RailsのActive Recordの解説&メソッドまとめ](https://qiita.com/ryokky59/items/a1d0b4e86bacbd7ef6e8)
[Active Record の基礎 Railsガイド](https://railsguides.jp/active_record_basics.html)
Windowsのbatで一定時間後に再起動

# やり方

```bat:5時間後に再起動する例
shutdown /r /t 18000
```

```shutdown``` にオプション付ける。（再起動はshutdownの一種）

```/r``` が再起動のオプション。（rebootのr）
```/t``` で 〇 **秒** 後を指定（timeのt）

18000 = 18000秒 = 60秒×60分×5時間

# シャットダウンコマンドの取消

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

# 蛇足

バッチはメモ帳で作って文字コードはANSIにする必要があることに注意。
最近のメモ帳は新規作成時の文字コードのデフォルトがUTF-8になっています。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1865
JavaScript Code Tips

##### 目録：
- [正規表現の例](#正規表現の例)
- [var let const区別](#var-let-const区別)
- [online練習サイト https://playcode.io/](https://playcode.io/)
- [jsコード勉強サイト](https://trailhead.salesforce.com/ja/content/learn/trails/learn-to-work-with-javascript)
---

##### 正規表現の例
1. /^[0-9]*$/：０から９までの数字の列、数字の数は制限なし。
参考：https://c.runoob.com/front-end/854/

2. 日付け:「2022-09-06 07:30」の様に設置regexp = "^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}$"。
":"はそのまま対照でき；"^"は開始；"$"は終わり；"\d{2}"は数字2桁を対応、でも"\d"の"\"を誤解されない様"\\"を使用。
もし、入力任意の項目で、空白""以外の場合、バリデーションを掛けたい場合、以下の様に設置
```java:"^$"で空白をマッチする、"|"で場合を分ける
regexp = "^$|^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}$"
```

3. 電話番号　:「+819012345678」の様に設置regexp = "^\\+\\d{12}$"

##### var let const区別
`var`、コードブロック`{}`を無視する、
`let`、コードブロック`{}`が有効(varより推奨)、
`const`、定数を宣言、普通のパラメーターは宣言後変更出来ない、が、constdで定義されたオブジェクトの項目やarrayの中身は変更できる
```javascript:constのオヴジェクトの項目は変更できる
const BRANDCOLOR = {
  primary: "blue",
  accent: "teal"
}
BRANDCOLOR.accent = 'gray';
console.log(BRANDCOLOR);
```
renameは便利だぞ～

## はじめに
バックアップを取るために、複数のファイルを一括でリネームしたいことは、度々あるかと思います。そんなときに便利なコマンドが、**rename**コマンドです。Linuxには、ファイル名を変更するコマンドとして**mv**が標準で入っていますが、mvは１ファイル単位でしかファイル名の変更ができません。複数のファイルに対して一括で変更する場合は、renameを使うことになります。renameコマンドは、Ubuntuにはデフォルトではインストールされていないため、もし、インストールされていなければ、新規にインストールしてください。

## 注意事項
renameコマンドは使い慣れると便利ですが、使い慣れるまでは、テストフォルダを作成して、自分がやりたいリネームが実現できているか、テストを行ってから、本番環境で実施してください。コマンドを間違って、想定外のファイル名にリネームしてしまった場合、後から手作業で１ファイルづつ元に戻すことになります。ご注意ください。

## 環境
Ubuntu20.4

## インストール

まずは、インストールされているかどうか確認します。
```
which rename
apt list --installed | grep rename
```

インストールされていないことが確認できれば、インストールします。
```
sudo apt-get update
sudo apt-get install rename
```

正常にインストールされたことを確認します。
```
which rename
/usr/bin/rename

apt list --installed | grep rename
rename/focal,focal,now 1.10-1 all [installed]
```

## 使い方（基礎）
使い方はいたって簡単です。**sed**コマンドを使ったことがある人であれば分かると思いますが、同じような使い方になります。

renameコマンドの使い方の雛形です。
```
rename "s/[置き換えたい単語]/[置き換え後の単語]" [ File-Path ]
```

## 使い方（準備）
テストファイルを３つ作成します。
```
touch test{1..3}.txt
```

空ファイルが３つ作成されました。
```
test1.txt
test2.txt
test3.txt
```

## 使い方（実践）

testをaaaにリネームします。（数字の１桁の部分は?で表しています）
```
rename "s/test/aaa/" test?.txt
```

このようにリネームされます。
```
aaa1.txt
aaa2.txt
aaa3.txt
```

aaaをtestにリネームします。このようにワイルドカードを使うこともできます。
```
rename "s/aaa/test/" *.txt
```

このように元に戻りました。
```
test1.txt
test2.txt
test3.txt
```

自分が個人的によく使う、バックアップファイルの命名法です。ファイル名の先頭にアンダーバーを付加しています。**^**は、ファイルの先頭を表しています。
```
rename "s/^/_/" *.txt
```

このようにリネームされます。
```
_test1.txt
_test2.txt
_test3.txt
```

このようにすれば、元のファイル名に戻せます。変換先に何も指定しなければ、文字を削除することができます。
```
rename "s/_//" *.txt
```

このように元に戻りました。
```
test1.txt
test2.txt
test3.txt
```

拡張子の後に文字を追加することもできます。拡張子の後にバックアップの意味合いを込めて、bkupの文字を追加しました。**$**は、ファイルの末尾を表しています。
```
rename "s/$/.bkup/" *.txt
```

このようにリネームされます。
```
test1.txt.bkup
test2.txt.bkup
test3.txt.bkup
```

このようにすれば、元のファイル名に戻せます。つまり、.bkupの文字列を削除しています。
```
rename "s/.bkup//" *.bkup
```

このように元に戻りました。
```
test1.txt
test2.txt
test3.txt
```

ファイル名の後に、_bkupを付加する場合は、次のようにします。この方法もよくやる、個人的なバックアップの命名法です。
```
rename "s/.txt/_bkup.txt/" *.txt
```

このようにリネームされます。
```
test1_bkup.txt
test2_bkup.txt
test3_bkup.txt
```

_bkupの文字列を削除してやれば、元のファイル名に戻ります。
```
rename "s/_bkup//" *.txt
```

このように元に戻りました。
```
test1.txt
test2.txt
test3.txt
```

## 最後に
確認が終わったら、テストファイルを削除しておきましょう。
```
rm test{1..3}.txt
```
phpMyAdminで既に存在するテーブルのCREATE TABLE文を生成する方法

https://teratail.com/questions/2601
テーブルのページの「エクスポート」から「SQL」で「構造」のみをエクスポートすれば見られると思います。
### 出力したいテーブルを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/05ab80f1-4cd4-82a5-f49c-ed725444524c.png)


### エクスポートをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/5f0d4573-fd6b-b9bd-2537-89ec1cd0722e.png)

### 詳細と出力をテキストで表示するをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/02a52f44-004c-5528-b2c7-b7c1ce42178f.png)

### 構造を選択して実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/b0844677-4f0e-d331-439d-98ada3505b02.png)
VLOOKUPの備忘録(初歩ver.)

## 要旨
GoogleスプレッドシートのVLOOKUPで文字列検索をしたい場合、最後の引数は`FALSE`にしてやらないと事故る。

## 使い方と引っかかった点
```
=VLOOKUP("検索キー", "検索範囲", "返す列の番号", ["検索型"(TRUE or FALSE)])
```

ここで検索キーを文字列にしている場合、第4引数を明示的に`FALSE`(もしくは`0`)にしていないと上手く検索できなかった。

* `FALSE`の場合は、検索キーと完全一致するものを検索する。見つからなかったらエラーになる。
* `TRUE`の場合、検索キーを超えない最大値を返却する。検索キーが数値の場合に最大値を見つける等で有効らしい。

第4引数はオプションだが、デフォルトで`TRUE`が入るため、完全一致検索をする場合は明示的に`FALSE`を代入する。

## ちなみに検索範囲について
第3引数は、返してほしい値が検索範囲の中で左から何番目の列にあるかを1オーダーで指定する。受け付けるのはintの数字だけ。

ちなみに検索範囲において、検索キー列が検索対象列よりも左の列にあることが前提になるらしい。
検索キー列よりも左側の値を返したい場合は、波カッコを使って検索範囲の左側に検索キー列をくっつける。

||A|B|C|
| --- | ---: | ---: |---:|
|**1**|商品NO.|商品名|価格|
|**2**|1|みかん|100|
|**3**|2|りんご|80|
|**4**|3|ぶどう|120|
|**5**|4|なし|150|

これで`商品名`(B列)を検索キー列にして、`商品NO.`(A列)を検索する場合、下のように書ける。
```
=VLOOKUP("ぶどう", {B:B,A:C}, 2, FALSE)    # return 3
```

検索範囲の前に検索キー列を結合しているので、第3引数は`2`(1+1)になる。

## おわり
たまに使わないと忘れるので自分用メモです。
インストーラから入れたnode.jsを削除しnvmをインストールしてnode.jsとyarnも入れる

# node.jsの削除(mac)

①フルパスを取得してどこにnodeがあるか調べる
```
which node
/usr/local/bin/node
```

②削除コマンド
```
sudo rm -rf /usr/local/bin/node

/以降は which node で調べたパスを入力
```

③削除できたか確認
```
node -v
bash: command not found: node

node -v で上記が表示されれば削除完了
バージョンが表示された場合は①〜③を繰り返す
```

④npmの削除
```
sudo rm -rf ~/.npm
```

⑤npmが削除できたか確認
```
npm -v
bash: command not found: npm
```

[参考:ローカルからnode.jsを削除する](https://qiita.com/gaipoi/items/406d6c4b1ccd1733318a)

***

# nvmのインストール

①nvmをインストール
```
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

②念の為.bash_profileを確認
```
open .bash_profile
```
下記が追記されていればOK
```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  
```
足りない文があれば上記をコピーして書き足す

:::note warn
zshの場合、nvmインストール後、
```
open .zshrc
```
上記を実行し、.bash_profileに追記されていた文をコピペして貼り付ける
:::

# node.js、npmのインストール
①最新のnode.jsをインストール（ltsは長期サポート版の意）
```
nvm install --lts
nvm use --lts
```
②インストールされているか確認
```
node -v
v16.16.0

上記のように表示されればOK
```
[参考：nvm + Node.js + npmのインストール](https://qiita.com/sansaisoba/items/242a8ba95bf70ba179d3)

# yarnのインストール
①npm 経由でyarnをインストール
```
npm install -g yarn
```

②yarnのバージョンを確認
```
yarn -v
```
[参考：yarnをインストールする](https://qiita.com/suisui654/items/1b89446e03991c7c2c3d)

お疲れ様でした。
【自分用】VS Code拡張機能一括インストールコマンド覚書【Win/Mac/Linux兼用】

コマンドを実行すると`~/.vscode/extensions/`フォルダを掘ってそこに機能拡張を突っ込まれます。
`code`は VSCode のプログラムファイル名です（`code.exe`など）。

下記のコード領域をPowerShellやターミナルなどにコピペすれば、以下のすべての拡張機能を一発でインストールできます！

```sh
# PHP
code --install-extension valeryanm.vscode-phpsab              # php の linter と自動フォーマッター
code --install-extension junstyle.php-cs-fixer                # php の linter と自動フォーマッター（サブ）
code --install-extension felixfbecker.php-intellisense        # php の自動補完
code --install-extension neilbrayfield.php-docblocker         # phpdoc コメントの入力補完

# フロントエンド自動整形
# code --install-extension esbenp.prettier-vscode

# CSS
code --install-extension HookyQR.minify   # JS/CSS の圧縮ツール

# javascript
code --install-extension dbaeumer.vscode-eslint   # JS 用の Linter
code --install-extension lllllllqw.jsdoc  # JS 用の関数コメントヘルパ

# 変換
code --install-extension ahebrank.yaml2json

# VSCode
code --install-extension ms-ceintl.vscode-language-pack-ja  # VSCode 日本語パック

# Markdown
code --install-extension shd101wyy.markdown-preview-enhanced  # Markdown の高性能プレビュアー
code --install-extension tht13.html-preview-vscode            # Markdown を HTML で出力する
code --install-extension yzane.markdown-pdf                   # Markdown を PDF で出力する
code --install-extension marp-team.marp-vscode                # Markdown でスライドを作成し、PDF で出力する

# editconfig
code --install-extension editorconfig.editorconfig  # テキストファイル全般の自動フォーマッター

# excel
code --install-extension GrapeCity.gc-excelviewer  # Excel ファイルビュアー

# sftp
code --install-extension Natizyskunk.sftp  # sftp 自動/手動アップロードクライアント

## ドキュメント管理
code --install-extension ics.japanese-proofreading     # textlint（日本語校正）
code --install-extension vanadium23.markdown-hashtags  # ハッシュタグ検索
code --install-extension oderwat.indent-rainbow        # インデントハイライト

# コーディング補助
#code --install-extension GitHub.copilot
code --install-extension kiteco.kite
code --install-extension oderwat.indent-rainbow  # インデントの深さを色で判別できるようにする

# Git
code --install-extension eamodio.gitlens   # カーソル位置の行が誰によっていつコミットされたかを表示する

# 作図
code --install-extension hediet.vscode-drawio  # ドローツールの draw.io で作図できる
```

現在インストール済みの機能拡張一覧を表示するコマンド。

```sh
code --list-extensions
```

## さいごに

おすすめの拡張機能がある場合、拡張機能名だけだと重複しているケースが散見されるので、パッケージ名（`ms-ceintl.vscode-language-pack-ja`みたいなやつ）で指定しましょう！
FileMaker Web ビューア


https://qiita.com/YKInoMT/items/f64893568b90158ad030

基本的には URL を指定するが、下記の様な感じで HTML 自体を書くことも可能。

```
"data:text/html,
<html>
・
・
・
・
</html>"
```

全体を　`"` （ダブルクォーテーション）で囲う必要があるので、html 内で `"` は使えないので、`'`（シングルクオーテーション）で置き換えるなどの対応が必要。

要は、データ URI スキームなので、メモ帳とかも埋め込める。

```
"data:text/html, <html contenteditable>"
```

なので、画像もいけるっぽい。

```
"data:image/png;base64,エンコードした文字列"
```

# Java Script
Java Script も動くが、script タグの中の改行が除去されてしまうので、 `//` を使ってコメントアウトしようとすると意図しない挙動になるので注意。

例えば、下記の様なソースを指定したとすると、 `alt` 関数は動きますが `modify` 関数は動きません。

```html
<html>
<head>
<script type='text/javascript'>
    function alt(){
        window.alert('!!!!!');
    }
    // Before to After
    function modify() {
        document.getElementById('test').textContent = 'After';
    }
</script>
<title>JSテスト</title>

</head>
<body>
<button onclick='alt()'>!</button><br>
<button onclick='modify()'>modify</button>
<p id='test'>
Before
</p>
</body>
</html>
```

FileMaker クライアントで見ててもよく分からないのですが、WebDirect 使って Chrome とかのデベロッパーツールを使うと下記の様な感じになってることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84947/890da3e5-7f93-c2ca-c99c-f012393b4169.png)

`// Before to After` から変なことになってますが、そもそも script タグ内の改行が全部無くなってる様に見えます。

結果として、下記の様な感じで途中からコメントアウトされてしまい、 `modify` 関数が定義されてない状態になるわけです。

```html
<script type="text/javascript">
     function alt(){              window.alert('!!!!!');          }     // Before to After     function modify() {         document.getElementById('test').textContent = 'After';     }      
</script>
```

と言うことで、script タグ内でコメント書きたい場合には、ブロックコメントを使うしかなさそうです。

```html
<script type='text/javascript'>
    function alt(){
        window.alert('!!!!!');
    }
    /* Before to After */
    function modify() {
        document.getElementById('test').textContent = 'After';
    }
</script>
```

これなら、改行がなくなっても大丈夫。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84947/6ec2c1e8-96a8-53d6-7f42-d999933b39dc.png)

ちなみに、この挙動は 「Web　ビューアの設定　> Web　アドレス」 で指定した場合は発生せず、「指定」から「計算式の指定」で設定した場合のみ発生する模様。

つまり、
![スクリーンショット 2022-08-23 10.31.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84947/faf6c9fa-b759-9a3b-488d-0ead75652a11.png)
ここで指定する分には改行は除去されない。

が、
![スクリーンショット 2022-08-23 10.33.12 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84947/e3bf494b-e202-3cf8-2f1b-99c0be1a483e.png)
こっちで指定すると入力された内容から改行が取り除かれる。（スペースに置換される？）

どちらにせよ、HTML　はテキストエディタなどから貼り付けるケースが大半だと思うので、「計算式の指定」ではなく「Web アドレス」に貼り付けた方が良さそう。

どうしても「計算式の指定」で設定したい場合には、`¶` を行末に入れれば改行される。
めんどいのでテキストエディタの行末置換で `¶` を入れるとかでも良いかも。
そうだ、mysql8.0サーバーを構築してみよう

社内ブログを久々に書きました。
https://tech.torico-corp.com/blog/%E3%81%9D%E3%81%86%E3%81%A0mysql80%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/
知っていて当たり前-17　三項演算子と ifelse()

# 知っていて当たり前-17　三項演算子と ifelse()

## 1.　三項演算子 `? :`


```julia
x = 3
x > 0 ? true : false
```




    true



## 2.　関数 `ifelse()`

引数がスカラーの場合は三項演算子と同じ結果になる。


```julia
ifelse(x > 0, true, false)
```




    true



関数がベクトルの場合は場合により不適切な結果になる。

以下の例では，`sqrt(abs(x))` を `sqrt(x)` にすると「`sqrt` の引数が負である」というエラーが生じる。

`ifelse()` は**第 2，第 3 引数を両方とも評価**し，第 1 引数の結果によりどちらかを返す。そのため引数が負の場合も `sqrt(x)` を実行するのでエラーが生じるのである。 


```julia
x = [-3, 0, 5]
@. ifelse(x >= 0, sqrt(abs(x)), x)
```




    3-element Vector{Real}:
     -3
      0.0
      2.23606797749979
日本で開発者コミュニティを構築しようとする CNCF Wasm Runtime (オープンソース)

初心者です、よろしくお願いします。 これが質問なのか記事なのかわからない?


Please give us some advice on how to build a devs community in Japan around WebAssembly, rust, Serverless functions, and WasmEdge?

We would like to build a small discussion group with topics like Serverless, cloud-native, K8s containers technologies and [find/ hire contributors who can help give features suggestions, raise issues on GitHub, or help translate](https://jobs.cncf.io/jobs/142577358-japanese-devrel-advocate-at-second-state-inc) WebAssembly blog articles and docs into Japanese. アドバイスをお願いします。

2022年12月7日 KubeDay Japanが横浜にやってきます. Open Source Summit Japanの翌日にリアルイベントとして開催されます。話をして開発者に会いたいです。

ノート:
[WasmEdge](https://wasmedge.org/)は軽量かつ高性能なオープンソースWebAssemblyランタイムです。Second State社が中心となって開発し、現在はCloud Native Computing Foundation（CNCF）のサンドボックスプロジェクトの一つになっています。

コンテナ標準のOCI対応、クラウドネイティブなWebAssemblyランタイム「WasmEdge」が、CNCFのサンドボックスプロジェクトに採用 — Publickey
WasmEdgeは主にC++で記述されており、公式のSDKを使うことで、C、Rust、Goなどで書かれたアプリケーションにWebAssemblyランタイムを組み込むことができます。


開発元のSecond State社は、このRust SDKの利用と開発を促進するために、期間限定の懸賞プログラムを発表しています。

参加を歓迎します:
[WasmEdge Rust SDKのバグを報告してNintendo Switchを勝ち取ろう](https://qiita.com/MileyFu/items/bb352b303d9974634579)（翻訳協力: @tatsuya6502）
サーバー移行| リダイレクト| .htaccess

# .htaccessとは
### 役割：ウェブサーバの設定ファイル
詳細：htaccess ファイルの命令文にしたがってサーバが処理してくれる
読み方：どっとえいちてぃーあくせす
### ルール
- ファイル名は".htaccess" 
- 文字コードはUTF-8(BOM無し)
- 改行コードはLF
- ファイルの最終行に空行を入れる
- httpd.conf で許可されている命令のみ指定可能
- 有効範囲は配置したディレクトリ以下


## オンラインツール
### 生成ツール
https://www.htaccessredirect.net/

http://www.htaccesseditor.com/

https://htaccess.cman.jp/explain/redirect.html
### チェックツール
https://tool.mface.jp/redirects/


## リダイレクトとは
ページに訪れたユーザーを別のページに転送すること


## リダイレクトの必要性
- 訪問ユーザー対策：サイトリニューアルやサイト移転の際、ユーザーに新しいURLを自動的に案内する
- 検索エンジン（Google）対策：古いURLに対する検索エンジンの評価を、新しいURLに引き継ぐ


## リダイレクト設定の書き方
### ドメイン移転 (301リダイレクト)
:::note info
#RewriteEngine を起動（コメントアウト）
RewriteEngine On
RewriteCond %{http_host} ^`www.old.com`
RewriteRule ^(.*) https://`www.new.com`/$1 [R=301,L]
:::
または

:::note info
Redirect permanent / https://`www.new.com`/
:::
※注意※
階層を保持しつつリダイレクトされるため、特定のページのみを違う場所へ転送させたい場合には、最初に書いておく

### ページのURL変更1
:::note info
RewriteEngine on
RewriteRule ^`old.html`$ /`new.html` [R=301,L]
:::
※`^` は正規表現の先頭を表す

### ページのURL変更2
:::note info
RewriteEngine on
RewriteRule https://`www.old.com/old.html` https://`www.new.com/new.html` [R=301,L]
:::
または

:::note info
Redirect permanent /old.html` https://`www.new.com/new.html`
:::

### ディレクトリの変更
:::note info
RewriteEngine on
RewriteRule ^`old`(.*)$ /`new`$1 [R=301,L]
:::

## モジュール
### mod_rewrite 
要求された URL をオンザフライで書き換える
| ディレクティブ | 処理 | 備考 |
|:-----------:|:------------:|:------------:|
| RewriteEngine | 処理の制御 |  |
| RewriteBase | リダイレクト先のベースディレクトリ指定 | ※.htaccess が置かれたディレクトリから相対パス | 
| RewriteRule | 書き換え | [R=301] ＝レスポンスコードを301に指定、 [L]＝（last）URLの書き換え処理終了 |
| RewriteCond | 条件定義 | RewriteRule ディレクティブの前に設置 |
| RewriteOptions | オプションを設定 | ディレクティブORサーバ単位 | 

### mod_alias
サーバにリクエストが到着したときに URL の操作や制御をする
| ディレクティブ | 処理 | 備考 |
|:--:|:--:|:--:|
| Redirect | リダイレクト | リダイレクト元の URL は、/ で、リダイレクト先の URL は絶対 URL で始める。※permanent＝恒久的にリダイレクト|
| RedirectMatch | 正規表現を用いたリダイレクト |  |


# 参考サイト
https://murashun.jp/article/programming/htaccess/index.html

https://www.crosswalk-seo.com/seo/%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95/

https://www.itti.jp/web-design/htaccess-redirect/

https://fastcoding.jp/blog/all/frontend/htaccessredirect/

https://service.grannet.co.jp/blog/htaccess_redirect
OpenStack Yoga

OPCELの資格を取りたくて、OpenStackを叩き始めたのはいいとして、
資格勉強本がREST API使って、サービス使ったりコマンド
を叩くためのトークンをKeystoneから発行するURLが全くわからなかった。

環境： Ubuntu-20.04.4
OpenStack: Yoga
構築方法： DevStack

~~~~~bash
#!/bin/bash
curl "http://localhost:5000/v3/auth/tokens"
~~~~~

普通はこのポートとURLにあるらしい。。。

でなんらかのヒントを得ようと "admin-openrc.sh"
を見たら、
~~~~~~bash
export OS_AUTH_URL=http://192.168.0.10/identity
~~~~~~
ってラインがあって、これの配下に無いかなって叩いたら大金星。

~~~~~bash
curl -i \
  -H "Content-Type: application/json" \
  -d '
{ "auth": {
    "identity": {
      "methods": ["password"],
      "password": {
        "user": {
          "name": "admin",
          "domain": { "id": "default" },
          "password": "your_password"
        }
      }
    }
  }
}' \
  "http://localhost/identity/v3/auth/tokens"; echo  
~~~~~
CADS Deployment Managerのインストール on Windows

# 解凍
SPSS_C_DS_DM_8.4_MW_M.zipを解凍します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/122018ed-3a38-7d71-9ce0-991105c7fdcd.png)

DeploymentManager_win64.exeを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b1448b67-3c68-b126-83de-bf5fb17626d5.png)

「OK」で進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7fe89326-9dfd-8def-0b6a-0915d1867a30.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c5508428-f87a-18e6-48ed-2a1d12aa3887.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b2334770-f9a2-5b79-6103-cd18739e0677.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e935782d-7312-80bf-de3b-3a73e2cf8502.png)

「In a new Program Group」を選び、「Create Icons for All Users」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/baec2a45-8141-1ab9-bba4-766b184980b6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/33876a1d-ca19-f78f-084c-e3faac781fbd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/df9688af-d46c-fd82-d877-f55e3a40d905.png)

# 接続

Deployment Managerを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0568b132-2f95-3e3c-aede-48623c47465b.png)

初回は、接続を定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/18058899-66e4-66cc-88db-05d3d278526f.png)

接続名とCADSサーバーのURLを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c204a174-0824-4cc2-8fd0-dcfff11f65a9.png)

登録した接続を右クリックし、「IDを指定してログオン」を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f010a635-1d1c-6fd2-0d64-5bd39c566150.png)

CADSのユーザーでログインします。adminのパスワードはインストール時に決めたものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/29053ee4-4799-a12b-e6c3-6c09ec6acca6.png)

少し待つと機能がCADSサーバーからダウンロードされて更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1b6439e3-cb12-ba75-5d5a-0dd140c7a900.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0e425743-1903-f043-148c-0d25055f300b.png)

一度閉じて、Deployment Managerを再起動して、ログインしなおすとコンテンツエクスプローラが開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/12f43d4f-81af-cc70-d6f0-772a52e0529b.png)

# 環境
* Windows Server 2019
* Windows 11
* CADS 8.4
CADSのファイアウォール設定 on Windows Server

CADSに接続するためにファイアウォールの設定を行います。

「Windows Defender ファイアウォール」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/43a1176a-780a-82d1-b192-a8bfa7257467.png)

「詳細設定」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8b5cf1b3-a19d-b84f-7aee-3ab2135285a1.png)

「受信の規則」を選び「新しい規則」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d0a5dd8e-8771-ba04-bbed-9bb6cd2ff22e.png)


「ポート」を選び、「次へ」で進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0873a570-c7d3-a758-5bdc-6a537c367b23.png)

特定のローカルポートにCADS接続で使うポートを設定します。httpなら9080、httpsなら9443がデフォルトです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cf2507c8-4903-bc0f-12fa-f992db92f983.png)

「接続を許可する」のまま、「次へ」で進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/493ff5bf-4d0f-df4c-3911-62aaae5d3700.png)

対象ネットワークを選択し、「次へ」で進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/210d49af-79d5-8812-230f-171c925aaefb.png)

「名前」や「説明」を入力して、「完了」で閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/90d933fe-ca08-0f92-0c74-84d4de80f9a6.png)

登録ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e5ee7fa5-000b-c6af-6f72-d15c08385f3c.png)

# 環境
* Windows Server 2019
* CADS 8.4