OmniAICreator/Qiita-1.07M huggingface dataset:
【設計】いいアプリは設計から 【開発者目線】

大きな案件ほど『設計』がものをいうと最近思う🤔

小さなアプリやスクラッチ開発(0から新規開発)でも
考えておくのは非常に大切だと思ったわん🐾

（ただベンチャーとか、設計が後回しになる理由もわかる……南無阿弥陀仏）


#実績のあるDDDのデザインパターンを使用する　"戦術的DDD"
	1番：良いモデルを作り、モデリングから利益を得るため。
			1.ドメイン(問題)についての理解を深め、モデルを改善し続け
            2.モデルを継続的にソフトウェアに反映する
	副産物：「メンテナンス性が高い(改修しやすい 技術的負債が少ない)コードが書ける」


#余談

通常モデルはDBに近いので、
コストを考えて変更が極力避けられがちなものです。

アーキテクチャレベルでしっかりした用意がなければ、
この要求に対応することは難しくなります。(メンテナンス性が低いアプリになる)



これにたいして、DDDでは

1.モデルをそのまま表現したソフトウェアを書く
2.実績のあるDDDのデザインパターンを使用する
というアプローチを提唱しています。


モデルを表現したソフトウェアを書く
モデルとソフトウェアのマッピングが明らかになるように、

モデルをできる限りソフトウェア上に表現することを目指します。

#設計って大事だよね
保守なんて…って思った時もあったけど
『保守しやすいアプリ』を触ってみて初めて設計の大切さを知った気がします。

当初の『０からシステム開発したい…！』って自分に反省を促したい。。。

もちろん新規開発、スクラッチ開発も経験したからこそ
『設計』って７割大変だし、７割大切なんや…って実感もしました🐾
（Test　や　後続に保守をしてくれる人のためにも)
S3 Object Lambdaで大量のテキストを並列加工

## はじめに
- S3 Object Lambdaを使って、大量のテキスト文を並列で形態素解析します。
- 形態素解析については別で[記事](https://qiita.com/sho-jp/items/50243956373f21b1e138)を書いています

## S3 Object Lambdaとは
> S3 Object Lambda を使用すると、クライアントアプリケーションによって S3 からオブジェクトを取得するときに、Lambda 関数を使用してデータを処理および変換できます。

![s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703256/53ad0823-d289-b26b-e8cc-185276169999.png)

[参照](https://aws.amazon.com/jp/blogs/news/translating-content-dynamically-by-using-amazon-s3-object-lambda)

S3にあるオブジェクトにGetアクセスした際に、裏側でLambdaが起動して処理した結果をレスポンスとして受け取ります。

## S3 Object Lambdaを使った並列処理
実際に書いてみる

- Lambda処理

```ruby
def handler(event:, context:)
  object_get_context = event['getObjectContext']
  request_route = object_get_context['outputRoute']
  request_token = object_get_context['outputToken']
  s3_url = object_get_context['inputS3Url']

  # S3のオブジェクトからテキストを取得
  uri = URI.parse(s3_url)
  res = Net::HTTP.get(uri)
  text = JSON.parse(res)

  # テキストを形態素解析処理
　　　　## 省略
 
  # S3 Object Lambdaのレスポンスとして返す
  s3_client.write_get_object_response(
    request_route: request_route,
    request_token: request_token,
    body: text
  )

  { 'statusCode': 200 }
end
```

- Client
 
```ruby
# 並行で以下の処理を実行

# S3にオブジェクト配置
s3_client.put_object(bucket: s3_lambda_bucket, key: s3_object_key, body: "This is test text")

# Lambdaで加工されたレスポンスを取得
res = s3_client.get_object(
  bucket: s3_lambda_bucket,
  key: s3_object_key
)
```

## 最後に
株式会社SARAHではサーバレスアーキテクチャを積極的に採用して、プロダクト開発を行っています。
サーバ移行について考えてみた（結論はない）

仕事でCentOSを使ってサーバを立てることが多かったので、サーバ移行をそろそろ考えないとな。
という、ふとした思いつきから本記事を書いています。

Centos8のサポートが昨年終了し、CentOS7のサポートは『2024/06/30』まで。(2022/01/06時点)
先述の通りCentOS（7）を使っているサーバが多いことが懸念。

あと2年もあるじゃないか。とも取れるが、言語のメジャーバージョンアップでも割と苦労したので、
サーバ移行はさらに工数がかかるんじゃないかと考えている。

- インフラ以降作業
- 全体の動作確認
- appサーバとDBサーバ兼務させてたらデータ移行
- ストレージサーバを兼務させてたらファイル移行

ざっと項目化したけど、細分化すると平行できない作業だったり、
ミドルウェアの設定云々で時間かかるんだろう。。。
（移行するOSの経験があれば早いとは思いますが）

## 移行先の候補を考えてみた

こちら↓の記事を参考にしました。
https://barecare.jp/blog/2021/06/29/42/

### CentOSはﾀﾋなない！

CentOSプロジェクトはCentOS Steamというものになるらしいですが、
これはRHEL(Red Hat Enterprise Linux)の開発の一部となるみたいです。

開発サイクルを個人的な主観で例えると、こんな感じかなと。

|  |  |
|:-|-|
| Fedora  | 開発ブランチ  |
| CentOS Steam  | 検証ブランチ（ステージング）  |
| RHEL  | リリースブランチ  |

なので、CentOS Steamはより本番には近いものだけど、
安定しないかもね。てへぺろ☆くらいのものだろう。

### Cent以外の選択肢

ランニングコストがかかるけど、それが問題ないなら・・・ **間違いなくRHELでしょう**

コストを抑えつつ聞いたことあるメジャー路線でいくなら・・・ **Ubuntuですかねぇ。**
ただ、パッケージ管理コマンドとか、WEBサーバがApache2デフォルトだった気がするので『慣れ』が必要ですね。

私の知識が浅いので、名前しか知らない・・・**AlmaLinux**
近いうちに触ってみて記事にしてみよう。


## 所感

情報量の多さから選択すると、RHELかUbuntuが強い気がしてます。
さらにコストが加わってくると、Ubuntuかなと。

私も昔はUbuntuをよく使ってましたけど、Centを使い慣れた今Ubuntuに戻れるかなという不安（笑）

あとは、名前しか知らなかったダークホースのAlmaLinux。（ダークホースではないｗ）
こいつは今使ってみたいですね。
興味的でいうと一番はAlmaLinux一択です（笑）

さて、商用でCentosをお使いの皆さんも、そろそろサーバ移行を意識してもいいかもしれまんよ。
（サーバレスという選択肢も忘れないでね！）
[速報]DynatraceのGUIが日本語化されました

Dynatraceをご利用中もしくは導入を検討中の皆様に朗報です。

なんとDynatraceのGUIが**日本語化**されました！
[リリースノート](https://www.dynatrace.com/support/help/shortlink/release-notes-saas-sprint-233#japanese-display-language-dynatrace-web-ui)

# 日本語メニューの一例

プロブレム一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/e5275ce8-2a3f-4a79-fa78-242c1cb3a0f4.png)
ホスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/5b417b9c-ed92-4128-d5e7-a12471cee6bb.png)
サービス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/072d3c82-d059-48b1-75b0-50e366340da2.png)
PurePath
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/1da3b0a2-34f1-4f8b-dce4-feefbf1fa97d.png)

# 表示言語の切り替え方

画面右上にある人のアイコンをクリックし、言語メニューを開くと言語を切り替えることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/160aa5fd-e6b5-94a2-dd30-a06d2ef62270.png)

# まとめ

今までは英語のGUIのみだったので、そこがネックだったという方はぜひこの機会に15日間の**[フリートライアル](https://www.dynatrace.com/ja/trial/)**を利用してDynatraceを体験してみてください。
[py2rb] キーワード引数と可変長引数の組み合わせ

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# 引数 (Python)
```python
def func1(a, b, *args):
    print(a, b, args)

def func2(a, b=None, *args):
    print(a, b, args)

def func3(a=None, b=None, *args):
    print(a, b, args)

func1('A')
func2('A')
func3(b='A')

func1('A', 'B')
func2('A', 'B')
func3(b='A', a='B')

func1('A', 'B', 'C', 'D')
func2('A', 'B', 'C', 'D')
func3('B', 'A', 'C', 'D')

#output
TypeError: func1() missing 1 required positional argument: 'b'
A None ()
None A () 
A B ()    
A B ()    
B A ()    
A B ('C', 'D')
A B ('C', 'D')
B A ('C', 'D')
```
引数を工夫することにより様々な関数を利用することができます。

https://www.shoeisha.co.jp/book/detail/9784798163642

独習Python 330p
# 引数 (Ruby)
```ruby
def func1(a, b, *args)
  p [a, b, args]
end

func1('A')
func1('A', 'B')
func1('A', 'B', 'C', 'D')

`func1': wrong number of arguments
["A", "B", []]
["A", "B", ["C", "D"]]
```
`func1`の動作は同じです。

```ruby
def func2(a, b: nil, *args)
  p [a, b, args]
end

syntax error, unexpected `end', expecting end-of-input
```
キーワード引数と可変長引数を同時に使用するとシンタックスエラーになります。

```ruby
def func2(a, b=nil, *args)
  p [a, b, args]
end

func2('A')
func2('A', 'B')
func2('A', 'B', 'C', 'D')

["A", nil, []]
["A", "B", []]        
["A", "B", ["C", "D"]]
```
デフォルト値付き引数と可変長引数であれば、エラーは発生しません。

```ruby
def func3(a=nil, b=nil, *args)
  p [a, b, args]
end

func3(b='A')
func3(b='A', a='B')
func3('B', 'A', 'C', 'D')

["A", nil, []]
["A", "B", []]        
["B", "A", ["C", "D"]]
```
しかし、エラーは発生しませんが、順番が問題になることが想定されます。

可変長引数の`**kwargs`を利用して渡すのが現実的でしょうか。
# メモ
+ Python の キーワード引数と可変長引数の組み合わせ を学習した
+ 百里を行く者は九十里を半ばとす
なぜ人はサーバーサイドバリデーションを書くのか

##概要
社内でサーバーサイドバリデーションの有用性や必要性などについて議論する機会があった。
そもそもサーバーサイドバリデーションは書くべきなのか書かないべきなのか、何を書くべきなのか
いろいろな視点を想定して自分なりに調べ考えたものをここに書き散らしていく。

なお、前提としてここで言うサーバーバリデーションとは処理前の入力バリデーションのことを指す。
筆者はphp（laravel)環境でこの議論をしているため、動的型付けであることを念頭に置いて読んでいただきたい。

