OmniAICreator/Qiita-1.07M huggingface dataset:
iPhoneで写真を撮ったら自動的にDropboxに保存されるようにする２　#ヘルスケア ＃医療

以前こちらの記事でIFTTTを使って、iPhoneの背面カメラで撮った写真が自動的にDropboxで指定したフォルダに保存される仕組みを紹介しました。

https://qiita.com/naokiuc/items/e9850fcb0a93ec1f982e

その後、@tishiyamaさんの[この記事](https://qiita.com/tishiyama/items/62b8e5530414c1853e99)を読みiOSショートカットアプリを使えば簡単に同じ仕組みを実装できることを知り、実装して現場で試したので新たに記事にしようと思います。

今回はじめてiOSショートカットアプを知りましたが、こちらの記事によくまとまっています。

https://time-space.kddi.com/mobile/20210628/3134


#背景
私は訪問診療に携わる医師です。
訪問診療では通院困難な方の家に訪問して診療を行います。
クラウド型のカルテを使用していて、診察の際はプリントアウトしたカルテを持って行き現地で診察しながらカルテを書いて、診察終了後にカルテの写真を撮ってクリニックにいる担当事務さんにLINE WORKSを使って写真を送りカルテを代行入力してもらうという一連の流れがあります。

特に施設などでまとめて複数名の診察をする際は診察の合間に写真を送りそびれて、カルテ入力の業務が滞るという課題がありました。
そこでiPaaSの仕組みを使い自動化できないかと考えたことが元々のきっかけです。

#実装

iOSのショートカットアプリから作成します。
・アプリを立ち上げ、右上の+から「新規ショートカット」を立ち上げ、「＋アクションを追加」をタップ。

・すると、アクションの候補が出てきます。
![写真 2021-11-27 4 46 19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/c5982dd4-84fc-e75a-9be8-e604e6a4686d.jpeg)

・検索欄に「カメラ」と入れてカメラを選択。

・「ビデオを撮る」「写真を撮る」の二択が表示されるので今回は「写真を撮る」を選択。

すると、この画面になります。
![写真 2021-11-27 4 50 20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/664e658e-4ece-4c10-2c1c-abdf865e61db.jpeg)
ここで青字になっている「１枚の写真」や「背面」をタップすると、撮る枚数やカメラを選択できます。

・次にまた「＋」をタップして新たなアクション追加。今後は検索欄に「Dropbox」と入れると可能なアクションの候補が出てきます。
![写真 2021-11-27 4 53 55.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/d1a0e890-1669-7c6a-0f63-d71742d4d8f7.jpeg)
・今回は「ファイルに追加」を選択。
![写真 2021-11-27 4 55 49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/f5669cd9-5432-5481-1488-361b03badc0f.jpeg)
・ここで「サービス」をタップし、今回は「Dropbox」を選びます。

・あとは、「ファイルパス」の部分に、保存したいファイル名を入力して最後にショートカット名を入れれば完成です。

ちなみに、「ファイルパス」の部分に入れるファイル名を「/」で繋ぐことでフォルダ内のフォルダに保存することができます。
当院であれあれば複数医師が訪問していて写真を撮った医師を区別する必要があるので、「カルテ保存」という共有フォルダ内に医師ごとのフォルダを作成するという形の運用となるのですが、その場合は「カルテ保存/内田」と「ファイルパス」の部分に入力します。

#実際に訪問診療で使ってみて
従来の運用では8タップが必要だった操作が3タップですみ簡単になりました。

ショートカット作成画面の「カメラ」のところにある「表示を増やす」をタップすると「カメラプレビューを表示」が出現し、デフォルトでオンになっているものをオフにすると2タップで操作可能となるのですが、写真を撮る画面すら表示されずどんな写真が撮ったかわからないので使いづらいです。

また、実際に運用していくつか課題がわかりました。
一つは、撮った写真が写真フォルダに保存されないこと。
このため、後で写真を振り返ることができません。
これが、次に書いていることと関係し一つの問題となりました。

もう一つの課題は、写真を撮って送信後、2-3秒してからショートカットが作動したことを示すこちらが表示されるのですが、
![写真 2021-11-27 5 08 32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/9365e19b-8870-c63d-6c62-67ce274d88a2.jpeg)
たまに、「エラーが出ました」と表示され、うまく作動しないことがあります。
しかし、表示されるのに2−3秒のタイムラグがあるため現場ではいちいち作動したかの確認をしていられません。
このため、写真を撮ったつもりが撮れておらず保存されていないということが、ごくたまにあります。

カルテであれば書いた紙が手元にあるためあまり問題にならないのですが、処方箋の場合手書きで修正した原本を患者さんに渡してくるため原本が手元になく、今回の運用では撮った写真が撮った写真が写真フォルダに保存されないため確認ができません。
このため、処方箋については従来の運用で写真を送ることにしました。

ちなみに、[前回記事で書いたIFTTTを用いた方法](https://qiita.com/naokiuc/items/e9850fcb0a93ec1f982e)であれば、IFTTTアプリ内で撮った写真が確認できるため、撮ったものの保存されていなくて確認できないという事象は生じません。
ただ、こちらの運用では写真の画質の悪さが課題となりました。
間にIFTTTアプリが入るせいか、今回のiOSショートカットで自動保存する場合よりも写真の画像が荒く記事入力する事務さんが見にくかったということです。

今後も在宅医療の現場を少しずつ自動化していこうと思います。
Pyinstaller DLL 不足のエラー解決 (dll was not found/ No module named XXX)

## 解決方法
最初のPyinstallerの実行で生成された(Pythonファイル名).spec を直接編集して不足しているdll/Moduleのパスを追加する。

```python
a = Analysis(
...
binaries=[(r'.\venv_exif\Lib\site-packages\pyexiv2\lib\py3.8-win\exiv2api.pyd', '.'),(r'.\venv_exif\Lib\site-packages\pyexiv2\lib\exiv2.dll', '.')]
...
```
その後、spec名指定でPyinstallerを実行する。

```python
Pyinstaller (Pythonファイル名).spec
```

### もしくは
--add-binary オプションで指定する。

```python
Pyinstaller (Pythonファイル名).py --add-binary "\venv_exif\Lib\site-packages\pyexiv2\lib\py3.8-win\exiv2api.pyd"
```


------------------

##Issue 
Imported package used in python script : pyexiv2
Exe creation by Pyinstaller was completed successfully but runtime error occurs.

###Error 1 (missing exiv2.dll)

```python
pyimod04_ctypes.PyInstallerImportError: 
Failed to load dynlib/dll 'C:\\Users\\xxx\\AppData\\Local\\Temp\\_MEI120722\\pyexiv2\\lib\\exiv2.dll'. 
Most likely this dynlib/dll was not found when the application was frozen.
```


###Error 2 (missing exiv2api.pyd)
```python
ModuleNotFoundError: No module named 'exiv2api'
```

##Solution : 
In spec file, you should specify exiv2api.pyd and exiv2.dll

```python
a = Analysis(
...
binaries=[(r'.\venv_exif\Lib\site-packages\pyexiv2\lib\py3.8-win\exiv2api.pyd', '.'),(r'.\venv_exif\Lib\site-packages\pyexiv2\lib\exiv2.dll', '.')]
...
```
(or using option --add-binary)
WSL2のubuntuにapacheとphpをインストールしてバージョン管理

この記事は、zennに書いた [WSL2のubuntuにapacheとphpをインストールしてバージョン管理](https://zenn.dev/sakots/articles/a4217c84e10a41) のコピーです。

---

さこつです。無事退職しました。

XAMPPのアップデートめんどくさい！でも自分のPC環境でphpのバージョン管理したい！！と試行錯誤した結果、
WSL2のubuntuにapacheとphpをインストールすることになったお話。

## ubuntuのapacheならラクそう

こういう記事があった。[ubuntu20.04.1 phpのバージョンを切り替える](https://mebee.info/2020/08/17/post-16891/)

## そうだ、WSL2のubuntuにapacheを入れて管理しよう

### 1.上記をもとにphpをインストール

ただし、2021年11月27日時点でphp8.1をインストールするとapacheが503エラーで動かなくなるので注意。
7.3、7.4、8.0くらいにしとく。 → 動くようになりました（2021/12/20 追記）

その後、apacheインストール。

apacheのphpバージョン変更はこちら。[https://mebee.info/2021/08/02/post-29391/](https://mebee.info/2021/08/02/post-29391/)

### 2.ドキュメントルート変更

ユーザーディレクトリ内にあったほうがテスト環境としては何かと便利である。
apache2.conf、000-default.conf(のコピー)、default-ssl.conf(のコピー)のドキュメントルートを、
`/home/ユーザー名/www`などに変更する。

### 3.ssl設定

せっかくなのでhttpsでアクセスできるようにする。

`default-ssl.conf(のコピー)`の

```
SSLCertificateFile	/etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
```

を

```
SSLCertificateFile	/etc/ssl/myssl.crt
SSLCertificateKeyFile /etc/ssl/myssl.key
```

とかに変更。

こちら [XAMPP for WindowsでSSLを有効にする](https://qiita.com/sutara79/items/21a068494bc3a08a4803) を参考に、
`/etc/ssl/`内で`openssl-san.cnf`を作成、

```tarminal:openssl-san.cnf
$ openssl req \
    -newkey     rsa:4096 \
    -keyout     myssl.key \
    -x509 \
    -nodes \
    -out        myssl.crt \
    -subj       "/CN=localhost" \
    -reqexts    SAN \
    -extensions SAN \
    -config     openssl-san.cnf \
    -days       365000
```

などとした。

※daysが3650のままでは現状で証明書の期限が切れている。またWSL内なので//CNのバックスラッシュは1つで良い。

### 4.apache再起動

```tarminal:tarminal
sudo a2dissite 000-default.conf
sudo a2dissite default-ssl.conf
sudo a2ensite 000-default(のコピー).conf
sudo a2ensite default-ssl(のコピー).conf
```

のあと

```tarminal:tarminal
sudo service apache2 restart
```

### 5.OKだ

![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569616/79c41081-6611-7124-d57e-a8208b258526.png)

## 所感

ubuntuだとphpのバージョンアップも apt update でできてホントよい。

なお、ファイルとフォルダのパーミッションに注意。
【SwiftUI】初期値 nil の Optional な Enum の Picker を実装する

# やりたいこと
フォームなどで Enum の値を Picker で選択させたい。
このとき、未選択の状態を nil で表現し、nil の場合は「選択してください」という項目にしたい。
<img src="https://i.gyazo.com/89ca4655576bd2005445cfbaedd2501f.gif" width=300px/>

# 実装
上の画像の実装コードを載せる。

```swift
enum Area: String, CaseIterable {
    case africa = "アフリカ"
    case asia = "アジア"
    case europa = "ヨーロッパ"
    case america = "アメリカ"
    case australia = "オーストラリア"
}
```

```swift
struct FormView: View {
    @State private var area: Area? = nil
    
    var body: some View {
        VStack {
            Text(area?.rawValue ?? "nilです")
            Picker("エリア", selection: $area) {
                Text("選択してください").tag(Area?(nil))
                ForEach(Area.allCases, id: \.self) { area in
                    Text(area.rawValue).tag(Area?.some(area))
                }
            }
        }
    }
}
```

# 解説
## enum
`String` に準拠させ Picker に表示する文字を指定しておく。
さらに `CaseIterable` で enum を配列化できるようにする。

```swift
enum Area: String, CaseIterable {
    case africa = "アフリカ"
    case asia = "アジア"
    case europa = "ヨーロッパ"
    case america = "アメリカ"
    case australia = "オーストラリア"
}
```

## Picker
重要なのは `tag` の振る舞い。
Picker の selection に適用された値に tag の値が連動するはずだが、以下だと動かない。
（そもそもこれだと nil の時の振る舞いが書かれていないが...）

```swift
struct FormView: View {
    @State private var area: Area? = nil
    
    var body: some View {
        VStack {
            Text(area?.rawValue ?? "nilです")
            Picker("エリア", selection: $area) {
                ForEach(Area.allCases, id: \.self) { area in
                    Text(area.rawValue).tag(area)
                }
            }
        }
    }
}

```

これは tag に与えられた `area` の型は `Area型`だが、`selection` に適応されているのは `Area?型` であるという違いが原因。
というわけで、`Area?.some(area)` でラップしてあげよう。

```swift
Picker("エリア", selection: $area) {
    ForEach(Area.allCases, id: \.self) { area in
        Text(area.rawValue).tag(Area?.some(area))
    }
}
```

あとは nil の際の振る舞いを追加する。
こちらもタグを使い、`Area?` の nil であることを表現してあげよう。

```swift
Picker("エリア", selection: $area) {
    Text("選択してください").tag(Area?(nil))
    ForEach(Area.allCases, id: \.self) { area in
        Text(area.rawValue).tag(Area?.some(area))
    }
}
```
MMPoseで骨格推定をやってみる（Google Colab）

# はじめに

姿勢推定（骨格推定）の代表的なフレームワークであるMMPoseを使ってみて、日本語の記事が少ないなと思ったので、姿勢推定や骨格推定してみたい方の参考になればいいなと思って、記事を書こうと思いました。

# 姿勢推定（骨格推定）とは
上の画像を入力として与えたときに、下の画像のように物体（ここでは牛）の鼻や目、足などのキーポイントをそれぞれ特定し、適切な部分を線で結んだ画像を得るタスクになります。
![input_cow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890361/b91fde1c-9738-7f5a-7b7c-55c879cb5dbd.png)![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890361/a75edcb9-fcaa-40d5-e6e0-dc7722935a82.png)

対象としては上記画像のように動物もあるし、人間もあります。人間の場合は例えばテニスのサーブのスイング時の姿勢を推定し、プロと素人でどこが違うのかのコーチングなどに活かされています。

この姿勢（骨格）推定アルゴリズムとしては大きく
・トップダウン方式
・ボトムアップ方式

の2つがあります。

##### トップダウン方式
画像の中の物体を特定（物体検知）し、特定した物体それぞれに対して骨格推定を行う方式

##### ボトムアップ方式
画像の中の物体全てにとりあえず骨格推定を行い、それぞれのキーポイントを同一物体同士で繋ぐ方式

精度としてはトップダウンの方が、一個一個の物体に対して骨格推定を行うので高い傾向にあります。
ボトムアップはキーポイントが推定できてもそれを同じ物体同士で繋ぐことを学習するのが難しいようです。

今回紹介するMMPoseの中のAnimalPoseというモデルは、トップダウン方式のモデルになります。
このトップダウン方式は物体検知と骨格推定がそれぞれ独立しています。
モデルの入出力の流れを説明すると以下のようになります。

画像を物体検知モデルに入力
↓
物体の位置を示したBBox座標を得る
↓
画像とBBox座標を骨格推定モデルに入力
↓
それぞれの物体のキーポイント座標を得る

つまりモデルが物体検知モデルと骨格推定モデルの2つが必要になります。


# MMPoseとは
骨格推定のモデルをたくさんまとめた汎用的なフレームワークのようなものになります。
公式ドキュメントも充実しており、様々なモデルを使用することができます。

ライセンスもApache-2.0 Licenseなので商用利用も可能です。

リポジトリ：https://github.com/open-mmlab/mmpose
公式ドキュメント：https://mmpose.readthedocs.io/en/latest/

# HRNet on AnimalPose
今回紹介するのは、AnimalPoseというデータセットで学習をしたHRNetというモデルになります。

![human_B1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890361/b674c151-a5ea-9a8e-de03-2793db953144.png)

論文リンク：https://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html

様々なスケールで学習をし、高解像度の持つ特徴量と低解像度の持つ特徴量を共有して骨格キーポイントを推定するモデルのようです。

# 導入・推論
MMPoseをローカル環境で動かすとなると、環境構築が結構めんどくさいです。
なので手軽に試してみたいという方は公式リポジトリのdemoノートブックをGoogle Colabで動かすのがいいでしょう。

デモノートブック
https://colab.research.google.com/github/open-mmlab/mmpose/blob/main/demo/MMPose_Tutorial.ipynb

これを上から順に実行すれば動いてくれます。
ただ注意点があって自分の場合は２つ目のセルを何回か実行しないとnumpyのバージョンが正しくならなかったです。

AnimalPoseを使用する場合は

```python
pose_config = 'configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py'
pose_checkpoint = 'https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth'

上記部分を

pose_config = 'configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/animalpose/hrnet_w48_animalpose_256x256.py'
pose_checkpoint = 'https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_animalpose_256x256-34644726_20210426.pth'
```

に変更すれば大丈夫なはずです。

configとmodelファイルを変更するだけで色々なモデルの推論を試せます。

# まとめ
簡単ですが、MMPoseの紹介です。学習済みのモデルを簡単に試せるのは非常に良いなと思いました。
次はローカルでの環境構築方法と物体検知モデルにYOLOv4を使用して動物の骨格推定を行うまでの流れを紹介したいと思います。
Verilog テストベンチで乱数を毎回供給する

### 環境
```
Icarus Verilog version 10.1
```

### やりたいこと
テストベンチにおいて、ターゲットモジュールのテストベンチとは別に毎回乱数を供給する処理を完結に記述したい。

### コード
```verilog
module tb_module():
  localparam PERIOD = 10;
  reg clk;
  always @(*) #(PERIOD/2)
    clk <= ~clk;

  reg rnd;
  always #(PERIOD) begin
   rnd <= $urandom_range(0,1);
  end
  
  target_module target_module(
   .clk(clk),
   .rnd(rnd)
  );

  initial begin
   /* ターゲットモジュールのテストベンチを書く */ 
  end
endmodule
```

### BAD
```verilog
always @(*) #(PERIOD/2)
    clk <= ~clk;
```
を真似て、

```verilog
reg rnd;
always @(*) #(PERIOD)
    rnd <= $urandom_range(0, 1);
```
と書いてみたが、うまく行かなかった。
【p5.js】beginShapeとvertex関数

p5.jsについての備忘録です。
rect関数などとは別に存在する描画方法、beginShapeとvertex関数についてまとめ。

## beginShape
```typescript
beginShape(kind?: BEGIN_KIND): p5;
```

beginShapeを使用することでより複雑な形を表現できる。
引数kindには形となるものを渡す必要があり、それは以下の通り

```
POINTS, LINES, TRIANGLES, TRIANGLE_FAN,
TRIANGLE_STRIP, QUADS, QUAD_STRIP
```
指定しない場合は不規則な多角形となる。

この関数を実行した後はvertex関数を呼び出す必要があり、
endShapeで描画を止める

beginShape内ではellipseやrectは使用できない。

## vertex
beginShape と endShapeの中でのみ使われる関数。
図形の頂点座標をvertex関数で指定する。

```typescript
vertex(x: number, y: number): p5;
```

例えばvertexを下記のように4つ指定した場合、正方形が出来上がる
（左側の罫線はendShape(CLOSE)とすることで描画できる）

```typescript
vertex(30, 20);
vertex(85, 20);
vertex(85, 75);
vertex(30, 75);
```

![スクリーンショット 2021-11-27 1.17.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/a06221e2-14a3-e291-02a1-a47872cafb21.png)


もしbeginShapeの引数にTRIANGLE_FANを渡していた場合、
頂点の結びは三角形を作ろうとするためマスのような図形になる
![スクリーンショット 2021-11-27 1.14.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/79d70d8d-db50-892e-44de-5b5dc3c482d3.png)



頂点を一つ増やし、一部を動的にすれば次のようになる

```typescript
vertex(30, frameCount);
```
![vertex.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358229/796d4c85-f2d3-3109-d4cf-0fad4becddcb.gif)

## 参考文献

https://qiita.com/bit0101/items/91818244dc26c767a0fe

https://p5js.org/reference/#/p5/beginShape

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/p5/src/core/shape/vertex.d.ts
【Git】【Ruby】 Gemfile,Gemfile.lock変更後、git push後にエラー

# 1. 概要

Ruby on rails アプリ(開発環境の更新が本番環境に反映されるようGitHub Actions設定済み)
にて、Gemfileに新機能を色々追加したり試したりした後
git push後にエラー発生・・時に自分が解決したやり方を記載

# 2.エラー内容/対処

Githubのactionsから最新ワークフローを確認した際に
Deploy時エラーが発生していた

![git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294345/8a5d743c-3ee5-6447-a203-cf7e5e38c6cd.png)

以下がエラー内容詳細

```
Run echo "$PRIVATE_KEY" > private_key && chmod 600 private_key
Warning: Permanently added '***' (ECDSA) to the list of known hosts.
From github.com:syokaturyou/sangoku
 * branch            main       -> FETCH_HEAD
   b1b89e5..4a8562f  main       -> origin/main
error: Your local changes to the following files would be overwritten by merge:
	Gemfile.lock
Please commit your changes or stash them before you merge.
Aborting
Error: Process completed with exit code 128.
```

本番環境のGemfile.lock　とpushした内容と食い違いがあるために起こったと考えられるため
本番環境(自分の場合aws EC2インスタンスを使用)のGemfile.lockを一旦削除
※Gemfileが確認できるディレクトリに移動し以下を実行

```
[ec2-user@ip-〇-〇-〇-〇 アプリ名] rm Gemfile.lock
```
→Gemfile.lock削除後には本番環境でgit pull origin main 実行

これで直ったと思い再度開発環境の更新内容をgit pushするも
今度はDeploy時エラーとして以下がgithubのactions上で発生していた。

```
Run echo "$PRIVATE_KEY" > private_key && chmod 600 private_key
Warning: Permanently added '***' (ECDSA) to the list of known hosts.
error: You have not concluded your merge (MERGE_HEAD exists).
hint: Please, commit your changes before merging.
fatal: Exiting because of unfinished merge.
Error: Process completed with exit code 128.
```

マージが完了しておらず、MERGE_HEADが存在しているために発生しているエラーと考えられる。
本番環境でgit pull した時には以下が発生していた。

```
[ec2-user@ip-〇-〇-〇-〇 アプリ名]$ git pull origin main
error: You have not concluded your merge (MERGE_HEAD exists).
hint: Please, commit your changes before merging.
fatal: Exiting because of unfinished merge.
```

「hint: Please, commit your changes before merging.」の記載に従って
本番環境下で空コミット

```
[ec2-user@ip-〇-〇-〇-〇 アプリ名]git commit --allow-empty -m "commitmessage"
```

空コミット後にgit pullを実行するとエラーは発生せず

```
[ec2-user@ip-〇-〇-〇-〇 アプリ名]$ git pull origin main
```

この状態で開発環境で修正内容をgit push すると本番環境でも正常更新された
【mt4/mql4】スプレッド拡大時には処理しない/する


# はじめに
<!-- 発端や概要を記載 -->
システムトレードプログラマのmt4/mql4のメモノートです。
初心者向けの簡単なトピックから公開していきます。
.noteでEAそのものも公開していますので良ければそちらも見てください。


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [処理内容](#処理内容)
1. [mql4ソースコード](#mql4ソースコード)

<!-- 各チャプター -->
<a id="#処理内容"></a>
# 処理内容
特定の時間帯や、急なイベント・ニュースの時には、スプレッドが急拡大するケースがあります。つまりエントリーor決済するのに、とっても不利な状況になるわけです。

この不利な状況の時にはエントリーしたくない。とか　そもそも異常事態なのでポジション決済して撤退したいなど、したい/したくない　というようなケースがあるかと思います。

この時に使えるコードを紹介します。

<a id="#mql4ソースコード"></a>
# mql4ソースコード

こちらがソースコードです。
関数部分です。まずは個別に通貨別のpip値を取得する関数と、スプレッドがいくつ以上離れたら本コードを実行させたいかをpipsで設定します。


```c++:test.mq4
//スプレッドが何pips以上になったら特別動作
double MaxSpread=50;//例 50pips

//+------------------------------------------------------------------+
//| pip単位を取得する                                                                 |
//+------------------------------------------------------------------+
double AdjustPoint(string Currency)
 {
  int Symbol_Digits=(int)MarketInfo(Currency,MODE_DIGITS);
  double Calculated_Point=0;
  if(Symbol_Digits==2 || Symbol_Digits==3)
    {
     Calculated_Point=0.01;
    }
  else
     if(Symbol_Digits==4 || Symbol_Digits==5)
       {
        Calculated_Point=0.0001;
       }
     else
        if(Symbol_Digits==1)
          {
           Calculated_Point=0.1;
          }
        else
           if(Symbol_Digits==0)
             {
              Calculated_Point=1;
             }
  return(Calculated_Point);
 }

```




以下が、処理実行メイン部分です。実際にはOnTimer()とかOnTickとかのループ関数無いに記述します。

以下の例はスプレッドが大きくない時だけやりたい処理の書き方です。もし大きいときだけやりたい処理を記述したい場合は　IFの条件式を反対の”>”に変更してください。


```c++:test.mq4
SymbolInfoTick(Symbol(), tick);
if((tick.ask - tick.bid)/AdjustPoint(Symbol()) < MaxSpread )
{

///ここにスプレッドが設定したpips以下でやりたい処理を記述

}
  }
```



皆様の手助けになりますように。
間違いなどあればご指摘いただけると助かります。
以上です
XrmToolbox：SQL 4 CDS

Dynamics OnPre開発経験者、SQL詳しい方に以下のツールを紹介いたします。
![MicrosoftTeams-image (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/e0250ae6-aa57-5ebf-9f6b-0a3d18a61fba.png)

SQLを入力する場合、列名のインテリジェンスが提示してくれます。列の日本語名も表示されます（SSMSにはない）
「Execute」ボタンを押すと、FetchXMLへ変換され、実行結果が「Results」に表示されます。
※複雑なクエリは対応できない場合があります
![MicrosoftTeams-image (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/60588734-734b-901d-79a6-39bdb02d6348.png)
テーブル名や列名をダブルクリックして自動入力可能、SQL実行時のFetchXML出力も可能
![MicrosoftTeams-image (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/25870bf0-1cae-81de-3111-23c34dcbb6ca.png)
出力したFetchXMLはFetchXML Builderで開く可能、FetchXML BuilderでJSやC#コードに変換可能
![MicrosoftTeams-image (29).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/3090d40b-34b3-7847-546f-7491ce08fb2c.png)
SQLでデータCRUD可能
![MicrosoftTeams-image (30).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/7e334dc4-4f46-e8a6-4692-f3e07178c3f2.png)
ユーザー偽装が可能、別のユーザーでCRUD、検索可能
![MicrosoftTeams-image (31).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/d7fad8ba-e501-a4b0-a637-4d11a984725c.png)
CRUD時、Pluginをバイパスすることも可能、ほかにも細かいの設定が制御可能
![MicrosoftTeams-image (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/d4f3c44e-4e97-78e8-7df4-0bdf82cf78ea.png)
開発、テスト時は便利かと思います、商用環境では利用する際に、十分注意が必要です。（検索のみ利用を推奨）
Dynamics365/PowerAppsモデル駆動アプリのFormにカスタムパラメータを渡す方法

JavascriptでFormを開く場合、テーブルの項目のデフォルト値をパラメータで渡すことができますが、テーブル項目以外の制御用のパラメータを渡して制御を行いたい場合（例えば、パラメータでFormのTab非表示を制御する場合）、以下の資料の方法で実現可能です。
https://docs.microsoft.com/ja-jp/dynamics365/customerengagement/on-premises/developer/configure-form-accept-custom-querystring-parameters?view=op-9-1
簡単な例を説明します。
Formのプロパティのパラメータータブに、必要なパラメーターを追加する
![MicrosoftTeams-image (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/03e732b3-cb85-7440-9fea-a7c264ba457f.png)
![MicrosoftTeams-image (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/df0102ff-54ae-02bc-b689-91c93429cba7.png)

サンプルコード
![MicrosoftTeams-image (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/5daa9804-cce0-796c-77c3-5b72044599e4.png)

コンソールで以下のテストコードを実行すると
![MicrosoftTeams-image (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/a77de430-6f27-b0b5-6605-1680976ee405.png)

実行結果
![MicrosoftTeams-image (25).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2307534/02fdf8c4-02e1-eac2-f95f-c8cf82f0a090.png)

。
ほかにも、ブラウザのsessionStorageを利用して、Form間の値渡しの実装も可能です。
【Android】マルチモジュールって何？

# この記事は
マルチモジュールって何だろうと思い、恥を忍んでAndroidのお師匠さんに聞いてみた私が、「マルチモジュール完全に理解した」になるまでの物語である。

# 先生、マルチモジュールって何ですか？
これまでpackageとして管理していたある機能を持つまとまりを、モジュールとしてライブラリのように切り離して扱う方法のこと。

...ﾊｧ？

# あの...モジュールって何ですか...？
ていうか、パッケージって何...(小声)

- packageとは

`app->com.ｳﾝﾆｬﾗｶﾝﾆｬﾗ`の下にあるフォルダ(?)
以下の画像における`view`や`viewModel`がパッケージとなる
![スクリーンショット 2021-11-25 16.46.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/94682283-3a77-7d74-27fa-b4fd99e0d97a.png)


- moduleとは

かの有名な[どすこい先生](https://twitter.com/dosukoi_android)のリポジトリを見てみましょう。
[GitHubClientForJetpackCompose](https://github.com/Naoki-Hidaka/GitHubClientForJetpackCompose)

自動生成されるものは省きますが、例えばdataやuiなどがモジュールに当たります。
![スクリーンショット 2021-11-26 23.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906559/f96c42ab-a539-5cf7-3dd1-f4362b786bd6.png)

このように、今まで`app`ディレクトリの中の`com.~~`配下で管理していた`ui(view, viewModel)`や`data(repository, usecase)`を`app`と同じディレクトリでモジュールとして切り離し、ライブラリのように扱うのがマルチモジュール(らしい)です。


# じゃあ、appには何が入ってるの？
いままでapp配下で管理していたuiやdataなどのパッケージを、app外に出すということは、逆にapp内には何が存在しているのか。
もはや、appの存在意義は何なのか。

app配下にはAndroidManifestなど、build時に必要なファイルが格納されている。
appの実行を通じて、他のモジュールも実行され、最終的にアプリがビルドされる流れであるので、appの存在意義としては、アプリのエントリポイントのようなものと言えるでしょう。


参考：[Android開発におけるモジュール分割](https://medium.com/eureka-engineering/multi-module-in-android-development-cbce00d932a3)
【SwiftUI】NavigationBar の戻るボタンのテキストを消す

# やりたいこと
以下のように、戻るボタンからテキスト部分だけを無くしたい。
Before - After
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516428/fdba6443-7b08-468b-8fc8-509ad7c62829.png" alt="スクリーンショット 2021-11-27 0.41.20.png" width=300px /><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516428/536c3691-007c-03cf-8cbe-7d34a6280e5a.png" width=300px />

# 実装
`navigationBarBackButtonHidden(true)` で戻るボタンごと削除する。
そして代わりに `toolbar` で、アイコンのみの戻るボタンを追加してあげれば OK。

```swift
struct NextPage: View {
    @Environment(\.presentationMode) var presentaion
  
    var body: some View {
        Text("Next Page!")
            .navigationTitle("Next Page")
            .navigationBarTitleDisplayMode(.inline)
            // 以下を追加
            .navigationBarBackButtonHidden(true)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                      Button(action: { presentaion.wrappedValue.dismiss() }) {
                        Image(systemName: "chevron.backward")
                    }
                }
            }
    }
}
```

ただし、これだけだとスワイプで戻れなくなってしまうので、以下の Extension を追加する。

```swift
extension UINavigationController: UIGestureRecognizerDelegate {
    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }
}
```

# Modifier にする
いろんな場面で使う場合、あんな長ったらしいコードは書きたくないので Modifier 化してしまおう。

```swift
struct NavigationBarBackButtonTextHidden: ViewModifier {
  @Environment(\.presentationMode) var presentaion
  
  func body(content: Content) -> some View {
    content
      .navigationBarBackButtonHidden(true)
      .toolbar {
        ToolbarItem(placement: .navigationBarLeading) {
          Button(action: { presentaion.wrappedValue.dismiss() }) {
            Image(systemName: "chevron.backward")
          }
        }
      }
  }
}

extension View {
  func navigationBarBackButtonTextHidden() -> some View {
    return self.modifier(NavigationBarBackButtonTextHidden())
  }
}
```

これにより、一行追加すれば適用されるようになる:tada:

```swift
struct NextPage: View {
    var body: some View {
        Text("Next Page!")
            .navigationTitle("Next Page")
            .navigationBarTitleDisplayMode(.inline)
            .navigationBarBackButtonTextHidden()
    }
}
```
# 参考
https://stackoverflow.com/questions/59234958/swiftui-navigationbarbackbuttonhidden-swipe-back-gesture
VScodeでWSLからSSH接続 

タイトル通りWSLからSSH接続を行ってVScodeを動かしたので，個人の忘備録として残していきたいと思います．その際トラブルが生じましたので，その解決方法と共に後述しています．
## VScodeのパスをWSLに変更  
以下のURLが参考となります．
https://qiita.com/_masa_u/items/d3c1fa7898b0783bc3ed

VScodeの`setting.json`を開き，`terminal.integrated.cwd`を追加しました．その後，Cドライブ上でのWSLのパスを`terminal.integrated.cwd`の後に書きました．
## VScodeからSSH接続  
ssh-keygenで秘密鍵id_rsaを設定し，WSL下の.sshに置きました．
その後，WSLからSSH接続を試みましたが，以下のようなエラーが出ました．
`no such identity: C:user\ユーザー名\.ssh\id_rsa: No such file or directory`

どうやらWindowsのCドライブの下に直接id_rsaを置かなければならないようです．
[紆余曲折](https://ja.stackoverflow.com/questions/83517/vscode%e3%81%aessh%e7%a7%98%e5%af%86%e9%8d%b5%e3%81%ae%e3%82%a2%e3%83%89%e3%83%ac%e3%82%b9%e8%a8%ad%e5%ae%9a%e3%81%ae%e5%a4%89%e6%9b%b4%e3%81%8c%e3%81%a7%e3%81%8d%e3%82%8b%e3%81%8b%e3%81%a9%e3%81%86%e3%81%8b)を得て，Cドライブ下にWSL下の秘密鍵のシンボリックリンクを置いたところ，VScodeでSSH接続に成功しました．

シンボリックリンクの作成法は以下のURLを参考にしました．
https://www.koikikukan.com/archives/2020/04/16-235555.php

## おわりに
もう少しできれば図を挟みながら説明したいと思っております．更新頑張ります．
ほぼフロント技術でネット麻雀を作ってみた

# はじめに

[NM](https://n-m.online/)というオンラインネット麻雀をtypescriptとjavascriptだけで作ってみました:mahjong:

javaなどのサーバーサイド言語を書かず、RDBSを設計せずネット麻雀を作成してみようと思いたち開発しました。
後発のネット麻雀なので、どうせならと思ってスタンダード？な開発を行わずに極力スピード優先で開発できるように技術選定を行いました。
この記事では採用した技術を紹介したいと思います。
まだバグなども残っている状況ですが、反響があれば詳細やなども記述して行きたいと思います。
 
## プレイ画面イメージ
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981928/a8bca3bf-da24-15f1-c476-301d4dddf4ea.jpeg)
![twitter_FDwlasFXIAUGAS-.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981928/d29b5ca6-6093-5d91-36cd-7baac947b6b7.jpeg)
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">全身動かせるようになって、表情もナチュラルに感じる。いつか麻雀系VTuberさんにプレイして欲しいものだ <a href="https://t.co/Nm6dYff6Up">pic.twitter.com/Nm6dYff6Up</a></p>&mdash; なみもん@オリジナルネット麻雀作りました (@MahjongNm) <a href="https://twitter.com/MahjongNm/status/1458824644799074305?ref_src=twsrc%5Etfw">November 11, 2021</a></blockquote>　
（この画像、シャンテン取得ロジック開発中のものです）


## 優位ポイント
### ユーザー目線
#### ビデオチャット
マイクとカメラがあればビデオチャットが使用可能。VRMを使ったVRMチャットも実装済み。
VRMをサイトにアップすれば、独自のアバターに変更可能。
もちろん、VRM同士のビデオチャットも可能です。

#### 言語変更可能
非日本語圏の人が初見で麻雀をプレイできるように、言語変更できるようにし、漢字を使わない麻雀牌をデザインしました。
![3en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981928/bda3daef-8da6-8eba-72b4-5b8cf222e265.png)
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Mahjong without Chinese tiles.<a href="https://twitter.com/hashtag/mahjong?src=hash&amp;ref_src=twsrc%5Etfw">#mahjong</a> <a href="https://twitter.com/hashtag/riichimahjong?src=hash&amp;ref_src=twsrc%5Etfw">#riichimahjong</a> <a href="https://t.co/YJmsbRRuKg">pic.twitter.com/YJmsbRRuKg</a></p>&mdash; なみもん@オリジナルネット麻雀作りました (@MahjongNm) <a href="https://twitter.com/MahjongNm/status/1461756539337728012?ref_src=twsrc%5Etfw">November 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


### 運用目線 
ゲーム進行がサーバーレスなので、サーバー負荷などを気にせず運用できる（はず）
この辺はfirebase代がどうなるのかわかりません（バズってないので）。

# 使用技術
## フロントエンド
### vue vuetify
vueの勉強をしたかったので
## 
### skyway
[skyway](https://webrtc.ecl.ntt.com/)
ゲーム中の情報のやり取りをサーバーレスにするので、P2P通信を行うため
### typescript 
説明略
### VRモデル
[VRM](https://vrm.dev/)

## ML関連
機械学習のモデルをビデオチャットとVRチャットで使ってます
#### bodypix 
[bodypix](https://github.com/tensorflow/tfjs-models/tree/master/body-pix)
ビデオチャットで背景を隠したりするために使用
#### face-api
[face-api](https://justadudewhohacks.github.io/face-api.js/docs/index.html)
表情の取得とVRMへの反映
#### holistic
[holistic](https://github.com/google/mediapipe) 
体勢の取得とVRMへの反映。kalidofaceを参考にさせていただきました
[kalidoface](https://github.com/yeemachine/kalidoface)

## サーバーサイド
### firebase 
[firebase](https://firebase.google.com/)
P2Pの接続、ユーザー管理機能、配牌作成など。コードは全てjsで書いています

# 今後の課題

### バグ再現が難しい 
クライアント側でロジックが走るかつ非同期で動かしているので、プレイヤーAで発現するバグがプレイヤーBからは見えなかったりする。サーバーサイドで管理していないので異常な状況を監視できない。

### スマホアチアチ問題
vueの作りが良くないのか。特にビデオチャット中は熱い。リファクタリングしないと…

### 雀魂にハマる
これも勉強だから…とやってたら聖1になってた。カンにゃ！
OpenSCAD のデータを Fusion360 にインポートする方法

OpenSCAD のデータを Fusion360 にインポートする必要がありましたが、Autodesk の公式フォーラムに記載された方法だとエラーに遭遇してしまったので、その解消法を備忘録として投稿します。

# 環境

- OS: MacOS Big Sur 11.6 (20G165)
- OpenSCAD: Version 2021.1
- FreeCAD: Version 0.19

# 手順

Autodesk の公式フォーラムに記載されているデータの変換方法は次のとおりです（翻訳は筆者）。

[How to import OpenSCAD file into Fusion360 as a solid body](https://forums.autodesk.com/t5/fusion-360-manage-ideas/how-to-import-openscad-file-into-fusion360-as-a-solid-body/idi-p/10174834)

> 1. OpenSCAD を **[https://www.openscad.org/](https://www.openscad.org/) からダウンロードしてファイルを開く**
> 2. インポートするモデルをレンダリングしてから `.csg` ファイルとしてエクスポートする
> 3. FreeCAD を**[https://www.freecadweb.org/](https://www.freecadweb.org/) からダウンロードする**
> 4. FreeCAD で先程エクスポートした `.csg` ファイルを開く
> 5. Model タブでエクスポートしたいモデルを選択する
> 6. メニューの「File > Export」と進んで .`STEP` 形式でエクスポートする
> 7. Fusion360 のメニューの「開く > マイコンピュータから開く...」と進んで先程エクスポートした `.step` ファイルを開く

この手順で OpenSCAD のデータを Fusion360 でインポート可能な `.step` ファイルに変換できるはずですが、中間変換を担う FreeCAD でエラーに遭遇しました。

## FreeCAD で遭遇したエラー

OpenSCAD のデータを読み込んだ時点で `<class 'OpenSCADUtils.OpenSCADError'>: 'OpenSCAD executable unavailable'` というエラーが Report View に表示され、読み込んだデータが表示されないという事態になりました。

エラーメッセージを手がかりに調べたところ、FreeCAD のバグが原因だと分かりましたので、次の Github の Issues に掲載されていた対応策を実行しました。

[https://github.com/FreeCAD/FreeCAD_Conda/issues/19](https://github.com/FreeCAD/FreeCAD_Conda/issues/19)

具体的には、`~/Library/Preferences/FreeCAD/user.cfg` を次のとおり修正しました。
（修正前のコードの記録を失念していたので、修正前のコードはうろ覚えですが、修正後は現在動いているコードです。）

```diff
<FCParamGroup Name="Mod">
　　<FCParamGroup Name="OpenSCAD">
 </FCParamGroup>
```

```diff
<FCParamGroup Name="Mod">
　　<FCParamGroup Name="OpenSCAD">
+　　　　<FCText Name="openscadexecutable">/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD</FCText>
 </FCParamGroup>
```

これで上記のエラーが解消され、読み込んだデータが表示されるようになったので、最初に示した手順に沿って OpenSCAD のデータを `.step` ファイルに変換できるようになりました。
LINEのBotからプッシュ通知する方法

## はじめに
以前にお試しでLINEのボットを作成したことがあるが、その時にプッシュ通知の方法についても調べたのでメモを残しておく。
（プッシュ通知のサンプルコードはPythonで作成。）



## メモ内容
① チャットボットの作成
② 作成したBotからプッシュ通知をしてみる。
③ 画像を送るプッシュ通知も試してみる。

### ① チャットボットの作成
LINEの公式アカウントが必要となるが、下記のサイトにBot作成までの流れが記載されているので、こちらを参考にすると良い。

https://first-contact.jp/blog/article/linebot/


### ② 作成したBotからプッシュ通知をしてみる
プッシュ通知の方法やルールについては、LINE Developers の公式サイトを確認すれば大体のやり方を把握できる。

https://developers.line.biz/ja/docs/messaging-api/sending-messages/

https://developers.line.biz/ja/reference/messaging-api/

　　　
単純なテキストをプッシュ通知する場合、下記の Manger 画面から、該当のチャネル（アカウント）を選んで配信することもできる。配信の方法は、`メッセージ配信 ⇒ メッセージの作成` から行える。
　※特別な指定をしなければ、友達追加してくれているメンバー全員にメッセージが送られる。

https://manager.line.biz/

　　　
また同じ様な処理を Python で書くと以下の様なコードになる。

```shell:必要パッケージのインストール
pip install line-bot-sdk
```

```py:sample.py
from linebot import LineBotApi
from linebot.models import TextSendMessage    #テキストメッセージを送る時に使うモジュール
from linebot.exceptions import LineBotApiError

line_bot_api = LineBotApi('<channel access token>')

try:
    # 該当botを友達追加している全員にメッセージを送る。
    line_bot_api.broadcast(TextSendMessage(text = "test message from python to all member"))

    # 特定の１ユーザーに送る時はこちら。その他にも、マルチキャスト、ナローキャストがある。
    # line_bot_api.push_message('<to>', TextSendMessage(text='test message from python to one user'))

except LineBotApiError as e:
    print(e)
```

※`<channnel access token>`に入るのは、LINE Developers の対象Botの`Messaging API設定`に表示されている、チャンネルアクセストークンとなる。
特定ユーザーに送る場合は、`<to>`にuserID入れる必要があるが、ここで入れるuserIDはLINEアカウントの友達検索で使うIDではないので注意。



### ③ 画像を送るプッシュ通知も試してみる
Manger画面から行う場合は、②のテキストプッシュ通知と同様に行える。
Python で送る場合は以下の様なコードとなる。

```py:sample2.py
from linebot import LineBotApi
from linebot.models import ImageSendMessage    #画像を送る時に使うモジュール
from linebot.exceptions import LineBotApiError

line_bot_api = LineBotApi('<channel access token>')

url = "<httpsで始まる画像のURL>"

try:
    # 特定の１ユーザーに送る。
    line_bot_api.push_message('<to>', ImageSendMessage(original_content_url = url, preview_image_url = url))

except LineBotApiError as e:
    print(e)
```
※ ローカルPCに格納してある画像ファイルのパスを指定して送ることはできず、httpsで始まるURLを設定しなければいけないっぽい。

また、上記では画像を送信するモジュールをインポートして使っているが、その他の送信に使う場合のモジュールは下記のサイトの `linebot.models.messages module` の事項を参考に。

https://line-bot-sdk-python.readthedocs.io/en/stable/linebot.models.html
AOJトライに関する知識知見の記録共有：Volume0-0051

# タスク概要

Differential II

https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0051

 
# コード実装例
TIPS

1. 例外処理含む評価パターンを追加
1. 入力値の小数対応

```Python
import pprint, sys, time
import itertools 

def core(arg, acc=False):
    if acc:
        pass
    else:
        perms = list(itertools.permutations(str(arg)))
        M, m = [float("".join(f(perms))) for f in [max, min]]
    return [M, m, M - m]

def app(*args):
    ret = []
    for arg in args:
        st = time.time()
        try:
            r = core(arg)
        except Exception as e:
            r = e
        ret.append([arg, round(time.time() - st, 6), r])
    return ret

print(sys.version)
pprint.pprint(app(
    # basic examples
    65539010,
    # additional examples
    1234.6,
    # exceptional examples
    "例外入力"
))
```

# 実行結果
各種補足情報出力（入力値FB、デバッグログ等）含む

```
3.8.10 (default, Jun  2 2021, 10:49:15) 
[GCC 9.4.0]
[[65539010, 0.012844, [96553100.0, 135569.0, 96417531.0]],
 [1234.6, 0.000144, [64321.0, 0.12346, 64320.87654]],
 ['例外入力', 1.3e-05, ValueError("could not convert string to float: '外力入例'")]]
```

# 補遺
残課題

1. 実行速度の改善（枝刈り、データ構造の見直し等）
1. 入力値の負数対応
IAMについて

AWSのCloudPractitionerの勉強の過程で、IAMについて紛らわしかったのでまとめる。
私はAWSについてちゃんと勉強する前、個人開発でEC2を使っていたことがあった。
その際管理者アカウントを常に使っていたので、「この機能いる？？」と思っていた。（いらない機能わざわざ用意しないよねってのは置いといて、、）

# IAMとは
`Identity and Access Management`の略。その名の通り、アクセス権限と認証を管理する機能。

# いつ使うのか
各アカウントにリソースを使う権限を付与したいとき。

# IAMポリシー
権限が書かれたファイル。
誰がどのサービスのどのリソースに対してどんな操作をするのか、といったことをJSON形式で記述する。
```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
```
こんな感じでどんな操作を許可するのかが書かれてる。

# IAMユーザー
管理者が作って、誰かに渡すアカウント。
マネジメントコンソールから作れる。
ユーザーにポリシーを割り当てることで、そのユーザーにポリシーの内容を適用できる。

# IAMグループ
IAMグループにIAMポリシーを割り当てられる。
IAMグループにはIAMユーザーを追加することができて、グループ内のユーザーはグループに付与されたポリシーの内容が適用される。
まとめると、「逐一IAMユーザーにポリシー割り当てるの面倒だからグループにいれちゃおうね」といった感じ。


以上IAMポリシー、IAMユーザー、IAMグループのぼんやりとした内容でした。
かなり大雑把なので不安な人は一次情報当たってください。
[AWS公式docs](https://docs.aws.amazon.com/iam/index.html)
SESからの転職に、転職サイトでなく転職エージェントがおすすめされる理由

## なぜ転職サイトではなく転職エージェントなのか

SESエンジニアとして多忙な業務の傍ら、転職活動を続けているという方もいるかと思います。
僕も今の会社に社内SEとして転職するまでは、客先に常駐して設計やら開発やら保守やらを続けながら転職活動をしていました。

当時（記事執筆時の半年前）の僕は、転職先探しと言えば転職サイトだと思っていたんですが、ネットで検索していると、「転職エージェント」というのが目に入ります。

最初は何がどう違うのか分からずにいたんですが、今考えると、転職サイトより転職エージェントがおすすめされるのも納得です。

そこで、なぜ転職サイトではなく転職エージェントがおすすめされるのか、僕なりにまとめてみました。

### そもそも求人数が圧倒的に多い

転職エージェントには非公開求人というものが多数掲載されています。
開発案件の内容を他社に公開したくないなどの理由で、一般には公開されない求人のことです。

非公開求人は、公開求人に比べて労働条件や待遇のいいものが多いので、転職エージェントを使うだけで、**条件の良い転職先**を見つけられる可能性が高くなります。

### 転職成功までサポートを受けられる

転職サイトを使う場合、基本的に自分一人で転職活動することになります。
その点、転職エージェントの場合はエージェントという担当者がついて、希望すれば色々なサポートを受けることができます。

自己PRの作成やキャリアプランの整理をはじめ、面接日程の調整や**年収の交渉**までやってくれるところもあります。

一人で転職活動をしていると時間がかかったり諦めなければいけなかったりすることも、妥協する必要がなくなります。

### 応募前の段階で企業の内部事情を聞ける

転職エージェントは求人を出している企業側との繋がりも強いので、企業の内部事情も把握していたりします。
そのため応募する前の段階で、企業の気になるところを聞くことができる可能性があります。
転職サイトの場合は応募して面接を受けてみるまで企業の中身を知ることはできませんし、入社してみないと分からないこともたくさんあります。

### 無料で使える

転職エージェントは転職希望者ではなく求人を出す企業から報酬をもらっているので、転職活動をする人は無料で使うことができます。
転職サイトと転職エージェントとでは手厚さが段違いなのに、同じように無料で使えるのであれば、転職エージェントを使った方がいい、というふうになるのは自然なことのように思います。

## エンジニアの転職に特化したエージェントがある

エンジニアがITのプロであるように、転職エージェントは転職活動を成功させるためのプロです。
そのなかでも、エンジニアの転職に特化した転職エージェントというのが存在ます。

保有している求人数や得意な業種など様々なので、**自分にあった転職エージェント**を見つけられると転職成功がぐっと近づきます。

エンジニアに特化した転職エージェントは、下記の記事にまとめているので、興味があれば覗いてみてください。
→[【厳選】ITエンジニアにおすすめの転職エージェント！SESから社内SEや自社開発への転職を実現！][1]
[1]:https://domona.info/ses-job-change-agent/
Istio on Minikube (using istioctl)

## やること

* Minikubeの上にistioをインストールする
* bookinfoを動かす
* Kialiをインストールする
* Kialiでサービスメッシュを確認する

## リファレンス

* https://istio.io/latest/docs/setup/getting-started/#download

## Istioのインストール

コマンド

```
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.12.0/
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled
```

## BookInfo のサンプルアプリをデプロイ

コマンド

```
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl get pods -w
```

レスポンス

```
NAME                              READY   STATUS            RESTARTS   AGE
details-v1-79f774bdb9-t89d9       0/2     PodInitializing   0          17s
productpage-v1-6b746f74dc-dsbbt   0/2     PodInitializing   0          16s
ratings-v1-b6994bb9-dzrqb         0/2     PodInitializing   0          16s
reviews-v1-545db77b95-sxp7w       0/2     PodInitializing   0          16s
reviews-v2-7bf8c9648f-c6998       0/2     PodInitializing   0          16s
reviews-v3-84779c7bbc-jzbnq       0/2     PodInitializing   0          16s
```

正常起動の確認

```
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
```

レスポンス

```
<title>Simple Bookstore App</title>
```

## ブラウザからアクセス

コマンド

```
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
istioctl analyze
minikube tunnel --cleanup
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export INGRESS_HOST=$(minikube ip)
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
echo "http://$GATEWAY_URL/productpage"
```

ブラウザアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325101/6662dd05-9091-5843-e4f4-0fee29ab0668.png)

## Kiali Dashboard にアクセス

コマンド

```
kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system
istioctl dashboard kiali
```

ブラウザアクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325101/4cf5aa56-ed4e-4173-825d-dc817ea17431.png)

できた。
MySQLエラー: MySQLに接続できない


## エラー

phpMyAdminを開くと`mysqli_real_connect(): (HY000/2002): Connection refused`の表示がでる。
laravelでビューを開くと`SQLSTATE[HY000] [2002] Connection refused (SQL: select * from 'sessions' where 'id' = y1F7Xe6g7pxGxGJo9AFhbakk2gl3RNjJCm9ToV7Z limit 1)`のエラーがでる。
MySQLにアクセスしようとしたら下記エラーが表示される。

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

## 対処のためにしたこと

```
mysql.server start
```
パスワードの入力を求められたが、心当たりのあるパスワードでは開かない（忘れただけ？）。
パスワード不要で開けるようにする

1. 「my.csf」を開く。
1. 「skip-grant-tables」を追記して保存。

```my.csf
# vi /etc/my.cnf
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION
skip-grant-tables //これを追記
```

ターミナルを開き直す。もう一度以下を実行

```
mysql.server start
```

新たなエラーが表示される。PIDファイルがないとのこと。（このときはMySQLの起動自体には成功した。）

```
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.. SUCCESS! 
```

touchコマンドでPIDファイルを作成する。<username><devicename>はそれぞれのターミナルに表示されているものを入力してください。

```
touch <username><devicename>.local.pid
```

MySQLサーバを再起動する。

```
mysql.server restart
```

これで解決した。
Flutter Apprentice のススメ【タイムリミットはあと1ヶ月】

こんにちは、海岸蒼と申します。

今年の8月半ばからFlutterの勉強を始めたFlutter初心者です。
本記事は、自分のような初心者の方にぜひ見て欲しい記事となっています。

さて、この記事が公開されるのは12月5日(日)の予定です。
今からちょうど2ヶ月前の10月6日、
Flutter界隈で大きな出来事があったのですが、覚えてらっしゃいますか？

・・・そう、Flutter Apprentice の無料公開が始まった日です！

「そういえば！」、という人もいれば、「なんじゃそりゃ？」という人もいるかもしれません。

(「なんじゃそりゃ？」という人は少々お待ちください。この後説明します。)

なぜ、この記事を書こうと思ったかというと、
このFlutter Apprenticeの無料公開がちょうど後1ヶ月(22年1月6日)で終わってしまうからです。

Flutter界隈の人、特にまだアプリをリリースしたことのない初心者にとって、
これを読まないのは本当にもったいないです。

注意喚起を含めて、この記事を書こうと決意しました。


本記事では、Flutter Apprenticeを無料公開から５日で読み切り、今でも5~6回は見返している自分の目線から、
Flutter Apprenticeの解説、読むことの利点を説明します。

ぜひ一読いただけますと幸いです。

<h2>Flutter Apprenticeとは</h2>

「だから、Flutter Apprenticeってなんなんだよ！！！」
とお怒りかもしれませんね。

申し訳ございません、説明します。

Flutter Apprenticeは、Ray Wenderlich チュートリアルチームが提供している、
オンラインで読むことができるFlutterの教本です。

この本をはApprentice(見習い)の名の通り、初心者向けの教本となっています。

具体的には、何かしらのサービスでプログラミングの基礎を一通り学んだ人
（クラス、オブジェクト指向がなんとなくわかるくらいの人）
のレベルに合わせて書かれた本です。

本の内容は、環境構築からデータベース、Firebaseの利用まで、一気通貫で書かれています。
アプリのリリース方法（ストアへのアップロードの仕方）まで書かれているので、
この本さえあればアプリをリリースできる、と言っても過言ではない内容となっています。

環境構築からリリースまで、　Flutterでのアプリリリースをサポートする初心者に寄り添った本、
それがFlutter Apprenticeです。


詳細はこちらのページをご覧ください。

https://flutter.dev/apprentice-giveaway

<h2>Flutter Apprenticeの何がいいの？</h2>

初心者向けなのはわかったけど、具体的に何がいいの？と思うかもしれません。
そんな方に向けてこの本を読む利点を以下の３つ紹介したいと思います。

・　項目が幅広い
・　サンプルコードが親切
・　公式が猛プッシュしている

<h3>項目が幅広い</h3>
Flutter Apprenticeを読む、１つ目の利点です。

先にも書きましたが、　環境構築からリリースまで一気通貫で学ぶことができます。

具体的な内容を書き並べると、以下の通りです。（一部省略）
・環境構築
・デモアプリ作成
・Widget
・Widgetの内部
・スクロール可能なWidget
・ユーザー入力のWidget
・画面遷移
・Shared Preference
・JSON
・APIを使ったネットワーキング
・状態管理手法とアーキテクチャ
・Stream
・データベース
・アプリリリース準備
・Androidのリリース手順
・iOSのリリース手順
・Firebaseを使ったチャットアプリの作成

どうですか？かなりボリュームがあると思いませんか？

特に後半のStreamやデータベースだったりは学んだことがない方もいるのではないでしょうか。

また、項目が幅広いため一回読めば辞書的に使えるのも利点です。
自分のアプリ開発時に何度も助けられました。

項目の幅広さ、これがの1つ目の利点です。


<h3>サンプルコードが親切</h3>
Flutter Apprenticeを読む、２つ目の利点です。

この本では料理をテーマにしたアプリを作る過程で、
さまざまな技術を学ぶ、という形で進んでいきます。

ベースとなるアプリのコードはGitHubに上がっており、ダウンロードが可能です。

そして、このサンプルコード、ものすごい親切にできています。

``` dart
//TODO: replace this Card
return Card()
```

このようにサンプルコードには至る所でTODOが書かれています。
本では、TODOを指定して書き換える指示を行っています。
これにより、書き換える場所をTODOから追うことができるので、
「どこを書き換えたらいいの？？」と悩む心配がありません。

ノーストレスで学ぶことができるのは大きなポイントだと思います。

また、書き換えたコードはほぼ1行ごとに解説が書かれています。
これにより、コピペしたとしても何を書いたのか理解することが可能です。


ノーストレスな親切さが、この本を読む２つ目の利点です。


<h3>公式が猛プッシュしている</h3>

Flutter Apprenticeを読む、3つ目の利点です。

現在、この本をFlutter公式は猛プッシュしています。

なぜこの本が最近話題になったかというと、
Flutter 公式がRayWenderlichと提携して、Flutter Apprenticeの無料公開を始めたからです。
（10月から3ヶ月限定なので、残り1ヶ月です。）

この本、普通に買うと約$60（日本円で約6800円）します。
これが無料で読めるなんて、驚きですよね。

さらにFlutter CommunityのYoutube channnelでFlutter Apprenticeの解説ライブを行っています。
（21年11月現在ではアーカイブも残っています。） 
サポートが手厚いですね。

https://www.youtube.com/channel/UCNUzIz3TsiHSbgn_66kLIww

Flutter 公式は、Flutter 始めるならこの本読め！ってくらいにプッシュしています。
公式のサポートによる読みやすさが、Flutter Apprentice を読む3つ目の利点です。

<h2>まとめ</h2>

Flutter Apprenticeの魅力、伝わりましたでしょうか。
Flutterの実力のレベルアップにはもってこいの本となっています。

一つ、弱点を挙げるすると、全編英語で書かれている点ですね。
ただ、比較的優しい英語で書かれているため、Google翻訳を使えば簡単に読むことができます。
（自分も訳すのが面倒な部分はGoogle翻訳を使って訳しました。）
Google翻訳を使ってでも読む価値はあると思っています。

重ねてになりますが、無料公開期間は後1ヶ月で終了してしまいます。
気軽に読むことができる機会なので、ぜひ読んでみてください！

https://www.raywenderlich.com/books/flutter-apprentice
メモアプリのホーム画面をコンポーネントなしで実装

# ホーム画面の実装

まずはコンポーネントを考えずに、App.jsxにメモアプリのホーム画面を実装する。

```jsx
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

// eslint-disable-next-line react/function-component-definition
export default function App() {
  return (
    <View style={styles.container}>
      
      <View style={styles.appbar}>
        <View style={styles.appbarInner}>
          <Text style={styles.appbarTitle}>MEMO</Text>
          <Text style={styles.appbarLogout}>ログアウト</Text>
        </View>
      </View>

      <View>

        <View style={styles.memoItem}>
          <View>
            <Text style={styles.memoItemTitle}>買い物</Text>
            <Text style={styles.memoItemDate}>2020年12月22日 10:00</Text>
          </View>
          <View>
            <Text>x</Text>
          </View>
        </View>

        <View style={styles.memoItem}>
          <View>
            <Text style={styles.memoItemTitle}>買い物2</Text>
            <Text style={styles.memoItemDate}>2020年12月22日 10:00</Text>
          </View>
          <View>
            <Text>x</Text>
          </View>
        </View>

      </View>

      <View style={styles.circleButton}>
        <Text style={styles.circleButtonLabel}>+</Text>
      </View>
      
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#FCE4EC',
  },
  appbar: {
    width: '100%',
    height: 110,
    backgroundColor: '#C51162',
    justifyContent: 'flex-end',
  },
  appbarInner: {
    alignItems: 'center',
  },
  appbarTitle: {
    color: '#fff',
    fontSize: 24,
    lineHeight: 32,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  appbarLogout: {
    position: 'absolute',
    right: 20,
    bottom: 12,
    color: 'rgba(255,255,255,0.7)',
  },
  memoItem: {
    backgroundColor: '#fff',
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingVertical: 16,
    paddingHorizontal: 19,
    alignItems: 'center',
    borderBottomWidth: 1,
    borderColor: 'rgba(0,0,0,0.20)',
  },
  memoItemTitle: {
    fontSize: 16,
    lineHeight: 32,
  },
  memoItemDate: {
    fontSize: 12,
    lineHeight: 16,
    color: '#616161',
  },
  circleButton: {
    backgroundColor: '#C51162',
    width: 65,
    height: 65,
    borderRadius: 32,
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
    right: 40,
    bottom: 40,
    /* shadowはiphoneにしか効かないCSS */
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 8 },
    shadowOpacity: 0.35,
    shadowRadius: 5,
    /* elevationはAndroid用のCSS */
    elevation: 8,
  },
  circleButtonLabel: {
    color: '#fff',
    fontSize: 32,
    lineHeight: 32,
    fontWeight: 'bold',
  },
});

```

スマホの画面はこんな感じ。
![S__42459327.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284107/705c8168-3a6f-4424-2dd1-57c7879c54d1.jpeg)
【Linux】LInux基本コマンドまとめ

#Linuxって何？
LinuxはOSの一種でコンピュータを動かすための基本ソフト
>OSとはシステム全体を管理し、さまざまなアプリケーションソフトを動かすための最も基本的なソフトウェア
※Windows, Mac, Unix(LinuxやBSDなと含む),Androidなど

#Linuxはどこで使われている？
サーバー、組み込み、デスクトップといった幅広い用途で使われている。

#Linuxの特徴
・オープンソースなので誰でも自由に使える。
・品質の高い多くのソフトウェアが利用でき、世界中で使用され信頼性も高い
・サーバーとして用いられていることが多い

#カーネルとディストリビューション
「Linux」は、厳密には二つの意味で分けられます。
・中核となるソフトウェア：**Linuxカーネル**。
・カーネルに色々なソフトウェアを組み合わして使いやすくしたもの：**Linuxディストリビューション**。
Linuxカーネルについてわかりやすくまとめられています。
https://qiita.com/uguis410/items/17ec1e447e9716bfdca7

#代表コマンドまとめ

#cd 
change directoryの略
ディレクトリを移動するコマンド

| ディレクトリ | 意味 | 指定方法 |
|:-----------:|:------------:|:------------:|
| カレントディレクトリ| 現在自分がいるディレクトリ| 「.」|
| 親ディレクトリ     | 一つ上の階層のディrクトリ      | 「..」 |
| ホームディレクトリ  | 「/home/ユーザー名」ディレクトリ | 「~」|
| ルートディレクトリ   | 「/」ディレクトリ | 「/」|

#pwd
print name of working directoryの略
カレントディレクトリ(今いるディレクトリ)を表示するコマンド
一番親の階層から、自分がいる階層までのパス（流れ・繋がり）を表示する

#ls
listの略
ファイルやディレクトリの一覧を表示するコマンド
こちらのqiita参照
https://qiita.com/chihiro/items/6e1404c41e1236a9efe1
     
#mkdir
make directoryの略
ディレクトリを作成するコマンド

|  |   | 
|:-----------|------------:|
| -p    | 必要に応じて親ディレクトリも作成する  | 


```
$ mkdir dir1	（カレントディレクトリに「dir1」というディレクトリを作成する）
$ mkdir dir1/subdir	（「dir1」の中に「subdir」というディレクトリを作成する）
$ mkdir -p dir1/dir2/dir3	（「dir1」「dir1/dir2」「dir1/dir2/dir3」というディレクトリを作成する）
```

#cat
concatenateの略
ファイルの中身を表示するコマンド

|  |   | 
|:-----------|------------:|
| -n    | 表示する内容に行番号をつける | 

```
$ cat sample1.txt
red
blue
yellow
green
orange
white
black
$ cat -n sample1.txt
     1  red
     2  blue
     3  yellow
     4  green
     5  orange
     6  white
     7  black
```

#touch
touchの略
空のファイルを作成するコマンド

#rm
removeの略
ファイル・ディレクトリを削除するコマンド

|  |   | 
|:-----------|------------:|
| -r   | ディレクトリも合わせて削除する | 
| -f   | ファイルを削除する際に警告文を表示しない | 
| -i   | ファイルの削除前に確認する| 

#mv
moveの略
ファイルの移動、ファイル名を変更するコマンド

|  |   | 
|:-----------|------------:|
| -i    | 上書きする前に確認する | 

こちらのqiita参照
https://qiita.com/nasuB7373/items/f46fe8dc7ffc7a26b249

#cp
copyの略
ファイル、ディレクトリをコピーするコマンド

|  |   | 
|:-----------|------------:|
| -i    | 上書きする前に確認する | 
| -r    | ディレクトリをコピーする | 

#find
findの略
ファイルを検索するコマンド

|  |   | 
|:-----------|------------:|
| -name  | ファイル名、大文字小文字を区別してファイルを検索 | 
| -iname    | ファイル名、大文字小文字区別せずファイルを検索 | 
| -type    | ファイルの種類で検索 | 
| -a    | 複数の検索条件を指定　-aは省略可能 | 

#chmod
change modeの略
 ファイルやディレクトリのパーミッションを設定する
こちらのqiita参照
https://qiita.com/shisama/items/5f4c4fa768642aad9e06