OmniAICreator/Qiita-1.07M huggingface dataset:
【javascript】Symbol()を使ってfilterMap()

#前置き

前回

https://qiita.com/noenture/items/121575071fec9fa11dd6

フィルタでfalsyな要素は`Symbol('ignore')`を返すようにする。

#function

```javascript
const APPS = {
	ignore: Symbol('ignore'),
	filterMap: (array, func) => {
		const arr = array.slice();
		const res = [];
		for (let i=0,len=arr.length; i<len; i++) {
			const v = func(arr[i], i, arr);
			if (v!==APPS.ignore) res.push(v);
		}
		return res;
	}
};

const arr = [...Array(10).keys()];
const chunk = APPS.filterMap(arr, (x,i,a) => i%3===0 ? a.slice(i,i+3) : APPS.ignore);
console.log( chunk );	//[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
```

これも`defineProperty`を使って設定したほうが良かったかも？

```javascript
const APPS = {
	ignore: Symbol('ignore')
};
Object.defineProperties(APPS, {
	ignore: {
		writable: false,
	},
	filterMap: {
		value: (array, fn) => {
			const arr = array.slice();
			const res = [];
			for (let i=0,len=arr.length; i<len; i++) {
				const v = fn(arr[i], i, arr);
				if (v!==APPS.ignore) res.push(v);
			}
			return res;
		},
	},
});
```
#Array.prototype

```javascript
if (!Array.prototype.filterMap && !this.ignore) {
	Object.defineProperty(Array.prototype, 'filterMap', {
		value: function(fn) {
			const arr = this;
			const res = [];
			for (let i=0,len=arr.length; i<len; i++) {
				const v = fn(arr[i], i, arr);
				if (v!==ignore) res.push(v);
			}
			return res;
		},
	});
	const ignore = Symbol('ignore');
	Object.defineProperty(this, 'ignore', {
		get() {
			return ignore;
		}
	});
};

const arr = [...Array(10).keys()];
const chunk = arr.filterMap((x,i,a) => i%3===0 ? a.slice(i,i+3) : ignore);
console.log( chunk );	//[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
```

**ignore**を`this.ignore`ではなく`Array`内部に留めたかったけど、しっくりこなかった。
Mavenで外部jarを扱う方法

# 方法

pom.xmlでjarを指定する。jarの場所は基本的にどこでも問題ないが、一般的にはプロジェクトルート配下のlibフォルダに配置されることが多い。以下はプロジェクトルート/libに配置した際の例。

```xml:pom.xml
<dependencies>
  <dependency>
    <groupId>jp.co.mylib</groupId>
    <artifactId>mylib</artifactId>
    <version>1.2.3</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/mylib-1.2.3.jar</systemPath>
  </dependency>
</dependencies>
```


```${project.basedir}``` はプロジェクトのルートを指す。

上記の設定でビルドは通るが、```mvn package```を実行した際に上記で指定したライブラリが含まれないためにサーバ実行時にエラーになる。パッケージに含めるよう以下の設定を追加する。


```xml:pom.xml
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <phase>compile</phase>
          <goals>
            <goal>copy-dependencies</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
      </configuration>
    </plugin>
  </plugins>
</build>
```
新method追加２

searchアクションのルーティングを設定しよう
-

|今回はsearchという命名で、7つの基本アクション以外のアクションを定義します。|
|--|


**collection**と**member**を学習します。

collectionとmember
-

collectionとmemberは、ルーティングを設定する際に使用できます。
これを使用すると、生成されるルーティングのURLと実行されるコントローラーを任意にカスタムできます。

collectionはルーティングに:idがつかない、memberは:idがつくという違いがあります。
=
1つずつ使用例を見ていきましょう。

【例】collectionで定義した場合

```rb
Rails.application.routes.draw do
  resources :tweets do
    collection do
      get 'search'
    end
  end
end
```

【例】collectionのルーティング

```rb
Prefix           Verb    URI                                 Pattern
search_tweets    GET    /tweets/search(.:format)              tweets#search
```

ルーティングに:idが付いていないことがわかります。

続いてmemberの場合を見てみましょう。

【例】memberで定義した場合

```br
Rails.application.routes.draw do
  resources :tweets do
    member do
      get 'search'
    end
  end
end
```

【例】memberのルーティング

```rb
Prefix           Verb    URI                                 Pattern
search_tweet      GET    /tweets/:id/search(.:format)       tweets#search
```

URLの指定先が、collectionは:idなし、memberが:idありとなっていることが確認できますね。

今回の検索機能の場合、詳細ページのような:idを指定して特定のページにいく必要がないため、collectionを使用してルーティングを設定しましょう。

routes.rbを以下のように編集します。

```rb:config/routes.rb
Rails.application.routes.draw do
  devise_for :users
  root to: 'tweets#index'
  resources :tweets do
    resources :comments, only: :create
    collection do
      get 'search'
    end
  end
  resources :users, only: :show
end
```
Pythonを使ってElasticsearchへ文字列の配列を登録する方法


Pythonを使用してElasticsearchへ
文字列の配列を登録する

Elasticsearchのマッピングは特殊なことはなく，
typeをキーワードに指定すれば良い

```mapping.py
#!/usr/bin/python3
# -*- coding:utf-8 -*-

from elasticsearch import Elasticsearch

es = Elasticsearch('http://localhost:9200')
mapping = {
    "mappings": {
        "properties": {
            "category" : {"type" : "keyword"}
        }
    }
}

es.indices.create(index="test", body=mapping)
es.close()
```

```
$ ./mapping.py
```

にて，マッピング

```regist.py
#!/usr/bin/python3
# -*- coding:utf-8 -*-

from elasticsearch import Elasticsearch

es = Elasticsearch('http://localhost:9200')
data = {
    "category" : ["aaa", "bbb", "ccc"]
}

es.index(index="test", body=data)

es.close()
```

上記のdataのように
配列はそのまま登録することが可能

```
./regist.py
```

で文字列の配列を登録することができる

配列を登録しておくことで，
Kibanaでの可視化の際にカテゴリごとの表示といったことが可能
has_secure_password　とは（rails）


has_secure_passwordは簡単に言ったらユーザー登録やログインの時に出てくるパスワード入力に関するrailsのメソッドです。
has_secure_passwordを用いることで少ないコードでパスワードを安全に保管できるようにしてくれたり、ユーザー登録画面によくある、パスワード、確認パスワードなども作成できるようになります

今回はその__has_secure_password__についてしっかりまとめていきたいと思います。

##has_secure_passwordの使用方法

```ruby:app/models/user.rb
class User < ApplicationRecord
・
・省略
・
  has_secure_password
end
```

##has_secure_passwordでできること
has_secure_passwordを用いると主に3つのことが可能になります
①セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
②2つのペアの仮想的な属性（passwordとpassword_confirmation）が使えるようになる。
③authenticateメソッドが使えるようになる（引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド）

###①セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
入力したパスワードをそのままデータベースに保存するのはセキュリティー上良くありません。
そのため__has_secure_password__を用いてハッシュ化といういわゆる暗号化を行い暗号化した状態でデータベースに保存します。
そしてログインするときなどにパスワードを入力すると思いますがそのパスワードもハッシュ化され、ハッシュ化されたパスワード同士を比べることでパスワードがあっているかどうかを確認します。
ハッシュ化にはさまざまなハッシュ関数が使われますが僕は__'bcrypt'__を使っています
下記のようにGemfileファイルに追加して使用します

```ruby:Gemfile
gem 'bcrypt','3.1.13'
```

###②2つのペアの仮想的な属性（passwordとpassword_confirmation）が使えるようになる。
__has_secure_password__を使うには1つ条件があり、それはモデル内に__password_digest__という属性が含まれていることです。（password,password_confirmation属性はhas_secure_passwordを用いることで自動に仮想的に作成され、フォームにも利用できるのでモデルで明示的に作成する必要はありません）
例えば、ユーザー登録に名前、メールアドレス、パスワードが必要ならば下記のコードをコマンドに記述すれば良いです

```ruby:コマンド
rails generate model User name:string email:string password_digest:string
```
このようにモデルにpassword_digest属性を追加することによってhas_secure_passwordメソッドが使えるようになり、仮想的な属性（passwordとpassword_confirmation）もフォームで使えるようになります
以下に使用例を記述します