→追記 
ご指摘、ご意見をくださった@Zap212さんありがとうございます！

##1. サーバーサイドバリデーション不要説

議論の一つとして上がった内容がこれ。
この意見の根拠を簡潔にまとめると

1. フロントエンドの実装にほぼ同じ内容のバリデーションを書くから(悪意のあるユーザーやバグによる想定外のリクエスト以外はフロント側で処理できる)
2. サーバーバリデーションは普通デフォルトではエラーログを吐かないので、クライアント側でサーバー側バリデーションのエラーをキャッチしていない時に
   クライアント側で予期していない動作が起こる可能性がある
3. クライアントでも書いているバリデーションロジックをサーバーサイドでも書くことによる単純な工数増加(工数増加に見合ったリターンが少ないと考える)
4. サーバーバリデーションを書いたから必ず期待しているリクエストが受け取れるわけではない
5. 想定外の型のデータが来たとしてもバグが出れば422エラーと違いサーバーログで捕捉できるからデバッグしやすい

##2. サーバーサイドバリデーション必要説

->サーバーサイドバリデーション不要説に対する異論やデメリット、リスクを上げていく


> フロントエンドの実装にほぼ同じ内容のバリデーションを書くから(悪意のあるユーザーやバグによる想定外のリクエスト以外はフロント側で処理できる)

フロントエンドのバリデーションに不足があった際に想定外の動作を引き起こす可能性はかなり高くなる
→処理側はリクエストの型や形式が一定のルールのものを期待している。
そこに制限がなければ期待していない動作を起こす可能性は非常に高い
 ex)　boolを期待しているパラメータにstringが来る、動的型付けだと空文字以外がtrueとみなされ、クライアントが期待しているリクエストと全く違うリクエストとして受け取られてしまう、など

> サーバーバリデーションは普通デフォルトではエラーログを吐かないので、クライアント側でサーバー側バリデーションのエラーをキャッチしていない時に
   クライアント側で予期していない動作が起こる可能性がある

そもそもクライアント側でエラーハンドリングは書く前提であるべきである。書かない場合は429や500など比較的発生しうる問題にも対応できないため非常に不安定なアプリケーションとなってしまう

> クライアントでも書いているバリデーションロジックをサーバーサイドでも書くことによる単純な工数増加(工数増加に見合ったリターンが少ないと考える)

サーバーサイドバリデーションを書かないことにより、実装の抜けが表面化せずリリース後など運用段階で表面化した際にかかる修正工数やサービスの信用等を考慮するならば書くべきではないか
(型を制限できないので全てのパラメータと型の組み合わせに対して処理を書く必要があり、無駄が多い。)

> サーバーバリデーションを書いたから必ず期待しているリクエストが受け取れるわけではない

laravel環境においてはFormRequestクラスからインスタンス関数のvalidated()メソッドを使うことによってバリデーションを通過したパラメータのみを含めた配列を取得することが可能。書かない場合は完全に実装側のセキュリティモラルに任せるしかない(複数代入・SQLインジェクション・...etc)
ホワイトリストでリクエストを受け取ることにより、意図していないリクエストをカットしつつ、おおよそ期待しているリクエストだけを取得することができる

> 想定外の型のデータが来たとしてもバグが出れば422エラーと違いサーバーログで捕捉できるからデバッグしやすい

トランザクション処理にしてなかったり、外部サービス依存の処理だったり、などエラーの捕捉と処理のロールバックができる設計ができていない場合、ログでバグの内容は捕捉できるが想定外の処理結果が残ってしまう。(バリデーションエラーもログ出力そのものは可能)


##結論
サーバーバリデーションは可能な限りセキュリティリスクを減らすために必須なものと考える。開発者のセキュリティモラルやテストの品質の高さである程度回避できるものはあるが、書かないことによる潜在的リスクの方が怖いのでとりあえず書いとけ派ではある。

→追記
フロントか、バックエンドのどちらかに書くのであればバックエンドに書いてバックエンド側からのバリデーションエラーレスポンスをフロント側で処理する方が良い
(フロントで書くよりサーバーとの通信の分少々遅くなるがセキュリティリスクは低減できる)

##参考にさせて頂いた記事
語彙力のない自分でもわかる範囲で言語化しただけで書いてあることは以下の記事の方がしっかりしているし詳細に理解できるのでこちらを読むことをお勧めする。

https://blog.ohgaki.net/there-are-3-types-of-validations

https://blog.ohgaki.net/2017-owasp-top-10-changes-web-security-rule


##最後に
- 普段なんで書くのかなどあまり考慮せず書くべきものだと思って書いていたが、改めてなぜ書くのか意味を明確にできていい機会になった。
- 今回、可能な範囲で様々な視点で考察してみたが、所詮一個人の一意見でしかないので、こういった考えの奴もいるんだな、程度で考えて欲しい。
- どの立場で考えるかによって何が正義か変わるので一概には決め難い点もある。(工数/納期/工賃/チームの開発力/開発者のセキュリティモラル/...etc)
sed や grep での正規表現で 'or' ができない？

# あらすじ

ある JSON データから、`"transcript": ...`と`"confidence": ...`とある行のみを抽出しようとしたときのこと･･･。
(ちなみに IBM Speech To Text の結果の JSON データ)

指定の文字列が存在する行を標準出力してくれる`grep`コマンドに、「`transcript`または`confidence`という文字列がある」と命令をしてやればいいわけだ。
正規表現で 'or' をするには`|`を挟んで文字列を記述すれば良いので、`transcript|confidence`と書いてやれば良いわけだ。
･･･が？

```sh
grep "transcript|confidence"
# (結果無し)
```

あれれ〜？おっかしいぞ〜？

# 原因

正規表現の書き方は何ら問題は無く、`|`は拡張正規表現であったというのが原因です。
`grep`で拡張正規表現を使えるようにするには`-E`オプションが必要です。

```sh
grep -E "transcript|confidence" input.json
#               "transcript": "テキスト",
#               "confidence": 0.56
```

(レスポンスされる JSON データにインデントが入っているので、結果の文字列左にスペースが入っています。)

正しく書いているハズなのに、正規表現が思った動きをしない？と思ったら、とりあえず`-E`をつけてみたら解決することがあるかもしれません。
ちなみに、`+` (直前の文字が 1回以上繰り返されている) も拡張正規表現のようです。

# 以下余談

JSON データ数が 150個近くあったので、目視で手作業でコピペしてという選択肢は初めから外れていました。
Python に JSON の標準ライブラリ使ってやりくりして、という形でも良かったのですが、ただ抽出するだけと単純な動作だけだったので sh コマンドで片付けました。
sh シェルスクリプトなら、for ループで書いても 5行くらいで書き終えられるから楽なんや･･･。

ちなみに、オプション探しに`grep`のヘルプを改めて読んでみたとき、「一致した行の前後 n行を表示」とかもありました。
cd: '/Users/xxx/.Trash/' is a rotten symlink を解決

## はじめに
Macのfish shell上で、ゴミ箱を見たくて`cd ~/.Trash/`すると、
`cd: '/Users/xxx/.Trash/' is a rotten symlink`と叱られて
ディレクトリに遷移できないことがあります。

bashなら`cd`は成功してディレクトリへの遷移はできるものの、
.Trashに遷移してから`ls`叩くと、
`Operation not permitted`とやはり叱られます。

## 解決方法

システム環境設定
→セキュリティとプライバシー
→プライバシー
→フルディスクアクセス

この中にターミナルアプリを追加してチェックを入れればOK。

標準アプリの「ターミナル」の他に、
「iTerm」「Visual Studio Code」など、
ターミナル使うアプリをそれぞれ許可してやる必要があります。

![CleanShot 2022-01-26 at 10.14.41@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24333/c352d6b8-0ca2-ecef-1d04-3d719f645020.png)

これ自体は割と色んな所に書かれている設定方法ですが、
前者の「rotten symlink」のエラーメッセージでググっても気の利いた解説がないので、
全国のfish使いのググラビリティ向上のために一本書いておきました。

## 参考サイト

