OmniAICreator/Qiita-1.07M huggingface dataset:
【Unity】オブジェクトの角速度を計算（推定）する

# はじめに
Transformやアニメーションで動かしている（Rigidbody不使用の）オブジェクトで角速度を取得したい。
Transform.rotationの変化を追って推定することくらいなら難しくないんじゃないかと甘く見ていたのですが、結構苦戦してしまいました。

「rotationがどれくらい変わったかを刻々と求めればいいはず」ということで、とりあえずクォータニオンの引き算っぽいことをすればいいんだろうとは思ったのですが…。
肝心の計算方法がすぐに分からず、色々試す羽目に。

## ソース
速度の推定もついでに入れて、GitHubにアップロードしました。
[unity-kinematic-estimator](https://github.com/neuneu9/unity-kinematic-estimator)

# コード内容
先に結論から。

1. 回転の変化（前フレームの回転の逆クォータニオン×現在の回転）から、[Quaternion.ToAngleAxis](https://docs.unity3d.com/ja/current/ScriptReference/Quaternion.ToAngleAxis.html)で角度と回転軸を得ます。
2. 得られた角度値は *[deg/frame]* なので *[rad/s]* に換算します。
3. それを（Rigidbody.angularVelocityの形になるように）軸ベクトルにかけて完了。

```cs:AngularVelocityEstimator.cs
using UnityEngine;

/// <summary>
/// 角速度推定コンポーネント
/// </summary>
public class AngularVelocityEstimator : MonoBehaviour
{
    /// <summary>
    /// 推定角速度 [rad/s]
    /// </summary>
    [SerializeField]
    private Vector3 _estimatedAngularVelocity = Vector3.zero;

    /// <summary>
    /// 回転前回値
    /// </summary>
    private Quaternion _rotationPrevious = Quaternion.identity;

    public Vector3 EstimatedAngularVelocity
    {
        get { return _estimatedAngularVelocity; }
    }

    private void FixedUpdate()
    {
        // 回転変化量を計算
        Quaternion deltaRotation = Quaternion.Inverse(_rotationPrevious) * transform.rotation;

        // 角度と回転軸に変換
        deltaRotation.ToAngleAxis(out float angle, out Vector3 axis);

        // 角速度 [rad/s] を算出
        float angularSpeed = (angle * Mathf.Deg2Rad) / Time.deltaTime;
        _estimatedAngularVelocity = axis * angularSpeed;

        // 今回値を覚えておく
        _rotationPrevious = transform.rotation;
    }
}
```

試しにこれをRigidbody付きのオブジェクトに付けてみて、
適当なトルクを加えたときのRigidbody.angularVelocityと比較してみます。
![angular_velocity_estimator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483690/52308d17-efe4-b984-3d53-26178f92eeba.png)

多少の誤差はありますが、angularDrag（というか角加速度）を考慮していないのでこんなものでしょうか。
（一応、angularDragが小さいほど誤差が小さくなりました。）

# 補足
以下は蛇足的情報です。スルーで構いません。

最初私は考えました。
**そもそもオイラー角の引き算じゃダメなの？**
要はこういうことですよね。

```cs:NG
        // 回転変化量を計算
        _estimatedAngularVelocity = transform.rotation.eulerAngles - _rotationPrevious.eulerAngles;
        _estimatedAngularVelocity = (_estimatedAngularVelocity * Mathf.Deg2Rad) / Time.deltaTime;

        // 今回値を覚えておく
        _rotationPrevious = transform.rotation;
```

ダメでした。
これについてはオイラー角の差分を見たとして、それはオイラー角変化量とでもいうべきものであり、角速度ベクトルとは別のものである、という自己解釈で納得しました。

# おわりに
浅学ゆえ正しく理解できているか不安ですが、今のところこれで欲しい結果を得ることができているので共有します。
間違いや誤解があるようでしたらご指摘頂けますと幸いです。
プロジェクトの中にプロジェクトを入れてそれをgitで管理したい！

# 注釈

やりたいことはタイトル通りなのですが書く事柄はgit submoduleです。
探しても探してもプロジェクトの中にプロジェクト入れてそれのサブモジュールどうやってるの？
となり続けて3日ほどかけたので備忘録として。私自身も見返したいですし。
というか実質自分の見返し用です。

# これやってー

相手「今あるプロジェクトに機能を追加したいのでよろしくぅ！
あ、ついでに楽に管理したいからサブモジュールとかその辺のなんかいいの使ってね！」

私「(gitを使い始めての1月ぐらいの私に頼むとか正気か…？)わからないことがあったら聞きますね！」

# プロジェクト構造どうなってます？

treeコマンドっていうのがあるんですね…
階層手書きしたくないなぁって思ってた私にはまさにありがたみしかないです。

取り敢えずとしてこんな階層のプロジェクトがあったとします。

```bash
C:\>tree project /f
C:\PROJECT
│  1.txt
│  2.txt
│  3.txt
│  4.txt
│  5.txt
│
└─Patch
    ├─SubProject
    ├─SubProject2
    ├─SubProject3
    ├─SubProject4
    └─SubProject5
```

このPatch直下にどんどんと**サブプロジェクト**が増えていくわけです。

# 今までの管理

そもそも今までの管理方法は？というと

今まではこんな感じでした

```bash
C:\>tree project /f
C:\PROJECT
│  1.txt
│  2.txt
│  3.txt
│  4.txt
│  5.txt
│  .git
│
└─Patch
    ├─SubProject
    ├─SubProject2
    ├─SubProject3
    ├─SubProject4
    └─SubProject5
```

大本プロジェクトのみgitで管理している状態です。

パッチ修正とかがあるたびに一気にコミットした瞬間のファイルが増えるし
一部回収なのに大元で管理とかばかばかしいと思いません？
後はほかの人が作ったパッチも入れたい！というとき毎回クローンしなければいけないですし、色々現実的じゃないですよねー…。

# というわけでsubmoduleさんの力を借りましょう

まずは、SubProjectを入れたい位置へ行きます。
移動したらサブモジュールとしてプロジェクトを追加します。

```bash
C:\>cd Project\Patch
C:\Project\Patch>git submodule add [FILEPATH]
```

上記でカレントディレクトリにプロジェクトがサブモジュールとして追加されます。
複数ある場合はこのままのカレントディレクトリで`git submodule add`で次々と追加していけます。

### ファイル数は一つなんですけども…

今現在追加するサブモジュールが一つの場合わざわざ移動はしなくてもそのまま指定してしまいましょう。

~~~bash
git submodule add [FILEPATH] foo/PluginFolderName
~~~

プラグイン名指定なしで階層だけ指定して作りたいんですけど今のところないみたいですのでこのようになります。

~~~bash
C:\Project>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitmodules
        Patch/

nothing added to commit but untracked files present (use "git add" to track)
~~~

.gitsubmoduleとPatch/
もしくは
.gitsubmoduleと追加したサブモジュールパス
が
Untracked files:
に存在すればサブモジュールの追加としては終了です。

これでサブモジュールとして管理されるようになったので
プロジェクトの中にプロジェクトに入っていてそれが親プロジェクトで管理されている状態が完成しました！！

# 参考

[Gitのサブモジュール機能を使ってプロジェクトを管理してみよう - ](http://vdeep.net/git-submodule)
Python （改造版）コラッツの予想

#問題
数学の未解決問題の一つに「コラッツの予想」があります。
>コラッツの予想
自然数nについて、
・nが偶数の場合、nを2で割る
・nが奇数の場合、nに3をかけて1を足す
という操作を繰り返すとき、初期値がどんな数であっても必ず1に到達する
（1 → 4 → 2 → 1のように繰り返す）

この予想を少し変えて、初期値が偶数の場合、
初回のみnに3をかけて1を足すことから始めることとし、
「最初の数」に戻るものを考えます。

例えば、2で始めた場合は以下のようになります。
　2→7→22→11→34→17→52→26→13→40→20→10→5→16→8→4→2

同様に、4で始めると以下のようになります。
　4→13→40→20→10→5→16→8→4

しかし、6で始めると、
 6→19→58→29→88→44→22→11→34→17→52→26→13→40→20→10→5→16→8→4→2→1→4→・・・

となり、6に戻ってくることはありません。

10000以下の偶数のうち、
上記の2や4のような「最初の数に戻る数」がいくつあるか、
その個数を求めてください。

> 引用「プログラマ脳を鍛える数学パズル　著者 増井 敏克」

#回答

```answer.py
l = [i for i in range(1, 10001) if i % 2 == 0]
count = 0

for j in l:
    check = j * 3 + 1
    while check != 1: 
        if check == j:
            count += 1
            break
        elif check % 2 == 0:
            check = check / 2
        else:
            check = check * 3 + 1

print(count)    # 34
```

#つまづいたところ
今回は`jupyter notebook`を使いながら回答しました。
いいですね`jupyter notebook`。
これでないとできないものがあった訳ではありませんが、
近々使う機会ができたので使用感のために触ってみました。

さて、今回の問題では特に大きくつまづいたところはありませんでした。
短縮できそうなところがあるかもしれませんが、
ひとまずは回答と合っていましたのでここまでにしました。

はじめに前半の部分、

```answer.py
l = [i for i in range(1, 10001) if i % 2 == 0]
count = 0
```
変数lには1から10000までの偶数を配列にして代入しています。
リスト内包表記でif文を加えています。

変数countは問題文の「個数を求めてください」の個数となる部分です。

次がメインとなる後半の部分。

```answer.py
for j in l:
    check = j * 3 + 1
    while check != 1: 
        if check == j:
            count += 1
            break
        elif check % 2 == 0:
            check = check / 2
        else:
            check = check * 3 + 1

print(count)    # 34
```

for文で変数lの要素ごとに処理が実行されるようにしています。
for文の中にさらにwhile文でコラッツの予想である、
> ・nが偶数の場合、nを2で割る
・nが奇数の場合、nに3をかけて1を足す

となるように処理をしています。

変数checkがjと同じの時は、
変数countに1を足してbreakによってwhlleを抜けるようにしています。
これが変数lの要素ごとに行われます。

最後のprintは回答確認ですね。

夏期休暇が終わってしまい、連続投稿が途絶えてしまいました。
１週間以内に再投稿できたのはよかったなあと自己満足しております笑

ご拝読ありがとうございました。
[自分用メモ] よく使うIntelliJ IDEAショートカット

特にWindowsのショートカットをよく忘れるのでメモ。順番には特に意味は無い。

| やりたいこと | macOS | Windows |
|:-----------------:|:------------------:|:------------------:|
| 空気を読む | Option + Enter | Alt + Enter |
| ファイル一覧に移動 | Command + 1 | Alt + 1 |
| エディタに移動 | Esc | Esc |
| 最近開いたものに移動 | Control + Tab (* n回) | Ctrl + Tab (* n回) |
| 最近開いたもの一覧 | Command + E | Ctrl + E |
| エディタの最大化 | Shift + Command + F12 | Ctrl + Shift + F12 |
| ターミナルに移動 | Option + F12 | ？？？ |
| 新規作成 | Command + N | Alt + Insert |
| 名前の変更 | Shift + F6 | Ctrl + F6 |
| 実行 | Control + Shift + R | Ctrl + Shift + F10 |
| デバッグ実行 | Control + Shift + D | - |
| 定義元にジャンプ | Command + B | Ctrl + B |
| 使われている箇所を検索 | Option + F7 | Alt + F7 |
| 何でも検索 | Shift + Shift | Shift + Shift |
| 下を改行 | Shift + Enter | Shift + Enter |
| 範囲選択 | Option + ↑ (↓) | (Shift + ) Ctrl + W |
ある整数が2で割り切れる回数を求める方法@Python

## TL;DR

競技プログラミングで、ある整数を2で何回割れるかを求める必要があった。
[ABC081B - Shift only](https://atcoder.jp/contests/abs/tasks/abc081_b)
ベタに2で割り切れなくなるまでwhile文で回して求めていたけれど、もう少し、洗練されたやり方がないかを考えた。

## 求めたいこと

ある整数nは、2で何回割れるか？

| 整数 | 割り算 | 答え |
|---|---|---|
| 2 | 2÷2=1 | 1回 |
| 8 | 8÷2=4<br />4÷2=2<br />2÷2=1| 3回|
| 100 | 100÷2=50<br />50÷2=25| 2回|

## ベタな数え方

while文を使って、2で割り切れなくなるまで割り続ける

```py:
num = int(input())
cnt = 0
while num % 2 == 0:
    num //= 2
    cnt += 1
print(cnt)
```

## 多少は数学的かも知れない求め方

2進数に変換して、右から検索して、最初に1が出現するまでの0の個数を数えればそれが答えであることに気づいた

| 10進数 | 2進数 | 求め方 | 答え |
|---|---|---|---|
|2|10|1[0]|1|
|8|1000|1[000]|3|
|100|1100100|11001[00]|2|

これをコードにすると以下の通り

```py
num = int(input())
print(format(num, 'b')[::-1].find('1'))
```

+ 与えられた数字を2進数に変換する
  + `format(num, 'b')` プレフィックスなしの2進数文字列  
  参考リンク：[pythonで2進数を表す - Qiita](https://qiita.com/umeda_takumi/items/29cf4ecd7f9c33f79336)
+ 右から1が出現するまで0の個数を数える
  + `[::-1]`：文字列を逆順にする  
  参考リンク：[Python 文字列反転 - Qiita](https://qiita.com/Hawk84/items/ecd0c7239e490ea22308)
  + `find('1')`：最初に1が出現する箇所を見つける

## 注意事項

+ 所詮は、数学苦手なおじさん(42歳東京都)が背伸びできる範囲内で考えた解法
+ よりエレガントな求め方があれば、教えて下さい

## 蛇足：昨日時点のウルトラ糞コード

[提出 #7088898 - AtCoder Beginners Selection](https://atcoder.jp/contests/abs/submissions/7088898)

俺は何がしたかったんだろう・・・:scream:
Chromedriverをheadlessで試す

###試す
いちいちheadlessに移行するために書き足したりコメントアウトするのめんどくさいからコマンドライン引数をとる

````python
import sys
from selenium import webdriver

try:
    sys.argv[2]
    if sys.argv[2] == "headless":
        options = webdriver.ChromeOptions()
        options.add_argument('--headless')
        driver = webdriver.Chrome('./chromedriver', options=options)
    else:
        # chromeを開く
        driver = webdriver.Chrome('./chromedriver')
except:
    # chromeを開く
    driver = webdriver.Chrome('./chromedriver')
````
これで

````
$python ~~~.py headless
````
でheadlessが動く
簡単
AWSのService Health Dashboardに表示される障害対応状況をLINEで受け取る方法

いつも忘れないように、コンセプトから。

###コンセプト
・お金かけてまでやりたくないのでほぼ無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ

さて、今週ずっと体調が悪くて会社休んでいたんですが、昨日ようやく動けるようになったので出社したんですが、出社していきなりAWSのトラブルですよ。上司に、「たまに出てみりゃこれですか」って思わず漏らしてしまいました。。。

###Service Health Dashboard
AWSでサービスのステータスを公開していて、会社では確認しながら対応していました。まあ、そもそもAZ全面障害でもないし、マルチAZで組んでいるシステムはうまく動いているので大したことない障害だなとか思っていたのに、Yahoo!とかが「AWS大障害」とか書いたせいで外野がうるさくて仕方がないです。大障害のうちに入らねーっつーの！
https://status.aws.amazon.com/

ただ、会社の環境もありますがローテクなもんで、基本的にF5を連打していた訳ですよ。そんなに頻繁に更新されるものでもないのでアタックはしていませんけど。で、気づいていたのがRSSのボタン。これでフィードさせればいいじゃん！って。でも忙しかったのでOutlookとかには設定しませんでした。

そこで今日いろいろ見ていたら同じことを感じたnasuvitzさんがいらっしゃることを発見。こりゃー思いっきりパクッて試してみようと思った訳です。
https://qiita.com/nasuvitz/items/173ed384e035e4879b6f


###Slackってほとんど使っていないんだが
一通り真似っこしてみてできたんですが、よく考えてみるとSlackってほとんど使っていません。以前知り合った外人がAWSSecurityForumというルームを招待してくれたんですが、それだけ。勉強熱心ではない私はほとんど見てないんですよ。

冷静になってみるとLINEのほうがいいんじゃない？ってことに気が付きました。LINEはよく見てますしね。

で、LINEでRSSフィードを受けられないかを調べてみるとありました。LINE-NOTIFYを使うんだそうです。公式のユーザーみたいなのがいて、それを招待すると通知してくれるようです。以下のURLを参考に設定してみました。
https://mirasin.com/line-notify/

少しだけIFTTTの設定画面が変わってましたが、特に難しいこともなく、単にRSS設定するだけです。新しいルールを作るところが自分のアカウントマークを押してcreateって出てくるところに変わっていたので、そこだけ注意してください。

###サービスごとってちと不便
RSS登録したのはEC2とRDSにしてみたんですが、なんかサービスが多すぎて不便ですね。主要なEC2とかを入れておけば良さそうな気はしましたけど。あーS3も落ちたら致命的だから入れておいたほうがいいかも。もうちょっと網羅的に、かつ簡単に拾える方法が無いかは考えてみようと思います。

とはいっても便利な世の中になりましたね。LINEも使っているうちに入らないレベルの使い方なんですけど、もうちょっといろいろ連携したら便利かも。

おしまい。
いろんな言語の標準ライブラリのみでjsonをPOSTする

# こんな時に役立ちます

- 標準ライブラリしか使えない宗教を信仰している時
- ライブラリを使うと死ぬ病に侵された時
- Lambdaでライブラリ管理したくない時

## Ruby

```ruby
require 'json'
require 'uri'
require 'net/https'

uri = URI.parse('https://example.com')
header = { 'Content-Type': 'application/json' }
body = { text: 'Hello World' }
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri.request_uri, header)
req.body = body.to_json
res = http.request(req)
pp res.body
```

## Node.js

```js
const https = require('https')

const data = JSON.stringify({ text: 'Hello World' })
const options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    }
}
const req = https.request('https://example.com', options, res => {
    console.log(res.statusCode)
})
req.write(data)
req.end()
```

## Python

```python
import json
import urllib.request

data = json.dumps({'text': 'Hello World'}).encode('utf-8')
headers = {'Content-Type': 'application/json'}
req = urllib.request.Request(
    'https://example.com',
    data=data,
    method='POST',
    headers=headers)
with urllib.request.urlopen(req) as res:
    print(res.read().decode('utf-8'))

```

## Shell Script (curl)

```shell
 curl -X POST -H "Content-Type: application/json" -d '{"text": "Hello World"}' https://example.com
```
static 変数の初期値に注意

# static 変数の初期値に注意

php でコードを書いていて「クラス/インスタンス間の static 変数ってどういう挙動だっけ？」と思って調べていたところ [PHPの静的変数 (static変数) の挙動まとめ](https://qiita.com/trashtoy/items/f4e2a97765e620bb2828)を見つけて、「あぁ、なるほど」と納得したんですが、微妙におかしな挙動を示したので備忘として残しておきます。

- OS: CentOS7
- php: 7.2.14

結論を言うと、上述の記事の通り確かに static 変数はクラス間で独立した挙動を示しますが、その**初期値が状況によって異なります**。

## 再現コード

上述の記事から引用して乗っかります。

> では、Test1 を継承した子クラスから実行した場合はどうなるでしょうか。結果は以下のコードから。(PHP 5.1.0 - 5.5.13 で確認)

```php
<?php
class Test1
{
    public static function testStaticMethod()
    {
        static $num = 0;
        $num++;
        echo __METHOD__ . $num . PHP_EOL;
    }
}

class Test2 extends Test1
{
}

class Test3 extends Test1
{
}

Test1::testStaticMethod();
Test2::testStaticMethod();
Test3::testStaticMethod();
Test1::testStaticMethod();
Test2::testStaticMethod();
Test3::testStaticMethod();
```

> このコードは以下を出力します。

```php
Test1::testStaticMethod1
Test1::testStaticMethod1
Test1::testStaticMethod1
Test1::testStaticMethod2
Test1::testStaticMethod2
Test1::testStaticMethod2
```

> この出力内容から分かる通り、Test1, Test2, Test3 のそれぞれのクラスで $num が独立して管理されていることが分かります。

この動作に全くおかしなところはありません。

ただし、クラスがロードされていないと static 変数の初期値が「既に設定されている親クラスの static 変数」に設定されてしまうようです。

```php
<?php
class Test1
{
    public static function testStaticMethod()
    {
        static $num = 0;
        $num++;
        echo __METHOD__ . $num . PHP_EOL;
    }
}

Test1::testStaticMethod();

if (true) {
    class Test2 extends Test1
    {
    }
}
Test2::testStaticMethod();
Test2::testStaticMethod();

if (true) {
    class Test3 extends Test1
    {
    }
}
Test3::testStaticMethod();
Test3::testStaticMethod();
```

php は一旦ソース全体をなめてシンボルの解決を行うので、それを防ぐためにクラス定義を `if (true)` で包んでいます。
要するにクラスのオートロードと同じ挙動になるような模倣です（≒必要になったときに読み込む）。

このコードは以下を出力します。

```
Test1::testStaticMethod1
Test1::testStaticMethod2
Test1::testStaticMethod3
Test1::testStaticMethod2
Test1::testStaticMethod3
```

`Test2::testStaticMethod()` は初回呼び出しにも関わらず、値が `2` になっています。
`Test3::testStaticMethod()` も同様です。
その後の呼び出しは独立して管理されているので、それぞれで `3` になります。

これは Test1 の既に代入されている `static $num` に影響を受けているためだと思われます。
実際、 `Test1::testStaticMethod()` を呼ばなければ `Test2` も `Test3` もそれぞれ `1` から始まります。

一応実行結果を置いておきます。

- https://3v4l.org/C79UV
- https://3v4l.org/trNoO

## 所感

公式ドキュメントに「クラス間の static 変数の挙動」や「継承した場合の static 変数の初期値」などの記載を見つけることは出来なかったんですが、おそらくこれはクラスローディングの際の php 不具合のような気がします。
（ロード時に static 部分が共用されてしまっている？）。

不具合ならば修正されるでしょうが、現在のところ「クラスがロードされているか？」で挙動が変わってしまうので、下手すると深刻・非常に分かりにくいバグの原因になります。
「クラスがロードされているか？」は状況によってかなり異なるためです。
とりあえず頭の片隅にでも入れておくと良いかもしれません。
Salesforce標準オブジェクト一覧

<img width="205" alt="StandObj.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480374/8e96a0f7-11d9-96c9-00be-af308ef67b81.png">

■参照URL
https://www.n-sysdes.co.jp/salesforce%E6%8A%80%E8%A1%93%E3%83%96%E3%83%AD%E3%82%B0%EF%BC%88%E3%82%B3%E3%83%94%E3%83%9A%E3%81%A7%E3%80%81%E7%B0%A1%E5%8D%98%E3%81%AB%EF%BC%81apex%E3%81%8B%E3%82%89%E5%AD%90%E3%83%AA%E3%83%AC/
英語版の開発者向けナレッジ共有サービス

英語版のQiitaのようなサービス（開発者が技術情報を共有するためのコミュニティサイト）を調査した。
結論としては、現時点では機能不足な点もあるが、[dev.to](https://dev.to)が開発者に特化しており有望であると感じた。


#### [Medium](https://medium.com/)

英語圏で人気のあるパブリッシングプラットフォーム

* ユーザー数が多く、SEOも強力である。
* アクセスする度にユーザー登録を促すポップアップが表示されたり、（無料かいい広告やSNSボタンの表示領域が大きいなど記事を読みにくい。（[参考](https://medium.com/@nikitonsky/medium-is-a-poor-choice-for-blogging-bb0048d19133)）
* 投稿画面から直接Markdownを投稿できないため、工夫が必要となる。
  * MarkdownのプレビューをMediumにコピペする（[参考](https://medium.com/@mono0926/markdown-medium-8a3ce20d8032)）
  * GistにMarkdownを投稿してMediumのURLインポート機能で取り込む（[参考](https://medium.com/@andymcfee/how-to-import-markdown-into-medium-c06dc981bd96)）
  * Byword、UlyseesなどMedium投稿機能を持つMarkdown（テキスト）エディタを使う（[参考](https://goroo.club/medium%E3%81%A7%E3%81%8D%E3%82%8B%E6%8A%95%E7%A8%BFmarkdown%E7%B3%BB%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E6%AF%94%E8%BC%83-2016%E5%B9%B44%E6%9C%887%E6%97%A5%E6%99%82%E7%82%B9-f748c317c335)）
  * Medium API（Markdown形式での投稿に対応している）を使う（[参考](https://matsubara0507.github.io/posts/2018-11-04-create-mdium.html)）
* コードのシンタックスハイライトがサポートされないため、ハイライトを実現するにはGistにアップロードして貼り付ける必要がある。（[参考](https://medium.com/@Maluen0/how-to-add-code-highlighting-in-medium-articles-without-leaving-the-editor-8f24f5a88d28)）
* 数式表示がサポートされないため、画像として埋め込む必要がある（[参考](https://medium.com/@tylerneylon/how-to-write-mathematics-on-medium-f89aa45c42a0)）

#### [Ghost](https://ghost.org/)

オープンソースのCMS [Ghost](https://github.com/tryghost/ghost) の有料ホスティングサービス

* 独自ドメインを使ってサイトを公開できる。
* Markdownでの投稿に対応しており、シンタックスハイライトもプラグインを組み込めば対応できる。（[参考](https://bironthemes.com/blog/how-to-add-syntax-highlighting-to-ghost/)）
* 料金は月額 $29 (Basic) からと高め（[参考](https://ghost.org/pricing/)）

#### [dev.to](https://dev.to)

プログラマがアイデアやナレッジを共有するためのコミュニティサービス

* Markdownでの投稿に対応しており、シンタックスハイライトもサポートされる
* タグや類似記事推薦機能など、記事を広めるための機能がある
* 数式表示はサポートされていなく、対応も優先度低となっている（[参考](https://github.com/thepracticaldev/dev.to/issues/182)）

#### [Coderwall](https://coderwall.com/)

プログラマがアイデアやナレッジを共有するためのコミュニティサービス

* dev.toよりも活発度が低い印象を受けた
Cloud Composer を使ったワークフロー開発に便利なコマンドまとめ

Web UI からポチポチしていると日が暮れるのでコマンドラインから開発できるように調べたまとめ

## デプロイ

`gcloud composer environments storage {dags,plugins} import` を使ってファイルをアップロードする。うちではディレクトリ構造を合わせて作って以下のようにデプロイしている。

不便なことに {dags,plugins} ディレクトリを丸ごとアップロードすることができず、`--source` でサブディレクトリを指定しないといけないため、find | xargs でサブディレクトリ一覧を作ってから import している。


```bash
find "composer/dags" -maxdepth 1 -mindepth 1 | xargs -t -P4 -I{} \
  gcloud composer environments storage dags import \
  --environment ${COMPOSER_ENVIRONMENT_NAME} \
  --location ${LOCATION} \
  --source {}

find "composer/plugins" -maxdepth 1 -mindepth 1 | xargs -t -P4 -I{} \
  gcloud composer environments storage plugins import \
  --environment ${COMPOSER_ENVIRONMENT_NAME} \
  --location ${LOCATION} \
  --source {}
```

## ゴミDAGもしくはゴミファイルの掃除

不便なことに `import` は上書きしかしてくれないため、ゴミファイルの掃除は別途しなければならない。

また、不要になったDAGを削除する際は、Composer 用の GCS からファイルを削除した上で、Airflow の `delete_dag` コマンドを使って、Airflow の MySQL からエントリを削除しなければならない。

ゴミDAGの削除

```bash
gcloud composer environments storage dags delete "${DAG}.py" \
  --environment ${COMPOSER_ENVIRONMENT_NAME} \
  --location ${LOCATION}

sleep 15

gcloud composer environments run \
  ${COMPOSER_ENVIRONMENT_NAME} --location ${LOCATION} \
  delete_dag -- "${DAG}"
```

ゴミ plugins ファイルの削除

```bash
gcloud composer environments storage plugins delete "${FILE}" \
  --environment ${COMPOSER_ENVIRONMENT_NAME} \
  --location ${LOCATION}
```

また `storage {dags,plugins} list` コマンドでファイルの一覧を参照できます。

TODO: sync してくれるようなスクリプトの作成

## DAGの特定タスクの実行

airflow の `test` コマンドを使って特定タスクの実行ができる。これを使って開発するかしないかで開発効率が全く違う。

```bash
gcloud composer environments run \
  ${COMPOSER_ENVIRONMENT_NAME} --location ${LOCATION} \
  test -- my_dag my_task 2019-08-23T00:00:00+0000
```

## DAG全体の実行

airflow の `trigger_dag` コマンドを使ってDAG全体に実行ができる。execution_time にユニーク制約があるので開発中は秒を 01 にしたり 02 にしたりすることがよくある。

```bash
gcloud composer environments run \
  ${COMPOSER_ENVIRONMENT_NAME} --location ${LOCATION} \
  trigger_dag -- my_dag -e 2019-08-23T00:00:00+0000
```

## Airflow WebUI URLの取得

Composer を作り直すと Airflow WebUI の URL が変わってしまうので次のように取得すると便利。

```bash
gcloud composer environments describe \
  ${COMPOSER_ENVIRONMENT_NAME} --location ${LOCATION} \
  | grep airflowUri | awk -F': ' '{print $2}'
```

macOS なら `open <URL>` コマンドでブラウザを開ける

## DAGファイルの Syntax チェック

See [Cloud Composer 向けの DAG ファイルの Syntax チェックをローカルで実行する](https://qiita.com/sonots/items/3cef03a1c41a25e3d6d7)
東方弾幕風 v0.12mにおけるスクリプトファイルの文字コードの話

# 概要
[東方弾幕風 v0.12m](https://touhougc.web.fc2.com/products/th_dnh.html)は文字コードがANSI（Shift_JIS）でないとスクリプトを読み込んでくれないので，スクリプトファイルを作成するときは文字コードをUTF-8などではなくANSIにする．

# 詳細
久しぶりに東方弾幕風で遊ぼうとしたら，メモ帳を用いて新たに作成したスクリプトファイル（txt形式）を弾幕風本体が読み込んでくれなくて困った．しかし，大昔に作成したスクリプトは読み込んでくれていた．いろいろ調べた結果，最終的にファイルの文字コードが原因であることがわかった．新たに作ったファイルは文字コードがUTF-8になっていたので，ANSIで保存し直したら無事に読み込んでくれた．
なぜこのようなことが起きたかというと，[Windows 10のアップデート](https://docs.microsoft.com/ja-jp/windows-insider/at-home/whats-new-wip-at-home-19h1#%E3%83%A1%E3%83%A2%E5%B8%B3%E3%81%AE%E6%9B%B4%E6%96%B0)によって，メモ帳のデフォルトの文字コードがANSIからUTF-8に変更されたからだった．
ちなみに，例えば「天狗のネタ帖」のような弾幕風専用のエディタを使えば，何も考えなくてもANSIで保存してくれる．

# 参考
- [東方弾幕風v0.12m](https://touhougc.web.fc2.com/products/th_dnh.html)
- [Windows 10 Insider Preview ビルド1903の新機能 - Windows Insider Program | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows-insider/at-home/whats-new-wip-at-home-19h1#%E3%83%A1%E3%83%A2%E5%B8%B3%E3%81%AE%E6%9B%B4%E6%96%B0)
- [メモ帳の文字コードが「ANSI」から「UTF-8」に【Windows 10 Ver.1903】: 世の中は不思議なことだらけ](http://snow-white.cocolog-nifty.com/first/2019/05/post-7ab7a5.html)
- [ツール・ライブラリ - 東方弾幕風wiki（仮・三代目）](https://danmakufu.wiki.fc2.com/wiki/%E3%83%84%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA)
 - 天狗のネタ帖はここからダウンロードできる．
MySQLを使ってのrake db:createができない。

MySQLを使用して```rake db:create```したら下記のエラーが出ました。
かなり時間がかかってしまったので備忘録に。
 
エラー文

```
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Couldn't create 'pictweet_development' database. Please check your configuration.
rake aborted!
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

Tasks: TOP => db:create
(See full trace by running task with --trace)
```

#原因考察と対処

1、
原因：mySQLが起動していない。
対処：SQLを再起動させる。

```
$ sudo mysql.server restart
ERROR! MySQL server PID file could not be found!
```
結果：失敗

2、アンインストールして再インストール。
対処：SQLを再インストール（よくある手法）

```
$ brew remove mysql
$ brew cleanup
```

sql関連のファイルを削除

```
$ sudo rm /usr/local/mysql
$ sudo rm -rf /usr/local/var/mysql
$ sudo rm -rf /usr/local/mysql*
$ sudo rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
$ sudo rm -rf /Library/StartupItems/MySQLCOM
$ sudo rm -rf /Library/PreferencePanes/My*
```

sqlの自動起動設定を解除

```
$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
```
結果：失敗


3、sqlに PIDファイルを作成し、権限パスを渡す(今回はこれ)

適当な名前でいいので、PIDファイルを作成

```
$ touch /usr/local/var/mysql/user-no-MacBook-Pro.local.pid
```

作成したpidファイルにsqlの権限パスを渡してあげる
/user/local/var/mysql以下のファイルの所有者をすべて_mysqlにすることで解決。

```
$ sudo chown -R _mysql:_mysql /usr/local/var/mysql/
$ sudo mysql.server restart
Starting MySQL
. SUCCESS! 
```
結果：成功！

今回、バックアップ取らずにアンインストールしていまいましたが（重要なデータはなかった…汗）
再インストールする時はバックアップを取ることをお勧めします。

参考
https://qiita.com/sato11/items/ba887a5655217f60f2a2
https://qiita.com/carotene4035/items/e00076fe3990b9178cc0
https://qiita.com/jonakp/items/477a18d4a94c01a31583
MNCTF2017 宛先暗号☆★★

#問題

http://mnctf.info/mnctf2017/top.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/fd24a4f1-4bd0-0220-7be3-9bd264a63722.png)

#解いてみた

EDR_log.csvの中身からvm.datが出てくるところを絞り込んでみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ee406164-8c90-5fb1-d2fc-3a406d1369d5.png)

一つだけありました。
これと同じコマンドを実行すればよさそうです。
wiresharkを実行させたうえでこのコマンドを実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/1bdc5efd-e29a-cf0d-cca5-a57559a919b9.png)

たくさんDNS通信が起きました。
今回の答えはFQDNなのでこのドメインを答えればよいですね。
How to create an Aruco dictionary

#### This function will create a totally new dictionary.So it maybe spend a lot of time.(ゼロからDictionaryを作成するため、時間がかなりかかります。)


- zero_custdictionary	=	cv.aruco.Dictionary_create(	markerSize, bitSize )

| parameters| purpose | datatype |
|:-:|:-:|:-:|
|markerSize   |  The number of markers | Integer  |
| bitSize  | The marker's binary size  |  Integer |

#### This function can base on a predefined dictionaries, add a new dictionary. (arUcoの予め準備したDictionaryの上でマーカーの数を追加する。)
- baseDictionary = cv.aruco.getPredefinedDictionr(cv.aruco.DICT_XXX_XXX)
- add_custdictionary = cv.aruco.Dictionary_create_from(	markerSize, bitSize, baseDictionary)
* <font color ="LightRed",size = 5 >Pay attetion: The new added dictionary's bitSize should be the same as predefined dictionary's.</font>

##### Source code example

```python
import cv2 as cv

aruco = cv.aruco
dictionary = aruco.getPredefinedDictionary(aruco.DICT_5X5_1000)

#マーカーの数
markerSize = 1050

#マーカーのバイナリーサイズ
bitSize = 5

#カスタマイズDictionary 
##arUcoの予め準備したDictionaryの上でマーカーの数を追加する
##例えばここはDICT_5X5_1000を基いて、100個を追加する。マーカーの数が大き程、最初Dictionaryの作成時間がかなりかかります。
custDictionary = aruco.custom_dictionary_from(markerSize, bitSize, dictionary)

##ゼロからDictionaryを作成するため、時間がかなりかかります。
#custDictionary = aruco.custom_dictionary(markerSize,bitSize)

generatMarker(custDictionary, 1040, 1234)

def generatMarker(dic,ID,data):
    marker = aruco.drawMarker(dic,ID,data)
    cv.imwrite('./ar_'+str(ID)+'_'+str(data)+'.png', marker)
```

*  <font color ="LightBlue",size = 5 >By the way, I ran the source code above at terminal and editor environment. And the terminal spent less time.</font>
* <font color ="LightBlue",size = 5 >For more informatin please check the site:</font>
  [dictionary.hpp](http://man.hubwiz.com/docset/OpenCV.docset/Contents/Resources/Documents/d5/d0b/classcv_1_1aruco_1_1Dictionary.html)

### How to choose a dictionary
- The relationship of correctionBits and markers size.

The inter-marker distance parameter:the minimum distance among its markers and it  determines the error detection and correction capabilities of the dictionary.
In general, lower dictionary sizes and higher marker sizes increase the inter-marker and vice-versa. However, the detection of markers with higher sizes is more complex, due to the higher amount of bits that need to be extracted from the image.
(理論的に,marker size(bitSize)が大きい且つmarker数（markerSize)が少ない場合、エラー訂正レベルが高いです。ただし、marker　Size（bitSize）が大きすぎると、検知される対象画像の画質の条件も厳しい。)
- 例、200個markerが必要でしたら、同じmarker size（bitSize）6の場合、DICT_6X6_250よりDICT_6X6_1000の方がロバスト性が強い。

- Create dictionary only one time and can be used at anytime.
The Dictionary parameters are:

```java
class Dictionary{
 public:
 Mat bytesList; // contains all the information about the marker codes
 int markSize;
 int maxCorrectionBits;//maximum number of bits that can be corrected
...} 
```
You should save the created dictionary(bytesList) as a csv/yml file. So that you can reuse it by reading this csv/yml file.

- Please reference this site: [save dictionary] (https://github.com/opencv/opencv_contrib/issues/1586)


#### <font color = 'red'>TODO</font>

- The time of creating a new dictionary.
Craft CMS でファイルが存在しているかどうかのTwigフィルタを追加する Existential プラグイン

Twig のテンプレートを書くときに、指定したファイルが存在してるかどうか？をチェックしてくれるプラグイン

> Existential
> https://plugins.craftcms.com/existential

```
{% if asset.getUrl() | fileExists %}
```

まぁ、プラグインがあるということは用途があるんだろう、という気がする。
リサイズされたファイルがあらかじめ存在してるかどうか？とかをチェックする、とかかな、、、？？
Goでのスタックもただのスライス＋appendで実装できる

# Goでのスタックもただのスライス＋appendで実装できる

[Goでのキューはただのスライス＋appendで実装できる](https://qiita.com/ruiu/items/8edf22cd5fc8f7511687)を見て、スライスでキューを実装できることに気づき、

```go
type intQueue []int

func (queue *intQueue) enqueue(i int) {
	*queue = append(*queue, i)
}

func (queue *intQueue) dequeue() int {
	result := (*queue)[0]
	*queue = (*queue)[1:]
	return result
}
```

みたいなコードを書いて、

```go
	var queue intQueue = make([]int, 0)
	queue.enqueue(0)
	for len(queue) != 0 {
		i := queue.dequeue()
		for _, j := range links[i] {
			if processed[j] {
				continue
			}
			results[j] += results[i]
			processed[j] = true
			queue.enqueue(j)
		}
	}
```

みたいに使っていたのだが、スタックもスライスで実装できることに気づいた.

```go
package main

import (
	"fmt"
)

type intStack []int

func (stack *intStack) push(i int) {
	*stack = append(*stack, i)
}

func (stack *intStack) pop() int {
	result := (*stack)[len(*stack)-1]
	*stack = (*stack)[:len(*stack)-1]
	return result
}

func main() {
	var stack intStack = make([]int, 0)
	stack.push(1)
	stack.push(2)
	fmt.Println(stack.pop())
	stack.push(3)
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
}
```

実行してみた.

```
2
3
1
```

問題なさそう.
MNCTF2017 賭博遊戯☆★★

#問題

http://mnctf.info/mnctf2017/top.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a11bc44d-77d2-e339-c56b-1941e4ca23a5.png)

#解いてみた

リンクをクリックしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f68a98f1-80fa-29b4-4e8a-1677dfe86b4e.png)

予想のプルダウンは1～6。
掛け金は1～5、10、20です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/42b1c449-4fdf-f991-a9c6-9b0bec08d596.png)

適当にかけてみるとサイコロなので外れまくります。
そして持ち金がなくなってもBETすることができてマイナスになるだけだということもわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5148ed3f-1fa3-99f4-e638-f52fd7751449.png)

正解するとBETの5倍もらえることがわかりました。
真面目にやると37337にするのは厳しそうです。

プルダウンのvalueを変えれば行けそうだなと思ってHTMLいじろうと思ったら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ae6ed0a4-8a4f-ea3c-d9c9-bab2c55db4cb.png)

へんなデバッガー処理が入っていてちゃんと動かない。
パケットを書き換えればいいのかなぁと思ってwiresharkで通信を見てみる。

と思ったら何も通信が起きない。
ローカル環境で完結している画面のようです。

htmlファイルをダウンロードして、ローカルで動かしてみる。
BETしまくっても何も画面が動かない。
ローカルでは動かないようです。。。

ということは何も操作ができそうないので、やはりサーバにあがってるHTMLのデバッガーをどうにかするしか道はなさそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0c600bbe-9daf-056a-eeb0-e7efa3a176bd.png)

ポーズされているときの再実行ボタン？を長押しすると右△が出てきてこれを押すと一気に処理が進んでくれて何秒後かに一瞬BETボタンが押せることがわかった。
なのでBETボタンを連打していればなんとか1回は押せる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/86ebee40-05ce-4001-96e1-7eacea989dc4.png)

試しに1のvalueを100にしてBETボタンを押してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/fb6ebab3-4190-1ec1-1a06-0f6e3efef606.png)

運よく2回押せた。
ということと100BTC損したということはvalueの値がそのまま反映されるということも分かった。
今持ち金が-103ということは37337にするには

```
37337 - (-103) = 37440
```

たぶんサイコロは当たらないので-37440をvalueに設定すれば-37440が引かれるからマイナスのマイナスでプラスになる作戦。
もしサイコロが当たったらやり直し。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d703e10e-4e9a-55e0-1fdf-d52f49661490.png)

あー設定ミスでダメでした。。。
アホすぎる。。。

```
37337 - 37340 = -3
```

で、再度行います。
マイナスのマイナスで3を設定すればよいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e2047a53-67f2-d8ec-d1d0-0b7435653a11.png)

ポップアップが出てきました。
Jupyter notebook nbextensions snippet登録

# はじめに 
snippet登録に苦労したので、自分用のメモとして記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232692/7caefb9a-9f34-d3e3-9cce-9bf38c3648be.png)

## jsonファイルがみつからない
初心者なので、こういう単純なところで躓きます。
検索してもみつけることができませんでした。
なので、半年くらい放置してました笑
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232692/7fa6b00a-442f-2d00-d880-6a27b1a97be0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232692/96f761ba-5cf8-3f9e-dba9-99d55c80c6e3.png)

ググったら教えてくれました。ありがとう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232692/d00d9fac-a457-d907-c063-82ae7bb88ee5.png)

後はファイルの中身を更新したらできました。これでsnippetが使えるようになった！
いっぱいsnippetに登録しよう！




## 異なる環境で、snippetが見当たらない

複数の環境を使用していると（Anacondaで）、その環境に再度nbextensionsをダウンロードする。
snippetファイルが見当たらず、右往左往していたところ、この記事に救われました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232692/304631e1-e7d5-4930-b884-69d5337d318b.png)

追記

jupyter --data-dirコマンドを打つ
パスが出てくる。
そのパスをエクスプローラーに貼り付ける
あとはnbextensions\snippets\snippets.jsonまでクリックしてみつける。



### 参考リンク
- https://qiita.com/s_yaginuma/items/cd11944921711663a4b6
- https://stackoverflow.com/questions/47606886/jupyter-nbextensions-directory
- https://chayarokurokuro.hatenablog.com/entry/2019/11/02/015051
Javaで複数値の最小公倍数を求めるサンプルソースコード

# ソースコード

```java:Main.java
package src;
import java.util.ArrayList;

public class Main {
	public static void main(String[] args) {
		int valueLCM = 0;
		ArrayList<Integer> list = new ArrayList<>();
		list.add(4);
		list.add(6);
		list.add(9);

		for(int index=0; index<list.size()-1; index++) {
			if( index==0 ) {
				valueLCM = calcLCM( list.get(index), list.get(index+1) );
			} else {
				valueLCM = calcLCM( valueLCM,        list.get(index+1) );
			}
		}
		System.out.println(valueLCM);
	}

	private static int calcLCM(int val1, int val2) {
		int maxValue = Math.max(val1, val2);
		int minValue = Math.min(val1, val2);
		long val3    = maxValue * minValue;

		if(minValue==0) return maxValue;

		int temp;
		while( (temp=maxValue%minValue)!=0 ) {
			maxValue=minValue;
			minValue=temp;
		}

		return (int)(val3/minValue);
	}

}
```

# 補足
ユークリッドの互除法による最大公約数を求めてから、
最小公倍数を求める。
Craft CMS で関連付けと関連付けられてるエントリの表示ができる Relations プラグイン

> Relations
> https://plugins.craftcms.com/relations

関連付けと関連付けられてるエントリの表示ができるプラグインっぽい。

似たようなのは Element Map かな。

> Element Map
> https://plugins.craftcms.com/element-map

CMS標準のエントリフィールドじゃないのを使う必要性があるときには検討してもいいのかもしれない。
VSCodeでPythonファイルを開いた時に、インデントが8スペース分で認識されることがある

## 解決したい問題
Visual Studio Codeでpythonファイルを開いた時にインデントが8スペース分で認識されることがありました。
（「Tab Size」は4に設定されている。）
調べた時にパッと求めている情報が手に入らなかったので備忘録として記事にします。

![20190824_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157383/3b678506-06ce-cce1-ec87-0931bc7df7bb.jpeg)
## 解決方法

設定の「Editor:Detect Indentation」を無効にする。
setting.jsonを編集する場合は、以下の値をfalseにする。
"editor.detectIndentation"

![20190824_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157383/a9ed07ec-54b8-4016-d212-4a9610f43fb4.jpeg)

設定を変更すると通常通り4スペース分として認識されるようになる。

簡単ですが以上になります。
VPCに所属したLambda関数からS3に通信するために

# 本題

LambdaからS3のドキュメントを取ってくることは簡単だが、LambdaをVPCに所属させることで、S3への通信が不可能になってしまう。
それを回避するためには、以下の2通りの策がある。

- S3 の VPC エンドポイントを利用する
- NAT ゲートウェイを設定する

S3のVPCエンドポイントを作成するほうが簡単であると思ったため、ここではVPCエンドポイントを作成する方法を紹介する。
手順は以下のとおりである。

- VPCの管理コンソールに行く
- エンドポイントを選択し、エンドポイントの作成を行う
- 「サービスカテゴリ」は「AWSサービス」、「サービス名」は「com.amazonaws.ap-northeast-1.s3」、VPCは適用したいVPCを選択し、適当なルートテーブルを選択する、ポリシーはフルアクセスにする

この設定を行うことで、VPCに所属したLambdaからS3に対してアクセスすることができる。

# 参考

[NATゲートウェイ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html)
aptコマンドの対話形式での応答を自動入力する

Ubuntuのaptコマンドによるパッケージのアップグレード、インストール作業を非対話形式で行う方法です。

# 背景
EC2インスタンス作成時にapt upgradeを「ユーザーデータまたは設定スクリプト」に登録しましたが、対話式の応答が求められてしまったようで、EC2インスタンス作成時の自動実行が失敗しました。

そこで、Ubuntu18.04をインストールする際に、「ユーザーデータまたは設定スクリプト」に追加の構築スクリプトを設定することで、インストール作業を簡略化する方法を調べました。

# 目的
aptコマンドによる非対話形式によるアップグレードが出来るようにする。

# 利用するサービス
- EC2

# 対象OS
- Ubuntu 18.04
- Ubuntu 17.10
- Ubuntu 17.04
- Ubuntu 16.10
- Ubuntu 16.04

# 手順
[Debian 管理者ハンドブック](https://debian-handbook.info/browse/ja-JP/stable/sect.automatic-upgrades.html)にある様に、以下のようにすることで対話式の応答をせずに、パッケージのアップグレードが出来ます。

```
export DEBIAN_FRONTEND=noninteractive
apt update
yes '' | apt -y -o DPkg::options::="--force-confdef" \
    -o DPkg::options::="--force-confold" upgrade

```

パッケージのインストールを行う場合には以下のようにします。
以下の例では、apacheとawscliをインストールしています。

```
export DEBIAN_FRONTEND=noninteractive
yes '' | apt -y -o DPkg::options::="--force-confdef" \
    -o DPkg::options::="--force-confold" install apache2 awscli

```

# まとめ
aptによるパッケージのインストール中に出る選択肢に対して自動回答するようにすることで、EC2でのOS構築が楽になりました。

# 参考サイト
[Debian 管理者ハンドブック](https://debian-handbook.info/browse/ja-JP/stable/sect.automatic-upgrades.html)
素人がiPhoneアプリを作った話＜開発したアプリの機能の構成＞

盛り込んだ機能と使ったツールは次の通りです。多少記憶がすでに曖昧なので、間違っているものもあるかもしれません。

#メッセージ表示画面（ホーム）
励ましメッセージが120ほどJSON形式で記述されており、JavaScriptでOnsenUIで作ったレイアウトのCardにランダムに画面の起動ごとにピックアップされたメッセージが表示される仕組み。画面下のホームボタンを押したり、別の画面から戻ったりすることでもシャッフルされるようになっています。

+ JavaScript 
+ JSON

# ローカルノーティフィケーション機能
これが２番目に苦労した機能。外部のサーバーからお知らせとして送る形式をとると、オフラインで定期にお知らせを出すことができないことと、バックエンドのプログラミングが全くわからなかったのと、勉強しようにもフロントエンドほど情報がないため、アプリ内部からお知らせを表示させる必要があるとわかりました。
かといって自分でアプリを起動していないときにどうやってバナーを表示させるのかなど、スクリプトを組むことができず、困って調べまくってプラグインがあることを突き止め、それがmonacaで動くかなど調べ、cordovaのプラグインなら組み込めると踏んでこのプラグインを入れました。
素人の私にはデバッガを作ってフライトチェックをするのがまた一苦労でした。
できればユーザーが自分で気に入ったメッセージを選んだり、ランダムに数種類のメッセージを表示させる、時間の間隔を選んで設定するなどができればよかったのですが、当時の私には現状が精一杯でした。

+ ローカルノーティフィケーション設定画面 
+ Cordova Plugin　https://github.com/katzer/cordova-plugin-local-notifications

#SNS機能

これは、このアプリの中で一番苦労した機能です。
一度クラウドファンディングの公約したプロジェクト完了に間に合わないので諦めた機能でもあります。
バックエンドのプログラムの問題もあって、自分一人では到底無理だと思いました。
でも、Appleに機能が貧弱でこんなの認められないと却下されたため、これを頑張るしかないとクラウドファンディングのプロジェクト完了を2ヶ月延ばしてもらい、調べまくってWP REST APIを使えば、WordPressをバックエンドに仕立ててSNSを作れるんじゃないかと頑張った！
最初はフレームとして丸々WordPressを表示させる方式にしたら、それも却下されました。
問題はメンバーオンリーにすることで、そのシステムがWP REST APIに対応していないのではないかなどたくさんの調べごとと勉強も必要で、よく2ヶ月であそこまでできたと自画自賛しています。
Restlet Clientを使ってテストなどを行いました。
OAuthも使ってユーザーの個人情報が守られる仕組みも作りましたが、ライセンスが高いのでGoogleの広告費などと合わせると毎年赤字です。

+ WordPress API
+ OAuth
+ jQuery
+ Ajax
+ 利用者制限: Ultimate Members 

##SNS機能の各ページと機能
ユーザー登録、ログイン、タイムライン、投稿、削除、アカウント削除、投票ができるようにしました。

###ユーザー登録
登録画面でメールを送信、届いたメールからURLリンクに飛んでWordPressのUltimate Membersの登録画面へ行き登録する。

###ログイン画面
アプリ内からWP REST APIを使って行う。認証部分とユーザー名やなどをローカルストレージに保存させたりするのに苦労しました。

###タイムライン
画面の表示がトリガーとなってAjaxでリクエスト、取り込んだデータをjQueryで整形して投稿を投稿順にOnsenUIでList Itemとして流し込んでレイアウトする。

###投稿画面
アプリ内からWP REST APIを使って行う。140文字の制限にしたがって入力可能文字数のカウントが出る仕組み。

###管理画面
アプリ内から自分の投稿の削除できる。自分の投稿だけが一覧になる。投稿ごとに削除ボタンが付いている。

###投票機能
バックエンドとしてフニクラを使って、投票機能（いいね的なボタン）を追加。monacaのサンプルにあったものを流用しています。サッドボタンをタップすると発信。UUIDで識別して、投稿の番号ごとにカウントし、数値が表示される。サッドボタンはタップされるとハッピーボタンに変わる。自分のタップは色がグレーからピンクになる。

#読み物 
月2回WordPressの投稿を更新しています。これがRSSリーダーでレイアウトされるページです。投票機能はmonacaのサンプルにあったものを利用しています。

+ RSSリーダー
+ Ajax, jQuery
+ 一覧画面
+ 投票機能
+ バックエンド：フニクラ 

アプリはこんな感じです。
![collage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193243/334294ed-85bd-8de1-c4df-f767c4acceb7.jpeg)

購入してくださる方はこちらで是非！！！:point_down_tone2::heart_eyes:
https://itunes.apple.com/jp/app/pom-squad/id1299381222?mt=8

次回は全体のページ機能でやりたかったこととできなかったことをまとめます。
Mac mini 2018 マシン名変更（macOS Server 対応編）

# マシン名変更に必要な３つのこと
  1. **「共有」でマシン名を変更**
  2. **「ネットワーク」のWINSの設定でNetBIOS名を変更する**
  3. **macOS Serverのマシン名設定を変更する**
  4. **ホスト名の確認**

## 1. **「共有」でマシン名を変更**
　システム環境設定の「共有」でマシン名を変更します。変更箇所は２箇所です。
　1. **「コンピュータ名」の変更**
　2. **「編集」ボタンから変更 **

### 「コンピュータ名」の変更  
  「システム環境設定」>>「共有」 >> 「コンピュータ名」欄を変更します。ここは日本語が入っている場合とかありますが、裏ではそれがアルファベットに直されて設定されていることが多いです。
しかし、ややこしいので、DNSに登録できるようなアルファベットに直してしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/8adaf1e9-506f-fdaa-296b-08a66e9ca2f2.png)

図赤枠の部分を新しい名前に変更してください。

### 「編集」ボタンから変更
  「システム環境設定」>>「共有」 >> 「コンピュータ名」欄に、「編集...」ボタンが存在します。 こちらでコンピュータ名を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/5b09e6ee-b9fe-3b8f-0e00-a618edf7b937.png)

図赤枠の部分を新しい名前に変更してください。


## 2. **「ネットワーク」のWINSの設定でNetBIOS名を変更する** 

WINS参照の設定でNetBIOS名を変更します。
NetBIOS名とは、Windows環境における名前解決の仕組みで指定するマシン名のことです。
「システム環境設定」>>「ネットワーク」>>対象のデバイス>>詳細ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/4884269c-71c0-79a3-f56a-2de061fd15fe.png)

次に、WINSタブをクリックして、NetBIOS名のところを変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/9d310afb-14e6-dd97-4899-5a3e2c03f0f1.png)
 

## 3. **macOS Serverのマシン名設定を変更する**
これはmacOS Serverを入れてらっしゃる方の名前変更方法です。
まず左側のメニュー最上位に現在の名前の項目があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/285b2270-d328-684a-b3cd-589bac753916.png)

すると、ホスト名変更ウィザードが立ち上がります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/23ee4308-5d14-e99b-211c-c7461b1fe849.png)

ここでは、対象のアクセス方法を選択して下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/7f0d0aef-f59a-5127-a356-e2470838e0c9.png)


コンピュータ名とホスト名を入力します。
ここで、ホスト名はドメイン名も含む名前を入力する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/d3e03aee-de91-2480-eaac-68415ab3c8e2.png)

これで、ホスト名が変更されました。

## 4. **ホスト名の確認**
ホスト名の確認方法はいくつかあると思いますが、Terminalで変更されているか確認しましょう。
Terminalの起動方法は以下の通りです。
起動はDockにあるLaunchpadから行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/e679f4ce-78d4-fc75-121b-00a48343fdc1.png)

「その他」の中に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/d0b05fda-0994-f6f4-b125-1ad70c952d68.png)

「ターミナル」を選択すると、ターミナルが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/6c390d67-409b-5750-1a78-c3206315b888.png)

すると、図の箇所でホスト名を確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132084/7b7aef62-a448-0932-aa6e-e811c7d549ac.png)
PycharmのProject:Interpreterで、PoetryのPythonを指定する

## Poetry

Poetryはpythonのモジュール/パッケージ管理ツールです.
最近 pipenv の代わりに使い始めました.
参考）https://org-technology.com/posts/python-poetry.html

普段手元でサクッとコードを書くぶんには、特段Poetryの便利さは体感できてないです（pipenvとそんなに変わらない）
パッケージ配布とかをするのであれば、恩恵があるのかなと思っています.

### Poetryのインストール先

Poetryの設定やコマンドからpythonのインストール先がサクッとわかるのかなと思ったら、少し探したので覚書き的に書いておきます.
私の場合、以下のpathでインストールされていました.

```bash
ls ~/Library/Caches/pypoetry/virtualenvs/dev-py3.6/bin/python
```
`dev-py3.6` の部分はインストールしたpythonのバージョンによって異なるはずです.

こちらのパスを Pycharmの `Project:Interpreter` に設定しましょう.

## Pycharmの設定

Pycharmでは御存知の通り `Project:Interpreter` の設定からPythonモジュールを読み込みます.
PoetryがインストールするPythonを指定しないと、Pycharmに `Unresolved Reference 'hogehoge'` で怒られてしまいます.

1. PyCharm -> Preference -> Project:Workspace -> Porject Interpreter
   と進みます.
   <img width="1006" alt="Preferences_と_Workspace____Workspace__-_____merpay-creditscore_features_composer_v20_dags_dag_prediction_py__Workspace_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305743/9862b222-5db7-e38e-0867-8d734d5f0d6c.png">
2. 右端の歯車をクリックして、 addを選択します
   <img width="1006" alt="Preferences_と_Workspace____Workspace__-_____merpay-creditscore_features_composer_v20_dags_dag_prediction_py__Workspace_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305743/74ab3480-dcce-f0a6-4cff-0a452b6e9162.png">

3. Existing environmentにチェック. パスからPoetryのインストールしたPythonの選択します.
<img width="1001" alt="Add_Python_Interpreter_と_Preferences.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305743/a7b52a60-24ee-0fcb-4367-f4d4e0de783c.png">
↓
<img width="722" alt="Add_Python_Interpreter_と_Preferences.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305743/71346d39-93ea-963e-9116-6956d4f8a0b3.png">

4. OKを押してダイアログを閉じると、設定が反映されます. 
<img width="1016" alt="Preferences_と_Workspace____Workspace__-_____merpay-creditscore_features_composer_v20_dags_dag_prediction_py__Workspace_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305743/f2e1fcb3-c35d-2178-7fff-021871570d8c.png">

## おまけ

私のよく使うpoetryコマンド（alias）

```bash
# poetry
alias po='poetry'
alias poa='poetry add'
alias poc='poetry config'
alias por='poetry run'
alias porm='poetry remove'
alias pos='poetry show'
```
エージェント指向＋サブジェクト指向＋オブジェクト指向＝新たなプログラミングパラダイム～プログラミングのあり方についての研究と考察③

##はじめに

どうも、こんにちは。
前回は簡単な例え・事例をつかって、「エージェント指向」、「サブジェクト指向」、「オブジェクト指向」について説明してきましたが、
今回は応用的な例え・事例をつかって説明していきたいと思います。(ところどころ、間違っていることもあるかもしれませんが・・・)
早速ですが、今回もどうぞお付き合いください。


##本文

今回は、”自動車が走るという現象”を、エージェント、サブジェクト、オブジェクトをつかって説明したいと思います。
今までの記事を読んでくださった方なら大体察しがつくと思いますが、この場合には、
自動車が「オブジェクト」、自動車を運転するのが「エージェント」、”自動車(オブジェクト)と運転手(エージェント)の相互のやりとりを受け持つのが「サブジェクト」となります。そして、それぞれが独立したスレッドとして実行されることとします。(３者のスレッドです)。

※ここからが例え・事例的な説明となります。
ここで、運転手はすでにクルマにキーを差し、エンジンを点火させ、駐車場から出て視界の開けた道にいるとします。
運転手(エージェント)は、視界の開けた道には、横着にも道を横切ろうとする歩行者や、危険な対向車がいないとします。
まず、運転手はこれを確認します。これは、サブジェクトからエージェントに状況が通知されることに対応します。
そして、前述のとおりに安全を確認した運転手はアクセルペダルを踏みこんで加速します。これは、すでにこのときにサブジェクトからエージェントに、”アクセルペダルを踏みこんで加速することについての許可”、いいかえれば「権利・権限」が与えられているということになります。

ついで、アクセルペダルが踏み込まれたことを、自動車と運転手の相互のやりとりを受け持つ仕組みであるサブジェクトがこれを検知して、
運転手(エージェント)から自動車(オブジェクト)へと、”アクセルペダルが踏み込まれた”というメッセージをサブジェクトが送ります。
※実際には、これは、”メソッド呼び出し”によって実装されるのですが、メッセージを送る方式でもよいかと思います。

そして、メッセージを受け取ったオブジェクト側のスレッドがこれを処理します。メッセージに合わせたプロパティ(あるフィールドに対するゲッターとセッターの組)を呼び出します。このばあい、”アクセルペダルを踏みこんでいるので”、アクセルペダルの状態を変更するセッターを呼び出すことになります。そして、オブジェクト側のスレッドが、アクセルペダルがある一定以上の力で踏み込まれたことを検知して、エンジンの回転数を上げます。

つづけて、オブジェクト側スレッドが、エンジンの回転数がある一定以上上がったことを検知して、エンジンの回転数をタイヤの回転数に変換します。さらにつづけて、タイヤの回転数を速力に変換します。やはり、オブジェクト側スレッドが、速力を自動車本体の(つぎの瞬間の)位置に変換し、自動車本体のフィールドにセットします。
(ここまでは、オブジェクトの持つ「トリガー」が連鎖して呼び出されています)。
※第１回目の記事には、「トリガー」とは、”エージェントが行動をとるとき、これをイベントとして、一定の処理や手続きを実行する”ものとして定義していますが、これは間違いでした。正しくは、”エージェントが行動をとるときや、エージェントがその結果を受け取るときに操作・手続きを実行するもの”でした。

最後に、サブジェクト側スレッドが、自動車本体の位置の変更を検知して、エージェント側スレッドに依頼して、エージェントの持つフィールドにセットします。(これで、自動車の位置の変更に合わせて、これに乗っている運転手の位置も変更されることになります。)

以上が、”自動車が走るという現象”についての説明です。

ちなみに今回の余談ですが、エージェント、サブジェクト、オブジェクトのそれぞれが独立したスレッドとして実行され、この３者のスレッドにより、一つの「コンテナ」が形成されます。
つまり、コンテナとは、３者のスレッドをまとめた一つのプロセスでもあるということです。
「コンテナ」以外には、シーンという考え方もあり、まだまだ説明は尽きませんが、今回はこのくらいにしておきます。

以上が今回のお話です。
いかがでしたでしょうか？
では今回はこれで終わりにします。
どうもお付き合いくださり、ありがとうございました。
bash でディレクトリ内のファイル数を取得したい【大量のファイル数カウント】

> 特定ディレクトリ内の**大量のファイルの数を知りたい**。
>
> 数万ファイルあるためか **`du` コマンドでは遅い**ので、なるべく速く調べられないか。

ここ最近の Qiita 記事で[「bash ファイル数 ディレクトリ内」でググって](https://www.google.com/search?q=site:qiita.com+bash+%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E5%86%85+%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%95%B0)もタイトルからヒットしなかったので、自分のググラビリティとして。

## TL; DR <sub><sup><sub><sup>（今北産業）</sub></sup></sub></sup>

1. カレント・ディレクトリ内のファイル数一覧

    ```bash
    ls -p -U1 | grep -v / | wc -l
    ```
2. 指定したディレクトリ内のファイル数一覧

    ```bash:
    # /root/data の場合
    ls -p -U1 /root/data | grep -v / | wc -l
    ```
3. 応用（指定したディレクトリ内のファイル数を表示する）

    ```bash:bashサンプル
    #!/bin/bash
    
    list_dir=(
      '/root/data'
      '/usr/me/data'
      '/usr/me/huge/data'
    )
    
    for path_dir in ${list_dir[@]}; do
      echo 'Path:' $path_dir ' Files:' $(ls -p -U1 $path_dir | grep -v / | wc -l);
    done
    ```

- [オンラインで動作を見る](https://paiza.io/projects/KyeCmBP2LfgNcGolrIwtmg) @ paiza.IO

## TS; DR

```bash
ls -p -U1 | grep -v / | wc -l
```

- `ls`：一覧表示
- `-p`：ディレクトリの場合はファイル名の末尾に `/` を追加
- `-U1`：ソートさせない（ファイルが大量なのでソートさせると遅いため）
- `|` `grep -v /`：パイプから受け取ったディレクトリ（`/`付きのファイル名）を除外
- `|` `wc -l`：パイプから受け取った行数をカウント

### 所感と経緯

機械学習でディレクトリ内に設置した大量のファイルをカウントする必要があったのです。下手に `ls` や `tree` しようもんなら、鉄砲玉で帰ってきやしません。

今までカレントディレクトリ内のファイル数をカウントする場合 `ls -U1 | wc -l` としていました。しかし、**サブ・ディレクトリが含まれていると、それらもカウントされている**ことに気づきました。

確かに、`ls -U1` だけを実行するとディレクトリも渡されています。`wc` コマンドにパイプ渡しする前にディレクトリだけ除外できればいいのですが、`ls` コマンドに `-p` オプションを付けてもファイル名の末尾に `/` と付くだけでした。

悩み始めたのでググってみたところ「`grep` で `/` 付きのファイルを `-v` で除外すればいい」という情報を得て、なんたるちあ。簡単なことでした。

ちなみに `ls` コマンドの [`-F` オプションを使った方法の情報もあった](https://qiita.com/stc1988/items/e3a1d7dccafe4ab573fa#comment-0a9fa80e52d73653110e)のですが、遅かったので `-p` `-U1` オプションを使っています。

```shell-session:-pと-Fオプションの速度比較
seq -f "file_%06g" 100000 | xargs touch

time ls -p -U1 | grep -v / | wc -l
time ls -F     | grep -v / | wc -l

# 結果
# real	0m0.060s
# user	0m0.026s
# sys	0m0.047s
# 
# real	0m0.450s
# user	0m0.263s
# sys	0m0.199s
```
- [オンラインで違いを見る](https://paiza.io/projects/9uJK0NTd2-Fioh0CUDdI1Q) @ paiza.IO

## 参考文献

- [List only regular files (but not directories) in current directory](https://unix.stackexchange.com/questions/48492/list-only-regular-files-but-not-directories-in-current-directory) @ StackExchange
- [ディレクトリ内のファイル数をカウントする](https://qiita.com/stc1988/items/e3a1d7dccafe4ab573fa) @ Qiita
「CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.」の対処法

# 問題

Windows10＋Anaconda＋GitBashの環境で「CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.」と出ました。

ログはこちらです。

```
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
If using 'conda activate' from a batch script, change your
invocation to 'CALL conda.bat activate'.

To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - cmd.exe
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.
```

# 対処法

メッセージに書いている通りに、.bashrcを修正したら解消しました。

## 修正前

`conda activate base`

## 修正後

`conda.bat activate base
`

# おわりに

.bashrcにCALL文を書いてもダメだったので参考になる人がいれば幸いです。

# 環境

Windows10 
Git(Bash) 2.21.0
Anaconda(conda) 4.7.10

# おまけ

Jenkinsのbat処理でconda activate するときは逆にCALLがないとダメです。
CALLなしにconda activateすると、conda.batが終了したら元のbat処理も終了してしまいます。
そこで、conda activate をCALL呼び出しする必要があります。

# おまけのおまけ

[ウチの子供にこんな迷路でひらがなを教えていて、結構よい感じでした。](https://めいろ.com)

こちらのサイトで古いですが公開しているので良かったら見てね。

![A_Z_A_44_1_out_square.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364248/9261f58c-6774-4c07-7c83-43bebede4666.png)