```ruby:app/view/shared/form.html.erb
<%= form_with(model: @user, local: true) do |f| %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.email_field :email  %>

      <%= f.label :password %>
      <%= f.password_field :password  %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation  %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
```
少し難しい記述はありますが、まず@userでユーザーモデルを元にフォームが作られていることがわかります。
そして、name,email,password, password_confirmationがフォームで使用されていることがわかります。
password_confirmationはモデルで明示的に記述していませんが、password_digestを追加することとhas_secure_passwordを記述することによって仮想的に作成され、使用できるようになっています

###③authenticateメソッドが使えるようになる
authenticateメソッドは非常に簡単で、authenticateメソッドの引数の文字列をハッシュ化した値と、データベース内にあるpassword_digestカラムの値を比較します。
その結果が同じならばTrue、違っていたらFalseを返します

```ruby:railsconsole
>> User.create(name: "Michael Jordan", email: "Jordan@example.com",
?>             password: "Michael", password_confirmation: "Michael")

>> user.authenticate("not_the_right_password")
false

>> user.authenticate("Michael")
True

```
Go 1.16用Makefile

[『改訂2版 みんなのGo言語』](https://www.amazon.co.jp/%E6%94%B9%E8%A8%822%E7%89%88-%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEGo%E8%A8%80%E8%AA%9E-%E6%9D%BE%E6%9C%A8-%E9%9B%85%E5%B9%B8/dp/4297107279)のMakefileがGo 1.16では動かなかったので、動くように書き換えました。

# フォルダ構成
`cmd/myapp/main.go`にメインアプリのソースコードが入っている。internalは内部でしか使わないパッケージ、pkgは外部から参照可能なパッケージ。

```shell
myproj/
├── Makefile
├── README.md
├── go.mod
├── bin/
│   └── myapp(ビルド後に生成)
├── cmd/
│   └── myapp/
│       └── main.go
├── internal/
└── pkg/
```

# Makefile

```makefile
# メタ情報
NAME := myproj
VERSION := $(gobump show -r)
REVISION := $(shell git rev-parse --short HEAD)
LDFLAGS := -X 'main.revision=$(REVISION)'

export GO111MODULE=on

.PHONY: deps
deps:
	go mod tidy

# 必要なツール類をセットアップする
.PHONY: devel-deps
devel-deps: deps
	go install \
		golang.org/x/lint/golint@latest
	go install \
		github.com/x-motemen/gobump/cmd/gobump@latest
	go install \
		github.com/Songmu/make2help/cmd/make2help@latest

# テストを実行する
## Run tests
.PHONY: test
test: deps
	go test ./...

## Lint
.PHONY: lint
lint: devel-deps
	go vet ./...
	golint --set_exit_status./...

## build binaries ex. make bin/myapp
bin/%: cmd/%/main.go deps
	go build -ldflags "$(LDFLAGS)" -o $@ $<

.PHONY: build
build: bin/myapp

## Show help
.PHONY: help
help:
	@make2help $(MAKEFILE_LIST)
```

## 実行手順
```shell
# makeで用いるツールのグローバルインストール
make devel-deps
# バイナリのビルド
make build
# 実行
./bin/myapp
```
アーキテクチャってなんや？？

#アーキテクチャってなんや？
アーキテクチャについて調べていたらゲシュタルト崩壊おこしたので、その言葉そのものの意味とIT分野で使用されるアーキテクチャとはなんぞやに紐づけて脳内整理するための記事。

##経緯
新しくアプリ開発を進めていく上で「ディレクトリ構成はどんなにすればええんやろか？」という疑問から調べていくと、「アーキテクチャ」という言葉がでてきた。「アーキテクチャ？なにそれ？おいしいの？」状態だったので、初学者なりに調べたのでアウトプット用にまとめてみます。

##アーキテクチャ（architecture）の語源ついて
古代ギリシアまで遡り「アルキテクトーン」という言葉が語源らしい。

##もともとは建築学で使用されていた言葉
建築様式のこと。建築様式とは「特定の特徴を持った建造物の様式」、またはその「建築手法」「構造」「対象物を特徴づける特定の建築手法」のこと。
これらの意味からIT分野でのアーキテクチャへ派生していったとされる。

##本題：IT分野において
情報システムの「設計方法」、「設計思想」、及びその「設計思想に基づいて構築されたシステムの構造」などのこと。
>IT用語辞典BINARY
>https://www.sophia-it.com/content/%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3

ん～、なんとなくわかったような気になれる。。。
それぞれどういう意味かも調べてみよう。

### 設計方法
業務の仕組みやコンピュータ・ソフトウェアを開発するための手法。開発のやり方や考え方そのものを扱う大きい枠の設計方法から、細かい機能を実装していくか過程を決める設計方法など、様々な層の設計方法がある。
例：ウォーターフォール開発、アジャイル開発、スパイラル開発など

### 設計思想
プロダクトを設計する際に意識する理念。理念とはプロダクトのあるべき姿に関するものであり、プロダクトの特徴として現れる。
設計は、今までにないものを作り上げるため、設計することへの意味付けが必要とされる。そうでないと、無意味なプロダクトが世にあふれることになる。
例：こだわりや設計に対する要求や実現方法の選択における優先順位付け。

### 設計思想に基づいて構築されたシステムの構造
これは各々構築されるシステムごとに異なるので特定した意味づけをすることは不可。

### アーキテクチャの種類
- ソフトウェアアーキテクチャ
    - ソフトウェアを設計するときに、最も必要であるのが「機能」や「性能」の全体像と製品本体の構成要素のバランス。
    - MVC、MVVMなど
- システムアーキテクチャ（略してSA）
    - システムに求められることを効率良く行っていくために必要な機能や相互データの更新を定める枠組み。
- エンタープライズアーキテクチャ（略してEA）
    - 組織や企業において目的を果たすために、業務手順や組織構成を含む情報システムを利用しやすいように適正化する手段。
- CUPのアーキテクチャ
    - ハードウェア部分なので今回は触れない。


### まとめ
IT分野における「アーキテクチャ」とはプロダクトを作るための方法だったり、何かを作る意味づけ、プロダクトの構造であることと理解した。
概念的な言葉なので一概にこれ！と同定することはできない言葉で、時と場合によって詳しい意味合いは変わってくるが、上記の意味は変わらないはず。

不足や間違いなどがございましたらご指摘していただけると幸いです。



#参考
>wiki
>https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3

>アーキテクチャとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
>https://wa3.i-3-i.info/word16015.html

>IT用語辞典BINARY
>https://www.sophia-it.com/content/%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3

>設計思想とは何か(pdfのダウンロードファイル)
https://sentankyo.repo.nii.ac.jp/?action=repository_action_common_download&item_id=18&item_no=1&attribute_id=22&file_no=1

>https://biz.trans-suite.jp/8540
AI Builder & Power Apps で名刺読み取りアプリを作成する

AI Builder の名刺リーダー機能を試してみたところ、思ったより精度よく日本語も読み取ってくれたので簡単に作成方法を共有します。

#アプリの作成
## 名刺リーダーの挿入
挿入＞AI Builder>名刺リーダー　から名刺リーダーを挿入する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/2ab82cde-0dfc-dfbd-33b1-7f995aad68fc.png)

##　読み取った文字列を表示する欄の作成
挿入＞入力＞テキスト入力　からテキスト入力を挿入する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/2bfb6d82-9f5e-4ce1-8243-a4400e71ff44.png)

**ここはラベルでもいいのですが、読み取った文字が間違っていた時に修正できるようにテキスト入力を使用しました。**

テキスト入力のDefault欄に
BusinessCardReader1.FullName
と入力すると、名刺リーダーで読み取った名刺の氏名が挿入されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/b26787be-595c-3560-6b22-c56546761511.png)

このFullNameのところを
Emailにすればメールアドレスが、BusinessPhoneにすれば電話番号がとってこれます。

詳しくは[こちら](https://docs.microsoft.com/ja-jp/ai-builder/business-card-reader-component-in-powerapps)をご覧ください。

# 動作確認テスト
名刺のスキャンをクリックし、名刺の画像を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/3b56be52-9fe7-c81d-90c9-c7d1baf5cc8b.png)

結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/764cd86a-2994-4847-4af0-009609de22f8.png)

一部、フリガナまで部署名と判別されてしましましたが、かなり高い精度で名刺を読み取ることができました！

いろいろ試してみたところ、現時点では日本語名は姓と名に分けて判別できないなどまだまだ問題もありますが、工夫をすればある程度使えそうだなという印象です。
これからの精度向上に期待です。
Pythonで１変数のニュートン法を実装してみる


16 - 2x^3 = 0 の解を求めてください。
簡単ですね、x = 2 が答えです。
x - y = 1, x + y = 3 なんてどうでしょう。
(x, y) = (2, 1)が答えです、これもすぐに求まりました。