* [macOS Mojave/Catalina の「Operation not permitted」を回避する（du/ls/mv/cp 実行時）](https://qiita.com/KEINOS/items/0366f1c281b574a79cfb)
    * とても詳しく書かれていて参考になります
* [Getting an error "cd: '/Users/x/Downloads/' is a rotten symlink" in Fish shell](https://stackoverflow.com/questions/69018553/getting-an-error-cd-users-x-downloads-is-a-rotten-symlink-in-fish-shell)
    * これ、fishのエラーメッセージまでは一緒なんだけど、解決方法のコメントに「ファイルとフォルダ」で許可せよと書いてあって、「フルディスクアクセス」には言及されてない。それじゃ解決しないんだよ〜。
git pushしたことを無かったことにしたい！

git pushしたけど間違えて違った変更を入れてしまったときに、一度git pushを取り消す方法です。
※commitした変更も全てローカルからなくなってしまうことに注意してください。

#git pushを無かったことにする取り消し
###ローカルの変更も同時に取り消す

```
// 直前のコミットを取り消す
git reset --hard HEAD^
// 変更を無かったことにしたいbranch（master）に強制的にPushする
git push -f origin master
```


[git pushの取り消し方法](https://www-creators.com/archives/2020)


追記
###直前のコミットを取り消す（変更は取り消さない）
```
// 直前のコミット操作を取り消す
git reset --soft HEAD^
```
Eloquentの発行するSQLを簡単に取得したい

EloquentのクエリオブジェクトをSQLの文字列に変換する方法を紹介します。

### 方法

まずは `->get()` や `->first()` をコメントアウトしてEloquentのクエリビルダを変数に代入するように変更します。

```php
$query = AwesomeModel::where('hoge', true);
// ->first();
```

次のように、バインドされた値を展開してSQLに変換します。
デバッガやdd()と組み合わせて使うイメージです。

```php
$sql = \Illuminate\Support\Str::replaceArray('?', array_map(function ($v) {return var_export($v, true);}, $query->getBindings()), $query->toSql());
```
TypeScriptでimport React from 'react'と書くとエラーになってしまう時の対処法

### まず、何もせずに書いてみる
```
import React from 'react'
```
すると以下のエラー出る。。。

```
Module '"...略/node_modules/@types/react/index"' has no default export.
Module '"...略/node_modules/@types/react/index"' can only be default-imported using 
the 'allowSyntheticDefaultImports' flag.
```

##### 対応策1.アスタリスク記号を使う
```
import * as React from 'react'
```

##### 対応策2 tsconfigを直す
```
allowSyntheticDefaultImports: true
```


https://www.typescriptlang.org/docs/handbook/compiler-options.html
> デフォルトエクスポートのないモジュールからのデフォルトインポートを許可するようにしました。これはコードエミットには影響せず、型チェックにのみ影響します。

解決しました！！！！

以上
TensoFlowとPyTorchを試してみた件

#背景：いろんな書き方がある
深層学習でよく使われているTensorFlowやPyTorchをどちらも使えると良いなと思い簡単に使ってみました。

#目的：フレームワークの違いを知る
フレームワークを使う時と使わない時でどういう違いが出るかを見るのが目的です。

#方法：それぞれでANDゲートを実装する
今回はANDゲートを実装します。1.フレームワークを使わない場合、2.TensorFlowを使うとき、3.PyTorchを使うときの3つを実装します。

#結果：実装したコード
TensoFlowとPyTorchを試してみた件.ipynb

https://colab.research.google.com/drive/1UxyTmPOOVYV1AvhvBNAHmZnJ6Hhzkn9j?usp=sharing
#考察：処理の流れの違いを通して誤差逆伝搬の流れを意識できた
型の違いやフレームワークでの計算の流れを意識出来ました。

#課題
1. 今回は簡単な実装だけでした。今後、コンペで使われる様なコードでも比較していければと思います。
1. 書いた後で気付いたのですが、今回の実装ではinit関数で実装したモジュールを使っていませんでした。そのうち更新していると思います。=>init関数を実装したモジュールは自動微分用に作っていました。こちらは別の投稿で更新したいと思います。

#関連
1. [GitHubから自作モジュールを使ってみる](https://qiita.com/tan0ry0shiny/items/70da22955b44b8c03829)
1. [自作モジュールのinit関数を使いたい](https://qiita.com/tan0ry0shiny/items/44c8b3fad8038cba6e15)
1. [なぜディープラーニングするのか？を自分なりに調べてみた件](https://qiita.com/tan0ry0shiny/items/e0d4233de1e59c4d4c03)
アニメの顔を切り抜く

#アニメ画像から顔を切り抜く方法です
<img src="https://user-images.githubusercontent.com/23278992/150891601-2653a96a-d895-4128-9d94-fbb2457bccd3.jpg", width=256> <img src="https://user-images.githubusercontent.com/23278992/150891597-3916db4c-e781-47fc-bd72-a38ae6579a0b.jpg", width=256>
#アニメデータセットをつくりたい
画風変換などで、アニメ画像のデータセットを作るときに、顔だけ切り抜きたい時があります。
大量の画像を自動で処理したい。

#animefaceで切り抜ける

OpenCVでanimefaceを使うことで、自動処理できます。

#コード
<img src="https://user-images.githubusercontent.com/23278992/150891603-2d5be34d-f069-4c9e-a5f4-95c817e76155.jpeg", width=512>

lbpcascade_animefaceをダウンロードします。

```shell
!wget https://raw.githubusercontent.com/nagadomi/lbpcascade_animeface/master/lbpcascade_animeface.xml
```

```python
import cv2

def crop_anime_face(path,write_path):
  face_detector = cv2.CascadeClassifier('lbpcascade_animeface.xml') # initialize detector
  input_img_name = path
  img = cv2.imread(input_img_name)

  faces = face_detector.detectMultiScale(img) # detect
  for x, y, w, h in faces:
    left = x
    top = y
    right = x + w
    bottom = y + h
    face_img = bg[int(top):int(bottom), int(left):int(right)] # crop
    cv2.imwrite(write_path,face_img)
```

<img src="https://user-images.githubusercontent.com/23278992/150891601-2653a96a-d895-4128-9d94-fbb2457bccd3.jpg", width=256> <img src="https://user-images.githubusercontent.com/23278992/150891597-3916db4c-e781-47fc-bd72-a38ae6579a0b.jpg", width=256>

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

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
neosでlogix その58

#概要

neosでlogixやってみる。
LineTransformコンポーネント
Remap -1..1 to 0..1ノード、使ってみた。

#写真

![2022-01-25 22.52.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e39452b9-eb67-2409-b097-f11c36324809.jpeg)


#Remap -1..1 to 0..1

```
Inputs
 	Float	Value
Outputs
 	Float	*
```

#手順

- devtooltipを装着
- 新規->3d->corn
- 新規->3d->corn
- 新規->3d->box
- インスペクターを開く
- Transform->Drivers->LineTransformを追加
- logixtooltipを装着
- そのインターフェースを取り出す
- ノードブラウザを表示
- Tをスポーン
- Sinをスポーン
- Remap -1..1 to 0..1をスポーン
- つなぐ

以上。
CentOS系へのMeCab導入

# [MeCab (和布蕪)](https://taku910.github.io/mecab/#download)とは

[MeCab](https://taku910.github.io/mecab/#download)は 京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトを通じて開発されたオープンソース 形態素解析エンジンです。 言語, 辞書,コーパスに依存しない汎用的な設計を 基本方針としています。 パラメータの推定に Conditional Random Fields (CRF) を用 いており, ChaSenが採用している 隠れマルコフモデルに比べ性能が向上しています。また、平均的に ChaSen, Juman, KAKASIより高速に動作します。 ちなみに和布蕪(めかぶ)は, 作者の好物です。 

# 導入手順

## lang-Cs
```bash
sudo yum -y install make gcc-c++
make --version <- 確認
g++ --version <- 確認
```

## iconv
```bash
wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
gzip -dc libiconv-1.16.tar.gz | tar xvf -
cd libiconv-1.16
./configure
make
sudo -s
make install
iconv --version <- 確認
```

## mecab
・本体

```bash
https://taku910.github.io/mecab/#download
tar zxfv mecab-0.996.tar.gz
./configure --with-charset=utf8
make
make check
sudo -s
make install
exit <- root抜ける
```

・辞書

```bash
https://taku910.github.io/mecab/#download
tar zxfv mecab-ipadic-2.7.0-XXXX.tar.gz
cd mecab-ipadic-2.7.0-XXXX/
./configure --with-charset=utf8
make
sudo -s
make install
exit <- root抜ける
mecab --version <- 確認
```

・テスト

```bash
$ mecab
すもももももももものうち
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
```
三角関数を二分法で計算しよう

三角関数を二分法を使って求めることができるので、もしかするとほかの方がもう紹介しているかもしれませんが、ここで紹介させていただきます。

#考え方

単位円を考え、その周に沿って二分探索をします。対応する三角関数の値を求めたい角度を$\theta \in (-\pi, \pi]$とします。

![cos_bisec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/fe011c09-143d-01a4-15ad-93d04daa9f26.png)

図のような単位円上の２点 $P_L,P_R$に対して、

```math
\vec{ O \tilde{P}_{piv}} = \vec{O P_L} + \vec{O P_R}
```

となるように点　$\tilde{P}\_{piv}$　をとります。また、$\theta\_{L/R/piv}$は原点$O$からそれぞれ対応する点へのベクトルとベクトル$(1,0)$がなす角です。また$\theta_L < \theta < \theta_R$とします。
このとき、四角形$ O P_R \tilde{P}\_{piv} P_L $はひし形となり、$ O \tilde{P}\_{piv}$は角 $ \angle P_R O P_L $ の二等分線となります。

これを規格化して $P_{piv}$を得て、
 
```math
\theta_{piv} = \frac{\theta_R + \theta_L}{2}
```

となります。

```math
\begin{align}
\theta<\theta_{piv} &\Rightarrow P_R \leftarrow P_{piv} \\
\theta>\theta_{piv} &\Rightarrow P_L \leftarrow P_{piv}
\end{align}
```

とすれば、$\theta_R-\theta_L$は更新前の半分になります。

これを繰り返していくと 

```math
\begin{align}
\theta_R, \theta_L &\rightarrow \theta \\
x_L,x_R &\rightarrow \cos{\theta} \\
y_L,y_R &\rightarrow \sin{\theta}
\end{align}
```

となります。
 
初期値は $P_L = (1,0;0), P_R = (-1,0,\pi)$からスタートしますが、このとき$\tilde{P}\_{piv}=O$となってしまうので、このときだけ$P_{piv} = (0,1,\pi/2)$と例外処理をします。

# 実装

```cos.cpp
#include<bits/stdc++.h>
#define rep(i,n) for ( int i=0; i< (n); ++i )
using namespace std;

const double th = 1e-7;

int main(){
    double x;
    cout << "pi*";
    cin >> x;
    x *= M_PI;
    auto dist2 = []( double x1, double y1, double x2, double y2 ){
        double x=x1-x2,y=y1-y2;
        return x*x+y*y;
    };
    double c1=1.,s1=0.,angle1=0,c2=-1.,s2=0.,angle2=M_PI;
    while( angle2-angle1 > th ){
        double c=(c1+c2)/2., s=(s1+s2)/2., angle = (angle1+angle2)/2.;
        double norm = sqrt(c*c+s*s);
        if( norm < 1e-12 ) s=1.;
        else c /=norm, s/=norm;
        if( angle < abs(x) ) c1=c,s1=s,angle1=angle;
        else c2=c,s2=s,angle2=angle;
    }
    if(x<0) s1*=-1.;
    cout << c1 << " " << s1 << endl;
    cout << cos(x) << " " << sin(x) << endl;
    return 0;
}

```

# 逆三角関数の二分探索

この考え方と同様にして逆三角関数を求めることもできます。例えば、以下のコードでArctanを計算できます。

```atan.cpp
#include<bits/stdc++.h>
#define rep(i,n) for ( int i=0; i< (n); ++i )
using namespace std;

const double th = 1e-10;

int main(){
    double x;
    cin >> x;
    auto dist2 = []( double x1, double y1, double x2, double y2 ){
        double x=x1-x2,y=y1-y2;
        return x*x+y*y;
    };
    double c1=0.,s1=-1.,angle1=-M_PI/2.,c2=0.,s2=1.,angle2=M_PI/2.;
    while( angle2-angle1 > th ){
        double c=(c1+c2)/2., s=(s1+s2)/2., angle = (angle1+angle2)/2.;
        double norm = sqrt(c*c+s*s);
        if( norm < 1e-12 ) c=1.;
        else c /=norm, s/=norm;
        if( s < c*x ) c1=c,s1=s,angle1=angle;
        else c2=c,s2=s,angle2=angle;
    }
    if(x<0) s1*=-1.;
    cout << angle1/M_PI << "*pi" <<  endl;
    cout << atan(x)/M_PI << "*pi" << endl;
    return 0;
}
```

このコードは$\theta=\arctan{x}$のときに、

```math
\begin{align}
\theta' < \theta &\Leftrightarrow \tan{\theta'} < \tan{\theta}=x \\
&\Leftrightarrow \sin{\theta'} < x \cos{\theta'}
\end{align}
```

となることを利用しています。
C++ お行儀の悪い標準入力

# はじめに

C++で競技プログラミングをしていてこう思ったことはありませんか？

「 標準入出力でシフト演算子 `>>` `<<` を書くのだるすぎ！！！！！！ 」

自分はいつも思っています

お行儀が悪いですが簡単にできる対処法をいくつか考えてみました

# 本文

## 1. カンマ演算子のオーバーロード

`>>` って打つのがだるいなら `,` ならマシだろ という安直な発想です

つまり

```c++
std::cin >> a >> b >> c;
```

としていたのを

```c++
std::cin >> a, b, c;
```

みたいに書こうということです

実装は簡単で,

```c++
#include <iostream>

template <typename T>
std::istream &operator,(std::istream &is, T &x){
  return is >> x;
}

int main(){
  int a;
  std::string s;

  std::cin >> a, s;
}
```

こんな感じに適当にオーバーロードすればいいです

## 2. 可変引数の関数

こっちのほうがまだマシなはずです

[可変引数テンプレート](https://cpprefjp.github.io/lang/cpp11/variadic_templates.html) を利用して, 可変長の引数を受け取れる関数を作ってみましょう

まず, 再帰呼び出しを利用した方法として

```c++
#include <iostream>

template <typename T>
void input(T &x){
  std::cin >> x;
}

template <typename T, typename... Args>
void input(T &x, Args&&... args){
  std::cin >> x;
  input(args...);
}


int main(){
  int a;
  std::string s;

  input(a, s);
}
```

こんな感じに書くことができます

二つ目以降の引数はすべて `args` に突っ込まれるわけですね

<br>

さて, これはこれでよさそうですが, C++17 以降ならもっと簡単に書くことができます

[畳み込み式](https://cpprefjp.github.io/lang/cpp17/folding_expressions.html) という言語機能が追加されているため, これを利用します

するとどうなるのかというと,

```c++
#include <iostream>

template <typename... Args>
void input(Args&&... args){
  (std::cin >> ... >> args);
}

int main(){
  int a;
  std::string s;

  input(a, s);
}
```

これだけでできます

これは 二項左畳み込み というやつです 詳しくは上のリンクに書いてあるので, ぜひ読んでみてください

# おわりに

いかがでしたか？

自分は競技プログラミングでいつもこの最後に書いた関数を使っています

もし気に入ったモノがあれば使ってみてください (ここにさらにマクロを使ったりしても楽しそうです)

そうでなくても,  せっかく [cpprefjp](https://cpprefjp.github.io/) という神サイトがあるのでこういった言語機能を調べてみるのもいいんじゃないかと思います

ありがとうございました
CentOS系へのNodeJSインストール手順

# CentOS系へのNodeJSインストール手順
## nodejsインストール

### repo追加
```bash
curl -fsSL https://rpm.nodesource.com/setup_17.x | sudo bash -
```

### repo確認
```bash
ls -1 /etc/yum.repos.d
nodesource-el8.repo <- 追加されている
```

### nodejs インストール
```bash
sudo yum install nodejs -y
```

### インストール確認
```bash
node -v
v17.4.0 <- バージョンが表示される
```
【Rails】Rails APIコントローラーの書き方

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## Rails APIコントローラーの書き方

```posts_controller.
class Api::V1::PostsController < ApplicationController

  def index
    render json: Post.all
  end

  def show
    render json: Post.find(params[:id])
  end

  def create
    post = Post.new(post_params)
    if post.save
      render json: post
    else
      render json: post.erros, status: 422
    end
  end

  def update
    post = Post.find(params[:id])
    if post.update(post_params)
      render json: post
    else
      render json: post.errors, status: 422
    end
  end

  def destroy
    post = Post.find(params[:id])
    post.destroy
    render json: post
  end

  private
    def post_params
      params.require(:post).permit(:name)
    end
end

```
7 の倍数の判定は 1000 進数における 11 の倍数判定と考えるとわかりやすいよという話

　[なんか見た](https://twitter.com/potetoichiro/status/1485958842970435586)ので久しぶりに7の倍数について思いを馳せました。

　7の倍数であるかどうかの判定は、他の数に比べて困難です。例えば、2や5だったら下一桁を見ればいいし、3や9だったら全ての桁を単純に足し上げていけばいいです。それに比べて、7の倍数であるかの判定は、

　**下から桁を3つずつ区切っていって、それらの値を順に足したり引いたりする** 

　という、一見とても非自明な操作を行います。これは**1000進数**の存在を考えることによって上手く整理できるので、説明していきます。

# Lv1...2,4,5,8の倍数か？

　そのために、単純な例として、2,4,5,8 の例を出していきます。2と5の場合は一番単純で、

-下1桁の数字が偶数であれば2の倍数
-下1桁の数字が0か5であれば10の倍数

　と一瞬で判定ができます。

　なぜ下1桁を見るだけでいいかというと、**10進数**だからです。1234 という数があった時に$1230+4$という風にこれらを分離した時、前者がどのような数であれ10の倍数であることは明らかです。10進数の時、最短で$10^n$にたどり着く倍数が$10=2\cdot5$となることから、これらが一番単純な例となります。

　同様に、4の倍数だと2桁目まで、8の倍数だと3桁目まで見れば十分ということになります。

# Lv2...3,9の倍数か？

　3,9の場合は少し複雑になります。なぜかというと、$10^n$は3の倍数では割り切れないからです。なので、原理的にすべての桁を見ないと判定ができません。しかし、各桁数のあまりについて着目すると面白い性質があります。

```math
\displaylines{
1 = 0 + 1\\
10 = 9 + 1\\
100 = 99 + 1\\
1000 = 999 + 1\\
\cdots
}
```
　全ての$10^n$について、3または9のあまりは1であることがわかります。

　例えば、12345という数字があった時に、

```math 
10000+2000+300+40+5
```

　と

```math 
1+2+3+4+5
```

　は、3で割ったあまりという意味では全く同じです。mod記号を用いて表せば

```math 
\displaylines{
12345 \equiv 1\cdot10000+2\cdot1000+3\cdot100+4\cdot10+5 \pmod 3\\
\equiv 1\cdot1 + 2\cdot1 + 3\cdot1 + 4\cdot1 + 5 \pmod3 \\
\equiv 1+2+3+4+5 \pmod 3 \\
\equiv 0 \pmod3
}
```

　となります。
　つまり、各桁の和が3や9の倍数かだけを見れば、その数自体がそうであるかを判別することができます。

# Lv3...11の倍数か？

　ここで7にいかず、一旦11に逸れます。

　11の倍数である場合はどうでしょうか。10進数だと少しややこしくなりそうですが、とりあえず$10^n$に対するあまりを見ていきます。

```math
\displaylines{
1 \equiv 1 \pmod{11}\\
10 \equiv 10\cdot 1 \equiv 10 \equiv -1 \pmod{11}\\
100 \equiv 10\cdot10\equiv -10 \equiv 1\pmod{11}\\
1000 \equiv 10\cdot 100 \equiv 10 \equiv -1 \pmod{11}\\
...
}
```

　という風に、-1と1を繰り返すことがわかります。

　つまり、各桁の数を交互に足し引きしたものが11の倍数であるかどうかを見ればよいということになります。

```math
\displaylines{
\text{ex)} 135795 \\
 \equiv 1\cdot100000+3\cdot10000+5\cdot1000+7\cdot100+9\cdot10+5 \pmod{11}\\
\equiv 1\cdot-1 + 3\cdot1 + 5\cdot-1 + 7\cdot 1 + 9 \cdot -1 + 5 \pmod{11}\\
\equiv -1+3-5+7-9+5 \pmod{11} \\
\equiv 0 \pmod{11}}
```

# Lv4...7の倍数か？

　やっと7の倍数にきます。7の倍数の時はもう少し話が複雑になります。今までの話は$10^n$について

- あるnより上はすべてその数の倍数になる
- あるnに対する余りが規則的である

　ということで成り立っていた議論でした。**7にそのような性質はありません**。

　ここで、**1000進数**という概念を考えます。

　この時、「1000進数における11の倍数」を考えると、これは前節と全く同じ議論ができます。

```math 
\displaylines{
1 \equiv 1 \pmod{11}\\
10 \equiv 10\cdot 1 \equiv 10 \equiv -1 \pmod{11}\\
100 \equiv 10\cdot10\equiv -10 \equiv 1\pmod{11}\\
1000 \equiv 10\cdot 100 \equiv 10 \equiv -1 \pmod{11}\\
...
}
```

　つまり、各桁の符号を変えながら足していけば良いです。

　**「1000進数における11」は「10進数における1001」** です。そして、1001は7の倍数なので（11や13の倍数でもあります）、ついでに7でも割り切れるという訳です。**「1000進数における各桁」とは「10進数における3桁区切りのかたまり」** になります。

　このように考えると、**下から桁を3つずつ区切っていって、それらの値を順に足したり引いたりする**という操作の意味が捉えやすくなるんじゃないかと思います。
2022/1/26主にITとかセキュリティの記事

ECサイト向けクレカ決済サービスに不正アクセス - メタップスP
https://www.security-next.com/133588

「Deep Security」などトレンド2製品に脆弱性 - 実証コードが公開済み
https://www.security-next.com/133574

「Redis」狙うパケットが1.8倍に - JPCERT/CC調査
https://www.security-next.com/133573

監査関係者向けに「プライバシーガバナンス」のセミナー - 「プライバシー・バイ・デザイン」提唱者も登壇
https://www.security-next.com/133579

NICTサイバーセキュリティシンポジウム2022(2/18開催)
https://www.d-wks.net/nict220218/?fbclid=IwAR0F_qVMcDD2jApm0T2nNy0TyvijYzwfdWPMajbPMegB85_1kwe8AY5Yjho

Ericsson、米国以外に欧州とブラジルでもAppleを提訴〜ライセンス料巡り(1/23)
https://iphone-mania.jp/news-433957/

F5のBIG-IPやBIG-IQに複数の脆弱性、アップデートを(1/24)
https://news.mynavi.jp/techplus/article/20220124-2254705/

McAfee Agent for Windowsに特権昇格の脆弱性、アップデートが必要(1/24)
https://news.mynavi.jp/techplus/article/20220124-2253935/

2021年第4四半期、届出があった脆弱性は153件 - IPA(1/24)
https://news.mynavi.jp/techplus/article/20220124-2254099/

政府が強化するサイバー防衛、世界で強まる同様の動き(1/24)
https://japan.zdnet.com/article/35182288/

特集　自分で作る！便利サーバー構築術
https://xtech.nikkei.com/atcl/nxt/column/18/01908/

豪首相の微信アカウント消滅、乗っ取り被害か 豪議員は中国政府の関与主張(1/24)
https://www.afpbb.com/articles/-/3386647?act=all

海賊版アニメに誘導疑い 警視庁、リーチサイトを初摘発(1/24)
https://www.47news.jp/news/7328146.html

おせっかいなWindows 11アップグレード案内のせいで、Windows 10を21H2にアップデートできない？(1/24)
https://atmarkit.itmedia.co.jp/ait/spv/2201/24/news025.html

Twitter、仏控訴審で敗訴〜ヘイトスピーチの放置が問題に(1/24)
https://iphone-mania.jp/news-434098/

インフラエンジニアとソフトウェアの関係、そして憂鬱(1/24)
https://www.orangeitems.com/entry/2022/01/24/121700

GMOインターネットがセキュリティー事業に参入　ホワイトハッカー集団イエラエがグループ入り(1/24)
https://ascii.jp/elem/000/004/081/4081280/?rss

送信サーバーの設定してる？未設定 Contact Form 7 からのメールがついに拒否(1/23)
https://iimono.town/topic/it/97626/

3割の人が独自ドメインのメールアドレスを活用、その理由は？(1/24)
https://news.mynavi.jp/techplus/article/20220124-2255694/

三菱UFJニコスでトラブル　カード情報をメールで誤送信(1/25)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031800050/011800035/

さくらインターネットのクラウドサービスに障害発生、利用企業10社超に影響か(1/25)
https://xtech.nikkei.com/atcl/nxt/column/18/00598/121500149/

Windowsファイル共有って何？(1/25)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800010/011800048/
SSL / SSH 

SSLとSSHについて説明します。

先日http通信プロトコルについて説明しましたが、実は最近はhttpsが主に使われています。
httpsは _http over SSL_ という意味で、よりセキュリティーが強化されたと思って貰えばいいです。
ここでSSLという単語が出ましたね。

まずはSSLの説明です。

## SSLとは

SSLはSecure Socket Layerの略称でWEBサーバとWEBブラウザ間の**暗号化通信**のためのプロトコルです。
どのように暗号化をするかを説明します。

SSLではデータを**暗号化**をして送る。
そしてその貰った暗号化されたデータ**解読**してデータを見ることができます。
ここで２つの**KEY**というものが登場します。
まずは**A KEY**と　**B KEY**に名前をつけます。
この２つのA,B KEYは以下のような特徴があります。

A　KEYで暗号化したデータは　B KEYでしか解読できない。
B　KEYで暗号化したデータは　A KEYでしか解読できない。　
つまり　A KEYで暗号化したデータはA KEYでは解読できません。

ここで　A KEYを　PUBLIC（公開）KEY、
　　　　　　　　　B KEYを　PRIVATE（秘密）KEYに呼び替えます。
PUBLIC KEYはサーバがデータを要求したクライアントに公開するKEYです。
PRIVATE　KEYは　名前通り、PRIVATEなので、公開しないKEYでサーバだけが持っています。

SSL通信が始まると、サーバは　クライアントに　**PUBLIC KEY**と　**PRIVATE KEYで暗号化したデータ**を渡します。
そしたら、クライアントはPUBLIC KEYで　暗号化されたデータを解読することで、サーバから貰ったPUBLIC KEYが本当にサーバから貰ったKEYだと確信できます。
そして、PUBLIC KEYをクラッカーに取られても、クライアントがサーバに提供するデータ（PUBLIC KEYで暗号化）はクラッカーが見ることができません。
こういった仕組みを非対称暗号化と言います。
これを使うことで、SSLはより優れたセキュリティー環境でデータのやり取りができます。

　
## SSHとは

最近はAWSを利用して、仮想サーバを制御する際によく見かけると思いますね。

SSHは　Secure Shellの略称で、命令語方式で遠隔でパソコン（サーバ）を制御する方式のプロトコルです。
他の遠隔制御サービスよりセキュリティーが強化されています。
SSLで説明した非対称暗号化でデータを暗号化するためです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/1cc1b394-13d4-179b-64c2-6d73d0bb4249.png)
MacOSではSSHのクライアントは設置されているため、特に設置は不要で、遠隔制御されるサーバにもSSH Serverが設置されていないと遠隔制御ができなません。


以上です。
MyDNSを使ってリモートサイトのIPアドレスを確認する

#MyDNSとは
MyDNSとはフリーで使えるダイナミックDNSサービス。フレッツ回線など固定IPが経済的にチェレンジングなネットワーク環境でもドメインが使えるというサービス。
しかもmydns.jpなど限られたFQDNでよければ自分のドメインをその下に持つことができるという便利なサービスです。
##まずは登録から
詳しくはホームページに詳しい解説があります。
https://www.mydns.jp/#howtouse
登録を無事終えるとメールが届きます。
そのメールにはマスターIDとパスワードが記載されているので、保存しておくのを忘れないように

MasterID & Password : 
		mydns１２３４５６７８	password



マスターIDを使ってログインすると
DOMAIN INFOのページに行って、自分のドメインを登録しましょう

![スクリーンショット 2022-01-26 0.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/5614a42b-905c-65e2-40fd-263939695d74.png)
fig. 1

これで、host1.noname.mydns.jp　という世界でただ一つのドメインが手に入ります。
Target IDというのが上から３つめの表に見えますが、ここにMasterIDが入っています。
この時点ではMasterIDしか選べませんが、このMyDNSのすごいところは、子IDを作って、複数のサイトに別のドメインをアサインすることができることです。（しかも無料で！！）
##子ドメインを作るために
子ドメインを作るためには、子IDをMasterIDから申請する必要があります。
子IDの申請はMasterIDでログインして、User Infoのページから申請できます。
いくつ申請するかの数（例えば２とする）を決めて申請すると、その数だけChildIDとパスワードが作成されます。
![スクリーンショット 2022-01-26 0.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/86a6c2e7-c52b-db40-21c6-250f792faaf7.png)
fig. 2

画面イメージ(fig. 2)のように、すでにChiledIDを持っていても、２５６個まで追加することができます（！）
このIDをつかって、 noname.mydns.jpの下に別のホストのドメインを設定することができます。
![スクリーンショット 2022-01-26 0.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/47dfe6c1-d33a-2796-7e98-117fbe5fa4fc.png)
fig. 3
図(fig. 3)のHost Nameが「remote1」となっているエントリがあります。ここのTarget IDを（host1とは別の）ChildIDに指定すると、remote1.noname.mydns.jpというドメインでリモートサイトにあるホストのドメインが設定できます。

```
> remote1.noname.mydns.jp
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	remote1.noname.mydns.jp
Address: 14.111.111.111
Name:	remote1.noname.mydns.jp
Address: 240b:251: ... :ead2
```
nslookupで、こんな感じで出てくればOKです。
#IPアドレスの通知することをお忘れなく
通知方法についてはホームページの「Let's Try」のセクションに詳しく載っています。
メールやHTTPでアクセスする方法などいろいろありますが、リモートサイト内にLunuがあるのであれば、そこからWGETコマンドをCRONで定期的にキックする方法が個人的には好みです。

```
#!/bin/sh
#
# TEST1.MYDNS.JP
/usr/bin/wget -O - 'http(s)://mydns111111:tp5YgZv4@ipv4.mydns.jp/login.html'
/usr/bin/wget -O - 'http(s)://mydns111111:tp5YgZv4@ipv6.mydns.jp/login.html'
#
#
# TEST2.0am.JP
/usr/bin/wget -O - 'http(s)://mydns222222:Ex8ZVkm7@ipv4.mydns.jp/login.html'
/usr/bin/wget -O - 'http(s)://mydns222222:Ex8ZVkm7@ipv6.mydns.jp/login.html'
#
#
# TEST3.0T0.JP
/usr/bin/wget -O - 'http(s)://mydns333333:QC6L2SF8@ipv4.mydns.jp/login.html'
/usr/bin/wget -O - 'http(s)://mydns333333:QC6L2SF8@ipv6.mydns.jp/login.html'
```
これはホームページの例そのものです。
原典はこちらにあります　→　https://www.mydns.jp/#lets-try

私が引っかかったのは Fig.3 のリモートサイトのドメイン登録を子IDのログインでサイトに入った後、Domain Infoの登録をして、「子IDではドメインの変更は行えません」的なメッセージが出てきて、あれっと・・・
MasterIDでログインして、そこのDomain Infoのページですべての子IDのドメインを Fig. 3にあるように設定するのですね。ちょっと混乱しやすいかな。
#ドメインを設定した後はサーバのポートはUFWなどを使って防衛することを忘れずに！
ルータのパートフォワーディングの設定とホストのFWの設定の整合性をチェックして漏れがないか、隙間がないか、確認しましょう。BotNetの温床にならないように、ソフトウェアのアップデートもこまめに、ね。
Sublime text エディターのカーソル位置を常に画面中央にするプラグイン

http://ja.uwenku.com/question/p-monrfyld-hw.html
引用元。そのままのコードで使えます。先人に感謝。

日本語で小説とか書いていると、複数行にまたがると、画面外に文字が出て行ってむきーってなるので、どうにかできないか考えていた。

```python
import sublime
import sublime_plugin 
class AlwaysCenterCommand(sublime_plugin.EventListener): 
    def on_modified(self, view): 
     sel = view.sel() 
     pt = sel[0].begin() if len(sel) == 1 else None 
     if pt != None: 
      view.show_at_center(pt) 
```

画面が変更されるたびに、カーソルがある位置を画面中央にする、というコードになる。
Rの異なるバージョンのインストール

# はじめに
RStudioがバージョン毎のパッケージを提供しています。
ビルド中にjava関連のエラーが出て詰まったのでこちらで。

# 環境
- Dell Optiplex 5060 SFF (2019), core i5 8400, M.2 256GB SSD, 32GB RAM
- Lubuntu 18.04

# 特定バージョンのdebのインストール

```
# ${R_VERSION}は欲しいバージョン
curl -O https://cdn.rstudio.com/r/ubuntu-1804/pkgs/r-${R_VERSION}_1_amd64.deb
sudo apt install ./r-${R_VERSION}_1_amd64.deb
```

パッケージは`/opt/R`にインストールされます。
インストールの確認をします。

```shell
/opt/R/${R_VERSION}/bin/R --version
```

`/usr/local`にリンクを貼ります。

```
# /usr/local/binにフォルダを作成
sudo mkdir /usr/local/bin/R /usr/local/bin/Rscript

# シンボリックリンクを貼る
sudo ln -s /opt/R/${R_VERSION}/bin/R /usr/local/bin/R
sudo ln -s /opt/R/${R_VERSION}/bin/Rscript /usr/local/bin/Rscript

# 環境変数の設定。vim ~/.profileで書き込んでもよし
cat <<EOF>> .profile
>export PATH=$PATH:/usr/local/bin/R:/usr/local/bin/Rsctipt

# 更新
source ~/.profile
```

# おわりに
Rの異なるバージョンのインストールを行いました。


# 参考
[RStudio Documentation](https://docs.rstudio.com/resources/install-r/)
Dockerのメリット

#Dockerとは
インフラ業界やDevOpsで注目されている[コンテナ](#コンテナ)型の仮想環境。Docker社が開発したもので、これまでの開発・配布・実行の方法を根本的に変化させたものといっても過言ではありません。Dockerを利用することでデスクトップPCであろうが、ノートPC であろうが、あるいはWindowsOSのPCであろうが、MacOSのPCであろうが全く同じように動作することが可能になります（<strong>サーバ、クラウドも問わない</strong>）。将来的には、どのシステム会社でもDocker、あるいは[コンテナ](#コンテナ)型の仮想環境が当たり前のように導入されているでしょう。もうすでに普及されているかもしれませんが。。。


#コンテナとは
ここを知ってる方は読み進めてください。

以下、O'Reilly社 Dockerを抜粋
https://www.oreilly.co.jp/books/9784873117768/
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516848/8199c3f2-3724-5a70-6b9e-e9845a0dcbd6.png"/>

>コンテナとはアプリケーションを依存対象とともにカプセル化したものです。一見すると、コンテナは単に軽量な仮想マシン（VM）のようにみえます。VMと同じように、コンテナは隔離されたオペレーティングシステム（OS）の環境を持ち、その中でアプリケーションを動作させることができる。しかしコンテナには、これまでのVMでは実現が難しい、あるいは不可能なユースケースを可能にしてくれる利点があります。<br/>
　・コンテナは、ホストOSとリソースを共有するので、
　　はるかに効率的です。コンテナの起動や停止は一
　　瞬で行えます。コンテナ内で動作するアプリケー
　　ションのオーバーヘッドは、ホストOSで直接動作
　　するアプリケーションと比較しても、ごくわずか、
　　ほとんどありません。<br/>
　・コンテナのポータビリティは動作環境のわずかな違
　　いによって生ずるようなタイプのバグを、すべて撲
　　滅できる可能性があります。昔からの開発者が繰り
　　返してきた「自分のマシンでは動くんだ！」という
　　フレーズさえも終わらせてくれるかも知れません。<br/>
　・コンテナは軽量なので、開発者は数十のコンテナを
　　同時に実行することが可能であり、実働環境そのま
　　まの分散システムをエミュレーションできます。運
　　用エンジニアはVMだけを使う場合に比べて、１台の
　　ホストマシンではるかに多くのコンテナを実行でき
　　ます。<br/>
　・エンドユーザーや開発者にとって、クラウドへのデ
　　プロイをしない場合でも、コンテナは利点がありま
　　す。ユーザーは、設定とインストールの問題に数時
　　間を費やしたり、システムへの変更についても気を
　　もんだりすることなく、複雑なアプリケーションを
　　ダウンロードして実行できます。一方で、そういっ
　　たアプリケーションの開発者は、ユーザの環境や利
　　用可能な依存対象の差異を心配せずに済むようにな
　　ります。

この「O'Reilly Docker」に記載されているようにコンテナはVMのデメリットをたくさん解消してくれています。投稿者（私）も友人と共同開発を進めた際に、SQL Serverを使用したいがため、勝手にWindows環境、言語はC#で開発を進めていたことがあります。しかし、友人はMac Bookしかもっておらず、SQL Serverのローカル環境でデバッグ、また開発を進めることができずに結局Pythonで開発をし直したという経験があります:sweat_smile:。しかしこのコンテナを使用していれば、Mac bookユーザの友人も開発が進めることができ、さらに容易に開発環境やソースを配布することができたと思います。

#メリット
上記[コンテナ](#コンテナ)の最後とも多少かぶりますが、開発現場や共同開発をするうえでのメリットを5つ挙げます。

1. どのOS、どのPCでも同じ動作が保証されている
2. 開発環境を容易に他人に配布することができる
3. 開発環境が壊れても、再度イメージを読み込むだけで開発環境が元通りになる。
4. ホストOSの電源を切ったとしても、仮想環境の電源は切れない。また仮想上で動くOSであるため、オーバーヘッドが抑えられる。
5. CI/CDの導入が楽。

以上。
borderで囲んだ画像のぼやけをCSSで解消する方法

## ぼやけた条件
- 140px × 140pxの枠
- border-width 2px
- 2倍の画像「280px × 280px」の画像を使用
- 画像は2倍じゃなくてもぼやける

## 原因
borderが2pxあるので、画像表示領域が4px分小さくなっているため
![border_in_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552308/201c1ce4-9a21-9162-6e6e-824f66d4a3d0.png)
※じゃあ136 ×136の画像を用意すればいいんじゃないの？っていう話ですが…
　まー、そうはいかない状況があったりなんかして…
　CSSでなんとかしたいと思った話です。

## 解決方法

```html
<div class="img_wrapper">
	<img src="画像のパス" alt="">
</div>
```
```css
.img_wrapper {
  width: 140px;
  height: 140px;
  border: 2px solid #333;
  overflow: hidden;
  position: relative;
}
.img_wrapper > img {
  width: 140px;
  position: absolute;
  top: -2px; /* borderが2pxのため */
  left: -2px; /* borderが2pxのため */
}
```
画像にposition: absolute;を使用しているのは、画像を中央に配置するためです。

### 〜 2022年2月2日修正、追記 〜

上記のよりももっと簡単な方法がありましたので修正します…すみません…
borderではなくoutlineを使えば大丈夫でした:pray:

```html
<div class="img_wrapper">
	<img src="画像のパス" alt="">
</div>
```
```css
.img_wrapper {
  width: 140px;
  outline: 2px solid #333; ←
}
.img_wrapper > img {
  width: 100%;
}
```
AWS クラウドプラティクショナー　流し見用 part2

●Amazon Route 53
Route53はAWSによるドメインネームシステムサービス
データセンターの物理的な災害、システム面での災害などが発生した場合、Route53サービスを使用してセカンダリサイトに簡単に切り替えることができる
また、Amazon Route 53は可用性が高くスケーラブルなDNSサービスでもある

●フォールトトレランスを向上させる方法
複数のアベイラビリティーゾーンにリソースを配置する
AWSリソースを複数のアベイラビリティーゾーンに配置することにより、Design For Failureの原則に従い、耐障害性を考慮した設計となっている
この構成により、１つのAZがダウンした場合でも他のAZがまだ稼働しているため、アプリケーションの耐障害性が向上する

●AWS Budgets,AWS Cost Explorerについて
AWS BudgetsはAWS Cost Explorerを利用しコスト表示を行い、事前にユーザーにより設定された良村のステータスを表示を行い推定コストの予測を提供する

●Design for Failureの原則をサポートできるものは？
リージョン、Elastic Load Balancing、アベイラビリティーゾーン

●AWSで作成されたユーザーとグループを管理するAWSツール
AWS Identity and Access Management(IAM)

●AWS CloudFormation
AWS CloudFormationはインフラストラクチャをコードとして管理可能であり、Amazon Web Serviceリソースのモデル化およびセットアップを可能にする
リソース管理に割く時間を減らし、AWSで実行するアプリケーションにさらに注力できるようになる

●AWS WAF
AWS WAFはセキュリティ侵害、リソースの過剰消費といった一般的なウェブの脆弱性からウェブアプリケーションまたはAPIを保護するウェブアプリケーションファイアウォール
AWS WAFには、特にSYNフラッド、DNSクエリフラッド、UDPリフレクション攻撃から保護するAWS Shield(追加費用なしのAWS Shield StandardとサブスクリプションでのAWS Shield Advanced)が含まれている

●共有セキュリティモデルに含まれるAWSの責任　例
・エッジ位置の確保
・物理デバイスのセキュリティの監視
・サービス組織管理（SOC)標準の実装

●疎結合化
疎結合の概念はアプリケーションのさまざまな構成要素を個別に管理および保守できるようにすることを意味する
すべてのコンポーネントが密結合している場合、１つのコンポーネントがダウンすると、アプリケーション全体がダウンする。そのため、アプリケーションコンポーネントを分離することは優れた設計手法にはる

●セキュリティ要件でAWSによって管理されるもの　例
・物理的セキュリティ
・ディスクの廃棄
・ハードウェアのパッチ適用

●AWSインフラストラクチャで禁止されている行動に関する情報はどこで確認できるか？
AWS利用規約

●AmazonSQS（Simple Queue Service)
AmazonSQSは、完全マネージド型のメッセージキューイングサービスであり、メッセージを効果的に保存することに限らず、マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングが可能
SQSではメッセージ指向ミドルウェアの管理や運用に関連する複雑さやオーバヘッドを排除できるため、開発者がコンポーネントの差別化作業に集中できる

●AWS EMR
Amazon EMRは業界をリードするクラウドネイティブなビッグデータプラットフォームで、多数のデータセット、大規模環境で大量のデータを迅速にコスト効率よく処理できる
EMRでは、Apache Spark,Apache Hive,Apache HBase, Apache Flink,Apache Hudi(incubating),prestoなどのオープンソースのツールと、Amazon EC2の動的なスケーラビリティおよびAmazon S3によるスケーラブルなストレージが組み合わされている

●Amazon Auroraなどのフルマネージドサービスでの共有責任モデルとは
Amazon Auroraなどのフルマネージドサービスでは、ユーザーはリレーショナルデータベースが存在するバックエンド EC2インスタンスにアクセスできない
従ってバックアップ、ソフトウェアの更新、OSの更新、パッチ適用、メンテナンス等はAmazonによって管理される

●AWSを利用するメリット
・可用性の高いインフラストラクチャ
・リソースをオンデマンドで使用可能

●幾つかの EC2インスタンスがクラッシュした場合でも、動作するアプリケーションを確実に保持するために採用する原則は？
フォールトトレラントシステムの使用

●AWS共有責任モデルに基づくAWSの責任　例
物理ハードウェアの保守

●AWSが従来のデータセンターよりも経済的なのは？
必要に応じてリソースをオンデマンドで起動できるため

●AWS VPC
VPCを使うと、AWS内に論理的に分離されたセクションをプロビジョニングし、利用者が定義した仮想ネットワークを作ることができる
UnauthorizedエラーでDockerのイメージがpullできない・docker loginコマンドでログインできない

# 確認環境
```
Docker Desktop 4.4.4 (73704)
```

# 経緯
いつものようにDockerコンテナを起動しようとしたら、何やらUnauthorizedといわれる。
直前にDocker Desktopのアップデートをかけたからか・・・？
今日付けでOrganizationにアカウントが紐づけられたからその影響もあるかもしれない。

```
$ docker-compose up -d  --build
[+] Building 7.9s (4/4) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                                               0.0s 
 => => transferring dockerfile: 32B                                                                                                                                                                                                0.0s 
 => [internal] load .dockerignore                                                                                                                                                                                                  0.0s 
 => => transferring context: 2B                                                                                                                                                                                                    0.0s 
 => ERROR [internal] load metadata for docker.io/library/php:8.0-fpm                                                                                                                                                               7.8s 
 => [auth] library/php:pull token for registry-1.docker.io                                                                                                                                                                         0.0s 
------
 > [internal] load metadata for docker.io/library/php:8.0-fpm:
------
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to authorize: rpc error: code = Unknown desc = failed to fetch oauth token: unexpected status: 40
1 Unauthorized
```

# 試したこと
ログインし直せばいいのでは？と思い、 `docker login` コマンドを叩くも、アクセストークンを使いなさいと言われる。

```
$ docker login
Authenticating with existing credentials...
Stored credentials invalid or expired
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (nagayoshi):
Password: 
Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: please use personal access token to login
```

そういや2要素認証設定したから、もしかしてアクセストークンを生成しないといけない・・・？そんなめんどうなことある・・・？

# 解決方法
Docker Desktop上でログインし直すことで解決した。アクセストークンは必要なかった！

- Docker Desktop上で `Sign out` する。ブラウザが起動してログアウトしたことを知らされる。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253650/348806c5-d4f0-0fe0-31a5-6d5304ce304e.png)

- 再びDocker Desktop上で `Sigh in` する。ブラウザが起動してユーザID/PW、2要素認証していればAuthentication Codeを求められるので、画面に沿ってログインする。

数日の間Docker使う機会がなかったんだけど、いつのまにかZoomのリンク開いたときみたいになってたのか。気になって調べたけど、リンクをクリックしたときにアプリケーションが起動して特定のコンテンツに遷移する仕組みのことをディープリンクというらしい。
とあるiOSエンジニアの 初投稿(自己紹介)

# 初投稿ということでまず自己紹介します:football:

現在関西の自社開発企業でiOSエンジニア（２年目）をしている２０代前半の男です。
趣味　：ダウンタウンを見ること、筋トレ、個人開発、ビートボックス、キャンプなど

僕自身以前は全くの異業種でして、ホテルマンとして働きながらiOSエンジニアになるために1年以上勉強していました。
僕は正直エンジニアになるのに普通の人より時間がかかった方だと思います。ですが毎日アホみたいにプログラムを書いたおかげでなんとか第一志望の企業に就職できました。
今後はまずiOSエンジニアを極めてiOSアプリならなんでも開発できるエンジニアになるためにiOSエンジニア専用の秘伝の巻物（要するにリファレンス）を作っていこうと思います。
まずiOSアプリ、その後は両OSのアプリもできるようにしていきます。
まだまだ未熟者ですが、数年後にはバケモンエンジニアになるので先輩方よろしくお願いします！:bow:
Spreadjsの初期化で学ぶ、React非同期処理

#何がしたいか
エクセルライクなスプレッドをWebアプリに組み込めるライブラリSpreadjsがあります。
その初期化処理中はローディングを出して、初期化が終わったらスプレットを出す実装の中で、
非同期の概念が少し理解できたので、まとめてみました。

#理解できないがとりあえず実現できたコード
```tsx
import GC from '@grapecity/spread-sheets'
import { Column, SpreadSheets, Worksheet } from '@grapecity/spread-sheets-react'
import '@grapecity/spread-sheets-resources-ja'
import { useState } from "react"

export const TestSheet = () => {
    const [isLoading, setIsLoading] = useState(true)

    const initSpread = (spread: GC.Spread.Sheets.Workbook) => {
        return new Promise<void>(resolve => {
            setTimeout(() => {
                // 3秒の重い処理を想定
                resolve()
            }, 3000) 
        })
    }

    return (
        <>
            {isLoading ? <h1>Loading....</h1> : <></>}
            <div style={{ visibility: isLoading ? 'hidden' : 'visible' }}>
                <SpreadSheets workbookInitialized={spread => {
                    initSpread(spread).then(() => setIsLoading(false))
                }}>
                    <Worksheet >
                        <Column />
                    </Worksheet>
                </SpreadSheets>
            </div>
        </>
    )
}
```

#非同期難しい
残念ながら、私はこのコードがなぜ上手くいくのか、理解できませんでした。
Promiseじゃなくて、async/awaitを使用したいし、setTimeoutも不要だと思ってました。
そして、色々消したり、付け加えたりしたのですが、うまくいきませんでした。
そこで、書籍を読み漁りました。

#読み漁りの結果
 [プログラミング TypeScript スケールするJavaScript アプリケーション開発](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0TypeScript-%E2%80%95%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8BJavaScript%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-Boris-Cherny/dp/4873119049)
上記書籍より、少しイメージがつかめたので説明します。

##ローディングのstateを変更するタイミング
重い処理が終わったタイミングでstateを変更すればよいので、
シンプルに重い処理の後に記述すればよく、.then()とか、awaitは不要です。

```tsx
 const initSpread = (spread: GC.Spread.Sheets.Workbook) => {
        return new Promise<void>(resolve => {
            setTimeout(() => {
                // 3秒の重い処理を想定
                setIsLoading(false) //new !!
                resolve()
            }, 3000) 
        })
    }

//省略
    return (
                <SpreadSheets workbookInitialized={spread => {
                    initSpread(spread) //.then(() => setIsLoading(false))
                }}>
    )

```

##Promiseやasyncが非同期を生み出すという勘違い
Promiseや、そのシンタックスシュガーであるasyncを付けるだけで非同期にはなりません。
非同期は、JavaScriptプラットフォームによって提供されているネイティブな非同期APIを呼び出す必要があります。

今回は、setTimeout()で非同期APIを呼び出しています。
そして、非同期APIを呼び出せば、その時点で、呼び出している関数(initSpread)も非同期になります。
よって、Promiseやasyncは不要です。

```tsx
 const initSpread = (spread: GC.Spread.Sheets.Workbook) => {
        setTimeout(() => {
            // 3秒の重い処理を想定
            setIsLoading(false)
        }, 3000) 
    }
```
##待つ必要がなければ、await不要→asyncも不要
initSpreadはバックグラウンドで勝手に処理されて、最後にloadingのstateをオフにすればよいので、
待つ必要はありません。asyncはawaitを書く際に必要になるものなので、
待つ必要がなければ、何も記述する必要はありません。
非同期処理がただ駆け抜けるだけです。

#まとめ
ただでさえ、非同期がわかっていないのに、Reactのレンダリングするタイミングも相まって、
非同期の理解がなかなか進みませんでした。
レンダリング内でawaitすれば、レンダリングが止まるのも、当たり前だと理解できるようになりました。
アダプティブカードから送信された値をBot Frameworkで受け取る方法

#前提

①アダプティブカードの基本的な作成ができる方向けに記事を書きます。
以下の記事に基本的な作成方法はまとめていますので、良かったら参考にしてください。
https://qiita.com/rei_441/items/6c93a3cfe3c2b89521a9

②Bot Frameworkを使用したことがある方向けになっています。
(いずれこちらもまとめて記事にしようと思っています。

##早速やっていきます

まず、クライアントはMicrosoftのTeamsを使用しています。
ユーザーからTeamsにてチャットが送信されると、TurnContextというオブジェクトがBot Framework側に送信されます。

この中にはM365のテナント情報やユーザーのIDなど、どのテナントの誰から送信されたメッセージなのかという情報を含んでいます。
実際にお見せしようと思ったのですが、隠さなければならない項目が多かったので割愛しますww

また、この中にはturnContext.Activity.Textという値があり、ここにはユーザーから送られたメッセージのテキストを保持しています。

では、まずアダプティブカードに入力した値をBot Frameworkに送信するにはどうすればよいのかやっていきます。

アダプティブカードのAction.Submitを使用することでInput.Textなどに入力された値を送信することができます。
Inputに使用できるパーツには以下のものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/aae08e97-89fd-1478-9315-926badc8e1b7.png)

では、前提に記載した記事の中で試作した以下のアダプティブカードを使用してやっていこうと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/b6f4ac28-d66a-833a-16da-d7dff5624840.png)

この場合まず三つの入力項目があります。
上から
①名前入力する。
②日付を入力する。
③時間を入力する。

そして送信ボタンは"type"にAction.Submitを定義しています

```
    "actions": [
        {
            "type": "Action.Submit",
            "title": "送信する"
        }
    ]
```

送信ボタンが押下されると入力された値がBot Frameworkへ送信されます。
受信した際にはturnContext.Activity.Valueの中に値が格納されるので、
自分はよく

```C#:test.cs
 string testString = TurnContext.Activity.Value.ToString();
 JObject details = JObject.Parse(testString);

```
のようにして値を取得しています。

しかし、このままだと値を取得することはできません。
先ほどのアダプティブカードの入力項目それぞれにIdを設定する必要があり、
そのIdと入力値がKeyとValueの関係になり、turnContext.Activity.Valueに格納されています。
Idを振ったアダプティブカードのJsonがこちらになります。

```json:sample.json
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.3",
    "body": [
        {
            "type": "TextBlock",
            "wrap": true,
            "text": "デモ版のアダプティブカードです。"
        },
        {
            "type": "Input.Text",
            "placeholder": "名前を入力してください",
            "id": "inputName"
        },
        {
            "type": "Input.Date",
            "id": "inputDate"
        },
        {
            "type": "Input.Time",
            "id": "inputTime"
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "送信する"
        }
    ]
}
```

"body"の各項目にIdが定義されています。
このIdはユニークなものである必要があるので重複しないように気をつけてください。

アダプティブカードデザイナーではPreview modeを使用することで実際に送信される値を確認することができます。

送信ボタンを押下後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031387/79b36f4a-762f-2cd9-5d08-5d10cfb3363c.png)

入力された値がIdと紐づいて送信されていることが確認できます。

これでアダプティブカード側の設定は終わったので、

BotFrameworkで受け取る処理を実装すれば完了です。

```C#:test2.cs
//入力された値をJObjectへ詰める
string testString = TurnContext.Activity.Value.ToString();
JObject details = JObject.Parse(testString);

//各項目の値を取得する
var inputName = details["inputName"];
var inputDate = details["inputDate"];
var inputTime = details["inputTime"];
```

これで値が取得できます。

###まとめ
アダプティブカードの値をBot Frameworkで取得するには
①アダプティブカードのInput項目にIdを定義する。
②アダプティブカードにAction.submitのボタンを定義する。
③Bot FrameworkにTurnContext.Activity.Valueの値を取得する処理を実装する。