OmniAICreator/Qiita-1.07M huggingface dataset:
railsチュートリアル 第五章 BootstrapとカスタムCSS

####BootstrapとカスタムCSS
前章では多くのHTML要素にCSSクラスを関連付けました。
CSSベースでレイアウトを構成する際に高い柔軟性を与える。
ラスの多くは、Twitterが作成したフレームワークであるBootstrap特有のもの
Bootstrapを使うと、洗練されたWebデザインとユーザーインターフェイス要素を簡単に導入できるCSSフレームワークを
HTML5アプリケーションに追加できます。

この節では、サンプルアプリケーションにスタイルを追加するために、カスタムCSSルールとBootstrapを組み合わせて使う。

注目すべき点は、Bootstrapを使うことでアプリケーションを```レスポンシブデザイン```（Responsive Design） にできる

bootstrap-sass gemを使ってRailsアプリケーションに導入する。
####Gemfileにbootstrap-sassを追加

```
source 'https://rubygems.org'

gem 'rails',          '6.0.3'
gem 'bootstrap-sass', '3.4.1'
gem 'puma',           '4.3.6'
.
.
.
```
```bundle install```を実行して、Bootstrapをインストール

```
$ bundle install
```
本チュートリアルでは（簡潔のために）すべてのCSSを1つにまとめる方針を採っています

```
$ touch app/assets/stylesheets/custom.scss
```
@importを使って、Bootstrap（とそれに関連するSprockets）を読み込みます。
####Bootstrap CSSを追加する

```css
@import "bootstrap-sprockets";
@import "bootstrap";
```
2行で、Bootstrap CSSのフレームワークを導入しています。
導入後、Webサーバーを再起動させると、アプリケーションに反映させている。

プレビューで確認 成功

Webサイト全体にわたってレイアウトと個別のページにスタイルを与えるためのCSSを追加
####すべてのページに適用される共通のスタイルをCSSに追加する

```css
@import "bootstrap-sprockets";
@import "bootstrap";

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}
```

```css
body {
  padding-top: 60px;
}
```
ページ上部に60ピクセルの余白を追加します

```css
.center {
  text-align: center;
}
```
centerクラスにtext-align: centerプロパティを関連付けています
.center冒頭のドット.は、このルールがクラスに対してスタイルを適用
冒頭がポンド記号#で始まる場合は、そのルールがCSSのidに対してスタイルを適用することを示します。
centerクラスに属している（divなどの）タグの内側にある要素が、すべて中央揃えになることを意味しています
洗練されたタイポグラフィーを利用するためのCSSを追加する
####洗練されたタイポグラフィーを利用するためのCSSを追加する

```css
@import "bootstrap-sprockets";
@import "bootstrap";
.
.
.
/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: #777;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}
```
プレビューで確認　成功したか分からない。

いくつかのルールをサイトロゴに追加します
####サイトロゴにCSSを追加する

```css
@import "bootstrap-sprockets";
@import "bootstrap";
.
.
.
/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
}

#logo:hover {
  color: #fff;
  text-decoration: none;
}
```
color: #fffは、ロゴの色を白に変更

####演習
1.ネコ画像をコメントアウト,ブラウザのHTMLインスペクタ機能を使って、コメントアウトするとHTMLのソースからも消えていることを確認
確認　成功

2.コードをcustom.scssに追加し、すべての画像を非表示にしてみてください
home.htmlにペースト

```css
img {
  display: none;
}
```
プレビューで確認　成功
Git LFS 利用時の Push で HTTP 413 エラーが出た時の対応

# はじめに
どうも、「バーチャルためにならない改変お姉さん」の水無月せきなです。
VRChat のために使っている Unity プロジェクトのバージョン管理を Git でしていて、合わせて Git LFS も利用しているのですが、これでたまにエラーが起きます。
フレンドさん[^1]に対応方法の１つを教えていただいたのですが忘れかけていたので、備忘録として残します。

# 環境
Windows 10 Home（ 20H2 ）
Git version 2.32.0.windows.2
Git-LFS /2.13.3 (GitHub; windows amd64; go 1.16.2; git a5e65851)
Sourcetree 3.4.6
リモートリポジトリ：Azure DevOps

# Push 時に LFS で HTTP 413 エラー
ローカルでのコミットはうまくいきますが、リモートへのプッシュ時に HTTP 413 のエラーが出ることがあります。
原因としては、Azure と LFS 絡みでファイルサイズの制限に引っかかているらしいです。

対応として、当該の LFS が有効な Git リポジトリのディレクトリで右クリックから Git Bush Hereを選択。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1843472/eb7616e9-12c7-7aa8-b7a0-5b31f24c5c5f.png)
開いた Bash で以下のコードを実行してから再度プッシュすると解決することがあります。

```Git:Git_Bush
git config http.version HTTP/1.1
```

これでもエラーが発生する場合は、別な解決策を探さなければいけません。

# 余談：HTTP 503 エラー
413 のエラーが発生せず一安心した時に、503 のエラーが発生したことがありました。
サーバーが一時的に使用不可というステータスコードですので、リトライするしかありません（ですよね？）。
実際、私ももう一度プッシュしたら無事に完了しました。

# おわりに
他にも遭遇しうるエラーやその対処法をご存知の方がいらっしゃいましたら、教えていただけると幸いです。

[^1]: たびたびお世話になっている、にしのんさんに教えていただきました。
jpsonic - dSub for subsonicでアクセスできない

なんでやん。

# 2021/09/19 追記
:::note warn
以下の方法でタイトル通りの問題は解決しますが、play:Subなどの以前使えていたアプリが使えなくなりました。
他のアプリを使っている方は注意してね。
:::

## 環境
Linux : Ubuntu20.04
Dockerによる仮想環境
traefikによるリバースプロキシ
OpenLDAPによるユーザー認証

使えるアプリ
iOS : Play:Sub
Android : subsonic for Android

使えなかったアプリ
dSub for subsonic をはじめ、いろんなアプリがダメだった。


### 調べたら以下が有力。
> https://github.com/airsonic/airsonic/issues/260
> https://bleepcoder.com/ja/airsonic/240477191/allow-ldap-auth-via-rest-api

ただ、対策がNginXだったので、traefikでsub_filterみたいな事ができんか探してたら、プラグインでできそう。

# 問題を要約
### DSubのリクエスト
> GET /airsonic/rest/ping.view?u=pogo&s=xxxxxxxxxxx&t=xxxxxxxxxxx&v=1.2.0&c=DSub HTTP/1.1

お返事
> `<?xml version="1.0" encoding="UTF-8"?> <subsonic-response xmlns="http://subsonic.org/restapi" status="failed" version="1.15.0"> <error code="40" message="Wrong username or password."/> </subsonic-response>`


### 公式のSubsonicのアプリ
> POST /airsonic/rest/ping.view?u=pogo&p=enc:xxxxxxxxxxxxxxxxxx&v=1.2.0&c=android HTTP/1.1

お返事
> `<?xml version="1.0" encoding="UTF-8"?> <subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.15.0"/>`


どうも上のリクエストだとAirsonic系列のjpsonicはちゃんと返事できないらしい。subsonicのリクエストだと返事する。

## 原因
LDAP認証だとはじかれるらしい。（jpsonicのデータベースに入ってるユーザーはログインできる）

# 対策
### traefikにプラグイン導入
> https://pilot.traefik.io/plugins/606d8063a316dece52c30c1c/subfilter

フィルターをインストールする。
リンク先の`Install Plugin`をクリックして、手順通りにやればとりあえずできる。

* traefik Pilotのトークンを発行する。
* プラグインを`traefik.yml`に呼び出すようにする。
* `middlewares`に設定。

```provider.yml
http:
  middlewares:
    jpsonic-dsub:
      plugin:
        subfilter:
          filters:
            - regex: subsonic
              replacement: madsonic
          lastModified: true
```
middlewaresの設定は[別の記事](https://qiita.com/peadhavu/items/0ffac33792e12fb0fef9)に書きました。

`madsonic`は、`jpsonic`や`airsonic`にかえたらダメだったので、`madsonic`である必要があるみたい。

# チラ裏

traefikに移行したのはいいが（昔はNginXだった）、エラーはくんだよな～

> Mixed Content: The page at 'https://おうちのドメイン/index' was loaded over HTTPS, but requested an insecure frame 'http://おうちのドメイン/home.view'. This request has been blocked; the content must be served over HTTPS.

これどうにかしたい。ウェブで再生できぬ……

あと、subsonicのアプリはいいのが多いが、どうも英語ばっかりでわからんかったりする……専門用語多かったりするしな。
アプリ作りたい欲が出てくるが、未知の世界だからすごいためらう。
flutter_hooksでプログレスバーをアニメーションする

# 背景
プログレスバーを無限にループさせる方法は非常に簡単ですが、flutter_hooksでプログレスバーを【時間】で推移させるアニメーション方法はWeb上でも記載少ないのでまとめました。
flutter_hooksには、デフォルトでuseAnimationのフックを備えているので今回はそちらを利用しています。

# 実装イメージ
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1424230/53833379-c0de-9c51-04e8-f5a91387e94c.gif)
※注: GIF的に無限ループしていますが、実装上は一回きりのアニメーション処理となっています


## プラグイン環境
flutter_hooks: ^0.18.0