では、5x - exp(x) = 0 の解はいくつでしょう。
答えは、x = 0.259171, 2.542641 です、ペンと紙があっても時間がかかりそうです。

このような複雑化された方程式の解を求める数値解法アルゴリズムには、

**ニュートン法**
**二分法**
**Regula-falsi法**
**Bairstow法**

などがあります。
今回は、そのうちのニュートン法をPythonで実装してみたいと思います。

# 目次
[1 ニュートン法とは](#1-ニュートン法とは)
[2 実装](#2-実装)



#1 ニュートン法とは


>まず初めに、予想される真の解に近いと思われる値をひとつとる。次に、そこでグラフの接線を考え、その&nbsp;<em>x</em>&nbsp;切片を計算する。この<em>x</em>切片の値は、予想される真の解により近いものとなるのが一般である。以後、この値に対してそこでグラフの接線を考え、同じ操作を繰り返していく。
<a href="https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%88%E3%83%B3%E6%B3%95">https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%88%E3%83%B3%E6%B3%95</a>


要は適当にxの値を決めて、徐々に真の解へと値を近づけていくというものです。
プログラムの流れは以下のような感じで実装します。

初期値 x = x0 (ここで f(x0) ≠ 0)とします。
真の解を xtrue とし、xtrue = x0 + Δx を仮定すると

f(x0 + Δx) = 0　　　‥‥‥①

が成り立ちます。
①をテイラー展開すると

f(xi + Δx) = 0 = f(xi) + f'(xi)Δx + ‥‥　　　‥‥‥②

②式のΔxの一次項までを考慮してΔxの近似値を計算すると

(Δxの近似値) ≅ - f(xi) / f'(xi)

次に

xi += (Δxの近似値)

これを繰り返して、 (Δxの近似値) ≅ 0 となった時、
xi を真の解 xtrue としてプログラムを終了します。



#2 実装


```python
from math import exp

def func(x):
    return 5 * x - exp(x)

def diff_func(x):
    return 5 - exp(x)

def main():
    max = 10
    dx = 0.0
    x = float(input("初期値x0："))

    for i in range(max):
        dx = - func(x)/diff_func(x)
        print("{}：dx = {:.6f}\n".format(i+1, dx))
        x += dx
        if -1.0e-6 &lt; dx and dx &lt; 1.0e-6:
            print("x = {:.6f}\n".format(x))
            exit()
    print("error\n")

if __name__ == "__main__":
    main()
```

```
>>出力1
初期値x0：1
1：dx = -1.000000
2：dx = 0.250000 
3：dx = 0.009157 
4：dx = 0.000015 
5：dx = 0.000000
x = 0.259171

>>出力2
初期値x0：2
1：dx = 1.092877 
2：dx = -0.385907
3：dx = -0.145130
4：dx = -0.018900
5：dx = -0.000298
6：dx = -0.000000
x = 2.542641
```


20数行とコンパクトに収めることができました。
特段難しい箇所があるわけでもなく、理解ができていれば実装は容易だと思います。
注意する点は、解が2つ存在するので初期値によって収束する値が異なるといったことくらいでしょうか。
[備忘録] Firebase HostingにBasic認証をつけるFunctionsをTypeScriptで書く場合の注意点

# はじめに

ReactやFlutter WebなどのSPAをFirebase HostingにデプロイするときにBasic認証をかけました。

[こちらの記事](https://note.com/rubymade/n/nafa8c82bd4cc) を参考にして実装しましたが、FunctionsをJavaScriptではなくTypeScriptにした場合に1つだけ変更点があったので、忘れないようメモしておきます。


# 変更点

- staticフォルダを functions フォルダの下ではなく functions/lib フォルダの下に置く。

JavaScriptと同じように functions フォルダの下に static フォルダを置くと、Basic認証が通った後に

> Cannot GET /

となってしまうのでご注意ください。

以下に TypeScript と JavaScript それぞれの場合のフォルダ構成を載せます。
staticフォルダをindex.jsを同じ階層に置くのがポイントのようです。

## TypeScriptの場合

```
(root)
  ├── functions
  │   ├── lib
  │   │   ├── index.js
  │   │   └── static        // index.js と同じ階層に置く
  │   ├── node_modules
  │   └── src
  │       └── index.ts
  │
  ├── public                // ここは空にする
  :

```

## JavaScriptの場合

```
(root)
  ├── functions
  │   ├── node_modules
  │   ├── index.js
  │   └── static            // index.js と同じ階層に置く
  │
  ├── public                // ここは空にする
  :
```
日本語をエスケープしないでJSON文字列を作る

# 概要
JSON形式で保存されているログを画面出力することがあった。

しかし、 `json_encode()` した文字列のままだと、
日本語部分が文字化けしたように読めない。

そのため、一度デコードして、整形し直してみる。

## 独自関数を作ってみる...
`$log=print_r($json, true)` でも配列の中身を出力できるが、
bool型のところがfalseの場合空文字になったりとイマイチ見た目が悪かった。

そのため、独自関数を作って対応してみる。

```php
/**
 * @param  string $json
 * @param  bool   $is_vector
 * @return string
 */
function decodeMbJsonString (string $json, $is_vector = false) {
    // 一度デコードして、日本語を読めるようにする
    $data = json_decode($json, true);

    // JSON形式に再整形する
    $data = array_map(function ($key, $value) {
        if (is_null($value)) {
            // nullの場合、nullという文字列に変換する
            $value = 'null';
        } else if (is_bool($value)) {
            // bool型の場合、文字列に変換する
            $value = $value === true ? 'true' : 'false';
        } else if (is_array($value)) {
            // 配列か連想配列か判定して、再帰処理する
            $is_vector = (array_values($value) === $value);
            $value = $this->decodeMbJsonString($value, $is_vector);
        }

        // キーが整数の場合は、「"」で囲まないようにする
        $format = (is_int($key)) ? '%s:"%s"' : '"%s":"%s"';
        return sprintf($format, $key, $value);
    }, array_keys($data), array_values($data));

    $format = ($is_vector === true) ? '[%s]' : '{%s}';
    return sprintf($format, implode(',', $data));
}
```

## json_encodeで対応できそう...
`json_encode()`関数のオプションで対応可能なようです。

```php
function decodeMbJsonString (string $json) {
    $data = json_decode($message, true);
    return json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
}
```

こっちの方が実装が楽ですね。
こんなオプションがあったとは知らなかった... （＾＾；）

## 参考サイト

* [JsonデータをPHPで作成した時のエスケープする、エスケープしないの選択処理の話](
https://engineering.dn-voice.info/prg-tips/php/jsonescape/)

以上
Rubyのdeleteメソッドで複数の文字列を削除

# deleteメソッドについて
最近paizaで勉強中なので、メモ用に残します。

### deleteメソッド
deleteメソッド、delete!メソッドは文字列から、指定の文字列を削除するメソッド。

### 使用例
```ruby
str = 'abcde'
puts str.delete('a') # bcde
puts str.delete('abc') # de
```

みたいな感じですね。。
そんなの言われなくてもわかってるよ！という方がほとんどですね

しかし、一つの文字列から複数の文字を削除したい時はどうでしょうか

```ruby
str = 'abcde'
puts str.delete('a' 'c') # bde
```

こうします。
カンマがいらないんですね〜
なんでなのかはわかりませんが..笑

もし知ってる方がいれば教えてください！

以上
対数（Logarithm）

**対数（logarithm）** は、**[冪乗（exponentiation）](https://qiita.com/sk9tokyo/items/a862ee68198346ee16d9)**を導く、
**逆函数（inverse function）**です。

```math
{x = b^n}
```

つまり、*定数 x* の対数（logarithm）は、

- **b** = `底（base）`

を *定数 x* にするための

- **n** = `指数（exponent）`

になります。

対数（logarithm）の最も単純な導出例は、
同じ数値による、乗算の繰り返し回数です。

例えば、

```math
{1000 = 10 \times 10 \times 10 = 10^3}
```

の場合、
10 を底（base）とする対数（logarithm）は、
1000 に対して 3 になります。

```math
{\log_{10} 1000 = 3}
```

として表記されます。

```c++:例
#include <math.h>
#include <stdio.h>

int main(void) {
  double x = 1000.0, y;

  y = log10(x);

  printf("The base 10 logarithm of %lf is %lf\n", x, y);
}
```

```bash:出力
The base 10 logarithm of 1000.000000 is 3.000000
```
CO2センサーの値をESP32-WROVER-EのSoftwareSerialで取得する

# はじめに
[前回](https://qiita.com/mine820/items/b5e4015afb206929f93d)、ハードウェアシリアルでつなぐことができなかったのでPWMでデータを取得したが、今回はソフトウェアシリアルで取得するようにしてみました。
ただし焦点がぼやけるので、AWS IoTへの接続部分は消しました。

# なぜハードウェアシリアルでつなぐことができなかったの？
ESP32-WROVER-Eには、ハードウェアシリアルが1つしかなく、PCとのやり取りで使用しているため、センサーとのやり取りには使えません。

# なぜソフトウェアシリアルを使わなかったの？
私の注意力不足です。
[mhz19_uart]のソースの以下の部分を見て、ソフトウェアシリアルを使っているものだと勘違いしていました。

```MHZ19_uart.cpp
#ifdef ARDUINO_ARCH_ESP32
	HardwareSerial hserial(_serialno);
	hserial.begin(9600, SERIAL_8N1, _rx_pin, _tx_pin);
#else
	SoftwareSerial hserial(_rx_pin, _tx_pin);
	hserial.begin(9600);
#endif
```

よく見るまでもなく、上のハードウェアシリアルの方が動いていました。

また、強制的にソフトウェアシリアルを呼んで試してみたときには、Outputできないポートを指定していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/039acbf3-b85f-afa6-25dc-697cc6e22a37.png)
この「IO34」「IO35」で試していたのですが、こちらもよく見るまでもなく、どちらもTypeが「I」でした。

# ソースコード
結局、「IO14」「IO12」を使用して、以下のようなソースにしてみたところ、問題なく動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/31e0ae96-875f-b304-5501-ce1d3a664513.png)

今回はMH-Z19用のライブラリとして[こちら](https://github.com/WifWaf/MH-Z19)を使用しました。

```c:co2.ino
#include <MHZ19.h>
#include <SoftwareSerial.h>

// MH-Z19C
MHZ19 myMHZ19;
const int rx_pin = 14; //Serial rx pin no
const int tx_pin = 12; //Serial tx pin no
SoftwareSerial mySerial(rx_pin, tx_pin);

void setup(){
  Serial.begin(115200);
  delay(100);

  mySerial.begin(9600);
  myMHZ19.begin(mySerial);
  Serial.println("Callibrating...");
  myMHZ19.autoCalibration(false);
}

void loop(){
  int CO2 = myMHZ19.getCO2();
  int8_t Temp = myMHZ19.getTemperature();

  Serial.println("CO2 (ppm): " + String(CO2) + "\tTemperature (C): " + String(Temp));

  delay(1000*5); // 5sec
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/6e992904-3261-86f6-c86d-75da8ae827a5.png)

# まとめ
もっと落ち着け、俺。
windowsでiverilog その99

#概要　

windowsでiverilogやってみた。
sha256のテストベンチ書いてみた。

#使用したライブラリー

https://github.com/secworks/sha256

#サンプルコード

```
module test();
	parameter DEBUG = 0;
	parameter CLK_HALF_PERIOD = 2;
	parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
	reg [511:0] tc1;
	reg [31:0] cycle_ctr;
	reg [31:0] error_ctr;
	reg [31:0] tc_ctr;
	reg tb_clk;
	reg tb_reset_n;
	reg tb_init;
	reg tb_next;
	reg tb_mode;
	reg [511:0] tb_block;
	wire tb_ready;
	wire [255:0] tb_digest;
	wire tb_digest_valid;
	sha256_core dut(.clk(tb_clk), .reset_n(tb_reset_n), .init(tb_init), .next(tb_next), .mode(tb_mode), .block(tb_block), .ready(tb_ready), .digest(tb_digest), .digest_valid(tb_digest_valid));
	task init_sim;
		begin
			cycle_ctr = 0;
			error_ctr = 0;
			tc_ctr = 0;
			tb_clk = 0;
			tb_reset_n = 1;
			tb_init = 0;
			tb_next = 0;
			tb_mode = 1;
			tb_block = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
		end
	endtask
	task reset_dut;
		begin
			$display("*** Toggle reset.");
			tb_reset_n = 0;
			#(4 * CLK_HALF_PERIOD);
			tb_reset_n = 1;
		end
	endtask
	task wait_ready;
		begin
			while (!tb_ready)
			begin
				#(CLK_PERIOD);
			end
		end
	endtask
	task block_test(input [511:0] block);
		begin
			tb_block = block;
			tb_init = 1;
			#(CLK_PERIOD);
			wait_ready();
			$display("in: 0x%064x", tb_block);
			$display("out: 0x%064x", tb_digest);
			$display("");
		end
	endtask
	always
	begin:clk_gen
		#CLK_HALF_PERIOD;
		tb_clk = !tb_clk;
	end
	always
	begin:sys_monitor
		cycle_ctr = cycle_ctr + 1;
		#(2 * CLK_HALF_PERIOD);
		if (DEBUG)
		begin
			dump_dut_state();
		end
	end
	initial
	begin:main
		$display("-- Testbench for sha256 core started --");
		init_sim();
		reset_dut();
		tc1 = 512'h80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
		block_test(tc1);
		tc1 = 512'hd3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008;
		block_test(tc1);
		tc1 = 512'h11af8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010;
		block_test(tc1);
		$display("*** Simulation done.");
		$finish;
	end
endmodule





```

#結果

```


-- Testbench for sha256 core started --
*** Toggle reset.
in: 0x80000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000
out: 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

in: 0xd3800000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000008
out: 0x28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1

in: 0x11af8000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000010
out: 0x5ca7133fa735326081558ac312c620eeca9970d1e70a4b95533d956f072d1f98

*** Simulation done.

```

以上。
plunkerでsha256 その2

#概要

plunkerでsha256やってみた。

#参考にしたページ

https://qiita.com/tnakagawa/items/6321472098a2b73836ab

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/90f0b491-67bd-1edc-d0ac-1db5ee8429e5.jpeg)


#サンプルコード

```
function run() {
  var src = document.getElementById("src0").value;
  let msg = [];
  for (let j = 0; j < src.length; j += 2) 
  {
    msg[j / 2] = parseInt(src.substr(j, 2), 16);
  }
  let hash = compute(padding(msg));
  let hs = hash2str(hash);
  document.getElementById("code0").value = hs;
  var src = document.getElementById("src1").value;
  msg = [];
  for (j = 0; j < src.length; j += 2) 
  {
    msg[j / 2] = parseInt(src.substr(j, 2), 16);
  }
  hash = compute(padding(msg));
  hs = hash2str(hash);
  document.getElementById("code1").value = hs;
  var src = document.getElementById("src2").value;
  msg = [];
  for (j = 0; j < src.length; j += 2) 
  {
    msg[j / 2] = parseInt(src.substr(j, 2), 16);
  }
  hash = compute(padding(msg));
  hs = hash2str(hash);
  document.getElementById("code2").value = hs;
}


```

#成果物

https://embed.plnkr.co/plunk/30dWQJvUXvYcd6kH

以上。
統計検定準1級　2019年6月　問2

## 問題

・[統計検定準1級 2019年6月](https://www.toukei-kentei.jp/wp-content/uploads/201906grade1semi.pdf)

## (1)

問題文より、幾何分布を用いる。

0種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{3}{3} = 1$

$E[X] = \frac{1}{p} = \frac{1}{\frac{3}{3}} = 1$

1種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{2}{3}$

$E[X] = \frac{1}{p} = \frac{1}{\frac{2}{3}} = \frac{3}{2}$

2種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{1}{3} $

$E[X] = \frac{1}{p} = \frac{1}{\frac{1}{3}} = \frac{3}{1} = 3$

よって、3種類のカードが揃うまでに必要な購入回数の期待値は

$E[X] = 1 + \frac{3}{2} + 3 = 1 + 1.5 + 3 = 5.5$

と求まる。

## (2)

(1) の状態で、新しいカードを1種類追加する。

3種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{1}{4} $

$E[X] = \frac{1}{p} = \frac{1}{\frac{1}{4}} = 4$

よって

$x = 5.5 + 4 = 9.5$

一方、最初から4種類のカードが発売されていた場合については、(1) と同様に求めることができる。

0種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{4}{4} = 1$

$E[X] = \frac{1}{p} = \frac{1}{\frac{4}{4}} = 1$

1種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{3}{4}$

$E[X] = \frac{1}{p} = \frac{1}{\frac{3}{4}} = \frac{4}{3}$

2種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p = \frac{2}{4} $

$E[X] = \frac{1}{p} = \frac{1}{\frac{2}{4}} = \frac{1}{\frac{1}{2}} = 2$

3種類のカードが揃っていて、手に入れていないものを1枚引くとき

$p= \frac{1}{4}$

$E[X] = \frac{1}{p} = \frac{1}{\frac{1}{4}} = 4$

よって、4種類のカードが揃うまでに必要な購入回数の期待値は

$y = 1 + \frac{4}{3} + 2 + 4 = \frac{50}{6} = \frac{25}{3}$

最後に

$x - y = 9.5 - \frac{25}{3} = \frac{57}{6} - \frac{50}{6} = \frac{7}{6}$

と求まる。
DevOpsの始め方を図式化にしてみた

# はじめに
「The DevOps ハンドブック　理論・原則・実践のすべて」（日経BPマーケティング）を参考、
DevOpsを始める為の概要を、視覚的にイメージできるよう図式化してみました。
※詳細な内容に関しては、参考資料1.を手に取って頂くことをお勧めします！

# DevOpsの始め方（俯瞰図）
![DevOps建て付けコピー-DevOpsの始め方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52012/8ec8fbcd-95f3-1cdf-f8ff-51e4ea4b8a8d.png)


# 参考資料
1. [The DevOps ハンドブック　理論・原則・実践のすべて](https://www.amazon.co.jp/dp/4822285480/ref=cm_sw_em_r_mt_dp_23XWJKMDK4E0Z3RJ2D8F)
2. [キャズム理論とは | イノベーター理論とキャズムを超える戦略を解説](https://boxil.jp/mag/a2991/?utm_source=google&utm_medium=cpc&utm_campaign=sfadsa-z&gclid=CjwKCAjwnPOEBhA0EiwA609Ree6XYet-9-VL0CdGxDNsMMyBu6NqAVjLW3vKRRQP8SSQv5SPxXKJeRoCupYQAvD_BwE)
plunkerでsha256

#概要

plunkerでsha256やってみた。
crypto.js使ってみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f79bee5f-2136-104e-8a82-d946d7cfd580.jpeg)


#サンプルコード

```
function run() {
  var src = document.getElementById("src0").value;
  src = CryptoJS.enc.Hex.parse(src);
  var sha256 = CryptoJS.SHA256(src, { 
		asBytes : true
	});
  document.getElementById("code0").value = sha256;
  var src = document.getElementById("src1").value;
  src = CryptoJS.enc.Hex.parse(src);
  var sha256 = CryptoJS.SHA256(src, { 
		asBytes : true
	});
  document.getElementById("code1").value = sha256;
  var src = document.getElementById("src2").value;
  src = CryptoJS.enc.Hex.parse(src);
  var sha256 = CryptoJS.SHA256(src, { 
		asBytes : true
	});
  document.getElementById("code2").value = sha256;
}


```

#成果物

https://embed.plnkr.co/plunk/dv1VOZCxpeMUn5IT

以上。
【AWS】EC2の概要(EC2の特徴と起動方法)

#プログラミング勉強日記
2021年5月14日

#EC2とは
　EC2はAmazon Elastic Compute Cloudの略で、AWSで利用できるシステムの1つ。AWS上に仮想サーバーを構築して自由に利用できる。クラウド環境において様々な役割を担っている。


#EC2の特徴


- 数分で利用可能な従量課金(時間~秒単位)
- 起動・ノードの追加・削除・マシンのスペック変更が数分で可能
- アンマネーシド型(物理的なインフラ管理はAWS側、立ち上がったサーバーの管理や設定はユーザ側)
- 物理的なインフラは汎用的なIntelアーキテクチャを使っている
- WindowsやLinuxなどほとんどのOSをサポート
- 独自のAmazon Machine Image(AMI)にOSを設定して保存してバックアップのように使える。


　EC2では仮想サーバーのことをインスタンスという単位で扱い、任意のAZにインスタンスを立ち上げてサーバーとして利用する。(インスタンスは1つのAZに設置し、リージョンに直接設置することない)インスタンスには様々な種類や性能のものがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/c1390b0e-eaa7-7dc3-c34d-4b4b76866a99.png)

#EC2の起動方法
　EC2の起動方法は以下の手順になる。

1. AMI(OSのセッティング)を選択する
2. インスタンスタイプを選択する
3. インスタンスタイプの詳細の設定をする
4. ストレージを選択する
5. タグを追加する
6. セキュリティグループを選択する
7. キーペアを設定する


(詳細な説明があるところは下記で詳しく説明する)

##1. AMI(OSのセッティング)を選択する
　AMIはOSのセッティングのこと。WindowsやLinuxなどの様々なOSがすでに設定されている状態でAMIとして提供されている。主に、AWS側で用意されたAMI、3rd partyが売っているAMI、自作できるカスタムIAMの3種類ある。カスタムAMIはバックアップのように再利用することができる。
　まずは、EC2インスタンスのOSを設定してそのOSでEC2インスタンスを作る。

##2. インスタンスタイプを選択する
　インスタンスタイプの呼び方は、`t2.nano`のようになっている。最初に出てくるアルファベット(`t`)はインスタンスの<b>ファミリー</b>。`t`は汎用インスタンスのtシリーズと呼ばれるファミリー。`2`は世代。`nano`はインスタンスの容量を決定する。

##3. インスタンスタイプの詳細の設定をする
　インスタンスの購入方式に応じて割引価格が提供されるので、用途に応じて割引価格を利用する。
　物理対応可能なインスタンスもあり、これは物理サーバーにインスタンスを起動して制御可能。

##4. ストレージを選択する
　EC2で直接利用できるストレージは、インスタンスストアとElastic Block Store(EBS)の2つ。

　インスタンスストアは、物理的にEC2インスタンスが起動しているサーバーにアタッチされているハードディスク。EC2の値段に含まれているので無料で使用することができる。内蔵ディスクはPCに入っている内蔵のハードディスクと同じようなもので、EC2の一時的なデータが保持されてEC2の停止・終了とともにクリアされる。

　Elastic Block Store(EBS)は、ネットワーク経由でEC2に接続して使うストレージ。基本的にはEC2と一緒に使う。デフォルトではEC2を削除するとEBSも同時に削除されるようになっている。(設定を変更すればEBSだけ保存することもできる)　EBSは別途料金が発生する。
ネットワークと情報セキュリティ 【備忘録】

#【ネットワークと情報セキュリティ】

基本情報技術者試験を通して、コンピュータサイエンスの基礎を学び直します。
自分用の備忘録です。
ご指摘などありましたら、コメント頂けますと幸いです。

※ 過去記事：[情報セキュリティ](https://qiita.com/uejima_haruki/items/e10c8d5c3f378523e3c5)

##パケットフィルタリング

IPアドレスの送信元や宛先アドレス、プロトコル、インターフェース、ポート番号などを検査して、
テーブルに事前に登録してあるデータと一致した場合に、そのパケットをネットワーク内外へ中継、遮断する。

**DMZによって、外部と内部セグメントとの通信セキュリティ**が確保されることが一般的。
　→ FWだけでは、パケットフィルタリングによる外部からの攻撃を防ぐには不十分。
なぜなら、DMZ内のWebサーバとDNSサーバへの正常なリクエストはFWで遮断してはならないから。

WebサーバとDNSサーバへの外部からの攻撃にの対応は別に考える必要がある。

###IDS（Intrusion Detection System）：不正侵入検知システム

ネットワークを監視して、不正な侵入や疑いを検知した場合に管理者に警告通知をおこなう。
　→ パケットの中身を調べて、不正な挙動を検出して、セキュリティを高める。

###IPS（Intrusion Prevention System）：不正侵入防止システム

不正な侵入や疑いを検知した場合に、通信できないように遮断する機能がある。
　→ IDSよりも迅速な対応が可能になる。

IPS機器が故障した場合には、通信の維持を最優先にするため、基本動作は全て通信許可となる。

##おわりに

IDSとIPSだけでセキュリティを高めることには限界がある。
FWやWAFなどを併用することでよりセキュリティを高められる。

セキュリティは大事なのでもっと学んでいく。
Pythonのバージョンが2から3に変わらない現象【体験談】

エンジニア歴2年のkitagawaです。

Pythonを触り始めて、バージョンが変わらない現象が起きました。
調べてみてたくさん記事が出てきましたが、手っ取り早くバージョンアップできる方法を忘備録として記載します。

```
% python -V      
Python 2.7.16
```

と表示されてしまいます。

そこで、`~/.bash_profile`の内容を変更し反映させれば、最新のバージョンになります。

```
vi ~/.bash_profile
```

```~/.bash_profile
export PATH=/Library/Frameworks/Python.framework/Versions/3.9/bin:$PATH
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

上記が記入できたらESC押下し、`:wq`と入力で保存して終了。（`:qa`だと保存せず終了）

`source ~/.bash_profile`をし反映させると、Pythonのバージョンが変わっていることが確認できます。

```
% source ~/.bash_profile
% python -V             
Python 3.9.4
```

ちなみに原因はわからないのですが、再起動してしまうとバージョンが戻ってしまうので、私はいつもsourceで反映させてからバージョンアップしています（謎）
NotionAPIを使ってみた

# 2021年5月13日 — APIを使ったシステム連携をはじめましょう👷🏻‍♀️👷🏾‍♂️
2021年5月13日にNotionのAPIのpublicbeta版が公開されたので使ってみます！

[参考リンク](https://www.notion.so/894bb0f08f744d76a506f382e54efb96)


## 新しいintegrationsを作成する

### 下記URLに接続
[https://www.notion.so/my-integrations](https://www.notion.so/my-integrations)
![スクリーンショット 2021-05-14 10.54.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/8fbda97b-2761-29ac-7d58-5db4c1223ad7.png)


### 名前をつけてsubmit
![スクリーンショット 2021-05-14 10.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/bd4b3d71-dc91-916a-4990-3e1ea94ef892.png)


### Tokenが発行されるので、どこかにメモしておく
![スクリーンショット 2021-05-14 10.59.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/9fc57623-c94e-8bc7-5e10-8c6731ea57be.png)


## integrationsとデータベースを共有する

### Notionでテーブルを作成する

![スクリーンショット 2021-05-14 11.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/d904d3e2-eea1-c2f1-6e15-e412cbea0b85.png)

![スクリーンショット 2021-05-14 11.05.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/e1e13b90-cca2-c9ef-1e90-377b35050f26.png)


### 右上のshereから作成したintegrationsを追加
![スクリーンショット 2021-05-14 11.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/3dcbecd3-3ed8-4555-0f4d-6c1f8db0ec96.png)

![スクリーンショット 2021-05-14 11.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/7f5de251-5253-e885-7504-ae1ac5313ad7.png)


### データベースにアイテムを追加する

ターミナル上のcurlコマンドで下記のコマンドを実行

```bash
curl -X POST https://api.notion.com/v1/pages \
  -H "Authorization: Bearer {MY_NOTION_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Notion-Version: 2021-05-13" \
  --data '{
    "parent": { "database_id": "{DATABASE_ID}" },
    "properties": {
      "Name": {
        "title": [
          {
            "text": {
              "content": "Yurts in Big Sur, California"
            }
          }
        ]
      }
    }
  }'
```

MY_NOTION_TOKENとDATABASE_IDは書き換える

MY_NOTION_TOKENは上記で発行したTOKEN
DATABASE_IDはデータベースのURLの下記の部分

```bash
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
                                  |--------- Database ID --------|
```

コマンドを実行するとカラムが一行追加される。
![スクリーンショット 2021-05-14 11.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/effe84d7-4915-e3fa-e767-5e6c3c09dce1.png)

## 最後に
APIが公開されたことで他ツールとの連携がバンバン出そうですね！
楽しみです！！
【PHP】基本文法メモ 配列

基本的なPHPの文法についてメモっておく。

## 対話モードで色々な文法を試す
```
$ php -a

PHP >
```
対話モードが立ち上がる。

### 配列
```
PHP > $animals = ["dog", "wani", "gorira"];
php > echo $animals;
PHP Notice:  Array to string conversion in php shell code on line 1
Array
php > echo $animals[1];
wani
```
こんな感じで配列を定義することができる。
IT用語【初心者向け】

#はじめに
私は今年の6月からインフラエンジニアとして内定を頂いており、業務前に自己学習を進めています。
ネットワークに関する入門書を手に取りましたが、IT用語を調べつつ読み進めていったのでその過程で出てきた用語をここにまとめます。
かなり大雑把な説明かと思いますが、実務に入りながら知識をより深めていきたいと思います。

#用語集

####CPU
>パソコンの脳みそに当たる部品。
コア数の数だけ同時に演算ができる。

####メモリ
>パソコンの作業机に当たる部品。
一時的なデータを記憶することができるが、電源が停止するとデータが全て消えてしまう。

####ハードディスク

>パソコンのデータの収納場所。

####ストレージ

>データを永続的に保存しておく装置。ハードディスクやCD、DVD、USBがこれに当たる。

####RAID

>複数のハードディスクを合体させて１つのハードディスクのようにした技術。


####パケット

>通信しやすいように細切れに分割されたデータ。
OSI基本参照モデルの階層によってはセグメント(４層トランスポート層)と言ったり、フレーム（２層データリンク層）と言ったり呼び方が変わったりする。

####I/O

>入出力すること。「Input」と「Output」

####パリティ

>データがおかしくなっていないかチェックするやり方。

####DoS攻撃(ドスこうげき)

>ネットワークやサーバーに対して膨大なデータを送りつけてサービスを妨害する。
以下のようなことが起こる
・大量のアクセス要求によって正規のユーザーがアクセスできなくなる。
・サーバに負荷がかかりすぎてサーバが使用不能になる。
・クラウド上で従量課金制のサービスであれば高額な請求が発生する。

####ディストリビューション

>主にLinuxディストリビューションの省略表現として使われる。
Linuxディストリビューションとはカーネルだけを差すのではなく、OSとしてのLinuxのこと。

####コンパイル

>ソースコードをパソコンの分かるオブジェクトコード(もしくはバイナリコードともいう)に変換する作業のこと。

####インターフェース

>接続部分。

####トラフィック

>ネットワーク上を流れる情報(量)。

####SNMP

>ネットワークに繋がれている機器をネットワーク経由で遠隔から監視・管理するときの約束事。

####ファームウェア

>ハードウェアの中のプログラム。
パソコンでいうBIOS(バイオス)がこれに当たる。起動時のOSの読み込みや、接続された装置・機器に対する基本的な入出力制御などを行うもの。

####VPN

>ネットワーク上に仮想的なネットワークを作る技術。データの通り道。
>>インターネットVPN・・・インターネット網で構築される。低コストで運用可能。セキュリティ対策は自己責任。

>>IP-VPN・・・通信業者が用意した閉網IP網。中・大規模拠点など、セキュリティが重視される場面や通信品質が求められる場面で利用される。

####ルータ

>LANとWANの境界線に位置する機器。しかし、ネットワークの規模によってルータが扱う機能は変わる。
小規模拠点では、「何でも屋さん」として活躍する。ネットワークの橋渡しだけではなく、ファイヤオールなどの様々な機能を１台のルータが担う。
一方、中・大規模拠点では「信頼性があり、より専門的」であることが求められ、ネットワークの橋渡しに専念する。外部向けに特化した働きをする。その理由として、内部のネットワークはレイヤスイッチ３が担ってくれるから。

#最後に

まだ実務に入っていないので、こんな用語普段使わないよ。なんてものもあるかもしれませんが、随時追加や更新していきたいと思います。
【iOS】古いMacとXcodeでバイナリを作ったらアプリが起動できなくなった話

# 概要
2020年9月末に社内配布用にバイナリ作成をしたところ、iOS13でアプリが起動できなくなってしまった。
（iOS11では起動できていた。）

## バイナリ作成環境
Mac Mojave
Xcode 9.4

## 調査
バイナリ作成者のKeychainを確認したところ、バイナリ作成時の署名に利用した証明書のステータスが「信頼されていません」になっていた。
証明書の問題かと思い、証明書を作り直すがステータスは変わらず、バイナリを作ってもやはりクラッシュのまま...


## 原因
一言で言うと、作業者のMacの中間証明書更新漏れ
＼(^o^)／
Appleからのお知らせにもありました。
Xcode 11.4.1以降を使用していたら自動で取得できている模様。
新しいXcodeを使っていない開発者は自分で取得する必要があるってことですね。

## まとめ
最新の中間証明書を取得してバイナリ作成したら動きました。
やはり、古いシステムは使い続けてもいいことないです。（当たり前）
皆さんは定期的にバージョンアップしましょう。

2021年内にプッシュ通知証明書の更新計画もあるようです。
当日になって慌てないよう事前の準備を心がけましょう。（当たり前）

### 関連
https://developer.apple.com/jp/support/wwdr-intermediate-certificate/

https://developer.apple.com/jp/support/expiration/

### 補足
中間認証局のしくみ
Apple Worldwide Developer Relations Certification Authority (WWDR) は、Appleに認証された開発者であることを証明してくれる中間認証局です。
Apple Root CA によって、この中間認証局の証明書が発行されています。そして、中間認証局が、iOSアプリ用の証明書を発行してくれます。
つまり以下のような関係になっています。
Apple Root CA (ルート認証局)
↓
WWDR (中間認証局)
↓
iOSアプリ用証明書
認証局の証明書が有効期限切れになると、発行された証明書も無効になります。
多段構成にすることによって、細かく有効期限を管理できるため、中間認証局を使うという構成が取られます。SSL/TLSのサーバ証明書も同じですね。
PowerShellでvimのVisual Block編集機能を使いたい

PowerShell2に移行したほうがいい（？）んでしょうけど、個人的な好みで、PowerShellを継続しています。

で、ssh接続してサーバ上でvimを使うことがよくあるんですが、MacのiTermやTeraTermを使っていたときには `Ctrl+v` でVisualBlock機能が使えていたのですが、PowerShellではペーストになってしまっていて、機能が使えませんでした。
どこかに設定があるんだろうなぁ～とは思いつつ、しばらく我慢して使っていたのですが、流石にコード編集時にあまりにも不便だったのできちんと調べて対応しましたが、日本語で今ひとつ情報が見つからなかったので自分のメモを兼ねて残しておきます。

## 設定場所

Terminalを起動した後、ウィンドウ上部にある下向きの矢印（＋の右側）をクリックしてメニューを表示。「設定」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45794/2b7502cd-82a1-5518-d3a0-c159acb8e8ce.png)

設定画面を開いたら、左下にある「Jsonファイルを開く」をクリックして、設定用のJsonファイルを開いてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45794/0dd598c7-ceca-5186-abe1-3da1bf5e63a1.png)

Jsonファイルの下の方（もしかしたら、利用しているバージョンなどにより内容が異なるかも？）に以下のような箇所がありますので、上から６行目と７行目Ctrl+cとCtrl+vに関する記述をコメントにします。

~~~json
    "actions":
    [
        // Copy and paste are bound to Ctrl+Shift+C and Ctrl+Shift+V in your defaults.json.
        // These two lines additionally bind them to Ctrl+C and Ctrl+V.
        // To learn more about selection, visit https://aka.ms/terminal-selection
        { "command": {"action": "copy", "singleLine": false }, "keys": "ctrl+c" },
        { "command": "paste", "keys": "ctrl+v" },

        // Press Ctrl+Shift+F to open the search box
        { "command": "find", "keys": "ctrl+shift+f" },

        // Press Alt+Shift+D to open a new pane.
        // - "split": "auto" makes this pane open in the direction that provides the most surface area.
        // - "splitMode": "duplicate" makes the new pane use the focused pane's profile.
        // To learn more about panes, visit https://aka.ms/terminal-panes
        { "command": { "action": "splitPane", "split": "auto", "splitMode": "duplicate" }, "keys": "alt+shift+d" }
    ]
~~~

これで、無事vim上でVisualBlockが使えるようになりました。

なお、コメントに記載されている通り、コピー＆ペーストは Ctrl+Shift+c および Ctrl+Shift+v で操作が可能ですので、両方使いたい！という方もコメントにしてしまって問題ないかと思います。
Herokuを使用したデプロイの方法

### Heroku CLIをインストール
----
下記のコマンドを実行するとherokuというコマンドが使用できるようになり、ターミナルからHerokuへアクセス可能になります。

```
% brew tap heroku/brew && brew install heroku
```
インストールが完了したら下記のコマンドを実行してバージョンを確認します。

```
% heroku --version

heroku/7.40.0 darwin-x64 node-v12.16.2
```
上記のようにバージョンが出力されれば成功です。（バージョンの値は実際と異なる場合があります。）


### Herokuにログイン
---
下記のコマンドを実行し、メールアドレスとパスワードを入力します。

```
% heroku login --interactive
```

### Heroku上にアプリケーションを作成
---
下記のコマンドを実行。

```
% heroku create アプリ名
 ```
下記のコマンドを実行し、正しく設定できたことを確認

```
% git config --list | grep heroku
```
### Heroku上でMySQLを使えるように設定
---

下記のコマンド実行でデーターベースをMySQLに設定します。

```
% heroku addons:add cleardb
```

Ruby on Railsを使う場合は、MySQLに対応するGemについて考慮する必要があり、そちらの設定もします。

まず、ClearDBデータベースのURLを変数heroku_cleardbに格納するため下記のコマンドを実行します。

```
% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`
```
続いて、データベースのURLを再設定するため下記のコマンドを実行します。

```
% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

### Heroku上にマスターキーを設定
---
Heroku上に環境変数を設定します。下記のコマンドを実行。

```
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```

設定が正しくできているか、Herokuの環境変数一覧を表示。

```
% heroku config
```


### Herokuで利用する環境を指定
---

Rubyのバージョン2.6.5が動作するStackを指定しました。下記を実行。（注：ダウングレードは極力避けた方が良いそうです。）

```
% heroku stack:set heroku-18 -a アプリ名
```

### Herokuへアプリケーションを追加
---

Gitで管理しているリポジトリをHerokuに反映させます。下記のコマンドを実行。

```
% git push heroku master
```

### Heroku上でマイグレーションファイルを実行
---

```
% heroku run rails db:migrate
```

### 公開を確認
---

下記のコマンドを実行すると公開されたアプリケーションの詳細を見ることができます。

```
% heroku apps:info
```

表示されたURLへアクセスすると、公開されたページを見ることができます。
4列カラムのページレイアウトを作る

確か、昔見たSalesforceのブログにやり方が書いてあったんですが... と思って

その時は3カラムレイアウト。3列ができれば、4列も可能ですよって回答したのですが　気に入らんかったようです。

仕方ないので実際に動くもので回答しました。

少し余白の設定は必要そうな気がしますが...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/48ecdd0d-7e96-e218-c262-ca8fcbb04707.png)


テンプレート用のコンポーネント

```
<aura:component implements="lightning:homeTemplate" access="global" >
    <aura:attribute name="first" type="Aura.Component[]" />
    <aura:attribute name="second" type="Aura.Component[]" />
    <aura:attribute name="third" type="Aura.Component[]" /> 
    <aura:attribute name="fourth" type="Aura.Component[]" /> 
    <aura:attribute name="all" type="Aura.Component[]" /> 
    
    <div class="slds-grid slds-wrap">
        <div class="slds-col slds-size_1-of-4">
            <span>{!v.first}</span>
        </div>
        <div class="slds-col slds-size_1-of-4">
            <span>{!v.second}</span>
        </div>
        <div class="slds-col slds-size_1-of-4">
            <span>{!v.third}</span>
        </div>
		<div class="slds-col slds-size_1-of-4">
            <span>{!v.fourth}</span>
        </div>      
        
        <div class="slds-col slds-size_4-of-4">
            <span>{!v.all}</span>
        </div>   
    </div>
</aura:component>
```


デザイン

```
<design:component label="My Four column Page">
    <flexipage:template>
        
        <flexipage:region name="first" defaultWidth="SMALL">
            <flexipage:formfactor type="MEDIUM" width="SMALL"/>
        </flexipage:region>
        
        <flexipage:region name="second" defaultWidth="SMALL">
            <flexipage:formfactor type="MEDIUM" width="SMALL"/>
        </flexipage:region>
        
        <flexipage:region name="third" defaultWidth="SMALL">
            <flexipage:formfactor type="MEDIUM" width="SMALL"/>
        </flexipage:region>
        
        <flexipage:region name="fourth" defaultWidth="SMALL">
            <flexipage:formfactor type="MEDIUM" width="SMALL"/>
        </flexipage:region>
        
        <flexipage:region name="all" defaultWidth="SMALL">
            <flexipage:formfactor type="MEDIUM" width="SMALL"/>
        </flexipage:region>
        
    </flexipage:template>
</design:component>
```


さて、ベストアンサーは頂けるかな？

[Create section grid for page layout](https://trailblazers.salesforce.com/answers?id=9064S000000kFgAQAU)
Subversionのリポジトリをすべてダンプする方法

#はじめに
メンテナンスやサーバ移行で、Subversionで管理しているリポジトリすべてのバックアップを取得したい場合があると思います。
リポジトリ自体のバックアップ作成方法はマニュアルや参考となるブログが多く存在しますが、Windows上ですべてのリポジトリを対象にしようとすると、バッチ(スクリプト)を作成するのが一般的かと思います。
ただし、コマンドプロンプト用のバッチファイルは文字列加工などが不得意なので、今回はPowerShellを使ってスクリプトを作成しています。
既にPowerShell自体はWindowsServer標準となっているので、ほとんどの環境で利用が可能かと思いますが、どうしてもバッチでなければいけないという場合は自力で読み替えてください。

#前提条件
WindowsでVisual Subversionを使って検証しています。

#スクリプト
```powershell:dump_repositories.ps1
#使用例
#.\dump_repositories.ps1 "C:\Repositories" "z:"
# "C:\Repositories"以下にあるリポジトリを、"z:"（ネットワーク）ドライブにダンプする

#リポジトリが保存されているディレクトリ
$repo_dir = $Args[0]

#リポジトリのダンプを保存する先
#スクリプトの実行者はログインユーザーとなるので、ネットワークドライブを指定することも可能です
$dump_dir = $Args[1]

$repo_list = @(Get-ChildItem $repo_dir | Where-Object{$_.PSIsContainer} | Select-Object FullName, Name)

#svnadmin.exeのパスを設定。ここでは、32bitアプリのインストールディレクトリを環境変数を用いて取得し、
#それ以降のパスとjoinさせている
$svnadmin = Join-Path ${env:ProgramFiles(x86)} "VisualSVN Server\bin\svnadmin.exe"

foreach($repo in $repo_list)
{
    #作成されるダンプファイル名 <リポジトリ名>.dump
    $dump_file = $repo.Name + ".dump"
    #作成されるダンプファイルのフルパス
    $dump_path = Join-Path $dump_dir $dump_file
    
    #svnadminに与える引数。空文字区切りで配列を結合しています
    $arguments = [string]::Join(" ", @("dump", $repo.FullName))
    
    #processの実行
    #-RedirectStandardOutput ダンプの出力先ファイルは標準出力のリダイレクト先として指定します
    #-Wait ダンプが終わるまで画面に処理を戻しません
    Start-Process -FilePath $svnadmin -ArgumentList $arguments -RedirectStandardOutput $dump_path -Wait
}
```
使い方は、ほとんどコード内に書いてあるが、例えば"C:\Repositories"にあるリポジトリ全てを、"z:\RepoDumps"フォルダにダンプする場合は、スクリプト(dump_repositories.ps1)が保存されているフォルダに移動し、以下のコマンドをPowershellで実行すればよい。

```powershell:実行
.\dump_repositories.ps1 "C:\Repositories" "z:\RepoDumps"
```

#注意点
リポジトリのファイルサイズがさほど大きくない場合でも、フルダンプを作成する場合には履歴のサイズに応じてダンプファイルが膨らんでしまう場合がある(うちで行った場合がまさにこのパターン)ので、ダンプ先の空き容量は、十分に大きなサイズを準備して行わないとエラーで終了してしまう可能性があります。
また、ダンプ元とダンプ先が同じドライブの場合はディスクI/Oがボトルネックとなって時間が余計にかかる可能性があるので、意図的に別のドライブを選択するように配慮しましょう。
同様に、ネットワークドライブを指定した場合にはネットワークの帯域や速度がボトルネックとなる可能性があります。場合によっては、外付けのストレージデバイスを利用したほうがいいケースもあります。

以上、なんちゃってサーバー管理者の私自身が悩まされた事象を老婆心ながら列挙してみました。
PDF・ワード・パワポをGoogleドライブで共有すると書式が崩れる

![スクリーンショット 2021-05-14 10.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/1646101c-540c-9250-0e0a-d4e0c18401c6.png)

わかりやすかった動画をメモ
https://www.youtube.com/watch?v=KLDruUtzSAE
docker-composeでMongoDBのレプリカセットを作る

# 下準備
Dockerで動かすために、ディレクトリを作成します。

```bash
mkdir -p primary/data/db
mkdir -p secondary/data/db
```

次に、初期化スクリプトを作成します。

```bash
mkdir init
touch init/init.js
```

```javascript:init.js
rs.initiate({
  _id: 'rs0',
  members: [
    {
      _id: 0,
      host: "mongodb-primary:27017",
      priority: 100
    },
    {
      _id: 1,
      host: "mongodb-secondary:27017",
      priority: 10
    },
    {
      _id: 2,
      host: "mongodb-arbiter:27017",
      arbiterOnly: true
    }
  ],
});
```

`priority`を設定することで、常に指定したコンテナをプライマリーに設定することができます。

# `docker-compose.yaml`を書く

`services.[name].command`に`mongod`の引数を入れます。
**ホストのmongodと衝突するのを防ぐために、ポートを27018にしています。適宜読み替えてください。**

```yaml:docker-compose.yaml
version: '3'
services: 
  mongodb-primary:
    image: mongo:4.4
    command:
      - --replSet
      - rs0
    volumes:
      - ./primary/data/db:/data/db
      - ./init:/docker-entrypoint-initdb.d:ro
    expose:
      - 27017
    ports:
      - 27018:27017
    restart: always

  mongodb-secondary:
    image: mongo:4.4
    command: 
      - --replSet
      - rs0
    volumes:
      - ./secondary/data/db:/data/db
    expose:
      - 27017
    restart: always

  mongodb-arbiter:
    image: mongo:4.4
    command:
      - --replSet
      - rs0
    expose:
      - 27017
    restart: always
```

# 起動

```bash
docker-compose up -d
```
Flutter Firestoreからドキュメントのフィールドを取得する

#前提
FlutterとFirebaseとの連携パートは省いています！

バージョンは下記の通り

```yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: "0.7.0"
  cloud_firestore: "^0.16.0+1"
```

#ドキュメントのフィールドとは？
![スクリーンショット 2021-05-14 10.01.43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/64bae449-cfbb-14b9-9dd1-0fda99980a68.jpeg)

赤丸で囲った部分のことです。
`コレクション＞ドキュメント＞フィールド`という具合にデータが格納されているイメージ

https://firebase.google.com/docs/firestore/data-model?hl=ja

#Firestoreからドキュメントのフィールドを取得する

```dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

// 省略

 fetchUserData() async {
    final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
    final FirebaseFirestore _firestore = FirebaseFirestore.instance;
    final userId = _firebaseAuth.currentUser.uid;
    DocumentSnapshot snapshot = await _firestore.doc('users/${userId}').get();
    print(snapshot.data()['email']);
    return snapshot.data();
  }

 @override
  Widget build(BuildContext context) {
// 省略
    TextButton(
      onPressed: fetchUserData, child: Text('取得！')),
}
```

上記のコードの場合、**emailのみ**取得します。

```dart
print(snapshot.data());
```

上記のコードの場合、**全てのフィールド**を取得します

こういうことって、何気に公式ドキュメントを読んでもわからなかったりするので。。。。
Safariでmp4動画が再生できないときの原因

![giraffe-1330814_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/2204cfbd-208e-d267-edbe-d0580d669514.jpeg)


##はじめに

こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html

## Copyrights 
コピーレフトのイラスト : [giraffe-africa-tanzania-wild](https://pixabay.com/photos/giraffe-africa-tanzania-wild-1330814/)
コピーレフトの動画 : [bright-autumn-colors](https://www.pexels.com/video/bright-autumn-colors-1583096/)

##目的
一部のサーバーを使用しているときにSafariでmp4動画ファイルを再生できない理由を理解します。

## ツール
2つのHTTPサーバーを比較します。
最初のサーバーは**Python3**のデフォルトのHTTPサーバーです。
2番目のサーバーは**Python3**のデフォルトサーバーに似ていますが、**Rangeリクエスト**もサポートしています。

## サーバーの比較
####Python3デフォルトサーバー

```bash
 python -m http.server
```

####Python3 RangeHTTPServer サーバー

```bash
pip install RangeHTTPServer
```

```bash
python -m RangeHTTPServer
```



## 結果

デスクトップバージョンのSafariバージョン14.1でのテスト。

#### Rangeリクエストサポートなしのサーバー
![Screen Shot 2021-05-14 at 9.31.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/6b16aa6a-4f6f-6c08-9fdf-03d5c2b85e02.png)


#### Rangeリクエストサポートありのサーバー
![Screen Shot 2021-05-14 at 9.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/364c8f78-bea9-198c-473f-777f1203cfb5.png)

##まとめ
**Range HTTPリクエストヘッダー**は、**Safari**でのmp4動画ファイル再生をサポートするために必須です。

## 情報元
https://github.com/danvk/RangeHTTPServer
https://blog.logrocket.com/streaming-video-in-safari/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range
https://pixabay.com/photos/giraffe-africa-tanzania-wild-1330814/
https://www.pexels.com/video/bright-autumn-colors-1583096/