OmniAICreator/Qiita-1.07M huggingface dataset:
TYPE-MOONの「月姫」からノベルデータを取り出し、青空文庫フォーマットのテキストファイルにする

# 目的

月姫ゲームディスクから、ノベル・データを取り出し、青空文庫フォーマットのテキストを抽出します。
![EjGCy6mUMAIDaoH.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666068/7bfbebc0-905b-c0fc-63fe-8af1abed81f7.jpeg)

青空文庫フォーマット閲覧アプリで読書ができるようになる。

![EinEUrKUMAMuKFG.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666068/781d2755-2185-daa4-9be7-fb648c18e846.jpeg)


# 準備するもの

* TYPE-MOON「月姫」ゲームディスク
* nExtracter https://ulicknormanowen.hatenadiary.org/entry/20131227/1388131132 
* * もしくは、ONscripterに含まれるsardec ツールを使う http://onscripter.osdn.jp/onscripter.html
* * もしくはnsdec.exe https://w8.vector.co.jp/detail.php?s_no=454329 （https://brain.fandom.com/ja/wiki/ONScripter ）
* Ruby  2.6系統 https://rubyinstaller.org/downloads/
* 拙作の変換スクリプト https://github.com/wutai3/novelread

# 作業の流れ
## ゲームディスクから sar を持ってくる

好きな作業ディレクトリに arc.sar を持ってきます

## nExtracter で展開

nExtracter.exeを実行し、入力ファイルに arc.sar を指定して実行します。

するとsar内のファイルがわらわらと展開されます。その中の DecodeScenario_nscript.txt ファイルを使います。

### nsdec を使う場合
同じフォルダに nscript.dat を置いて「復号化.bat」を起動すると、result.txt が生成されます。

## WindowsにRubyを入れる

https://rubyinstaller.org/downloads/

WITHOUT DEVKITなほうから、 Ruby 2.6.6-2 (x64) あたりをダウンロードし、インストールします。

## tsukiime-aoz.rb を拾ってくる

こちらのファイルを、右クリックで名前をつけて保存します。

 https://raw.githubusercontent.com/wutai3/novelread/master/tsukihime-aoz.rb

## 生成
以下のファイルを同一フォルダに入れます。

*  DecodeScenario_nscript.txt 
*  tsukihime-aoz.rb

コマンドプロンプトで、以下を実行します。

  > ruby  tsukihime-aoz.rb

同じフォルダにノベルデータが生成されました。

# Footnote

選択肢ジャンプは適当に攻略サイトをみて入力しているので、見落としがあったら教えてください。
【Salesforce, Apex】Listを繰り返し、要素を削除していく

リストをループさせ任意の項目だけ削除していく実装をした際に以下実装でしていこうとしました。

```Java
for (Integer i = 0; i < this.productList.size(); i++) {
    if (this.productList.get(i).isRemove) {
        this.productList.remove(i);
    }
}
```

しかし、これだと期待する動きにならない。
一個スルーされてしまう要素が出てしまいます。

## 何故
リストのサイズが3で以下のような中身だったとします。

```java
List{
    0 => productObj1,
    1 => productObj2,
    2 => productObj3
}
```

1回目のループで削除の分岐に入り削除されると以下のような形になります。

```java
List{
    0 => productObj2,
    1 => productObj3
}
```
indexが振られ直されています。
ループカウンタの i はというと ０ -> 1 にインクリメントされてます。
まぁ当たり前ですよね

2回目のループでも削除されたとします。
中身はこんな感じになります。

```java
List{
    0 => productObj2
}
```

そしてループ終了。
削除を免れたproductObj2。許しません。



# 案1 カウンタ変数をデクリメントする。

```Java
for (Integer i = 0; i < this.productList.size(); i++) {
    if (this.productList.get(i).isRemove) {
        this.productList.remove(i);
        i--;
    }
}
```

# 案2 whileバージョン
削除した時にはカウンタ変数をインクリメントさせません。

```Java
Integer i = 0;
while (i < this.productList.size()) {
    if (this.productList.get(i).isRemove) {
        this.productList.remove(i);
        continue; // continueしてインクリメントさせないようにする
    }
    i++;
}
```

# 案3 ケツから削除
あとはこんな方法も？
合計数(-1)をカウンタ変数に入れデクリメントしながらループさせ、ケツから削除していきましょう。

```Java
for (Integer i = this.productList.size() - 1; i >= 0; i--) {
    if (this.productList.get(i).isRemove) {
        this.productList.remove(i);
    }
}
```
リモートでのスクラム・モブワークに便利なツールまとめ

# この記事について

この記事は、[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html)の開発チーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu)」にて行っているアウトプット企画である
「[チーム「オキザリス」Advent Calendar](https://qiita.com/advent-calendar/2020/oxalis)」の16日目の記事です。

# チーム「オキザリス」の働き方
私が所属しているチーム「オキザリス」では、完全リモートでのアジャイル開発・スクラム＆モブワークを実践しています。
zoomに2～7人で集まり、30分を1Sprintとして、ちょっとした開発や各種ドキュメントの作成、イベントの準備などすべて共同作業で行っています。

# リモートでのモブワークで利用しているツールたち
この記事では、チーム「オキザリス」の活動で私たちが利用しているツールたちをご紹介したいと思います。

## 1. zoom
すでに皆さんご存知かと思いますが、リモートワークに欠かせないツールがzoomです。
zoomは無料でも利用することができるオンライン会議システムです。オンラインでの会議を開催できることはもちろん、共有されている画面に対してみんなでスタンプや文字を書き入れられたり、ホワイトボードを利用して簡単な図を描いて共有したり、チャットでリンクを共有することもできます。

<div align="center">
<img width="700" alt="zoom" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345439/71656b04-7036-1a9b-25ef-9d07712d7b58.png">
</div>

私たちがモブワークでzoomを利用する際は、基本的にカメラをオンにして、お互いの顔が見えるようにして仕事を行っています。PCやカメラの性能によってはあまり画質が良くないこともありますが、なんとなくでも一緒に作業をしている方の様子や表情がわかると安心して仕事を行うことができるため、おすすめです。

## 2. Mattermost
[Mattermost](https://aslead.nri.co.jp/products/mattermost.html) は企業向けコラボレーションチャットツールです。
『[今日からできる！生産性向上のためのMattermost活用法](https://qiita.com/shiasa/items/dd0024d5416892bc19e4)』でご紹介いただいている通り、シンプルな見た目ながら様々な便利機能が備わっています。

「共有情報」や「承認依頼」のようにチャットの内容に合わせてチャネルを作成しておくことで、チーム外の人とのコミュニケーションも円滑になります。

## 3. Confluence
[Confluence](https://aslead.nri.co.jp/products/confluence.html)は企業向けwikiツールです。
こちらも『[Confluenceを使いこなそう！便利な機能5選](https://qiita.com/aykooo/items/2131fb0bdb393ecb7d96)』でご紹介いただいていますが、Confluenceではドキュメントを作成する際にオンラインで同時に同じページを編集することができます。

議事録の作成やイベントの実況を複数人で同時に行うと誤記の修正や補足の追記を随時行うことができ、とても効率が良いと感じています。

## 4. Jira Software
[Jira Software](https://aslead.nri.co.jp/products/jira.html)はプロジェクト管理ツールです。
アジャイル開発では、主にバックログの管理を行っています。
チケットごとにストーリーポイントを設定しておくことで、スプリント終了時にバーンダウンチャートを表示することもできます。
<div align="center">
<img width="700" alt="backlog" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345439/dc41a2c5-106e-bf71-aff6-753700729af5.png">
</div>

## 5. Miro
Miro はオンラインホワイトボードツールです。
スクラムではポストイットを使ってタスク管理や共有事項を管理することがあると思いますが、オンラインでは物理の付箋は利用できないため、オンラインホワイトボードであるMiroを利用しています。
Jiraで管理されているバックログアイテムの詳細化や勤怠管理などなど、アイディア次第で様々なことに利用できます。

有料プランであればビデオチャットやタイマーの利用、Jiraとの連携もできますし、無料でも連携できるツールがたくさんあるため試してみてはいかがでしょうか。

## 6. Mobster
MobStarはモブワークに便利な機能を備えたタイマーアプリです。
チームメンバーを登録し、画面上のサイコロを回すと、ドライバーとナビゲータを指名してくれます。設定した時間が経過すると、バックグラウンドで起動していたアプリが画面上に表示され、次のドライバーとナビゲータが表示されます。デフォルトでは画面全体に通知が出るため、時間を忘れて作業し続けてしまうという心配もありません。
チームが成熟してくると自発的にドライバーとナビゲータを実施するようになったため、最近はあまり使っていませんが、チームが立ち上がって間もないときはドライバーとナビゲータを指名・立候補することに多少の抵抗があるかと思いますので、機械的に決めてくれるこの機能は便利かと思います。
<div align="center">
<img width="700" alt="mobster" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345439/27a16d34-67ff-d521-fa1e-c4f5a85f9418.png">
</div>



# おわりに
普段使用しているツールを書き出してみるとたくさんあることに気が付きました。
リモートワークだからこそ必要になる新しい便利なツールを探していきたいと思いつつ、できればツールの連携機能等を活用してツール数減らしたいところですね。
micro:bitの独自カスタムブロックを作る


micro:bitのMakeCodeを使っていると関数というより新たにつける基板の拡張のブロックを作りたい時があります。ここではカスタムブロックを作り、そのカスタムブロック自体を公開せず組み込んだコードだけを共有し他人に使ってもら得る方法を説明します。

## 全体の流れ

1. MakeCodeで[ブロック]を[JavaScript]に変更する
2. 左下にあるエクスプローラーを開き[+]をクリックする
3. [ブロック]に戻し[Custom]という項目に[fib]と[foo]のブロックができているのを確認する
4. プログラムに組み込み左上の[共有]を押しURLで他人と共有する

## カスタムブロックの(雛形の)作り方

まずはカスタムブロックを作ります。
上部にある[ブロック]を[JavaScript]に切り替えコードを書く状態にします。
micro:bitのエミュレータの左下に表示されている[エクスプローラー]をひらきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/4e1f6e80-3e8a-4916-7b0a-f6bd3dbf2d00.png)

そこに表示されている[+]をクリックするとカスタムブロックを作成する雛形を作れます。
クリックするとプロンプトが表示されますので[つづける]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/9bbe54d1-1b7a-0b71-ccf5-c9d1fe2a3372.png)

画面全体がリフレッシュされエクスプローラーに[custom.ts]が追加されそれが開いている状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/f655bbd9-97ef-5db1-a2af-615a80244b70.png)

この状態で[ブロック]に戻すとリフレッシュされカスタムブロックが追加されてるのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/a9b6f3e0-faaf-b066-f62c-59dc68be9a3f.png)
※ブロックに戻すことで反映されて表示されます。

そのカスタムブロックを適当に配置することができます。どういう動作をするかはcustom.tsの中を確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/e9d8a53f-30df-23cb-cefd-aad000fb9479.png)

この作られたブロックは作ったカスタムブロックが含まれる状態で共有が可能です。
通常通り共有してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/45c4c6c1-c577-36c4-16d7-94a46f0da3ee.png)