# 準備
プラグインをインストールするために、pubspec.yamlのdependenciesにflutter_hooksを追加

```yaml:
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  flutter_hooks: ^0.18.0  # ←✨追加✨
```

# 実装
以下のflutter_hooksプラグインの公式[1]とこちらのQiita記事[2]を参考にして実装しました。
[1] https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useAnimation.html
[2] https://qiita.com/toda-axiaworks/items/f1f7acf9a636f52c67b3

もし、以下ソースコードを簡単に動かしたい場合は、[GitHub](https://github.com/ko-izumi/progress_bar_using_hooks)に置いたので参考にしていただければと。


```dart:
class HooksProgressBar extends HookWidget {
  const HooksProgressBar({Key key, @required this.progressTime})
      : super(key: key);

  final Duration progressTime;

  @override
  Widget build(BuildContext context) {
    /// forwardは1回きり。repeatで繰り返しの表現となりますが、プログレスバーなので1回で良いかなと。
    final controller = useAnimationController(
      duration: progressTime,
    )..forward();

    /// AnimatedBuilderを使うことがポイント✨✨これがないとアニメーションしない。
    return AnimatedBuilder(
      animation: controller,
      builder: (context, _) {
        return LinearProgressIndicator(
          value: controller.value,

          /// 色を変更したい場合も念のため、記載しておきます。微妙にハマったので。
          valueColor: AlwaysStoppedAnimation<Color>(Colors.orange),
        );
      },
    );
  }
}

```

参考のため、呼び出し元も記載しておきます。

```dart:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hooks ProgressBar',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Hooks ProgressBar'),
        ),
        body: Center(
          /// アニメーションに掛ける時間として、Durationクラスを渡す。仮で5秒を設定。
          child: HooksProgressBar(
            progressTime: Duration(seconds: 5),
          ),
        ),
      ),
    );
  }
}
```
【Laravel】コレクション型の空値

#はじめに#
　LaravelのEloquentを用いてgetメソッドやfirstメソッドで値を取得すると戻り値はCollection型になります。値がある時とない時で条件分岐させようとしてもemptyやissetなどでは判定ができません。

#isEmptyメソッド#
　Collection型の空値の判定にはisEmptyメソッドを使います。
公式ドキュメントを見てみましょう。
>isEmptyメソッドはコレクションが空の場合にtrueを返します。そうでなければfalseを返します。

実際には下記のように使います。

```controller.php
public function judge()
{
  $user_id = \Auth::id();
  $comments = Comment::where('user_id',$user_id)->get();
  return view('view',compact('comments'));
}
```

```view.php
  //・・・略
  @if($comments->isEmpty())
     <p>コメントがないとき・・・</p>
  @else
　　　　　　　　　　<p>コメントがあるときーー！！</p>
  @endif
```

これで、\$commentsにデータがなければ、if文の中身が、あればelse文の中身が表示されます。

#終わりに#
　公式ドキュメント最強！
docker-composeで修正が反映されない時


# 発生した事象
docker-compose.yml と同階層の.envを変えても反映されない。
DB_NAMEやDB_USERを変えてもMySQLWorkBenchで確認したら変わっていなかった。
ところがWEB_PORTを変えたらブラウザでそのポート番号を叩くと画面表示できた。


```.env
WEB_PORT=84
DB_PORT=3302
DB_NAME=cms_template
DB_USER=phper
DB_PASS=secret
```

# 原因
結論からいうと、今回はDBをvolumesで永続化しているので

```
docker-compose -up --build
```
では、WEBサーバとPHPサーバのコンテナは全消去して作り直していたが、
DBサーバのコンテナは前の設定のまま残っていたから。
そもそも永続化しているのだから当たり前と言えば当たり前だが、docker-compose.yamlの変数部分と.envばかり見ていてなかなか
気づけなかった。

調べている途中で便利コマンドを載せてくれている記事を見つけました。
以下のコマンドを打つと、.envの変数を代入した後の状態のdocker-compose.yamlを表示してくれます。
これを使うと変数名が間違っているのかそれ以外の原因かで切り分けられます。

```
docker-compose config
```

そしてこれが解決法のコマンド。永続化したボリュームごと初期化する。
これを打ってから、docker-compose -up --build をやり直せば反映されました。

```
docker-compose down -v --rmi local
```

消さずにDB名後から変えたいとかだとMYSQLコマンドで直接DBを触ることになるのかなと思います。
オブジェクトとインスタンス β版

# オブジェクトとインスタンス β版

## Note:

この記事は~~ほぼ忘れかけられている~~[しろくま＠胡瓜's Blog](https://shirokuma-89.github.io)のクラス解説の続きのβ版です。僕自身ハード担当でプログラムよわよわ人間です。こちらにβ版として投稿したらTwitter上のつよつよさん達が訂正・指摘してくれると信じて投稿させていただきます。

なお、正式版は後日ブログの方に書きます。

## β版を出すことによって確認したいところ

- そもそもの理解があっているか
- クラス自体はオブジェクトじゃなかった気がするがそこが不安（自分の中ではクラスはあくまで型でありそれを元にメモリ上に実態（=オブジェクト）にしたものがインスタンスであるという解釈）
- 画力がなさすぎてそもそも説明の絵として成り立っていない説

## この記事の目標到達点

- C++に出てくる用語のクラス、オブジェクト、インスタンスの三つの違いを理解する

なお[#1](https://shirokuma-89.github.io/20210822/), [#2](https://shirokuma-89.github.io/20210831/)の記事と同様、C++言語以外の言語との整合性は保証できません。（僕はJavaとか全く使えないので…）

またこのシリーズはあくまで『クラスに関して「なんとなくわかった」程度の理解を目指す記事』なので詳しい説明は省きます。C++を始めたばかりでクラスの概念が理解できておらずつまづいている人の救済を目的とした記事です。

## この記事で扱う範囲・扱わない範囲

### 扱う

- クラスとインスタンスの関係
- オブジェクトとは何か？

### 扱わない

- 動的なメモリ確保
- クラスの継承
- コンストラクタとデストラクタ

## クラスとは？

とある白熊がケーキ職人になりました。改良に改良を重ねようやく完成しました。

![IMG_A6C13AFAF6D4-1](https://user-images.githubusercontent.com/47915291/133863286-192ee42a-f3ea-4a7f-b4de-a303e37449ed.jpeg)

**この原作をクラスとします。**

## インスタンスとは？

一回作り方を習得したあなたはこれを元にいくらでも同じものを作ることができます。

![IMG_29C8453C6408-1](https://user-images.githubusercontent.com/47915291/133863501-6f8159a6-be16-45a1-897b-a53473eb5bd8.jpeg)

この原作のクラスを元にしてできたケーキのことをインスタンスと呼びます。

ひとつのインスタンスに注目してみてみましょう。

![IMG_BDB13B396A66-1](https://user-images.githubusercontent.com/47915291/133863639-552b0a9e-19c3-4e15-a229-879de4197559.jpeg)

ケーキを構成する要素としてクリームやイチゴソース、スポンジなどさまざまなものが挙げられます。これが変数や関数に当たります。食えるもんは全部変数や関数です。

では商品棚に作ったケーキを並べましょう。

![IMG_27FD6AE19083-1](https://user-images.githubusercontent.com/47915291/133864717-cfb73fdd-2e56-4aeb-8c47-d9bcf0977846.jpeg)

これでお客さんが利用できる状態になりました。注意しなければならないのはクラスは商品棚には並ばないということです。原型がなくなってしまったらそれを元にケーキを作れなくなってしまうからです。~~腐る？そんな現象は存在しない~~

このクラスのインスタンスを生成する一連の作業を「インスタンス化」と呼びます。

## オブジェクト is 何

説明の前に結論だけ述べると「商品棚に載っている全てのもの」がオブジェクトです。

商品棚に乗っているケーキは一種類ではないかもしれません。そもそもケーキすらなく、トッピング用のチョコ単体とか蝋燭かもしれません。

![IMG_06DE52446A5F-1](https://user-images.githubusercontent.com/47915291/133871127-9ab389c4-cd73-4c7e-a00b-c399a9326646.jpeg)

この商品棚に乗っている全てのものがオブジェクトです。それがインスタンス化されていない蝋燭単体やチョコレートであってもそれはオブジェクトです。

この商品棚というのは実際のプログラムではメモリに当たります。

このようにまとめると

- オブジェクトは商品棚に乗っているケーキである
- インスタンスはオブジェクトである

といえます。ただし後者に関しては逆は必ずしも成り立ちません。

![IMG_055B62F08AFF-1](https://user-images.githubusercontent.com/47915291/133871357-5016e213-bd1a-41f6-b05a-08772355521e.jpeg)
PICと気圧センサで高度計を作成する

# 動機
趣味でロードバイクをやっており、GPSによる高度情報は精度が低いようで、走りながら高度情報を正しく把握したくなりました。
特に獲得高度といわれる、通算でどのぐらいの高度上がったかという情報は負荷の目安になるため、走りながら把握したいと思っていました。
Garminを購入すればいいのでしょうが、予算超過ですので、自分で作成してみることにしました。
# 要件
要件をまとめてみました

- 小型であること(ロードバイクのハンドルに取り付ける想定)
- コイン電池(CR2032)で一定時間持つように低消費電力動作
- できる限り精度の良いセンサを利用する
- 視認性の良い表示デバイスを利用する

上記を満たすものとして、自分で開発環境があることから、マイコンはPIC(18F14K50)を利用し、気圧センサはLPS25HBを利用して作成することにした。表示デバイスは小型のグラフィック液晶を利用することにしました。

#回路図
PICとセンサとLCDをSPI接続している程度の簡単なものです。スイッチは2つ設けて、表示内容の切り替えや、高度補正用の操作を可能としています。
バッテリ電圧監視のためにADコンバータを利用し電池電圧を分圧して監視します。
下段のコネクタはPIC kit3と接続するプログラム書き込み用のコネクタです。

![PressPIC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/06c6d1f5-7f3e-bc70-52e2-a30db953b0d9.png)

### 主要部品リスト
- ＰＩＣ１８Ｆ１４Ｋ５０－Ｉ／ＳＯ
- 超小型グラフィックＬＣＤ　ＡＱＭ１２４８Ａ
- ＬＰＳ２５ＨＢ使用　気圧センサーモジュールＤＩＰ化キット

いずれも秋月電子で入手しました。小型にするために、PICはSOP20パッケージです。LCDのピンも1.28mmピッチの為、ユニバーサル基板は1.28mmピッチのものを利用します。
これらを配線し、CR2032用の電池ホルダを組み合わせてタカチのケースPS-65に入れます。

### 写真

気圧と温度を表示するモード
![DSC_0455.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/d0e0f7b2-77d9-3613-1bb6-a83dae1999c6.jpeg)

高度と獲得高度を表示するモード
![DSC_0453.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/c33154b6-3e8f-a559-ad1e-3e3de0648bbd.jpeg)

現在高度を設定するモードです。
![DSC_0449.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/50b275f9-d6fd-d432-baaa-873b48bd97e5.jpeg)

内部の様子1
![DSC_0445.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/88c18509-bb45-3477-1d0d-6c26ae26d8d2.jpeg)

内部の様子2
![DSC_0447.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/792c262d-1ef1-1762-1cef-a0f3e6044cb1.jpeg)

背面（穴はセンサの箇所です）
![DSC_0443.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/278efa2b-8090-feaf-5cdd-89eadf989f0f.jpeg)


# プログラム

流れはこのようになります。1秒毎にループしてデータを表示しています。
獲得高度ですが、気圧センサの誤差影響を避けるため、一定量以上の差が出たときだけ高度を加算するロジックになっています。

- 各種初期化実施
- ループ開始
    - 気圧・温度測定
    - 高度計算
    - 気圧が前回測定値と比較して下がっている場合、獲得高度を計算して加算
    - バッテリ電圧確認
    - 結果表示(気圧・温度　または　高度・獲得高度 電池状態は3段階でアイコン表示)
    - スリープ
    - WDTでウエイクアップ(1秒毎)
- ループ開始に戻る

# 動作確認

近くを散歩して高度を評価しました。
地図上の標高差は32mあるはずの坂道を歩いて上ったところ、この高度計での獲得高度は26mと表示されました。
どうやら、上のロジックの中の一定量以上の差が出た時だけ高度を加算する仕掛けの部分が悪さをして、実際よりも低めに出るようです、アルゴリズムの見直しが必要ですね。
PICで作成する場合、浮動小数点計算をおこなうと、どうしてもメモリサイズの制限が出てきます。その為Arudinoを利用したものを別途製作予定です。加速度センサを利用して、移動していることを検知し、その際だけ高度を加算する方法でこの誤差の問題を解消できないかと検討中です。
【Apex】【エラー】Non-selective query against large object type

#その日事件は突然起こった
運用中の本番環境、ケースレコードを作成したときに発生したエラー。

```
System.QueryException: Non-selective query against large object type (more than 200000 rows).
```
これまでは普通に登録できており、エラー内容も初めて見るものでした。
ログを見ていると、ケーストリガ内で実行されたのSOQLが悪さをしているようです。
問題のSOQLはこんな感じ↓

```
SELECT Id, Name, Phone FROM Account WHERE Phone IN :phoneNumbers
```
ケースレコードに登録されている電話番号をphoneNumbers（Set）に格納して、phoneNumbersで取引先レコードを検索しています。
何の変哲もない、どこにでもあるSOQLです。
直近のリリースなどはなく、サンドボックスでも再現ができません。なんだこれ～～。

#犯人はお前だ
エラー文で検索すると、Salesforce公式さんのヘルプページを発見
https://help.salesforce.com/s/articleView?id=000323572&type=1

ふむふむ、なんと20万件を超えると出ちゃうエラーのようです。
たしかに、本番環境には20万件強の取引先レコードができていました。サンドボックスで再現しないわけだ。

読んでいるとどうやらSQLを選択的にする必要があるらしいのですが、、、
すでに運用していて問題なく使えていた。
下手に改修するとリスクがあるし工数もかかる。

といことで、カスタムインデックス付与を依頼することにしました。

#サポートに問い合わせ
Salesforce公式さん、ご丁寧にこんなヘルプもありました。
https://help.salesforce.com/s/articleView?id=000335072&type=1

a. ●●●（組織ID）
b. SELECT Id, Name, Phone FROM Account WHERE Phone IN  ( '03-1234-5678','03-2345-6789','03-3456-7890')
c. ●●●(実行ユーザ名)
d. はい
e. Account 
f. Phone

必要な情報を書きました。今回の場合はPhoneで検索かけるのでこれにカスタムインデックスを付与してもらいます。

#そして平和がおとずれた
カスタムインデックス付与をしてもらうと、これまでどおりにケースレコード作成ができるようになりました。
急に身に覚えのないエラーが発生してビビった話でした。

#参考
https://help.salesforce.com/s/articleView?id=000323572&type=1
https://help.salesforce.com/s/articleView?id=000335072&type=1
(WSL2の)debian busterでgitのより新しいバージョンをインストールする

# 実行するコマンド

```shell
# buster-backportsを使えるようにする
# WSL2のdebianなら最初から使えるのでやらなくて良いはず
sudo apt edit-sources # 'deb http://ftp.debian.org/debian buster-backports main' という行がなければ追加する
sudo apt update

# buster-backportsを指定してgitをインストールする
sudo apt -t buster-backports install git
```

これで2021/09/18時点ではgit 2.20から2.30に上げることができました（`git restore`できるようになる）。

# backports

https://wiki.debian.org/Backports#Adding_the_repository

安定バージョンに各種パッケージの新しいバージョンを取り込むために用意されているレポジトリのようです。
手順は上記ページの内容を参考にしています。
【Python】変数代入について

<img src="https://img.shields.io/badge/MacOS-10.15.7-999999.svg?logo=apple&style=flat-square"> <img src="https://img.shields.io/badge/Python-3.8.2-3776AB.svg?logo=python&style=flat-square">



複数の変数に1行のシンプルなコードでまとめて値を代入する際の書き方。

### 複数の値を代入する場合の書き方

```Python
a, b = 10, 20

print(a) #10
print(b) #20
```

### 同じ値を代入する場合の書き方

```Python
a = b = 100

print(a) #100
print(b) #100
```
[Ruby] AtCoder過去問 B - Trained?

##はじめに
AtCoderの過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc065/custom_test

##B - Trained?
問題のシチュエーションに理解が苦しみましたが、、、w

とりあえず入力を受け取ります。

```ruby
n = gets.to_i
a = readlines.map(&:to_i)
```

続いて、答えとなる変数countと、光っているボタンを表す変数on_btnを用意します（変数の名前をつけるのが本当に苦手です）

はじめに光っているボタンは必ずボタン1なのでon_btnには1を代入しておきます

```ruby
n = gets.to_i
a = readlines.map(&:to_i)

on_btn = 1
count = 0
```

on_btnが2になったら処理を終了させるwhile文を書きます。
実際に配列aで光っているボタンを表すときは```a[on_btn-1]```となります。
添字（インデックス数）は0から数えますからね。

ボタンを押すたびにon_btnの値を光るボタンの値に書き換えていきます。

```ruby
n = gets.to_i
a = readlines.map(&:to_i)

on_btn = 1
count = 0

while on_btn != 2
 count += 1
 on_btn = a[on_btn-1]
end
```

この記述ではボタン2が光らない場合の処理が書かれていないので無限ループする可能性があります。
n(aの要素の数)以上countが大きくなる場合は配列aの中に2が存在していないか、2はあるけど2を通らない処理を繰り返しているかのどちらかです。

ですのでcountとnが同じ値になった時点で-1を出力させて処理をbreakで抜け出します。

```ruby
n = gets.to_i
a = readlines.map(&:to_i)

on_btn = 1
count = 0

while on_btn != 2
 count += 1
 on_btn = a[on_btn-1]
 if count == n
   puts -1
   break
 end
end
```

あとはcountを出力すれば完成です。

if文でcountがnよりも小さい数で処理が終わっていればcountを出力させます。

```ruby
n = gets.to_i
a = readlines.map(&:to_i)

on_btn = 1
count = 0

while on_btn != 2
 count += 1
 on_btn = a[on_btn-1]
 if count == n
   puts -1
   break
 end
end

if count < n
  puts count
end
```
【Jest入門】前後処理が呼び出されるタイミング~beforeEach、beforeAll、afterAll、afterEach~

# はじめに
Jestでテストを書いていて、DBのクリーンアップ処理やモックのリセットをする際に、```beforeAll```や```beforeEach```などを使う機会がありました。改めて調べると、呼び出されるタイミングが特殊なものもあったのでまとめました。


## 調査

describe関数をネストする例で、beforeEach、beforeAll、afterAll、afterEachの実行タイミングを調べてみました。


```javascript:timing.test.js
// 前後処理の実行されるタイミング
describe("テスト", () => {
  beforeAll(() => console.log("1 - beforeAll"));
  afterAll(() => console.log("1 - afterAll"));
  beforeEach(() => console.log("1 - beforeEach"));
  afterEach(() => console.log("1 - afterEach"));
  test("テスト1", () => console.log("1 - test")); //テスト1

  describe("ネストされたテスト", () => {
    beforeAll(() => console.log("2 - beforeAll"));
    afterAll(() => console.log("2 - afterAll"));
    beforeEach(() => console.log("2 - beforeEach"));
    afterEach(() => console.log("2 - afterEach"));
    test("テスト2", () => console.log("2 - test"));//テスト2
  });
});
````

## 結果

```shell
$ npm test jest-basic/src/timing.test.js

> jest-basic@1.0.0 test jest-basic
> jest "/Users/jest-basic/src/timing.test.js"

 PASS  src/timing.test.js
  テスト
    ✓ テスト1 (3 ms)
    ネストされたテスト
      ✓ テスト2 (3 ms)

  console.log
    1 - beforeAll

      at src/timing.test.js:3:27

  console.log
    1 - beforeEach

      at Object.<anonymous> (src/timing.test.js:5:28)

  console.log
    1 - test

      at Object.<anonymous> (src/timing.test.js:7:30)

  console.log
    1 - afterEach

      at Object.<anonymous> (src/timing.test.js:6:27)

  console.log
    2 - beforeAll

      at src/timing.test.js:10:29

  console.log
    1 - beforeEach

      at Object.<anonymous> (src/timing.test.js:5:28)

  console.log
    2 - beforeEach

      at Object.<anonymous> (src/timing.test.js:12:30)

  console.log
    2 - test

      at Object.<anonymous> (src/timing.test.js:14:32)

  console.log
    2 - afterEach

      at Object.<anonymous> (src/timing.test.js:13:29)

  console.log
    1 - afterEach

      at Object.<anonymous> (src/timing.test.js:6:27)

  console.log
    2 - afterAll

      at src/timing.test.js:11:28

  console.log
    1 - afterAll

      at src/timing.test.js:4:26

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.47 s, estimated 1 s
Ran all test suites matching
```

## まとめ
1. 1 - beforeAll
1. 1 - beforeEach
1. 1 - test
1. 1 - afterEach
1. 2 - beforeAll
1. 1 - beforeEach　←　注意
1. 2 - test
1. 2 - afterEach
1. 1 - afterEach ←　注意
1. 2 - afterAll
1. 1 - afterAll 


ネストされたテストでは、外側のテストの```beforeEach```と```afterEach```が実行されていることが確認できました。beforeEach、beforeAll、afterAll、afterEachを使う際は、タイミングを意識したTestを書く必要がありますね。
Googleデータポータル（DataStudio）で時間を集計する方法

# はじめに

Googleスプレッドシートで以下のように`2:11`のような形式で時間を記録していて、それをGoogleデータポータルで集計したいときに一工夫必要だったので残しておきます。

![スクリーンショット 2021-09-14 23.04.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/8a80eef5-d02c-eb47-a21f-7327beeb44c2.png)

ここでは労働時間を集計したいとします。
これをそのままデータポータルに追加すると、労働時間はテキストと認識されてしまい、うまく集計することができません（下図左：時間の集計ではなく件数として集計されてしまっている）。
タイプを数値に設定してもうまくいきません（下図右：null）。

![スクリーンショット 2021-09-14 23.30.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/92f81ce9-28b3-b6b7-5a85-fa002aa84f91.png)

# 方法1：スプレッドシート側で数値に変換

スプレッドシート側に変更を加える方法です。
例えば、以下のようにします。

```
=ARRAYFORMULA(IF(F2:F1000,VALUE(F2:F1000)*24,""))
```

![スクリーンショット 2021-09-14 23.51.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/e09e4027-0941-6310-5b14-ca61ee3ee986.png)

ポイントは`VALUE(F2:F1000)*24`で、例えば`2:11`を`2.18`(≒ 2 + 11/60)のように時間単位の数値に変換できます。

https://support.google.com/docs/answer/3094220?hl=ja

あとはこれをデータポータルに再接続すれば、数値フィールドとして認識され、時間を集計することができます。

![スクリーンショット 2021-09-18 12.03.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/164d29f7-3497-8ed2-9edd-3b397642a178.png)

# 方法2：データポータルの計算フィールドを利用

方法1では、データソースであるスプレッドシートに手を加える必要があります。
データソースはそのままに、データポータル側で対処することもできます。

`労働時間`は`2:11`のような時間の文字列が入ったフィールドだとします。
このとき、カスタムの計算フィールドで計算式を以下のようにします。

```
HOUR(PARSE_DATETIME('%H:%M', 労働時間)) 
+ MINUTE(PARSE_DATETIME('%H:%M', 労働時間)) / 60
```

![スクリーンショット 2021-09-14 23.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/60aa3418-6811-998c-e3b3-c0dad69248e0.png)

中身としては、`PARSE_DATETIME('%H:%M', 労働時間)`で`2:11`のような時間の文字列をDATETIMEにします。
そのDATETIMEからHOURとMINUTEで時間の部分（=2）と分の部分（=11）を取り出します。
分は時間に変換するために60で割ります（11/60≒0.18）。
時間の部分の数値（2）と分を時間に変換した数値（0.18）を足して、`2:11`を時間に変換した数値（2.18）が得られます（方法1で説明した数値と合っていますね）。

https://support.google.com/datastudio/answer/9739558

https://support.google.com/datastudio/answer/7583437?hl=ja&ref_topic=7583292

https://support.google.com/datastudio/answer/7583308?hl=ja&ref_topic=7583292

これでデータソースに手を加えずに時間を集計することができました。

![スクリーンショット 2021-09-18 11.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/5c8e4ac6-9958-6cbb-c205-bcd641e59947.png)

※形式の異なるデータが混じっていると下のようなエラーが出るかもしれません。

![スクリーンショット 2021-09-15 0.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131596/7ed6d63a-7ef7-3bdb-9f27-c15d08607c65.png)

余談ですが計算フィールドにはグラフ固有のものとデータソースのものがあり、それぞれ異なる利点があります。
詳しくは下記を参照のこと。

https://support.google.com/datastudio/answer/6299685?hl=ja#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9

# おわりに

そもそもデータポータルを使わずスプレッドシートで十分ならば方法1だけ知っていれば大丈夫です。
とはいえデータポータルも何かと便利な場面があるので、この記事が誰かのお役に立てば幸いです。
【Flutter】VSCodeでAndroid開発「cmdline-tools component is missing」をやっつける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/1b60631f-6526-0e66-3e3f-f39d92836fca.png)

## やりたいこと
VSCodeで、Flutter開発をしていました。
Androidアプリも開発してみたくなったため、[こちら](https://www.casleyconsulting.co.jp/blog/engineer/4587/)の記事などに勉強させていただきながら、

- VScode
- Android Studio
- Flutter

の環境構築をしました。
ゴールは、flutter doctorしてAndroidに関して何のエラーも出ないようにすることです。

## やったこと
まず、

```
flutter doctor 
```
します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/d537d1a9-83e9-898e-6edd-0b21a4b1962e.png)

みての通りAndroidについて

### 【エラー1】Android SDK のコマンドラインツールが存在しない

```
cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
```
と言われてしまっているので対処します。
Android Studioを開き、
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/5c4c9f54-3bde-92df-8f8a-4c89a1af52bc.png' width=512>
↑「More Actions」から「SDK Manager」を開きます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/e1fed7f1-0c05-beb2-fe98-b560019d7b8e.png' width=512>

↑この画面に、sdkのパスがあります。ちょうどモザイクしているところですね。(後で使います。)
エラー1で指摘されている「cmdline-tools」をインストールしたいので、「SDK Tools」を選択し、
「Android SDK Command-line Tools (latest)」をインストールします。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/33c7d3f1-36ad-cbd5-604f-455e9e723348.png' width=512>
インストール完了の様子

その後、あたらめてflutter doctorします↓
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/c9d9ed5e-af9a-bf85-dfc4-453752e92f86.png)



今度は、

### 【エラー2】プロジェクトまでのパスが通っていない

```
ANDROID_HOME =
      /~Flutterプロジェクトまでのパス~/android-sdk-linux
      but Android SDK not found at this location.
```
と言われてしまっています。
先ほど「後で使います」と言ったsdkのパスを利用して、以下のようにパスを通します。

```
$ flutter config --android-sdk <sdkのパス>

Setting "android-sdk" value to "<sdkのパス>".
```
うまくいってそうですね。その後、あたらめてflutter doctorします↓


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/bd2ee3f6-2492-f60b-a137-934a5849384c.png)
いけましたね。
※SDKバージョンの違いやライセンスについてエラーが出るかもしれないですが、その辺りはエラーで丁寧に教えてくれている通りなので省略します。

## 参考
https://stackoverflow.com/questions/49175231/flutter-does-not-find-android-sdk
mf-tag-write 関連に時間取得を追加

# wtag 1.18

![wtag-times-sa-small.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239081/505a048a-9cf4-c5c6-22be-ff51b06290fb.png)

##ダウンロード
[github.com - wtag 1.18](https://github.com/s-fubuki/wtag)

# 変更点
## mf-tag-read: 時間とビットレートの取得
ダミータグ ` *time`(spaceはじまり)に秒数とビットレート(1/1000)をリストで得ます。alias シンボルは `*time`(こちらは space なし)。
通常 2要素のリストですが mp3 は 3要素目にシンボル `vbr` が, oma は `*` が入る事があり、それぞれ可変長、誤差在りの場合です。
m4p は可変長でも何も付きません(現在未調査で未対応のため)。

```emacs-lisp:example.el
(assoc '*time (mf-tag-read-alias "01-Take It Easy.mp3"))
;; --> (*time " *time" 214 128 vbr)

;; assoc-default (または alist-get) なら CAR にタグ、 CDR にその値が得られる
(alist-get '*time (mf-tag-read-alias "01-Take It Easy.mp3"))
;; --> (" *time" 214 128 vbr)
(mf-sec-to-times 214) ; CADR
;; --> (0 3 34)
```

### wtag: 内部のタグ表示
曲名の行で `C-c =` とタイプするとエイリアス・タイプのリストでエコー・エリアにすべてのタグが表示されます。
アートワーク等のバイナリタグは含まれません。

## mf-lib-mp3: lyric 取得時のバグをfix
mf-tag-read-alist, mf-tag-read-arias から `lyric` にアクセスした場合正常に動かなかったのを修正。

`lyric` から `:dsc` プロパティをなくし(これをタグと見なし誤動作していた)、そこにセットされていたデータを `:cdsc` プロパティにセットするようにしたので、もしこのプロパティを利用している人がいたら書換えてください.

## wav ライブラリを追加
### wav 標準の LIST info タグを読み ID3 タグにして書き戻します。
これらは共存できるのですが、どちらを見るかはアプリによって違うので、整合性が取れるよう元の LIST info も ID3 に合わせて書換えされます。
sjis の LIST が読めずに化けてしまっていた fre:ac 等も ID3 を参照するようになり正常に表示されます。

### コンテナの配置も変更します.
WMP で作った wav なのに エクスプローラからはタイトルが見えない等の問題回避をするため、コンテナの配置順序を変えます。
これによりエクスプローラや Grooveミュージックでもタイトルが正常に出るようになります。
  
  mf-tag-write へのライブリの事後追加が正常にできているかのテストを兼ねているので、今のところ標準ではインストールされないので、必要なら `init.el` 等で `(require 'mf-tag-write)` の後に `(require 'mf-lib-wav)` としてください.

```emacs-lisp:example.el
(require 'mf-lib-wav)
(mf-tag-read-alist "01 乙女 パスタに感動.wav")
;; --> (("TRCK" . "1") ("TCON" . "J-Pop") ("TALB" . "乙女 パスタに感動") ("TIT2" . "乙女 パスタに感動") ("TPE1" . "タンポポ") (" *ver" . "wav") (" *time" 273 1411))
```

## アーカイブの整理
mf-lib-utility, tiny-ted を外しました。
サンプルの体で入れていましたが、今では関数 mf-tag-read-alias, mf-tag-read-alist 等でタグを抜き出し lisp プリミティブな連想リスト関連の関数に渡すだけで平易にタグにアクセスできるので、特にサンプルも不要だと思われるのと、以前からグシャグシャな utility はサンプルとして如何なものかと思っていたので、`lib-wav` 追加でまたファイルが増えたのを契機に除外しました.

```emacs-lisp:diredからエコーエリアにタグを表示
(defun dired-tagput ()
  (interactive)
  (let ((col (mf-tag-read-alias (dired-get-filename) (* 1024 30) t))
        ret)
    (dolist (a '(title artist album genre year))
      (setq ret (cons (cdr (alist-get a col)) ret)))
    (message "%s" (mapconcat #'identity (reverse ret) " | "))))
```

以上です。
[Docker] docker コンテナが終了できなくなったとき (無保証)


## はじめに

ごくまれに、docker コンテナが終了できなくなり、何も操作できない状況に陥ることがあります。

- docker-compose down → `UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)` でエラーになる
- docker stop xxxx → ダンマリ。
- docker kill xxxx → ダンマリ。。
- docker rm -f xxxx → ダンマリ。。。

こんな状態。。

あとは dockerd を再起動して解決とありますが、そう簡単に dockerd 再起動できない状況もあります。

ちなみに、コンテナに restart ポリシーを設定していると、dockerd 再起動や OS 再起動をしても停止できないままのコンテナが復帰してしまいます。

そもそも、docker inspect xxxx などをやってもダンマリなので、restart ポリシーを変更することもできません。

- docker update --restart=no xxxx → ダンマリ。。。。



## 確認できた現象

今回は以下のような状態で、同現象が発生しました。

- アプリケーション + fluentd などサイドカー付きの docker-compose 構成
- fluentd など、サイドカーの一部が落ちた状態

サイドカーの一部が落ちていたのは、restart ポリシーの設定不備で dockerd 再起動時に片側だけ復帰していたため。

この状態で、まず docker-compose down が効かなくなります。

次に、 docker stop、docker kill 等を試みるわけですが、そうするとコンテナ内部で実行するコマンド(nginx や node など) が終了して、コンテナ情報の外枠だけ残るというおかしな状態になってしまいました。


```
$ docker stop xxxxxxxxxxxx

    ダンマリになるので Ctrl-C で終了

$ ps ax | grep nginx
=> コンテナ内で実行していたコマンドは終わっている

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  ...
    :
xxxxxxxxxxxx        my_nginx:latest     "sh /entrypoint.sh '…"  ...
=> コンテナ情報だけ残る
```


コンテナが残っているのに、何もコマンドを受け付けない状態になってしまいます。。

また、今回は restart ポリシーを設定していたため、dockerd を再起動してもコンテナが復帰してしまいます。



## 対処法１

docker ps -a で見て、終了してしまったサイドカーの相方が残っていた場合、これを docker start することで docker-compose down が効くようになりました。
ただ、これは必ず成功するわけではないようです。

```
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  ...
    :
xxxxxxxxxxxx        my_nginx:latest     "sh /entrypoint.sh '…"  ...   Up ddd hours
yyyyyyyyyyyy        fluentd:latest      "tini -- /bin/entryp…"  ...   Exited (0) ddd hours ago ★終了した相方

$ docker start yyyyyyyyyyyy

$ docker-compose down
```



## 対処法２  ※無保証

今回は restart ポリシーの設定不備と合わさって、dockerd 再起動でも復旧できなかったので、restart ポリシーを修正する方法を取ります。

docker update --restart=no xxxx は操作が効かないので、コンテナの実ファイルを見てみます。


コンテナの実体は以下のディレクトリにありました。(root でないと見れません)

```
# ls 
 -1 /var/lib/docker/containers/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-json.log
checkpoints
config.v2.json
hostconfig.json
hostname
hosts
mounts
resolv.conf
resolv.conf.hash
```

この中の hostconfig.json に restart ポリシーの設定があるようです。

```
# cat /var/lib/docker/containers/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/hostconfig.json | jq .
{
  "Binds": [],
  "ContainerIDFile": "",
  "LogConfig": {
    "Type": "json-file",
    "Config": {
      "max-file": "10",
      "max-size": "10m"
    }
  },
  "NetworkMode": "storage_default",
  "PortBindings": {},
  "RestartPolicy": {  ★コレ
    "Name": "always",
    "MaximumRetryCount": 0
  },
  :
}
```

これを強引に書き換えてみます。※無保証

```
"RestartPolicy":{"Name":"always","MaximumRetryCount":0}
    ↓
"RestartPolicy":{}
```

restart ポリシーの設定をクリアしたら、dockerd を再起動するとおかしくなっていたコンテナは削除できました。

```
$ sudo systemctl restart docker
```



## おわりに

強引な方法で、とりあえず復旧することができました。

restart ポリシーの設定不備はともかく、コンテナ操作ができなくなってしまうのは怖いです。

コンテナ内部のコマンドが終了していても、外枠のコンテナ情報が残ってしまう辺りが謎なので、どういう仕組みなのか調べてみたいですね。


// EOF
qiitaに冷凍食品の保存ノウハウを展開し、凍結解除されるまで。

####はじめに
　日本国内のプログラマやエンジニア、はたまた私のように趣味でjsやらcssやらを弄っている者にとって、qiitaは最も信頼できる情報源の一つである。
　同時に、思いついた良いcode、解決した困り事、仕事や趣味に打ち込む上で心掛けている方法論を自ら発信、展開する場としても大変有益であると推察される。
　日本のIT従事者、趣味者が共存、共栄する上で、もはや欠かす事のできないプラットフォームだ。
　そんなqiitaを如何に有利に活用するかという点で、なかなか興味深い出来事が起きたので、書き留めておく。

####1.冷凍食品の記事を投稿したらアカウントが凍結された。
　より良いcodeを書く上で参考にすべきものはcode sampleや言語仕様だけではない。
　合理性、汎用性、可視性...こうした概念へのアプローチの方法は日常の凡ゆる物事から学び知ることが出来る。
　冷凍お好み焼き（豚玉）もそうだ。プログラム趣味者たる者、外袋に入った冷凍お好み焼き（豚玉）をそのまま冷凍庫に入れるなどという非合理な行動を取るべきではない。
　冷凍庫に入れる前に外袋から出すだけで、容量削減、一括処理、可視性、ひいてはトッピングのカプセル化など、無視できない利益を齎す。
　冷凍庫の中身の煩雑さに何の対策も打てない者が、sauce..いやsourceのリファクタリングなどできるだろうか。そう思って書いた冷凍お好み焼き（豚玉）の記事だったが、投稿後おそらく5分と経たないうちに閲覧不能にされ、作成したばかりのこのアカウントも木苺の如く一瞬でフリーズドライされてしまった。
　私の心は、買い溜めていた牧場しぼりのラムレーズン味より冷たくなった。

####2.スパムの疑いを掛けられたため、『取り上げたのは缶詰ではなく冷凍食品である』旨をサポートに伝えた。

　『500エラー』という謎のメッセージとともに、下書きページや投稿ボタンなどが操作禁止にされてしまった。
　qiitaからの自動配信メールを読むと、『スパムの疑い』が掛けられているという。
　まさか、たった1度の投稿で『同じメッセージを色んなところに大量に送りつけるやつ』扱いされるはずもない。きっと疑いを掛けられている『スパム』というのは、ググると一番上に出てくるアイツの事である。
　『スパムではない場合はサポートにメールを。』と記されていたので、私は正直に、『私が書いた記事は冷凍食品に関するものであって、缶詰に関するものではありません。』と送った。

####3.アカウントが解凍され、記事も第三者が閲覧できるようになった。

　凍結されるのも迅速だったが、「解凍」されるのも早かった。冷凍お好み焼きを実際にレンチンする時のほうがよほどヤキモキする。
　「或る日、レンチンを開始してすぐにキッチンから部屋へ戻りmacbookを広げ、jsを弄り始めると止まらなくなり、お好み焼きの事はすっかり忘れて（それが1週間続いて）レンジの中のお好み焼きがカビだらけになっていた」という経験なら人生で2、3度あるが、qiitaのそれ（解凍時間）は我が家の最大700Wのレンジとは違った。
　メールを送り、次にQiitaに足を踏み入れた時には何もかも解決していた。
　全てがAIではないにしても、何らかの自動化の仕組みが高度に組み込まれている事が読み取れる。さすがは日本最大のプログラマ・コミュニティだ。

####4.ただただ、『冷凍お好み焼きについての記事が閲覧可能になった』という謎だけが残った。

　2021年現在、Googleで『お好み焼き 可視性』を検索すると、<a href=./ed52c509de69a9720323>該当記事</a>が最上位に出てくる。
　『お好み焼きの可視性について何か気になった』という日本人が今後10年のうちに一人でも現れるかどうかについては甚だ疑わしいが、『クックパッドを開こうと思ったらQiitaだった』という小さな奇跡が、日本のどこかにいつか舞い降りてくれることを細やかながら期待したい。

####今回わかったこと

1. qiitaにはsourceを書くべきであり、sauceについて語るべきではない。

2. スパムを疑われた場合、『缶詰じゃねーよ。』との一言が解決に導く。

3. 「AIに凍結され、人に解凍される」というプロセスはそんなに悪くない。
59日後にITパスポートを受けるFラン私大文系既卒(51日目)

# ICANN(The Internet Corporation for Assigned Names and Numbers)
* ICANNとは? 
 * ドメイン名、IPアドレス、プロトコルポート番号、パラメータ番号、DNSルートネームサーバを世界的に調達する非営利組織

# IEC(International Electrotechnology Commission)
* IECとは?
 * 電気及び電子技術の国際規格を作成している国際標準化機関

# IEEE(Institute of Electric and Electronic Engineers)
* IEEEとは?
 * 電子・電気の研究を目的とする世界最大規模の学会

# ITU(International Telecommunication Union)
* ITUとは?
 * 電気通信における国際標準を定めることを目的とした組織
Twitter 推し・神絵師・えっっな 画像保存[Tweepy]

#諸君よ（冒頭ポエム）

「Twitterで神絵師の画像を保存したい！！！」

僕らが空に叫んだあの日から何日が経っただろう。

神絵師をフォローし、タイムラインに流れてくる癒やしを眺めるのも良い。
そして、神絵師どうしのリプにひとつひとついいねを推していくのが我々の使命だ。

＿人人人人人＿
＞　しかし　＜
￣Y^Y^Y^Y^Y^￣

フォローしている神絵師の画像がワンクリックで大量に保存できたらどれほどいいだろうか？

僕らはなんのためにプログラミングをしている？

そう、神絵師の画像を保存するためだ。

※この人はつい先日、超超超超真面目にプログラミングについて語った記事を投稿したばかりです。

https://qiita.com/mio256/items/eb70d6d2239acc2ce94c

# 僕らの味方Python

この記事はPythonをある程度扱えることが前提に進んでいく、

もしPythonが初めてなら、ある程度学んでから戻ってきてほしい。

# 僕らの味方Twitter

冒頭でネタ記事と思われたかもしれないが、僕は本気だ。

さくっとTwitterDeveloperを登録していく。

偉大なる先人がとても丁寧に解説してくださっているため、そちらを参考してほしい（あるまじき引用行為）

https://pocco.net/twitter-developer/

# 僕らの味方Tweepy

Tweepyはとても便利なPythonでTwitterAPIを扱うためのライブラリだ。

やりたいことをググりながら、わからなくなったときはDocsを見るのが一番手っ取り早い。

https://kurozumi.github.io/tweepy/

# 僕らのtwpic

Pythonを0から勉強し、完成したものがこちらです。（温度差）

https://github.com/mio256/tweepy


Twitterでフォローしている人の投稿画像を新着順で自動保存するツールです。

1 . twipicディレクトリに[config.py]で自分のTwitterディベロッパーアカウントのユーザー情報を入れてください。

  Linux 例）/home/[ユーザー名]/tweepy/twpic/config.py

  Win 例）C:\\tweepy\\twpic\\config.py

```python:config.py
consumer_key = 'ココ'
consumer_secret = 'ココ'
access_token = 'ココ'
access_token_secret = 'ココ'
```

2 . processing導入環境であれば、twpic_show.pdeを実行

processingにより、保存した画像をリアルタイムで表示しています。

比較的簡単に導入できるため、余裕があればインストールしてください。

3 . twpic.pyを実行

win勢はtwpic_win.pyをどうぞ。

4 . skip?>>[ココ]

[no]か[yes]でスキップ機能を切り替えます。

スキップ機能を有効にすると10枚以上同じ画像を検知した場合に次のフォローしている人に飛びます。

5 . How?>>[ココ]

自然数を入力して、一人あたりの探索するツイート数を指定します。

※10を入力した場合、[最新10ツイートを検索]という意味です。保存する画像数ではありません。

6 . Processingに画像が表示される

7 . tweepy/savepicに画像が保存される

## やってみよう！

<iframe width="560" height="315" src="https://www.youtube.com/embed/OLQY0QR9HyA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 参考

https://qiita.com/kamihork/items/2936ec91f34b51a09bf2
【Node.js】【Express】req.bodyが取得できない

Progateを参考に`Node.js`、`Express`、`ejs`でアプリを作成していたのだが、
POST処理の`req.body`でFromの値を取得することができない。


```app.js
app.post('/edit/:id',(req,res) => {
  connection.query(
    'UPDATE users SET name = $1 WHERE id = $2',
    [req.body.nname, req.params.id],  //ここでキャッチしたい〜
    (error,result) => {
      res.redirect('/top');
    }
  );
});
```

なんでや〜

いろいろ調べた結果、2つの原因が判明したので、メモ( ・∇・)

#原因1：body-parser
Expressでクライアントからデータを取得する場合、`body-parser`をインストールして`req.body`経由でデータを取得する必要があった。
なので以下の処理を実施

####1.body-parser のインストール

```
 $ npm install body-parser --save
```

####2.app.jsで使用できるように記述

```app.js
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
    extended: true
}));
```

##だがしかし！！！！！！！！！！
Express __ver.4.16.0以降は、Body-Parserの機能が標準で搭載__されているみたい！
そのため、わざわざ`body-parser`のインストールしなくてもよく、代わりに`express.json()`を使用すればいいみたい。

####1.express.json()を使用できるように、app.jsを編集

```app.js
//const bodyParser = require("body-parser");
//app.use(bodyParser.urlencoded({
//    extended: true
//}));
//↓に変更
app.use(express.json());
app.use(express.urlencoded({
    extended: true
}));
```

#原因２：httpヘッダーのcontent-type
httpヘッダーのcontent-typeが`application/x-www-form-urlencoded`でないといけないとのこと。
自分はファイルの保存がしたくて、`multipart/form-data`にしていたため、`req.body`が取得できなかったみたい。

Formでのcontent-typenの指定は、`enctype=""`で指定します。
ちなみに、何も指定しない場合は、デフォルトで`application/x-www-form-urlencoded`となっているようです。

#おわりに
以上の２点を気をつけることで、無事に`req.body`を取得することができるようになりました。
これ解決するまで2日くらいがんばりました。
終わってみれば、「こんなことかー」て思いますが、ここまでたどり着くのは大変でしたね。
ほんと独学は疲れる。
安価にRailsアプリを公開する方法

**2023年1月4日更新**
Herokuの無料プランがなくなってしまって、本記事のタイトルから嘘になってしまったのでタイトルを修正します。（元の記事タイトルは「完全無料でRailsアプリを公開する方法」でした。。。）
記事の中身は若干修正しましたが、ほぼ無料時代のものですので、現状と異なる点はご容赦ください。

# はじめに
初めて記事を書きます。
私が最近、Railsでサイト( BountyHunterという賞金切り口のコンテスト情報集めサイト。有料化や、ドメインの更新に伴い閉鎖 )を公開しましたので、その構成やら苦労話をつづります。（宣伝も兼ねて）
なお、タイトルにも記載していますが、*無料で*公開することにこだわって作ったため、使い勝手は良いとは言えない点は許していただければと思います。
**また、冒頭にも記載した通り、Herokuの無料プランがなくなってしまったため、無料ではなくなりました...**

# なぜ無料にこだわっているのか
そもそも、私がプログラミング経験がないことから端を発しておりまして、Webアプリを作って継続的に育ててみたいと思ったところから、なんとなく身近で開発している人がいたRailsを選択し、まずは[Rails Tutorial](https://railstutorial.jp/)を勉強し始めました。

Rails TutorialではCloud9を開発環境として使うのですが、AWSの最小構成にしていても1年以上経過すると無料枠が使えなくなって有償になります(極少額ですが)。有償になると、クレジットカードに請求が来たりと家庭内でコソコソ勉強している身からすると面倒なので、完全無料で実現しようと思い、Rails Tutorialをなんとか完走し、開発環境を無料の環境に乗り換えることを画策し始めました。
ま、無料に越したことはないですし。

# どんな環境か
絵で表すとこんな感じです。
![構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95950/6f749739-736e-fce1-da26-a00a41cc4235.png)

Railsのアプリを公開するにはいくつか検討すべき構成要素があります。
- Webサーバ
- DBサーバ
- 独自ドメイン
- HTTPS
- 画像ストレージ(後述)

### Webサーバ
まず、Web兼アプリケーションサーバについてはRailsのアプリであればHerokuを使うことで無料での公開ができます。もちろん、無料枠にはもろもろ制約がありますので、詳しくは[Herokuのサイト](https://jp.heroku.com/free)をご確認ください。

### DBサーバ
Herokuでは無料でPostgreSQLを使えます。ただし、登録可能なレコード数が1万という制限がありますので、それに収まるようなサービス内容であれば無料で使えます。
こちらも[Herokuのサイト](https://jp.heroku.com/free)に細かい制約条件が書いてあるのでご確認ください。

### 独自ドメイン
次に対象サイトを公開するのですが、Herokuで払い出してもらったURLそのままというのは何とも怪しいサイトっぽく見えてしまうので、独自ドメインを使おうと思いました。
ここでは、[Freenom](https://www.freenom.com/ja/index.html)というサービスを利用して、ドメインを取得しています。このサービスは取得できるドメインに選択可能なgTLDの制限がありますが無料で使い続けられます。
詳しくは[こちら](https://qiita.com/shin555/items/edf6831aba051fe7ece7)

### HTTPS
Heroku でWebサイトを公開する場合、独自ドメインをHTTPS化しようとすると有償になってしまいます。そのため、CloudflareというCDNサービスを間に挟みます。こちらも無料枠で使える範囲には制限があるものの、CDNとしての機能や無料のHTTPS、DNSなどを提供してくれます。詳しくは[Cloudflareのサイト](https://www.cloudflare.com/ja-jp/plans/)へ
詳細な手順は[こちら](https://qiita.com/shin555/items/edf6831aba051fe7ece7)

### 画像ストレージ
無料枠のHeroku を使うと、デプロイ対象の資材以外はDBにデータを溜める(PostgreSQLは無料で使える)ことしかできません。（コンテナなので揮発してしまう）
ファイルを溜めようと思うと、AWSのS3を利用するなど有償になってしまいます。
この画面キャプチャを保存する場所が無い！というのが課題になりまして、もろもろ頑張ってDBにバイナリで保存する方法をとっています。

# この構成に決まるまで
それぞれの構成要素でそれなりに工夫（というか、右往左往）しながら↑の構成までたどり着いたので、その辺の苦労話はまた別の記事に載せていきたいと思います。
なんかしらリアクションもらえると喜んで次々書いていきます！

# 詳細を掘り下げた記事
[無料で独自ドメインをHTTPS公開する](https://qiita.com/shin555/items/edf6831aba051fe7ece7)
【Unity】TextMeshProのバージョンの違いにおけるメモリリーク

#バージョン2.0.1
TMPro.DropdownでTMPro.TextMeshProUGUIのメモリが解放されません。
シーンの再読み込みやResources.UnloadUnusedAssetsでは解放されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035506/90988db9-9312-a58e-bc1a-b8ae0f217576.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035506/7eee85c3-9a19-ae88-b028-046993df48b7.png)
参照を辿ってみると、ドロップダウンのCaptionTextのメモリが残っているようです。

#バージョン2.1.6
2.0.1での現象は解消されています。
しかしながら、プロファイルをしていないため原因は不明ですが、WebGL版にて大きな使用メモリの増加が起きます。
Editor上やStandalone版では発生しません。

#補足
実務上でメモリリークを検証していた時に遭遇した問題なので、詳しい検証や他のバージョンとの比較は行っていません。
こちらに詳しいバージョンのログがあります(https://docs.unity3d.com/Packages/com.unity.textmeshpro@2.1/changelog/CHANGELOG.html)
私がプロジェクトで使用しているUnityのバージョンは2019.3ですが、デフォルトのTMProのバージョンが2.0.1なので、原因不明のメモリリークに悩んでいる方は最新版を試してみてもいいかもしれません。
TMProのバージョン変更の際はシーン上のTextのAlignmentが変更される可能性があるので、あらかじめバックアップを取っておくことを推奨します。
共有Linuxマシンでbashやvimやtig設定がキツい場合の応急処置


## 概要

短期間 (〜1週間以内) のみ、とある Linux マシンにて **共通アカウント** で作業をすることがある.
このとき bash や vim や tig が次のような馴染めない挙動のことが多い.

・vim の相対行番号表示 `set relativenumber` が有効になっている.
・vim の配色[^1] やインデント幅 が自分とは違う
・vimdiff の配色がデフォルトで見辛い
・bash プロンプトがフルパス表示になっている
・tig コマンドの配色が見辛い
・tig コマンドの表示結果にハッシュ値が載っていない


そこで、一時的に .bashrc や .vimrc や .tigrc を設置することがあるので書き出しておく.


## $HOME/.bashrc_my

勝手に \$HOME/.bashrc を変更すると怒られるので、
次のように \$HOME/.bashrc<font color="red">_my</font> を作成する.

.bashrc_my の中では、「.vimrc_my や .tigrc_my を読み込む」ようにしている.

実際に使用する際は、(面倒だが) ログイン後に `source $HOME/.bashrc_my` として読み込む.[^2]

```bash
## プロンプトを短くする. デフォルトだとフルパス表示で見辛い.
export PS1='${debian_chroot:+($debian_chroot)}\u:[\W]_$ '
 
## 自分用のエイリアスを定義する
alias l='ls -ltrA'
alias p='pwd'
alias grpe='grep'
 
## 既存 vim および vimdiff の配色や挙動が自分には辛い場合がある.
## そこで 最小設定を記した .vimrc_my を読み込むように vim と vimdiff の挙動を変えてやる.
alias vim='vim -u $HOME/.vimrc_my'
alias vimdiff='vimdiff -u $HOME/.vimrc_my'

## tig 設定ファイルは $HOME/.tigrc_my を読み込むようにする
export TIGRC_USER=$HOME/.tigrc_my
```


## $HOME/.vimrc_my

デフォルトの vim で動く範囲での (個人的な) 最小設定.

```vim
" 行番号を表示する
set nu
" TABキーを押した際にタブ文字の代わりにスペースを入れる
set expandtab
set tabstop=4
set shiftwidth=4
 
" vimdiff の配色
highlight DiffAdd    cterm=bold ctermfg=10 ctermbg=22
highlight DiffDelete cterm=bold ctermfg=10 ctermbg=52
highlight DiffChange cterm=bold ctermfg=10 ctermbg=17
highlight DiffText   cterm=bold ctermfg=10 ctermbg=21
autocmd FilterWritePre * if &diff | setlocal wrap< | endif
```

## $HOME/.tigrc_my

システムに tig が導入されている前提である.

```bash
#################################################
# 表示内容の変更
# https://qiita.com/yoshikazusawa/items/d99e8b5d6f6a45aa6e2e
#################################################
set main-view = id date author commit-title:graph=yes,refs=yes

#################################################
# 配色変更
# https://qiita.com/astrsk_hori/items/bb0fc9ee8f3425880063
#################################################
set ignore-space = all          # 空白無視

# Color Settings
color default white black
color cursor default magenta
color status white green bold
color id white default
color date yellow default
color delimiter cyan default
color line-number yellow default
color diff-header yellow default
color diff-index cyan default
color diff-chunk magenta default
color diff-stat cyan default
color "Reported-by:" green default
color graph-commit yellow default

# 水平分割したウィンドウの下画面サイズを % で指定（行数指定も可）
set split-view-height = 80%

# 画面を垂直方向に分割する
# set vertical-split = yes
# 横分割に強制する
set vertical-split = no
# デフォルト値
# set vertical-split = auto
#
# 差分の前後の表示行数（diff-context)を指定 
set diff-context = 6
```

　

## 参考情報

・https://qiita.com/yoshikazusawa/items/d99e8b5d6f6a45aa6e2e
・https://qiita.com/astrsk_hori/items/bb0fc9ee8f3425880063
・https://qiita.com/takaakikasai/items/b46a0b8c94e476e57e31
・https://try2explore.com/questions/jp/10431114


以上


[^1]: 10人中 10人が見辛いという配色に遭遇したが、とある1名が $HOME/.vimrc にその見辛い配色を設定してしまっている

[^2]: ssh 接続時に環境変数を定義しても良いのかも知れない → https://qiita.com/ktooi/items/d93778fbc0a60910fbb7
pythonにおけるシングルアローが検索に引っかからないので書きました

# pythonにおけるシングルアロー(->)とは
- pythonにおける`シングルアロー`(`->`)は、アノテーション(関数アノテーション)です。
- [この記事](https://techacademy.jp/magazine/46675)を見ただけですが、現時点で検索にひっかからなかったので、記事に書きました。
- 検索語としては、`python`、`シングルアロー`、とか、`アロー演算子`とかで検索する人(自分)が普通かなと思います。初めから、`->`を調べようとして、`python`、`アノテーション`って検索する人はあまりいないと思います。

# 関数アノテーション

- pythonでも型を意識したプログラミングをできるようにと、python3.6から`関数アノテーション`が利用できるようになりました。

```
def 関数名(引数1, 引数2, ...) -> "返り値の型名":
    処理内容
```

- 関数アノテーションの説明については、有名サイトを参考にして下さい。
- [note.nkmk.me Pythonの関数アノテーション](https://note.nkmk.me/python-function-annotations-typing/)

# pythonのデコレータについて
- pythonにおいて、関数の1行上に書く`@+文字列`のことをデコレータと言います。
  - なぜ、ここでPythonのデコレータに言及するかというと、Javaにおいて、関数の上に`@+文字列`をつけることを`アノテーション`というので、Javaをかじっている人は、関数の上につける`@+文字列`のことを、アノテーションなのかデコレータなのか、ごちゃごちゃになってしまってしまうことがあるので、確認のために書きました。注意されたし。

# あとがき
- この記事は、上記で書いたように`python`、`シングルアロー`とか検索しても、目的の`関数アノテーション`に早くたどり着けるように書いただけです。
UITableView内のボタンを発火させる方法。

cellの中のボタンをタップさせて関数を実行する方法

cellタップはdidselectatでできるが、ボタンは意外とつまったのでメモ。

```swift
//cellのコード
class ContactCell:UITableViewCell {
    
    //Mark:Properties
    var link:デリゲート先VC名!
    
    private var button:UIButton = {
        let button = UIButton(type: .system)
        //ボタンのUI装飾をよしなにやる
        return button
    }()
    
    //Mark: initialize
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
         //アクセサリービューにbuttonを設定する
        accessoryView = button
　　　　　　　　　　　　　　　　　//ボタンにアドターゲットをする
        button.addTarget(self, action: #selector(handleInvite), for: UIControl.Event.touchUpInside)
    }
    
    required init?(coder: NSCoder) {
        fatalError()
    }
    
    //Mark: selector
    @objc private func handleInvite() {
        link?.someMethod(cell: self)
    }
}
```



```swift
//tableview側のコード

func someMethod(cell:UITableViewCell) {
          print(#function)
          let indexTapped = テーブルビュー名.indexPath(for:cell)
          print(indexTapped)
        }

.
.
.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCell(withIdentifier:cellId, for: indexPath) as! ContactCell
        cell.link = self //ここで実施するのはワイだよ！！と宣言する！
        return cell
    }
```
Automation360 v22を眺めてみる

#はじめに
Automation360 Community edtionでv22が使えるようになったので眺めてみました。
正式な説明は以下にあります。
https://docs.automationanywhere.com/jp-JP/bundle/enterprise-v2019/page/enterprise-cloud/topics/release-notes/release-community-edition-a360-v22.html

いろいろと変わっていますが、私的に嬉しかった部分を上げてみます。

# Botの実行タイムアウト

Botの詳細設定からタイムアウトを指定できます。
V11のタイムアウトと違って、アクションからAutomation360に戻って来ない場合でもタイムアウトになります。

例えば以下のBotで4行目のマクロが戻ってこない場合でも、タイムアウト指定しておくとこのタスクは（エラーで）終了します。
![macro01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/7f5be2ca-d053-fbfc-e86c-77603333620a.png)

# Text fileアクション
テキストファイルの中身を読み込んで変数に代入できます。
![textfile01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/c6141b6e-2cbb-07df-fce0-8fcb4a08b867.png)

# ファイルを開くで正規表現
ファイルパッケージの開くアクションでファイル名を正規表現で指定できます。
![openfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/5f70e134-ed3c-80e1-7c20-b1199b3615ce.png)

正規表現は固定の文字列部分と正規表現のパターン部を個々に指定します。
文字列部の.など自動でエスケープしてくれるのは優しいですね。

ファイル名の末尾に年月日が入っていてファイル名組み立てるのが面倒な場合に、便利。
ただ複数マッチしてもエラーとはならず最初にマッチしたファイルを開くようなので、そこは注意。

#  Excelを開くでワイルドカード
「Excelの高度な操作」パッケージの開くアクションでファイル名にワイルドカードを指定できます。
![openExcelfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/9e1d1944-8f43-eff9-43a4-b68996987cc2.png)

これもExcelファイル名に日付入ってて毎回ファイル名が変わるときなどに便利。
なぜこちらは、ワイルドカード？

# ExcelなどのセッションがBot間で共用可能に
これはV11であった機能ですね。
![globalsession.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/e6bc327c-b650-f068-493f-d34651f5efd0.jpeg)
Local sessionでも必ず名前を付けないといけなくなったので注意（Defaultが入っていない）。

# ディクショナリの挿入(Put)で値を直接指定できる
今までディクショナリのあるキーに値を入れる場合、変数でしか指定できませんでした。
ここが値を指定できるようになりました。

# Local deviceとRemote Devices
接続しているデバイス名の箇所でLocal deviceとRemote Devicesが区別されるようになっています。
デバイス接続が別のPCになっているのを忘れてて、実行ボタンを押したときに、自分のPCでなく別のPCで動いてしまってるのに気づかず、あれ？動かない？と悩む事が減るかな。
（そんな人、あんまりいない？ 私はありました...）
![device02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/86ccf961-42d0-1510-5c4e-6aa64bb440ce.jpeg)

どうせなら複数デバイスの接続ができて、この部分でLocalかRemoteかデバイスを切り替える事でできると面白かったけど、それは今までと同様、ダメみたいです。
デバイスは1個しか登録できないよ、というエラーになります。
![device1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/26972e16-8514-0078-9f44-80d0f3e1ea5d.png)

# マネージと管理
画面左側のメニューで、「管理」が２つあったのが、「マネージ」と「管理」になりました。
「左メニューの"上の方"の"管理"を開いて」．．．．という説明していたのが少し楽になるｗ。

# WindowsパッケージのClose Allアクション
ウィンドを全部閉じる、ができます。
また、このウィンドは残しておきたい、という追加指定もできます。

Restoreアクションというのも追加されていますが、私はちょっと使いどころが思いつかないです。
欲しい人には嬉しい機能かも。

# Botエディタでの検索
Ctrl +  f で検索できます。１文字打つごとにインクリメンタル検索しますし、Botエディタの表示では隠れている変数名とかも検索してくれるので、とっても便利。

# さいごに
他にもいろいろありますので、詳しくは最初に書いたURLを。
Swift 画面遷移前に値渡しをする方法２個

方法①プロトコル、デリゲートで渡す

```swift
//ViewController(画面遷移後）
protocol プロトコル名 {
    func 関数名(送りたいデータ)
}

class ViewController {
.
.
　　　　　　var delegate:プロトコル名
　　　　　　
.
.
//前の画面遷移前に戻るタイミングでこれを書く。
self.delegate.関数名(送りたいデータ）
}

　//画面遷移前の画面

 class FirstViewController:プロトコル名 {
//delegateメソッドを自身に設定
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            let nextVC = segue.destination as! ViewController
            nextVC.delegate = self
        }
func 関数名（送りたいデータ）{
  //送りたいデータが入ってくる
}

}
```



方法②モーダルの場合、

```swift
前の画面
 @IBAction func getData(_ unwindSegue: UIStoryboardSegue) {
        //unWindViewController
        guard let vc = unwindSegue.source as? 繊維元VC else { return }
        vc.でプロパティにアクセスしてデータを取ってこれる。
    }

遷移もとのVC
 @IBAction func back(_ sender: Any) {
        performSegue(withIdentifier: 設定した識別子, sender: nil)
    }
//StoryBoard上でExitから繊維元のVCに接続して自分で作った関数名がでてくるのでそれを選択。
//その後segueの識別子を選択して完了
```