これで他人も触れるカスタムブロックが完成しました！

## これ以降は何を・・・
基本的にカスタムブロックは他のブロックなどgithub上に存在してるので、その中身を参考にしたりしながらコードを改造します。
ある程度出来上がってきたら保存の横にあるgithubアイコンをクリックすると自身のgithubにカスタムブロックを公開できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/07039172-ba29-9b91-cc6f-5b4feb2c555d.png)
ただし公式のものとは違い拡張機能から検索する場合にはgithubのURLをいれる必要があります。
OCaml Upcoming Changes 2020: __FUNCTION__

この記事は[ML Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ml) 15日目の記事です。

OCamlにそろそろ入りそうな機能を紹介します。

今回は、次のOCaml 4.12で入る [Add primitive \_\_FUNCTION\_\_ that returns the name of current scope by nojb · Pull Request #9554 · ocaml/ocaml](https://github.com/ocaml/ocaml/pull/9554) の紹介をします。

---

OCamlの`Stdlib`には`__FILE__`, `__LINE__`, `__POS__`, `__LOC__`, `__MODULE__` といった、現在のソースコード上の位置や、現在のモジュール名を取得するための値が用意されている。

このPRではさらに、 `__FUNCTION__` という、現在のスコープ名を文字列として取得する値を導入する。このとき得られる文字列は、OCaml 4.11.0以降でバックトレースに表示される関数名と同じ形式だ（[Print function names in backtraces by stedolan · Pull Request #9096 · ocaml/ocaml](https://github.com/ocaml/ocaml/pull/9096) を参照）。ちなみに、 `__FUNCTION__` という名前にもかかわらず、現在定義中の変数の名前や、メソッドの名前も取ることができる。

具体的にどのような名前が得られるかを見てみよう。

```ocaml:locs.ml
let f = __FUNCTION__

module Mod1 = struct
  module Nested = struct
    let f () = __FUNCTION__
  end
end

let anon () =
  Fun.id (fun () -> __FUNCTION__) ()

let local_module () =
  let module N = struct
    let foo () = __FUNCTION__
  end
  in N.foo ()

class klass = object
    method meth () = __FUNCTION__
end

let () =
  print_endline @@ f;
  (*
    Locs.f
    変数定義の右辺の場合は、現在定義中の変数名が取れる。
    先頭のLocsはこのファイルがLocsモジュールになることに由来する。以下同じ
   *)

  print_endline @@ Mod1.Nested.f ();
  (*
    Locs.Mod1.Nested.f
    モジュールを入れ子にするとそれがパス風に付加される
   *)

  print_endline @@ anon ();
  (*
    Locs.anon.(fun)
    関数anon内の無名関数。無名関数は (fun) で表現する
   *)

  print_endline @@ local_module ();
  (*
    Locs.local_module.N.foo
    関数 local_module 内のローカルモジュールN、さらにその中の関数foo
   *)

  print_endline @@ (new klass)#meth ();
  (*
    Locs.klass#meth
    klassクラスのメソッドmeth
   *)

  ()
```

モジュール内の要素を参照するときのモジュールパスと似たような形式になっている。[ocaml/testsuite/tests/translprim/locs.ml](https://github.com/ocaml/ocaml/blob/f177b95042f656983dc084eb35ab4a5364f491e7/testsuite/tests/translprim/locs.ml#L48), [ocaml/testsuite/tests/translprim/locs.reference](https://github.com/ocaml/ocaml/blob/f177b95042f656983dc084eb35ab4a5364f491e7/testsuite/tests/translprim/locs.reference#L12) にはより複雑な例がある。

ちなみに、この機能はコンパイラプリミティブとして提供されているので、ユーザーレベルで同じような機能を実現することはできない。おおまかな流れとしては以下のように `Typedtree` から `Lambda` に致る段階で識別子の参照から文字列定数へ置き換えられている（`Parsetree`、`Typedtree`、`Lambda` はコンパイラの中間表現の名前）。

1. ソースコード: `__FUNCTION__` <br /> ↓ 構文解析
1. Parsetree: `Pexp_ident "__FUNCTION__"` <br /> ↓ 型推論・型検査
1. Typedtree: `Texp_ident "Stdlib!.__FUNCTION__"` <br /> ↓ パターンマッチのコンパイル。モジュール、クラスの除去。 `__FUNCTION__` 等プリミティブの変換
1. Lambda: `Lconst (Const_immstring "Locs.f")` <br /> ↓ バイトコード/ネイティブコード生成へ
1. …

各ステップの様子は `ocamlc -dparsetree -dtypedtree -dlambda` のようにしてコンパイラを実行すると見ることができる。
GatsbyでSEO対策をする

##メタデータを追加するための準備

```
yarn add gatsby-plugin-react-helmet react-helmet
```


gatsby-config.jsに`gatsby-plugin-react-helmet`の設定を追加する


####gatsby-plugin-react-helmet
このプラグインを使って、タイトルやメタ属性などの属性をコンポーネントに追加すると、それらがGatsbyが構築する静的なHTMLページに追加されます。これはサイト閲覧者にとってだけでなく、SEOにとっても重要です。


####react-helmet
headタグの管理をするコンポーネント


##メタデータの設定を記述するファイルを準備

```
import React from "react";
import {Helmet} from "react-helmet";

class Application extends React.Component {
  render () {
    return (
        <div className="application">
            <Helmet>
               <html lang="言語の種類" />
　　　　　　　　　<meta charSet="utf-8" />
               <title>My Title</title>
　　　　　　　　　<meta name="description" content="説明" />
               <link rel="canonical" href="http://mysite.com/example" />
            </Helmet>
            ...
        </div>
    );
  }
};
```


##サイト全体で使用するメタデータの値を用意する
サイト全体で繰り返し使用したいメタデータは、siteMetadataとして用意しておくとGraphQLのクエリで取得できるようになる


gatsby-config.js

```
module.exports = {
/* Your site config here */
siteMetadata: {
title: `Example`,
description: `Example description`,
lang: `ja`,
siteUrl: `https://*******.netlify.app`
},
plugins: [
...
```


##ページごとにメタデータの値を変える

example.js


```
export default ({data}) => (
  <Layout>
    <SEO
      pagetitle="example"
      pagedesc="example description"
    />
   <div>
   ...
```



参考文献：
Webサイト高速化のための静的サイトジェネレーター活用入門
react-helmet: https://github.com/nfl/react-helmet
gatsby-plugin-react-hemet: https://www.gatsbyjs.com/plugins/gatsby-plugin-react-helmet/
Pythonを使ったSlack APIで特定のチャンネルの特定のユーザーの一定期間経過しているメッセージを削除する方法

## 前提
Slack APIの登録方法及び、Slack APIの使用方法の説明は省略しています。
まだ、お済みでない方は下記URLより登録してください。
https://api.slack.com/

##### 参考文献
https://qiita.com/kou_pg_0131/items/56dd81f2f4716ca292ef


## 目的
Slack APIで、特定のチャンネルの、特定のユーザーの、投稿されてから3日以上経過しているメッセージを削除する。

## 使用する言語
Python3.8.5

## 手順
①Slack APIで、特定のチャンネルのメッセージを取得し、その中のメッセージのタイムスタンプを取得する。
②メッセージのタイムスタンプの中から、Slack APIで、3日以上経過しているメッセージを削除する。

##使用するSlack API
・特定のチャンネルのメッセージのタイムスタンプを取得するのは、`conversations.history`
https://api.slack.com/methods/conversations.history
・メッセージを削除するのは、`chat.delete`
https://api.slack.com/methods/chat.delete

## ソースコード
```python
# 必要なライブラリのインポート
import requests
from datetime import datetime
import re

# チャンネルを指定してメッセージを取得する
# Web APIのURL
url = "https://slack.com/api/conversations.history"
# ワークスペースのトークン
token = "ワークスペースのトークン"
# 対象のチャンネルのID
channel = "対象のチャンネルのID"

# 各メッセージのタイムスタンプの格納用のリスト
timestamplist = []

# 情報を辞書型にする
payload = {"token": token,  "channel": channel}
# チャンネル情報の取得
response = requests.get(url, params=payload)
# json形式に変換
message_json = response.json()

# メッセージのタイムスタンプをリストに格納していく
for m in message_json["messages"]:
    try:
        # user一覧のリストを作成(重複あり)
        timestamplist.append(m["ts"])
    # tsキーがない場合、KeyErrorとなるので例外処理
    except KeyError:
        pass
print(timestamplist)

# 今日の日付のタイムスタンプを取得
current_ts = int(datetime.now().strftime('%s'))
# チャンネルの特定のユーザーのメッセージを削除
for ts in timestamplist:
    # Web APIのURL
    url = "https://slack.com/api/chat.delete"
    # ワークスペースのトークン
    token = "ワークスペースのトークン"
    # 対象のチャンネルのID
    channel = "対象のチャンネルのID"
    # 3日前
    term = 60 * 60 * 24 * 3
    # タイムスタンプ
    ts = ts
    # ユーザーの指定
    as_user = "ユーザーのID"
    # 現在からタイムスタンプが3日以上経過している場合、メッセージを削除
    if current_ts - int(re.sub(r'\.\d+$', '', ts)) > term:
        payload = {"token": token,  "channel": channel,
                   "ts": ts, "as_user": as_user}
        response = requests.post(url, params=payload)
        json = response.json()

```

##補足

###as_user
上記のソースコードでは、変数as_userに特定のユーザーのIDを渡すことで、
対象期間内の特定のユーザーのメッセージを削除するようにしています。
ユーザーを指定しない場合は、対象期間内の全ユーザーのメッセージが削除されます。

### 変数term
Pythonでは、「秒 * 分 * 時間 * 日」とすることで、時間間隔を表すことができます。
例えば、1週間では、「60 * 60 * 24 * 7」と、12時間30分40秒では、「40 * 30 * 12」となります。
この数値を変えることで、削除の対象となるメッセージの範囲を変えることができます。


### reモジュール
Pythonで正規表現の処理を行うための標準ライブラリ。
正規表現パターンによる文字列の抽出や置換、分割などができる。

#### subメソッド
マッチした部分を他の文字列に置換することができる。
使い方は以下の通り。
`sub(r'置換したい文字列', '置換後の文字列', 対象のオブジェクト名)`
今回の`re.sub(r'\.\d+$', '', ts)`の場合、
「tsにおいて、ドット以降末尾まで半角数字がある場合、空に変換(削除すると同義)する。」という意味になる。

#####参考文献
・Pythonドキュメント
https://docs.python.org/ja/3/library/re.html
・Pythonの正規表現モジュールreの使い方（match、search、subなど）
https://note.nkmk.me/python-re-match-search-findall-etc/

## 参考文献
https://michimani.net/post/programming-delete-old-slack-messages/
FlutterのAndroid開発における64K問題の解決方法

## TL; DR
Androidでは、アプリおよびアプリが参照するライブラリが65,536メソッドを超えるとビルドエラーが発生します。
65,536 = 64 × 1,024(K)なので64K問題と言います。

## 解決策1: アプリが使用するメソッドやライブラリを見直す
一番シンプルで当たり前の解決策。とはいえ、必要だからライブラリを入れているのであって、実際に効果はそこまで期待できないと思われます。
実際は、解決策2, 3のどちらかを選択することになるでしょう。

## 解決策2: 対象のSDKを21以上にする
Android 5.0(API 21)移行ではデフォルトでmultidexに対応しているので、何らかの理由でそれ以前のバージョンに対応する必要がなければ単純に対象のSDKを21以上にするのが良いです。

```android/app/build.gradle
android {
    defaultConfig {
        applicationId "com.example.sample"
        // minSdkVersion 16
        minSdkVersion 21 // 最小サポートSDKを21以上にする
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
}
```

## 解決策3： multidexサポートライブラリを使用する
何らかの事情がある場合にはmultidexサポートライブラリを使用することでも解決できます。

```android/app/build.gradle
android {
    defaultConfig {
        applicationId "com.example.sample"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        multiDexEnabled true // multidexサポートライブラリを使用する
    }
}
```



## 解決策4: ビルド時に圧縮する（参考）
Flutterでできるのかは要調査（調査するとは言っていない）。
ビルド時に不要なメソッドを除くことができるはず。

## 検索用
**1. `flutter run`を実行した際に64K問題が発生したときのログ**

この時は、`cloud_firestore`を`pubspec.yaml`に追加したことでアプリ全体のメソッド数が85242個と64Kよりも大きくなってしまった。

```
D8: Cannot fit requested classes in a single dex file (# methods: 85242 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
The number of method references in a .dex file cannot exceed 64K.       
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
```

## 参考資料
https://developer.android.com/studio/build/multidex?hl=ja
Everyday Rails でRSpecを学ぶ。サンプルアプリをbundle install するまで。

テストコードの重要性を認識して、everyday rails にてRSpecを学びはじめました。
bundle installできるまでに時間がかかったので
記事にします。

まず、git hub からgit clone　してきます。
そしてbundle install.
できない。

nokogiriのエラー。
source ~/.bash_profileにて環境変数を変えることにより解決。

gem ffiがインストールできない。

Gemflie.lockを削除後、bundle installで解決！

やった！
FortiGate チートシート

# FortiGate チートシート

「あれどうやるんだっけ？」となった時のためのメモ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83224/af4e7911-a51e-d0da-cb6f-3fb7e6b12ff0.png" width="200">

## FortiCloud 無効化
```
config system central-management
set type none
end
```

## FortiGate Setup 無効化
```
config system global
set gui-firmware-upgrade-setup-warning disable
end
```
## WAN インターフェース設定
PPPoE接続
MTU: 1454
MSS: 1414 (MTU - 40)

```
config system interface
edit "wan1"
set mode pppoe
set allowaccess ping
set tcp-mss 1414
set role wan
set username "foo@sample.com"
set password himitsu
set dns-server-override disable
set mtu-override enable
set mtu 1454
next
```

## アドレス追加・変更
```
config firewall address
edit "pc01"
set subnet 192.168.0.10 255.255.255.255
next
edit "network01"
set subnet 192.168.0.0 255.255.255.0
next
end
```

## アドレスグループ追加・変更
```
config firewall addrgrp
edit "team4"
set member "pc01" "pc02"
end
```

## SSL-VPN タイムアウト値の調整
idle: 300 -> 5min
auth: 28800 -> 8h

```
config vpn ssl settings
set idle-timeout 300
set auth-timeout 28800
end
```

## セッションタイムアウトの調整

```
準備中
```
【Ruby】演算子"::(コロンコロン)"【定数】

#まえがき
Railsを使っていれば、誰でも以下の記述を見たことあると思います。

```ruby:models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
#以下省略
```
`ApplicationRecord`に`ActiveRecord::Base`を継承していますよね。

なんにも変わったことありませんね。


・・・

・・

・

って、え、え、ちょっと待って下さい。
なんですか、`::`って！？！？！？
怖い！！！

ということで、Ruby初学者である私が、`::`について調べたことを健忘録として残します。

#結論
`::`は２つの特徴があります。

1.`名前空間の絶対パスを指定する`

```ruby
module Hoge
  class Fuga
    def self.fuga
      p "fugaです"
    end
  end
end

Hoge::Fuga.fuga #=> "fugaです"
Fuga.fuga #エラー

#Fugaクラスを作成
class Fuga
  def self.fuga
    p "fugaです"
  end
end

Hoge::Fuga.fuga #=> "fugaです"
Fuga.fuga #=> "fugaです"
```

2.`定数のスコープ演算子`

クラスまたはモジュールで定義された定数をスコープ外部から参照するためには`::`を使います。

```ruby
class Hoge
  FUGA = "FUGA" #定数FUGA
  
  p FUGA #=> "FUGA"
end

#スコープ外から定数FUGAを出力する。
p Hoge::FUGA #=> "FUGA"

```
また、**Rubyではクラスやモジュールも定数として扱われます。**
例えばHogeクラスを生成した時、Hogeクラスオブジェクトは、**Hogeという名前の定数**に代入されています。

# 結局、ActiveRecord::Baseの`::`は？？
ActiveRecord::Baseの`::`は**ActiveRecordモジュール内のBaseクラスを指しています！！**
ActiveRecordにネストされたBaseクラスなんですね〜。
簡単に書くと以下の通りです。

```ruby:active_record/base.rb
module ActiveRecord

#省略

  class Base
  #省略
  end

#省略

end
```
ActiveRecord::Baseの正式な中身は以下の通りです。
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb

ActiveRecordの機能についてはこの方が深くまとめております。
[Rails: ActiveRecord::Baseメソッドのまとめ
]("https://qiita.com/penguin_note/items/adb0b9bf7c13c1b1d44d")

#参考
Ruby公式リファレンス 変数と定数
https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html#const

Railsガイド Active Record の基礎
https://railsguides.jp/active_record_basics.html
Djangoチュートリアルまとめ

# 概要
Djangoチュートリアルを通して学んだDjango開発のフローを備忘録的にまとめていきます。チュートリアルを始める前にイメージを掴むための記事です。
[Djangoチュートリアル](https://docs.djangoproject.com/ja/3.1/intro/tutorial01/)では簡単な投票アプリを作ることで基本的な機能を学ぶことができます。
# 流れ
プロジェクト作成
⇨アプリ作成（モデル⇨ルーティング（URL）⇨ビュー（フロント＆バック））
※機能ごとにアプリを分けていくイメージ
## イメージ図
「Django アーキテクチャ」で検索すると、それぞれのファイルの役割の関係図・イメージ図を知ることができます。
チュートリアルを始める前に、それぞれの関係をつかんでおくことをおすすめします。
アーキテクチャ図が載っている記事

- [基礎から学ぶDjango開発①](https://medium.com/@kosa3/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6django%E9%96%8B%E7%99%BA%E2%91%A0-14066e174ef4)
- [MDN Djangoの紹介](https://developer.mozilla.org/ja/docs/Learn/Server-side/Django/Introduction)

## よく使うファイル
- model.py
データモデルの定義を行う

- view.py & templeates
View(見た目)を作る。HTMLファイルをTemplatesフォルダ配下におき、バックエンドの処理をView.pyで定義します。

- urls.py
ルーティング（URL,パス）に関する処理を定義

- settings.py
設定に関するファイル

- admin.py
Django特有の機能であるDjango Adimin(ブラウザ上でDBの作成などができる)の設定に関するファイル
## 開発環境
今回はDockerを使って開発した。
公式のガイドである[クィックスタート: Compose と Django](https://docs.docker.jp/compose/django.html)を参考にした。
このドキュメントにしたがって作成してもDBの設定情報を書かないとエラーが出る可能性があるので以下の記事などを参考に修正を・・・
[djangoとpostgresqlをDockerで接続しようとしたときに「django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known」というエラーが出る](https://qiita.com/takos/items/c04ac2a64d519894ee13)
【自分用】VueがIE11で動かなかった

WebpackとBabelを通しているがIE11で何も表示されなくなった

```
SCRIPT1002: Syntax error
```

Eval関数のところでエラーが出ていたので、webpackに以下の設定を追加してみたが、直らなかった

```javascript:webpack.config.js
module.exports = {
    //...
    devtool: 'none'
}
```

原因はvueの読み込みところだった

```javascript:script.js
import Vue from 'vue/dist/vue.esm.browser.min.js'
```

以下に変更

```javascript:script.js
import Vue from 'vue'
```

`resolve.alias` の設定がされていないので、追加

```javascript:webpack.config.js
module.exports = {
    //...
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
        }
    }
}
```

`resolve.alias` の指定は以下の記事を参考にした
https://blog.websandbag.com/entry/2020/08/07/190655

他のPJでは動いていたので、根本的な原因は別のところにあると思うが、とりあえず解決したのでここまで
DynamoDBでアイテム新規作成時にcreatedAt, updatedAtを保存し、更新時にはupdatedAtだけを更新する

`if_not_exists`を使用して`updateItem`を行えばよい。

```
    // use if_not_exists()
    UpdateExpression: `SET #QQ_ID = :answer, #updatedAt = :updatedAt, #createdAt = if_not_exists(#createdAt, :createdAt)`,
    ExpressionAttributeNames: {
        '#QQ_ID'   : `QQ_${question_id}`,
        '#updatedAt': 'UpdatedAt',
        '#createdAt': 'CreatedAt',
    },
    ExpressionAttributeValues: {
        ':answer': answer,
        ':updatedAt' : now.toISOString(), 
        ':createdAt' : now.toISOString(), 
    }
```
https://stackoverflow.com/questions/53666369/how-to-upsert-item-in-dynamodb-and-maintain-createdat-and-updatedat-fields


>if_not_exists (path, value)
>指定された path で項目が属性を含まない場合、if_not_exists は value に評価されます。それ以外の場合は、path に評価されます。
>https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET

# 参考
- [DynamoDBでレコードがない時は作成、あるときは値をインクリメントする方法 | Simple is Beautiful.](https://blog.kozakana.net/2019/11/create-if-no-item-in-dynamodb-increment-if-exist-item/)
ITMS-90626エラーの解決方法


#**ITMS-90626エラーの解決方法**

##■問題

バイナリをAppStoreConnectにアップロードした後、ITMS-90626エラーが発生した。
※アップロード自体は成功したが、メールにて通知がきた。
（環境：XCode 12.2 / macOS Catalina)

![スクリーンショット 2020-12-15 16.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51578/ce351bc4-15da-d818-872d-01649132a480.png)

◇実際のエラー内容
```ITMS-90626: Invalid Siri Support - Localized title for custom intent: 'Configuration' not found for locale: ja```

##■原因
調べるとどうやらiOS14から追加されたWidgetKitを追加したことが影響していたようだ。

Siriに関する実装はしていないはずなのにSiri関連のエラーはおかしいなと思ったら、
WidgetKitをターゲットに追加する時のウィザードで、Configurationを有効にして作成すると、自動的にSiri Intent Definitionというものが作成されていた。

今回のエラーは、その作成されたSiri Intent Definition(*.intentdefinitionファイル)のローカライズがされていないための警告だった。

![スクリーンショット 2020-12-15 16.38.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51578/ebe85559-c66f-6c72-284f-b4dc3f39fafa.png)

##■対策
今回は、このSiri Intent Definitionを特に意識的に使用していないのだが、Widget側のコードにもConfigurationIntentが登場しており、単純にターゲットから外す訳にはいかないので、Siri Intent Definitionのローカライズを追加することで対応した。

![スクリーンショット 2020-12-15 17.16.40 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51578/cf36b9da-7e57-2daa-1062-ca6a07308ec4.png)

しかし、よくよく考えてみると、既にウィジェット機能を追加したアプリは公開済で、前回まではこのエラーは発生していなかった。
今回のアップデートで追加した機能が関係するとすると、
アプリ側の永続化データをウィジェット側で取得したくなり、
UserDefaultsの連携ができるように、App Groupsの追加をしたので、
そのことが関係するのかもしれない。

※ローカライズの話なので、日本語化、多言語対応とかした場合に直接顕在化する問題だと思うが、その対応は前回以前にしていたので、このタイミングで出たエラー理由ではなさそう。
ま、あとはApple側のチェック機構がこのタイミングでなされたかですかね。
Amazon Linux2 + Freenom + Let's Encrypt で 無料で HTTPS 化する

Amazon Linux2 + Freenom + Let's Encrypt で 無料で HTTPS 化したので、後で同じ作業を行ったときに困らないときようのためにメモ。
基本は Let's Encrypt の作業をメインに書いていく。



#EC2#

- 証明書を発行するための、セキュリティグループ インバウンド 80,443 ポートを開けておく。

#Freenom#

- ドメイン名を取得済であり、Aレコードを作成済であること。
 - www.naata.com IN A IPアドレス

#Let’s Encrypt#

##Let’s Encrypt のCertbot クライアントをインストール##

```
$ sudo amazon-linux-extras install epel
```

##certbot、python-certbot-apache のパッケージをインストール##

```
$ sudo yum install certbot python-certbot-apache
```

##ServerNameの編集##

```http:httpd.conf
ServerName:www.naata.com
```

##certbotコマンドによるサーバー証明書の取得##

```
$ sudo certbot certonly --webroot -w /var/www/html/ -d www.naata.com
```

```
$ sudo ls -l /etc/letsencrypt/live/www.naata.com
total 4
lrwxrwxrwx 1 root root  56 Sep 25 07:50 cert.pem -> ../../archive/www.naata.com
lrwxrwxrwx 1 root root  57 Sep 25 07:50 chain.pem -> ../../archive/www.naata.com
lrwxrwxrwx 1 root root  61 Sep 25 07:50 fullchain.pem -> ../../archive/www.naata.com
lrwxrwxrwx 1 root root  59 Sep 25 07:50 privkey.pem -> ../../archive/www.naata.com
-rw-r--r-- 1 root root 692 Sep 25 07:50 README
```

##httpdの再起動##

```
$ sudo systemctl restart httpd.service
$ sudo systemctl status httpd.service
```

##ssl.confの編集##

```http:ssl.conf
SSLCertificateFile /etc/letsencrypt/live//www.naata.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live//www.naata.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live//www.naata.com/chain.pem
```

#動作確認#

```
$ curl -vv https://www.naata.com
```
SSMSでストアドプロシージャ実行までの流れ

# 対象
SSMSでストアドプロシージャを作成しようとして詰まっている人
ストアドプロシージャがなにか、とかはここでは触れません
代わりに手順だけはできるだけ詳細に書いていきます

##まず
SQL serverとSSMSのインストールを済ませておいてください。

##手順
SSMSを立ち上げてサーバー名を選択して接続。
データベースを右クリック→｢新しいデータベース｣
データベース名を入れてOK

できたデータベースをダブルクリックして一個下の階層に入る。
テーブルを右クリック→｢新規作成｣→｢テーブル｣でテーブルをつくります。
今回は例として簡単なものを。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955588/d436c1f2-13c7-55f8-d97f-1511bd0a62a5.png)

テーブルの名前を付けて保存。

テーブルの下の階層にdbo.テーブル名というのができているので右クリック→上位1000行の選択
そうするとSELECT文が出てくるのでFROM以降の部分をコピー。

```SELECT TOP (1000) [student_name]
      ,[student_id]
  FROM [db_example].[dbo].[table_example]```

(ここなら[db_example].[dbo].[table_example]をコピー。)
(赤い波線が出ている人はSSMSを一度再起動してください。)

次に上部の｢新しいクエリ｣を選択。

例としてINSERT文を入れます。

```CREATE PROCEDURE insert_example
AS
BEGIN
INSERT INTO [db_example].[dbo].[table_example] VALUES 
	('hogehoge',
	1)
END```

この状態で左上の実行を一度押すと｢コマンドは正常に完了しました。｣とでます。
二度押すと｢データベースに 'insert_example' という名前のオブジェクトが既に存在します。｣とでますが気にしないでください。

オブジェクトエクスプローラをプログラミング→ストアドプロシージャと進むとdbo.insert_exampleができているので右クリック→｢ストアドプロシージャの実行｣→OK。

これでINSERTされたはずです。
確認のためにdbo.table_exampleをもう一度右クリック→上位1000行の選択。
レコードが追加されているはずです。
自動運転システムについて

<h1>はじめに</h1>
　<p>自動運転車は、これからのAI時代におけるシンボル的存在となる乗り物です。国内外で多くの自動運転システムが開発されているので、今回調べました。</p>
<h2>自動運転車について</h2>
<p> 自動運転車とは「運転操作が自動化される」車のことです。今まではドライバーが目的地まで車を運転していましたが、ドライバーは何もしなくても目的地にたどり着くことが可能になる時代もそう遠くないと考えられています。
自動運転は、米運輸省道路交通安全局（NHTSA）が発表した6段階の「自動運転レベル」で定義されています。</p>

レベル0：運転自動化なし
レベル1：運転支援
レベル2：部分運転自動化
レベル3：条件付き運転自動化
レベル4：高度運転自動化
レベル5：完全運転自動化

現在、日本では、レベル3までが解禁されています。
<h3>自動運転車のメリット</h3>
　<p>自動運転車のメリットは次の4つが考えられます。</p>
**1、運転から解放される**
<p>自動運転が実現されれば、長距離運転や知らないところを走行するときに運転する緊張感から解放されます。</p>
**2、交通事故の減少**
<p>自動運転になれば、操作ミスなどがなくなり、事故が少なくなります。</p>
**3、環境問題に貢献**
<p>必要以上の2酸化炭素をしたりしなくなります。</p>
**4、運転できない人の移動手段となる**
<p>高齢者や、障害がある人でも車を運転することができます。</p>
<h4>自動運転車のデメリット</h4>
<p>自動運転車が普及すると、これまでの生活スタイルが大きく変わる楽しみがありますが、まだまだ課題は多くあります</p>
**事故発生時の責任**
**システムのトラブルやハッキングの問題**
**緊急時などのドライバーの対応**
**事故不可時などの高度な判断**
**自動車・交通産業の就職人口に影響**
<p>など現在でもさまざまな問題がありますが、今後自動運転技術が発達するにつれ、ほかの問題が出てくる可能性があります。</p>
<h5>まとめ</h5>
<p>今回調べてみて、自動運転車にはたくさんのメリットがあるが、まだまだたくさんの問題があることがわかった。自分も技術者として、たくさんのプログラムに携わる可能性があるので、もっと勉強したいと思いました。</p>
MacでVirtualBox使っててホストオンリーアダプターが設定できない

`brew`で入れた。

metasploitable3をvirtualboxで運用したかったので、導入したらNATしか使えなかった。

ネットワーク設定で、ホストオンリーアダプターを選択すると名前が未選択になる。
こいつが原因だが、デフォルトではなぜかホストのアダプターが追加されていない。

下記サイトの通りにしたらできた。
http://by-oneself.com/mac_virtualbox/

関連：https://qiita.com/aru12/items/29a677360a12371e0424
自動ドアについて

<h1>はじめに</h1>
 <p> 身近にある自動ドアがどんな仕組みなのか気になって調べてみました。</p>
<h2>自動ドアの各装置</h2>
**ドアオペレーター**
 <p>ドアを開閉動作させる駆動装置、制御装置の一式です。
ドアエンジン、コントローラー、従動プーリ―、ドアハンガ―、ドアストッパー、ベルトなどから構成されます。</p>
**メンテナンス用スイッチ**
<p>メンテナンス時にドアオペレーターの電源ON、OFF に使用します。</p>
**起動センサー**
<p>通行者を検知し、ドアオペレーターに作動信号を送信します。</p>
**補助光電センサー**
<p>起動センサーでは検知しにくいドア軌道上の人や物を検知し、
ドアオペレーターに作動信号を送信します。</p>
**閉保護センサー**
<p>閉じ作動中にドアと衝突する可能性がある領域を監視するセンサーです。
閉じ作動中にセンサーが検知するとドアへ検知信号を送信します。</p>
**無目**
<p>ドアオペレーターなどを納めるためのケースです。</p>
**ガイドレール**
<p>ドアの床面に設置した案内用レールです。</p>
**錠前**
<p>ドアを手動で施錠・解錠するための鍵です。</P>
などがあります。
<h3>センサーについて</h3>
<p>自動ドアにはセンサーが装備されており、「起動センサー」、「補助センサー」、「保護センサー」に分けられます。</p>
**起動センサー**
<p>ドアを開けるためのセンサー。
光線反射・電波方式とタッチ方式があります。</p>
**補助センサー**
<p>ドア通過中の人やドア間近で停止した人などが、閉じるドアに挟まれないよう安全性を高めるセンサー。
光電方式、光線反射方式、超音波方式があります。</p>
**保護センサー**
<p>ドア通過中の人やドア間近で立ち止まった人などが、閉じるドアに接触（衝突）しないよう、ドアの作動範囲を監視するセンサー。
光電方式、光線反射方式があります。</p>
<h4>自動ドアが反応しない理由</h4>
<p>自動ドアが反応しない理由はセンサーによって違いがありました。</p>
**赤外線反射センサー**
<p>このセンサーは色や素材で左右されることが多いため、反射がうまく返ってこないと、それらの差を判断ができず反応しません。</p>
**光電センサー**
<p>通過するものの表面積が大きければ作動しやすいため、痩せていると検知しづらくなります。</p>
**感圧マット**
<p>およそ10kg以上で作動するようになっており、感度によっては上で飛んだり跳ねたりしないと作動しない場合も多々ありました。</p>
などがありました。
<h5>最後に</h5>
<p>身近にある自動ドアの仕組みが少しわかった。
小さいときに自動ドアがなかなか反応しない理由が分かった。
自動ドアは接触することなくドアが開くので感染症対策になると思った。
</p>
<p>参考サイト
https://www.seikatsu110.jp/corporative/co_automatic_door/15936/
https://nabco.nabtesco.com/automatic-door/structure/
</p>
【CakePHP】bin/cake bake migration_diff 差分を生成できない。

## 前提・実現したいこと

```
bin/cake bake migration_diff
```
でDBとの差分を生成したい。


## 発生したエラーメッセージ

```
Your migrations history is not in sync with your migrations files. Make sure all your migrations have been migrated before baking a diff.
```

## Google翻訳

```ここに言語名を入力
移行履歴が移行ファイルと同期していません。 差分をベイクする前に、すべての移行が移行されていることを確認してください。
```

## 原因

・cakeのapp内にある、マイグレーションファイルと、DB内にあるphinxlogテーブルが同じ状態でなかったためエラーを吐いていた。

## 対応

app内の方を基準としたかったので、phinxlogテーブルにある不要レコードを削除し、実行したら通りました。

## 開発環境
MAMP
cakephp3.7.3
Visual Studio Code のショートカットキー

<h1>Visual Studio Code のショートカットキー</h1>
普段授業でVisual Studio Codeを使用してコーディングを行っていますが、より効率的に行うためにはショートカットキーを使うととても便利です。よりはやくコーディングできるように今回は代表的で便利なショートカットキーを調べてみました。
<h2>基本操作</h2>
**エクスプローラーを開く**
<p>Ctrl + Shift+ E</p>
HTMLの授業などでブラウザで確認するときにキーボードから手を放さずに時短することができます。
<br>
**名前を付けてファイルを保存**
<p>Ctrl + Shift + S</p>
今のコードを一回崩さないようにしたい時などに一度別の名前で保存することで試し書きなどをしやすくなります。
<br>
**コマンドパレットを開く**
<p>Ctrl + Shift + P</p>
コマンドパレットを使えばいろいろなことができるようです。そのためこのショートカットキーを覚えておけば色々なことが素早くできます。
<br>
**行選択**
Ctrl + L

これを使うことで行選択を行えます。いちいちマウスを握るもありません。
<h2>コーディング</h2>
**選択行の移動、削除、コピー**
<p>Alt + 矢印,Ctrl + Shift + K ,Alt + Shift + 矢印</p>
私はいままで行の選択をマウスで行っていましたが、キーボードだけでできると知ったので使ってみようと思いました。
<br>
**タグで囲う**
1,囲みたい部分を選ぶ
2,コマンドパレットで「wrap with abbreviation」を選ぶ
3,ひな形が出てくるので名前を入力

見た中で一番すごいなと思いました。後からここ囲めばよかったと思ったところを一発で囲めてしまいます。
<br>
**文字の置換**
Ctrl + H

これを使うことでワークスペース内の同じ文字を一気に置き換えることができます。スペルミスなどがあったときに使用すると便利です。
<br>
**現在行をコメントアウト（toggle）**
Ctrl + /

これで選んでる行をコメントをつけたり、外したりできます。一度その行を消して実行してみたい時などに便利だと思います。

<br>
**複数行をコメントアウト（toggle）**
Shift + Alt + A

一つ上で紹介した複数行バージョンです。この前で紹介した行選択と組み合わせるとなおいいと思います。
<h1>感想</h1>
今回紹介したのは一部のみで、もっとたくさん使い勝手のいいものもあると思います。ショートカットキーを使うことで作業効率が上がっていくと思うので自分にあったショートカットキーを皆さん探してみてください。
Method Illuminate\Http\UploadedFile::getClientSize does not exist. と出た場合の対処法

# 結論
```top.php
$request->file('file')->getClientSize()
               ↓ //変更する
$request->file('file')->getSize()
```
新しいバージョンのLaravelだとgetClientSize()は使えないみたい(;´Д｀)
Linuxについて①

Linuxはosの一種であり、コンピュータを動かすための基本ソフト
1991年にリーナス・トーバルズが開発

▼用途
サーバー（web業界）
組み込み
デスクトップ等々


▼特徴
オープンソースである⇨誰でも自由に使える
品質の高いソフトウェアが利用できる

▼欠点
日本語対応していない
商用アプリケーションがあまり存在しない（画像、動画、音声が苦手）


以上
リロードしないとJavascriptが動かないバグを修正

# はじめに
Rails6.0でアプリを作成していてJavascriptでタブUIの実装をしました。
いざブラウザで確認してみると、該当ページを開いているうちは問題なく動作するのですが
ページ遷移をしてもう一度該当ページに戻ってくると、タブのコンテンツが真っ白になってしまいました。。


その画面でリロードすると正しく動作をするのですが、これではアプリとしてよろしくないので
今回はこのバグの修正の仕方をまとめたいと思います。

# 目次
[1.バグの正体：Turbolinks](#1-バグの正体：Turbolinks)
[2.解決方法](#2-解決方法)

## 1. バグの正体：Turbolinks
そもそもTurobolinksとは？

Rails4から公式に導入されたGemのひとつです。
簡単に言えば、**ウェブアプリケーションをより速く導いてくれる機能**が備わっています。

turbolinksでページ遷移するときはページの表示に必要なすべての要素を読み込まずbody要素だけ入れ替えます。しかも入れ替えるときにはjavascriptやjsonを読み込まないでHTMLだけ読み込むのでページ遷移が高速化するという仕組みです。

タイトルにある通り、リロードしないとJSファイルが読み込まれないのは、ページ遷移時にTurbolinksがJSファイルを読み込まないことが原因で起こっていたんですね。

## 2. 解決方法
解決方法は複数あるようですが、今回はJSファイルにturbolinks:loadというイベントを追加する方法で解決します。このイベントはturbolinksが働くごとにjavascriptを読み込むことを意味します。

```php:test.js
document.addEventListener("turbolinks:load", function() {
  // 処理内容
})
```
この記述をすることでページが遷移しても本来JSファイルを無視するTurbolinksがうまくJSファイルを読み込んでくれるようになります！

# おわりに
最後まで読んでいただきありがとうございました！
お疲れさまでした。。
【Rails】dockerでrailsコンソールを使う方法

個人メモです。

dockerで起動しているアプリケーションのrails consoleにアクセスする方法。

dockerのコンテナ内で`rails c`を実行する。


##rails consoleの起動

```:ターミナル
##入りたいコンテナ名を確認
docker ps

##コンテナに入る
docker exec -it コンテナ名 /bin/bash

##railsコンソールを開く
root@96913c74e902:/app# rails c

`Redis#exists(key)` will return an Integer by default in redis-rb 4.3. The option to explicitly disable this behaviour via `Redis.exists_returns_integer` will be removed in 5.0. You should use `exists?` instead.
Loading development environment (Rails 6.0.3.2)

irb(main):001:0>
```

ターミナルが、ローカル($) -> docker(root@96913c74e902:) -> rails(irb(main))の順に変わっていく。

irbはrailsの対話モード。
Interactive Rubyの略。


<br>
##終了方法と注意点
終了するときは`exit`か`quit`。

※末尾の番号が0以外のときは`ctrl + c`でクリアしてから

```:
##末尾が0以外だと抜けられない（式の途中と見做されている）
irb(main):014:2> quit
irb(main):015:2> exit
irb(main):016:2> 

##ctrl + c でクリアしてからexit
irb(main):017:0> exit 
```


<br>
##コマンドの実行例

```:1行の場合
irb(main):001:0> p "hello rails"
"hello rails"
=> "hello rails"


irb(main):002:0> 1+2
=> 3
```

```:複数行の場合
irb(main):015:0> for i in 1...11 do
irb(main):016:1*   print "#{i} "
irb(main):017:1> end
1 2 3 4 5 6 7 8 9 10 => 1...11
```
C言語で二分木を作る

#二分木の構造体
下記の図のようにノードの関係は親一つに対して2つの子を持ちます。
![node.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/f02b28fb-8c83-46c9-5ec2-ae3064b471f0.png)

#二分木にノードを追加するステップの説明
![example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/c47fef39-b6f4-79c5-f5be-1f909144b184.png)

#コードで生成される二分木の例
コードで作成する二分木は下記のようになります。
![tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/e71d3ecc-2c6d-84ce-cdfa-badcf4281e61.png)

#コード
```btree.c
#include <stdio.h>
#include <stdlib.h>

//declare node for tree structure
struct tree{
  int data;
  struct tree *left;
  struct tree *right;
};

//declare functions
void insert(struct tree **, int);
void preorder(struct tree *);
void inorder(struct tree *);
void postorder(struct tree *);

void main(){
  //declare variable for getting user input
  int i=1, req, num;
  //declare pointer to point to tree structure
  struct tree *bt;
  
  //set pointer to empty tree
  bt = NULL;
  
  //get number of nodes to be insert to tree
  printf("Specify the number of data items to be inserted:\n");
  scanf("%d",&req);
  
  //get user input
  while(i++<=req){
    printf("Enter the data:");
    scanf("%d",&num);
    insert(&bt,num);
  }
  
  //display inorder traversal
  printf("Inorder Traversal:\n");
  inorder(bt);

  //display preorder traversal
  printf("Preorder Traversal:\n");
  preorder(bt);

  //display postorder traversal
  printf("Postorder Traversal:\n");
  postorder(bt);
}

//display preorder traversal
void preorder(struct tree *q){
  if(q!=NULL){
    printf("%d\n",q->data);
    preorder(q->left);
    preorder(q->right);
  }
  
  return;
}

//display inorder traversal
void inorder(struct tree *q){
  if(q!=NULL){
    inorder(q->left);
    printf("%d\n",q->data);
    inorder(q->right);
  }
  
  return;
}

//display postorder traversal
void postorder(struct tree *q){
  if(q!=NULL){
    postorder(q->left);
    postorder(q->right);
    printf("%d\n",q->data);
  }
  
  return;
}

//insert node to tree using recursive method
void insert(struct tree **q, int num){
  //if node is not created
  if(*q==NULL){
    //create new node
    *q = malloc(sizeof(struct tree));
    //set data
    (*q)->data = num;
    //set left child to null
    (*q)->left = NULL;
    //set right child to null
    (*q)->right = NULL;
    
    return;
  }else{
    //check if given number is less than node's data
    if((*q)->data >= num){
      //insert at left child
      insert(&((*q)->left), num);
    }else{
      //if given number is bigger than node's data, insert at right child
      insert(&((*q)->right),num);
    }
  }
  
  return;
}
```

#コードの実行結果
![execute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797320/43f9bcc6-fc1c-d74c-e4e3-5a1542d51360.png)


#二分木の表示説明
1) 行きがけ順(preorder)
親→左子→右子の順に表示をします。
コードの実行結果を見ると下記のような順番として表示されます。
6→1→0→5→3→2→4→8→7→9
※親から調べたい時に、こちらの順序を使用します。

2) 通りがけ順(inorder)
左子→親→右子の順に表示をします。
コードの実行結果を見ると下記のような順番として表示されます。
0→1→2→3→4→5→6→7→8→9

3) 帰りがけ順(postorder)
左子→右子→親の順に表示をします。
コードの実行結果を見ると下記のような順番として表示されます。
0→2→4→3→5→1→7→9→8→6
※子から調べたい時に、こちらの順序を使用します。
pg_restoreのよく使われると思われるオプション

## オプション

|オプション  |意味  |
|---|---|
|--clean  |再作成前にデータベースオブジェクトを整理（削除）します。  |
|--if-exists  |データベースオブジェクトを初期化するときに、条件コマンドを使います(つまりIF EXISTS句を追加します)。 このオプションは、--cleanも指定されているのでなければ有効にはなりません。  |
|--verbose  |冗長モードを指定します。（詳細表示）  |
|-Fc   |Postgres専用のフォーマットでpg_dumpしたときはそれに対応するようにつける  |

## あ
- ifexistをつけておくと、リストア先のデータベースが存在するとスキップする
Webサイトにログインするpowershellスクリプト

# これはなに
WebGUIログインを自動化したかったので、powershellで作りました。
ホスト名、ID、アクセス先を引数で渡し、パスワードはローカルのテキストファイルから読み込みします。
# スクリプト

```powershell

# パラメータ 
Param(
    [string]$hostname, #ホスト名
    [string]$userid, #ユーザーID
    [string]$ipaddr #ipアドレス 
    )
$url = "https://" + $ipaddr + ":82/" #ログインページのURL
$userpass = Get-Content -Path "Path" | Select-String -Pattern　$hostname #パスワード抽出
$userpass = $passwd -replace $hostname, ""　#パスワード抽出

# シェルオブジェクト
$shell = New-Object -ComObject Shell.Application
# IEオブジェクト
$ie = New-Object -ComObject InternetExplorer.Application
# ブラウザオープン
$ie.Visible = $true
# HWND
$hwnd = $ie.HWND
# URLオープン(キャッシュ無効)
$ie.Navigate($url, 4)

# ここで再度IEを取得　これやらないとページを読み込めない
while ($ie.Document -isnot [mshtml.HTMLDocumentClass]) {
  $ie = $shell.Windows() | ? { $_.HWND -eq $hwnd }
}

#メソッドの再定義　これやらないと、存在しないメソッドみたいなエラーが返ってくる
function OverrideMethod ([mshtml.HTMLDocumentClass]$Document)   {
  $doc = $Document | Add-Member -MemberType ScriptMethod -Name "getElementById" -Value {
     param($Id)
     [System.__ComObject].InvokeMember(
         "getElementById",
         [System.Reflection.BindingFlags]::InvokeMethod,
         $null,
         $this,
         $Id
     ) | ? { $_ -ne [System.DBNull]::Value }
  } -Force -PassThru
  $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByClassName" -Value {
     param($ClassName)
     [System.__ComObject].InvokeMember(
         "getElementsByClassName",
         [System.Reflection.BindingFlags]::InvokeMethod,
         $null,
         $this,
         $ClassName
     ) | ? { $_ -ne [System.DBNull]::Value }
  } -Force
  $doc | Add-Member -MemberType ScriptMethod -Name "getElementsByTagName" -Value {
     param($TagName)
     [System.__ComObject].InvokeMember(
         "getElementsByTagName",
         [System.Reflection.BindingFlags]::InvokeMethod,
         $null,
         $this,
         $TagName
     ) | ? { $_ -ne [System.DBNull]::Value }
  } -Force
  return $doc
}

#オーバーライドメソッドを実行し、WEBページの中身を得る
$document = OverrideMethod($ie.Document)

#ページの中から、フォームに割当てられたFieldというクラスを持つ要素を抜き出す
#ログインしたいページによって異なる
#IDが割り当てられている場合は$document.getElementByIdを使った方がよい

#非常に重要なエラーハンドリング
#きちんと変数に情報が格納されたことを確認しないと、無限にエラーが返ってくる
while ($true) {
  $textbox_id = $document.getElementById("input__mailtel") #ログインidを入力するテキストボックスのid
  if ($textbox_id) { break }
  Start-Sleep -Milliseconds 100
}

while ($true) {
    $textbox_pwd = $document.getElementById("input__password") #パスワードを入力するテキストボックスのid
    if ($textbox_pwd) { break }
    Start-Sleep -Milliseconds 100
  }

while ($true) {
  @($textbox_id)[0].value = $userid
  @($textbox_pwd)[0].value = $userpass
  if (@($textbox_id)[0].value){
    if (@($textbox_pwd)[0].value){
      { break }
    }
  }
  Start-Sleep -Milliseconds 100
}

#ログインボタンの取得とクリック
while ($true) {
  $button = $document.getElementById("login__submit") #ログインボタンのid
  if ($button) { break }
  Start-Sleep -Milliseconds 100
}
$button.click()
```

# 参考
https://qiita.com/flasksrw/items/a1ff5fbbc3b660e01d96
https://yukituna.com/2417/
CakePHP2のfind('count')とgroupを組み合わせた時の返却値

他の方にとっては基本中の基本かも知れませんが、CakePHP2のfind('count')とgroupを組み合わせた時の返却値について、注意点を書きます。
ほんと簡単な例として、次のアソシエーションを考えてみます！

<h4>顧客データ(Customer)

|顧客ID  |名前  |
|---|---|
|1  |山田太郎  |
|2  |鈴木次郎  |
|3  |田中三郎  |

<h4>注文データ(Order)

|注文ID  |顧客ID  |品名  |
|---|---|---|
|1  |1  |ラーメン
|2  |2  |餃子
|3  |2  |チャーハン 

顧客と注文は一対多(hasMany)の関係があり、山田さんが「ラーメン」を鈴木さんが「餃子」と「チャーハン」を注文したデータがあるとします。

その時、各お客さんの注文数をカウントする時、次の処理になると思います。

```php
$count = $this->Customer->find('count', array(
            'joins' => array(
                array(
                    'type' => 'INNER',
                    'table' => 'orders',
                    'alias' => 'Order',
                    'conditions' => array(
                        'Customer.orderId = Order.id'
                    )
                )
            ),
            'group' => 'Customer.id'
        ));
```
この時、山田さんの注文数は1、鈴木さんの注文数は2、さて田中さんの注文数は幾つになるでしょうか？




恥ずかしいことに自分は「count」という文字につられて、0になると想定していたところ、Falseが返却されました。Joinするデータがないのに、groupを指定しているためです。

以上、簡単な内容になりますが、そのカウント数を元に分岐処理する場合は気をつけましょうという話でした。
Railsのform_withはデフォルトでAjax通信をする

## 生じた現象

- formを入力してPOST送信をして返ってきたレスポンスのHTMLが、ブラウザでレンダリングされなかった。

## 対策

```ruby

form_with(model: @form, local: true) do |f|
   # inputたち
end
```

のように、`local: true`指定してやれば良い。



## 参考

- https://stackoverflow.com/a/50647776 によると、以下。



> Forms generated with form_with by default has data-remote set to true.
> If the data-remote is set to true your form makes an AJAX call. So your view is getting rendered as the response of that AJAX call. That is why you are not getting any errors.
>Add local: true in your form_with.
アナログ回路 その2

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。


# R直列回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/726ccdc6-6693-6019-1374-42036f9a0d7d.jpeg)


# 説明

同じ抵抗が、直列になると、抵抗は倍になる。
電流は、半分の2.5mAとなる。
抵抗にかかる電圧は、抵抗×電流なので、2.5Vとなる。


# 成果物

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

以上。
Unity - Arduino間でBluetooth Serial通信をするとUnity終了時にSerialを閉じるのに失敗する

#はじめに
生じた問題はタイトルのとおりです．
Arduino（私の場合はTeensy4.0）からUnityにシリアルでデータを送る際，有線だとUnity終了時にSerialPort.Close()が機能したのですが，Bluetooth経由だと機能せずにアプリケーション終了後もゾンビスレッドが爆誕してしまった．といった感じです

#環境
Windows10
Unity2019.4.3f1

マイコン : Teensy4.0
Bluetoothモジュール : [BlueSMiRF Gold](https://www.switch-science.com/catalog/2275/)

#使用スクリプト
Unity-Arduino間のシリアル通信であまりにも有名なスクリプトを用いています．
今回は一昔前のThreadを使用したものではなく，Taskを用いた以下の記事を参考にさせていただいています．

[[Unity]非同期処理(Task)の利用例(UDP送受信，SerialPortのRead)](
https://qiita.com/togucchi/items/45cf6e65c883e6f47d3d)

#原因
なぜ`SerialPort.Close()`が失敗するかですが，それは`SerialPort.Close()`を呼ぶタイミングでも裏で走っている以下の`ReadAsync()`タスク内の`SerialPort.ReadLine()`が終了していないからです．
もっと正確に言うと，`SerialPort.Readline()`でシリアルからの入力を待ち続けてしまっており，そのときに`Serial.Close()`を呼び出してしまうとこのTaskがゾンビTaskになってアプリケーション終了後も走り続けてしまう，といった感じでしょうか...（Unityを落とせばこのTaskも消えます.）

```:SerialHandler.cs
async Task ReadAsync()
    {
        await Task.Run(() => {
            while (isRunning && serialPort != null && serialPort.IsOpen)
            {
                try
                {
                    string message = serialPort.ReadLine();
                    OnDataReceived.Invoke(message);
                }
                catch (System.Exception e)
                {
                    Debug.LogWarning(e.Message);
                }
            }
        });
    }
```
何も入力がないときは`SerialPort.ReadLine()`が終了するように，`Serial.Open()`時に以下のようにタイムアウトを設定してあげましょう．（タイムアウトの間隔はアプリに合わせて変えてあげましょう．）

```:SerialHandler.cs
    public void Open(string portName)
    {
        if(isRunning) return;

        currentPortName = portName;

        serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);

        // ここでReadのタイムアウトを設定する．
        serialPort.ReadTimeout = 500; //[milliseconds]

        serialPort.Open();
        isRunning = true;
    }
```

これで`Serial.Close()`がちゃんと機能し，ゾンビタスクが爆誕することはなくなりました．

なぜ有線だとこのタイムアウトの設定がいらなくてBluetoothだと必要なのかが未だにわかっていませんが，とりあえず良しとします．
iCloud・iTunesのバックアップを考慮したUnityのデータ保存における注意点

この記事は[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos)の18日目の記事です。
昨日は@nisei275さんの「RustとWebSocketでユーザの位置情報を双方通信する仕組みを実装してみる」でした。

#はじめに
本記事では、iCloud・iTunesのバックアップにおいてUnityのどのディレクトリが対象・非対象になるのか、
Unityでのデータを保存する上で注意点について紹介していきます。

#iCloud・iTunesのバックアップについて
https://support.apple.com/ja-jp/HT204136

iCloudバックアップは**iCloudのオンラインストレージ上からバックアップ**、
iTunesバックアップは**PC上からバックアップ**。
以前は、バックアップできる項目に差異があったようですが、現時点ではほとんど変わりません。


#Unityでのバックアップ対象・非対象ディレクトリ
iCloud・iTunesのバックアップでは、アプリ内ディレクトリの一部がバックアップ対象となります。

以下、Unityで主に使用されるディレクトリを該当するiOSアプリのディレクトリを列挙したものとなります。

|Unity|iOSアプリ|バックアップ対象・非対象|
|---|---|---|
|**Application.persitantDataPath**<br>永続性のあるデータを保存するためのパス  |**Documents/**|**対象**|
|**Application.temporaryCachePath**<br>一時的なデータを保存するためのパス  | **Library/Caches/** |**非対象**|
|**PlayerPrefs**<br>簡易的にデータの保存・読み込み機能  | **Library/Preferences/**<br>(NSUserDefaults) |**対象**|



#データを保存する上での注意点

### バックアップ対象のディレクトリに比較的容量が大きいファイルを含めない
_**2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected**_

AssetBundleや比較的容量が大きいファイルをバックアップ対象に含めてしまうと、
リジェクトされる可能性があります。

Apple側としてはバックアップ必要なものはバックアップディレクトリに含めて、
バックアップ不要なものはバックアップされないディレクトリもしくは、"do not back up"として、
バックアップされないように明示的に指定してほしいといった意図があるようです。
https://developer.apple.com/icloud/documentation/data-storage/index.html


そのためUnityではバックアップ対象から外す設定が提供されております。

```
#if UNITY_IOS
UnityEngine.iOS.Device.SetNoBackupFlag(Application.persitantDataPath);
#endif
```

### 端末一意のデータ、ユーザー認証情報をバックアップ対象に含めない
例えばですが、以下のケースが考えれます。

PlayerPrefsに**端末を識別するID**や**ユーザー作成時に作られる情報**を保存していた場合。
（PlayerPrefsは**iCloud・iTunesのバックアップ対象**となっています）

1. Aの端末でバックアップを作成
2. Bの端末でAの端末データのバックアップデータを用いて機種変更
3. Bの端末にはAの端末データのPlayerPrefsが含められている状態

つまり、Aの端末（ユーザーA）= Bの端末（ユーザーA）といった**ユーザーの複製**が行えてしまいます。
これにより**1つのユーザーデータに対して複数端末からのアクセス**ができる状況が発生します。

アプリによっては、これを良しとするものもあるかと思います。
しかし意図しない挙動が発生したり、ユーザーデータの破損にも繋がる可能性もあるため、
予め想定した設計をする必要があります。

例えば、**PlayerPrefsに保存している一部の情報をバックアップ対象とされないディレクトリに逃すこと**や、
サーバーを介してログインを行っているアプリであれば、
ログイン時にトークンを発行してそのトークンと一致している端末のみ
プレイ可能にするといった方法も考えられます。


#おわりに
- 各種プラットフォームでアプリを提供する場合は、プラットフォームごとのディレクトリの用途を予め確認する必要があります
- 保存する先のディレクトリがバックアップ対象・非対象かを確認し、目的に応じて使い分けることが重要

明日は@MilayYadokariさんの記事です。