OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】使用しているブラウザを判定する

使用しているブラウザを判定するには```JavaScript```の **`NavigatorID.userAgent`**プロパティを使います。
#ブラウザ情報の取得

```js

var userAgent = window.navigator.userAgent;
```
これで、ブラウザの情報を取得できますが、ユーザーエージェントを使って取得できる情報は大文字・小文字が乱立している文字列なので、判定しやすくするために全て大文字、または全て小文字に統一します。そこで先ほどのソースに「toLowerCase()」を追記してこの文字列を扱いやすいように修正します。

# ブラウザの識別子

以下の文字列で各ブラウザを識別できます。

|ブラウザ|識別子|
|:-----------------:|:------------------:|
|IE（11未満)|MSIE|
|IE（11以上)|Trident|
|旧Edge|Edge|
|Edge(最新バージョン)|Edg|
|Google Chrome|Chrome|
|FireFox|Firefox|
|Safari|Safari|
#ブラウザ情報の判定

```js

var userAgent = window.navigator.userAgent.toLowerCase();
```
indexOfを使って判定します。

```js
if(userAgent.indexOf('msie') != -1) {
  console.log('ブラウザはInternet Explorerです');
}
```
書き方としてはこれで問題ないですが、複数のブラウザを比較する場合は**`If文を記述する順序に注意が必要`**です。

#なぜ順序に注意が必要なのか？
以下はchrome使用時のブラウザ情報ですが、後ろの方にSafariと書いてあります。
文字列「Safari」はSafariブラウザの識別子です。If文の順序を間違えるとchromeを使用しているにも関わらず、
Safariと判定される可能性があるため、If文の記述順序は注意が必要です。

```
Mozilla/5.0 (windows nt 6.3; wow64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
```

#記述順序
特に「Edge」→「Chrome」→「Safari」の順番に注意して記述します。

```js

if(userAgent.indexOf('msie') != -1 ) {
    console.log('ブラウザはInternet Explorerです');
} else if(userAgent.indexOf('edge') != -1) {
    console.log('ブラウザはEdgeです');
} else if(userAgent.indexOf('chrome') != -1) {
    console.log('ブラウザはChromeです');
} else if(userAgent.indexOf('safari') != -1) {
    console.log('ブラウザはSafariです');
} else (userAgent.indexOf('firefox') != -1) {
    console.log('ブラウザはFireFoxです');
}
```
#参照
[MDN webdocs ](https://developer.mozilla.org/ja/docs/Web/API/NavigatorID/userAgent)
[UserAgentからOS/ブラウザなどの調べかたのまとめ](https://qiita.com/nightyknite/items/b2590a69f2e0135756dc)
[JavaScriptでブラウザを判定して処理を条件分岐する方法](https://arts-factory.net/useragentbrowser/#toc2)
継続的にリファクタリングを行うソフトウェア開発ステップはチック・タックが適切かもしれない

[インテルチック・タック](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB_%E3%83%81%E3%83%83%E3%82%AF%E3%83%BB%E3%82%BF%E3%83%83%E3%82%AF)というものをご存じでしょうか？
インテルプロセッサのロードマップモデルだったものです。アーキテクチャはそのままでプロセスルールの縮小を行う「チック」と、プロセスルールそのままでアーキテクチャの改善を行う「タック」これを交互に行い、継続的に新製品を投入するというものです。現在はプロセスルールの微細化が困難になり破綻していますが、長く続いたモデルです。

ちょっと強引ですが、これをソフトウェアに当てはめ、機能はそのままでリファクタリングを行う「チック」と、機能改善・新機能の開発を行う「タック」と考えると、チック・タックでリファクタリングを行いつつ、改善を続けるという継続的な開発ステップになるのではないでしょうか？

インテルの戦略は、プロセスルールの微細化が物理限界に近づいたことで破綻していますが、「リファクタリングが物理限界に到達する」なんてことはありませんから、同じ理由で破綻することはないでしょう。

ってことで、私のおすすめの開発ステップがチックタックモデルなわけです。こういう考え方はもともとあるものでしょうが、この話をすると、チックタックって何？と知っている人があまりいなかったので、啓蒙の意味を込めて書いています。

# リファクタリングは行わなければならない

どのように作られたソフトウェアも時間の流れとともにその設計が陳腐化し、時には技術的負債と言われるようになってしまいます。そのため、継続的にリファクタリングは行わなければなりません。技術的負債を放置したままでは、新機能の開発も計画通りに進めることはできず、不具合の温床になってしまいますので、技術的負債を先送りして良いことはないでしょう。
とはいえ、リファクタリングが十分に行われないまま、技術的負債をため込んでしまっているソフトウェアは多いことでしょう。

そのようなプロジェクトを担当することになった時、どのように開発を進めていけばいいでしょうか？

本音を言えば、新機能の開発は当面とめて、ひたすらリファクタリングに取り組みたいところではありますが、ビジネス的な観点から新機能の開発をすべて止めるという判断はなかなかできるものではありません。提案しても受け入れられる可能性はかなり小さいでしょう。
新機能を開発する場合に、修正する周辺をリファクタリングしていくということは通常行われると思いますが、これでは新機能の入る場所以外のリファクタリングが進みませんし、全体に影響のあるリファクタリングを実施するのは難しく、新機能の開発も妥協の上に行わざるを得ない場合も出てきてしまいます。

そのため、開発ステップを「チック」「タック」に分け、「チック」ではリファクタリングに集中し、「タック」で新機能の開発に取り組みます。これを繰り返すことで、継続的に新機能を実装しつつも、ソフトウェアの品質を高めていくことができます。

負債が多い状態では、チックに長い時間をかけたり、ステップを分けてチック・チック・タックとしてもいいでしょう。リファクタリングが進み、負債が少なくなったらチック・タック・タックとしても良いでしょう。当初考えていた負債を返済し終える頃には、当初リファクタリングした箇所が負債になり始めていたりするので終わりはありません。いつまでもこのステップを続けましょう。

リファクタリングを行うことを開発ステップにルールを決めて組み込んでしまえば、次々に開発タスクが積まれてリファクタリングに取り組めない、みたいな状況でも、今はリファクタリングのステップだから開発は次のステップで、と説明しやすいですし、非エンジニアから見ても、スケジュールやエンジニアリソースの見通しがわかりやすくなりメリットがあります。計画に取り込むに当たっても説得しやすいのではないでしょうか？
「チック」を挟むことで開発速度が落ちる懸念もされますが、実際はほとんど落ちません。初期は多少落ちるかもしれませんが、回を追うごとに開発効率が上がっていき、開発速度はどんどん上がっていきます。何より、エンジニアのモチベーションが上がりますしね。

呼び方は何でもいいですが、チック・タックでモダンな環境を維持しつつ、継続的に成長するソフトウェア開発を行いましょう。というお話でした。
TypeScriptの型推論がいつの間にか定義時以外でも使えるようになっていた話

久しぶりにJavaScriptを書いていて

```javascript
let a;
a = 1;
```

よし、`a`に`/** @type {number} */`を付けよう！と思っていたら`a`が`number`に型推論されていた。

```javascript
const a = [];
a.push(1);
```

なんとこれも`a`は`number[]`に推論される。

```javascript
const a = Array();
a.push(1);
```

これは`a: any[]`だった。ジェネリクスなら何でも行けるわけではなさそう。この感じだと`Map`とかも無理そうだ。

TypeScriptのリリースノートは追っていたつもりだったのに全く気付かなかった。どなたかどのバージョンでこの機能が導入されたのかご存知でしょうか・・・。
bundle installのエラー

##エラーが起きました
Gemfileに使いたいGemを記載してbundle installっと！
あれっ、


```ruby:ターミナル
You have requested:
  listen >= 3.0.5, < 3.2

The bundle currently has listen locked at 3.2.1.
Try running `bundle update listen`

If you are updating multiple gems in your Gemfile at once,
try passing them all to `bundle update`

```

おおう…
なんて書いてあるんだ…

私は英語ができないのでGoogle翻訳さんに任せてみます

```ruby:ターミナル
あなたは要求しました：
  リッスン> = 3.0.5、<3.2

バンドルは現在、3.2.1でリッスンロックされています。
`bundle updatelisten`を実行してみてください

Gemfile内の複数のgemを一度に更新する場合は、
それらすべてを `bundleupdate`に渡してみてください
```

とGoogle翻訳さんは申されました。

どういうことかというと、
このlistenというGemのバージョンは3.0.5以上、3.2未満というバージョンで指定していて、bundle側は3.2.1しか対応してないよ〜だからupdateしてよ〜
と言っているとういうことですかね

##解決策
これはターミナルさんに言われた通りに

```ruby:ターミナル
bundle update
```

これやってからbundle installすれば解決しました
どうやらRailsとBundlerのサポートしているバージョンが異なればこういうことが起きるそうです

iPhoneユーザーなら似た様な経験ある人いるんじゃないですかね

「iOSの新バージョン出たからアップデートしよっ」
「よしアップデート終わったな、ゲームでもするか」
「あれっ、アプリが起動しない…」

これも最新iOSとアプリのバージョンが対応していないから起きる現象なようです
だから最新バージョンが出たからといって無闇にアップデートしない方が良いと言われていますよね（私は速攻でやりますけど^o^）

バージョンなんて新しい方がいいに決まってんじゃん！！
なんて最初は思っていましたが、アップデートしたことにより今まで動いていた機能が動かなくなることはエンジニアの現場ではあるそうですね
新しい物好きの人は要注意です！！

##bundle installとbundle updateの使い方

bundle installというのはGemfile.lockを元にGemをインストールする
Gemfile記載あり、Gemfile.lockに記載ないという場合に、対象のGemをインストールした後、Gemfile.lockを更新する

bundle updateというのはGemfileを元にGemをインストールして、Gemfile.lockを更新する

結局Gemfile.lockが更新されないとアプリには反映されないんですね
よく触るのはGemfileだけど、最終決定権はGemfile.lockに委ねられるって感じで認識してます


##参考
https://github.com/rubygems/bundler/issues/7034
クラウドサービスを使うときは、チームメンバー全員、クラウド利用費を意識しようという話

私は、普段の業務でAWSの各サービスを利用しています。
AWS,Azure,GCPと、使ってる基盤は違えど、パブリッククラウドを使用している企業さんは今時多いんじゃないかと思います。

身の丈に合ったリソースを柔軟・簡単・迅速に構築でき、使った分だけ請求される。非常に便利なパブリッククラウドの各サービス達ですが、気づいた時には、
社長「あれ？思ったより高額じゃね？」「もっとコスト下げんかい！」って話になってしまうリスクもあります。

このあたりのクラウド利用コストは、エンジニアがきちんとコスト感を持っていれば防げるものも多いと思います。
トップダウンでコスト削減の話が降ってきたときにはもう手遅れ、「やっちまった」と思いたいものです。
私が過去、痛い目を見た経験も踏まえ、クラウドを利用する際のコスト意識について書いてみようと思います。
※AWSを例に挙げて話していこうと思います。



###1.まずは現実を受け止めよう
https://aws.amazon.com/jp/aws-cost-management/aws-cost-and-usage-reporting/

AWSは毎月コストレポートを出してくれます。
どのリソースにいくら使ってるのか？まずは現実を知る所からです。

###2.直ぐに削れるところはないか?確認しよう

まずはEC2,RDSといった、予めインスタンスを確保しておき、確保した分に対して料金を払うサービスを見直してみましょう。

**①POCや技術検証の為に作ったけど、今は利用していないもの。**
**②例えば負荷試験の為に一時的にスケールアップしているが、試験は終了していて今は最低限のリソースで十分なもの。**
**③開発の計画が変更になり、元々必要で立てたものの、不要になったもの。**

上記のようなリソースは無いでしょうか。意外と残ってたりするんじゃないでしょうか。
この辺の管理はしっかり行いましょう。私の居たチームでは過去、この辺りの管理が雑になっており、毎月ウン万単位の無駄なコストが発生していました。

**~対策~**
①エクセルでも何でも良いので、まずは管理しましょう。自分たちが使っているサービスのインスタンスタイプは？ストレージは？(分散基盤の場合)ノード数は?
②その上で、不要なものは直ぐに削除、下げられるリソースは徹底的に下げましょう。クラウドサービスの多くは従量課金になっており、下げた・消したその瞬間から料金は下がります。早いに越したことはありません。



###3.使った分だけしか請求されない=使った分だけ請求される

次にAthena,Lambdaや、RDSからのデータ抽出など、「使った分だけ課金される」部分の見直しです。
タイトルの通り、
**使った分だけしか請求されない=使った分だけ請求される**
ということです。
無駄なクエリは打っていないでしょうか。無駄なデータ抽出を行っていないでしょうか。
この辺のサービスは、処理1つ1つがコストです。、
開発中だから色々試しちゃえーー！と、ジャブジャブ処理を動かしていると、その分お金も溶けていきます。

**~対策~**
私は、この辺はもう意識の問題かと思っています。
自分の打つクエリ1つ1つがコストです。本当にこのクエリで思った通りのデータが取ってこれるか？思った通りの処理を実現できるか？しっかり確認しましょう。


###4.まとめ

ここまで読んでいただきありがとうございます。
「なんだ、当たり前の事しか書いてないじゃん」と思われた方も多いと思いますが、
特に小数のチームだと、この辺りの管理って雑になりがちだと思っています。
また、当たり前のことほど難しいものです。


しっかり意識するために、チーム単位でPL表などを作成してみるのも良いと思います。
私のチームはPL表を作成し、マネージャではなくエンジニアが管理することで、
全員がコスト意識を持ち、煩雑だったあの当時に比べ、AWSコストは本当に必要な部分のみに徹底的に抑えられています。


(自分へのメッセージでもありますが、)
エンジニアとして、本当に必要な部分でコストかけて勝負できるように、
日々コスト意識をもって、無駄なコストは徹底的に、管理&削減していきましょう。
「gyp: No Xcode or CLT version detected!」というエラーを直した

vue.jsのvue createdでディレクトリを作成中、「gyp: No Xcode or CLT version detected!」というエラーが出ていたので対処することに。

初心者なりに試行錯誤したのでもっとスマートな方法があると思いますが備忘録として。

##環境
macOS バージョン 10.15.7
Xcode バージョン 12.1

##試したこと
https://github.com/nodejs/node-gyp/blob/master/macOS_Catalina.md
こちらを参考にしました。

https://developer.apple.com/download/more/
ここから、Command Line Tools for Xcode 12を選択。
インストーラから、Command Line Toolsをインストール。

そして

`xcode-select --install`

を実行。するとまたしてもエラーが。
![760B4B44-91F6-493F-BC9E-E72FB3BFBFAA_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616103/b5e06bc0-8119-8a64-8605-f5ed8b23f4a3.jpeg)
いろいろ調べた結果、XCodeのCommand Line Toolsのパスが違うらしい。

https://techracho.bpsinc.jp/hachi8833/2016_09_09/25454
こちらの記事の「パス修正の手順」を参考にパスを変更しました。

再びvue createdを実行。すると今度はエラーなく実行出来ました。
参考になれば幸いです。
Firestoreひと言メモ(reference × snapshot)

#referenceとは
**参照情報でデータの実体は持っていない**
1、collectionを参照するreference
2、documentを参照するreference
がある。

```js

const ref = db.collection('item');
```

データの更新追加削除はreferenceに対して行う。（データベースを<font color="red">操作したい時</font>はreference）

#snpashotとは
**データの実体を取得するための橋渡しのようなもの**
.data()をにて実体を取得できる。


#まとめ
refarence snapshot .data()の流れが基本のようだ
用語について ― J 言語入門

J では、自然言語の文法用語に由来する言葉が多く使われます。例えば、noun, verb, adverb, conjunction は、いずれも品詞を表します。

これらの単語は もちろん日本語に翻訳できるのですが、「副詞」や「接続詞」といった言葉を使うと逆に混乱を招く おそれもあります。というのも、漢字を見て受けるイメージと実際の意味との間にギャップがあるからです。

そこで、記事では あえて文法用語は英語のままにして、注釈として日本語訳を載せるようにしました。

また、explicit definition のように、自然な日本語に訳すのが難しい語句についても、意訳を避けて英語表記を使うことにしています。

公式なドキュメントや J Wiki の記事は全て英語なので、詳しく調べたい場合は英語の説明を読む必要があります。始めから英語で覚えておくことに損はないと思います。

---

\[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \]
ボックス ― J 言語入門

J には、もう一つ重要な型、ボックス型 (boxed type) があります。

C# や Java 等を知っている人なら「ボックス化 (ボクシング)」という言葉を聞いたことがあると思います。同じ用語を使いますが、実際は**似て非なる機能**です。

# ボックス化

J の配列は高機能ですが、型の制限があるので「数値と文字列の組」のようなものは表現できません。また、ジャグ配列を扱うこともできません。

そこで、**どんな値でも格納できる** [^1] 箱 (box) の機能が用意されています。値を箱に入れる (ボックス化する) には、`<` (monad) を使います。

```j
   a=: <1
   a
┌─┐
│1│
└─┘
```

ボックスは、四角の枠で囲んで表示されます。中に何が入っていても同じボックス型と見なされます。そのため、異なる種類の値の配列を作ることも可能です。

```j
   a , <'abc'
┌─┬───┐
│1│abc│
└─┴───┘
```

上の結果にもあるように、ボックスの配列は四角の枠が連結した形で描かれます。

# 値を取り出す

ボックスは、そのままでは中身にアクセスできません。

```j
   2 + a
|domain error
|   2    +a
```

値を使うときは、**必ずボックスを開けて取り出さなければなりません**。暗黙的に変換されることはありません。

値を取り出す verb は、`>` (monad) です。

```j
   >a
1
   2 + >a
3
   >2
2
```

ボックス以外の値に `>` を使っても、エラーにはなりません。(そのままの値が返ります。)

# ボックスの配列

ボックスの配列は非常によく使われます。

例えば、`'abcde'` と `'abc'` という 2 つの文字列で配列を作りたいとします。`,:` を使えばできそうな気もしますが、文字列の長さが違うので上手くいきません。

```j
   'abcde' ,: 'abc'
abcde
abc  
   NB. 'abc  ' (余分なスペースが 2 つ加わる)
   $'abcde' ,: 'abc'
2 5
```

shape を整えるために末尾にスペースが加えられています。(数値の場合は 0 で埋められます。)

ボックスのリストを使えば、正しく表すことができます。

```j
   (<'abcde') , <'abc'
┌─────┬───┐
│abcde│abc│
└─────┴───┘
```

## リストの構築

上の例のように `,` と `<` を組み合わせる方法は、リストの要素数が増えると括弧の数も増えて読みにくく なります。

```j
(<'abcde') , (<'abc') , (<'xyz') , <'12345'
```

代わりに、`;` (dyad) を使いましょう。

```j
   'abc' ; 1
┌───┬─┐
│abc│1│
└───┴─┘
   'abc' ; <1     NB. 右側がボックスでも同じ
┌───┬─┐
│abc│1│
└───┴─┘
   'abcde' ; 'abc' ; 'xyz' ; '12345'
┌─────┬───┬───┬─────┐
│abcde│abc│xyz│12345│
└─────┴───┴───┴─────┘
```

`;` は、2 つの値をボックス化して、連結します。

ただし、`;` の右の引数がボックス型の場合、左の引数だけがボックス化され、連結されます。それによって、`a ; b ; c` のように続けて書くことができます。

## リストの展開

```j
   a=: 'abcde' ; 'abc' ; 'xyz'
   a
┌─────┬───┬───┐
│abcde│abc│xyz│
└─────┴───┴───┘
   ;a
abcdeabcxyz
```

`;` (monad) は、ボックスのリストから中身を取り出して連結します。配列を作るので、型が合わないとエラーになります。

```j
   ;'abc' ; 1
|domain error
|       ;'abc';1
```

# 空のボックス

`a:` は空のボックスを表します。

```j
   a:
┌┐
││
└┘
```

「空」のボックスと書きましたが、実際には長さ 0 の配列が中に入っています。

# 入れ子

J のボックスは、入れ子にすることもできます。

```j
   <<1
┌───┐
│┌─┐│
││1││
│└─┘│
└───┘
   <<<1
┌─────┐
│┌───┐│
││┌─┐││
│││1│││
││└─┘││
│└───┘│
└─────┘
   <'abc' ; 1
┌───────┐
│┌───┬─┐│
││abc│1││
│└───┴─┘│
└───────┘
```

`;` と一緒に使う場合、右の引数の扱いに注意しましょう。

```j
   (<1) ; 2
┌───┬─┐
│┌─┐│2│
││1││ │
│└─┘│ │
└───┴─┘
   1 ; <2
┌─┬─┐
│1│2│
└─┴─┘
   1 ; <<2
┌─┬───┐
│1│┌─┐│
│ ││2││
│ │└─┘│
└─┴───┘
   (<1) ; <<2
┌───┬───┐
│┌─┐│┌─┐│
││1│││2││
│└─┘│└─┘│
└───┴───┘
   1 ; (2 ; 3) ; 4
┌─┬─────┬─┐
│1│┌─┬─┐│4│
│ ││2│3││ │
│ │└─┴─┘│ │
└─┴─────┴─┘
```

入れ子のボックスは、**木構造**を表すのに便利です。

```j
   1 ; '+' ; <2 ; '*' ; 3
┌─┬─┬───────┐
│1│+│┌─┬─┬─┐│
│ │ ││2│*│3││
│ │ │└─┴─┴─┘│
└─┴─┴───────┘
```

---

J には、構造体のようなデータ型を定義する機能はありません。その代わりに、汎用的なデータ構造として、ボックスが用意されています。

言葉の通り「箱に入れる」「箱から取り出す」といった操作をイメージすると理解しやすいと思います。

---

\[ 前 : [多次元配列](https://qiita.com/unsigned-wrong-wrong-int/items/813c4e216d60ce80e770) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [様々な数値](https://qiita.com/unsigned-wrong-wrong-int/items/96ed987360617667c29b) \]

[^1]: ここでの「値」は noun のこと。
多次元配列 ― J 言語入門

引き続き配列の話です。この記事では二次元以上の配列を扱います。

# テーブル・ブリック

J では二次元配列を**テーブル** (table)、三次元配列を**ブリック** (brick: れんが) と呼びます。四次元以上の配列は、あまり使わないので別名はついていません。

特に数値のテーブルは、行列 (matrix) を表すのに使われます。

数値の多次元配列は、`i.` (monad) で簡単に作れます。

```j
   i.2 3    NB. 2 * 3 の行列
0 1 2
3 4 5
   i.2 2 3  NB. 2 * (2 * 3) のブリック
0  1  2
3  4  5

6  7  8
9 10 11
```

上の結果を見ると、三次元以上の配列は空行で区切って表示されていることが分かります。

二次元配列が分かれば三次元以上も分かると思うので、二次元配列を例として使うことにします。

# 配列の形

`#` (monad) は配列の長さを求める verb でしたね。これをテーブルに使ってみましょう。

```j
   a=: i.2 3
   #a
2
```

`a` には 6 個の要素がありますが、`#` は 2 を返しました。この理由は、`a` が `0 1 2` と `3 4 5` を要素とする配列とみなされるからです。`#` は配列の最初の次元の長さを返します。

配列は **shape** (形) と **rank** (階数) と呼ばれる性質を持っています。shape は、`$` (monad) で調べられます。

```j
   $a
2 3
```

`$` は、**各次元の要素数をリストにして**返します。これを使えば、全体の要素の個数 (ここでは 6) を求める式も書けますね [^1]。

rank は、配列の次元の数です。これは言い換えると、shape の要素数を意味します。

```j
   NB. #$ で rank を求める
   #$a         NB. テーブル
2
   #$1 2 3     NB. リスト
1
   #$1         NB. アトム
0
```

ちなみに、アトムの shape は空のリストです。

# テーブルを作る

リストからテーブルを作る方法は、いくつか あります。その中でも よく使うものを紹介します。

## `$` (dyad)

`$` を dyad として使うと、shape を指定して配列を作ることができます。

```j
   2 3 $ 5
5 5 5
5 5 5
   2 3 $ 'abcdef'
abc
def
   2 3 $ 0 1      NB. 要素数が足りない場合は繰り返される
0 1 0
1 0 1
```

## `,:` (dyad)

`,:` は、リストを要素としてテーブルを作ります。

```j
   1 2 3 , 4 5 6
1 2 3 4 5 6
   1 2 3 ,: 4 5 6
1 2 3
4 5 6
```

# テーブルをリストにする

テーブルの要素を取り出してリストにするには、monad の `,` を使います。

```j
   ,a
0 1 2 3
```

`,` の結果は常に一次元配列です。

# 行列

J では行列の演算もシンプルに書けます。ベクターと同様、`+` 等は それぞれの要素に適用されます。

```j
   a=: i.2 2
   a
0 1
2 3
   NB. スカラー倍
   2 * a
0 2
4 6
   NB. 和
   a + a
0 2
4 6
   NB. 行列式
   -/ .*a
_2
   NB. 積
   a +/ .* a
2  3
6 11
```

`/` と `.` の間には**空白が必要** [^2] なので注意してください。

`.` は **conjunction** (接続詞) です。conjunction は、引数 (被演算子) が 2 つである点を除いて、adverb と同じです。

```j
(- /) . (*)
(+ /) . (*)
```

`.` は行列の計算以外で使うことは まず無いので、どう動いているかの説明は省きます。

---

ひとまずは、配列の話はここまでとします。

---

\[ 前 : [文字と文字列](https://qiita.com/unsigned-wrong-wrong-int/items/bafe9f327fe4180e0fbd) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [ボックス](https://qiita.com/unsigned-wrong-wrong-int/items/2b0825008ed95ea722ce) \]

[^1]: ヒント: `/` を使います。
[^2]: 空白が無いと `/.` (別の adverb) になってしまいます。
文字と文字列 ― J 言語入門

数値の次は文字を扱います。前回に引き続き配列の話がメインです。

# 文字列リテラル

文字列は、`'` (シングルクオーテーション) で囲んで表記します。

```j
   'Hello, world!'
Hello, world!
   'abc''123'''
abc'123'
```

`'` 自体を表すには、`''` と書きます。*改行等の特殊な文字をエスケープする方法はありません*。

文字列は、**文字のリスト**なので、ベクターと同様の機能が使えます。

```j
   a=: 'abcde'
   #a
5
   2 { a
c
   a i. 'e'
4
```

## 文字

リテラルが ちょうど 1 文字 [^1] だけ含む場合、それは「文字」を表します。

```j
'a'   NB. 文字
''''  NB. 文字
'ab'  NB. 文字列
''    NB. (空の) 文字列
```

「文字」と「文字列」の関係は、「数値」と「ベクター」の対応に似ています。

```j
0      NB. 数値
0 1    NB. ベクター
```

文字を並べたものが文字列に、数値を並べたものがベクターになります。

# 連結

リストの連結には `,` (dyad) を使います。

```j
   'abc' , 'de'
abcde
   'a' , 'bc' , 'd'
abcd
   'a' , 'b'
ab
```

これを使うと、改行などを含めることができます。

```j
   'abc' , LF , 'de'
abc
de
```

`,` はリストの操作なので、数値の場合も同じように使えます。

```j
   1 2 3 , 0 1
1 2 3 0 1
```

# 文字と数値

文字と数値は型が違うので、混ぜるとエラーになります。暗黙の変換が行われることもありません。

```j
   1 2 , 'ab'
|domain error
|   1 2    ,'ab'
```

domain error は、予期しない値が使われたことを示しています。(J でコードを書くにあたって、一番よく見るエラーだと思います。)

`+` や `*` を文字に対して使うこともできません。

```j
   'ab' + 'c'
|domain error
|   'ab'    +'c'
   'ab' * 2
|domain error
|   'ab'    *2
```

# バイト / 整数 の変換

0 以上 255 以下のバイト値が、`a.` というリストに順番に格納されています。(`a.` の要素の型は文字です。) これによって、文字と整数の相互変換ができます。

```j
   65 { a.     NB. 整数 -> 文字
A
   a. i. 'A'   NB. 文字 -> 整数
65
```

`a.` は制御文字も含んでいるので、直接中身を見ることはできません。印字可能な文字の一覧は、次のようにすれば得られます。

```j
(32 + i.95) { a.
```

# 比較

さて、ここで比較の話をしておきます。比較には以下の verb (いずれも dyad) を使います。

- `=` `~:`
- `<` `<:` `>` `>:` (数値のみ)

`~:` は「等しくない」を表し、`<:` と `>:` はそれぞれ「以下」「以上」を意味します。それ以外は、他の言語と同じです。

```j
   1 = 1
1
   1 = 0
0
   'a' = 'a'
1
   'a' ~: 'b'
1
   0 > 1
0
   1 <: 2
1
   1 >: 1
1
```

`=` と `~:` は、数値と文字とを比較することもできます [^2]。

```j
   1 = '1'
0
   1 ~: '1'
1
```

## リストの比較

`=` をリストに対して使うと、面白い結果が得られます。

```j
   a
abcde
   a = 'apple'
1 0 0 0 1
   a = 'd'
0 0 0 1 0
   a = 'abc'
|length error
|   a    ='abc'
```

なんと、**それぞれの要素** (文字) について、比較が行われているのです。試してみれば分かりますが、ベクターでも同様です。

上に挙げた比較の verb は全て、「1 つの値」ごとに比較します。この「1 つの値」(つまり 数値や文字) のことを、**アトム** (atom) と呼びます。比較だけでなく `+` 等も、アトムに対する演算です。

アトムごと ではなく、**全体**を比較するには、`-:` を使います。

```j
   a -: 'a'
0
   a -: 'abcde'
1
```

配列を比較する場合は、気をつけるようにしましょう。

---

\[ 前 : [数値の配列 (ベクター)](https://qiita.com/unsigned-wrong-wrong-int/items/a9871cb5cfc34e625a67) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [多次元配列](https://qiita.com/unsigned-wrong-wrong-int/items/813c4e216d60ce80e770) \]

[^1]: 正確には 1 バイト。
[^2]: 等しくなることはありませんが。
数値の配列 (ベクター) ― J 言語入門

「J らしい」機能の一つ、配列の計算です。

# 配列とは

J の配列は、多くのスクリプト言語とは異なり、**固定長**です。また、**ジャグ配列ではない**ので、二次元配列のそれぞれの列の長さも揃っている必要があります (三次元以上の配列でも同様)。

さらに、全ての要素の型が同じでなければなりません。

# ベクター

J では一次元配列を**リスト** (list) と呼び、その中でも数値のリストを特に**ベクター** (vector) と言います。

ベクターは非常に簡単に書けます。

```j
   1 2 3
1 2 3
   1.2 _3 _ 5e_8
1.2 _3 _ 5e_8
```

数値を空白で区切って並べるだけです。

ただ、簡単とは言え何度も手で入力するのは面倒なので、変数に代入しておきましょう。

```j
   a=: 8 7 2 6 3 1 3    NB. a に代入
   a                    NB. a の値を確認
8 7 2 6 3 1 3
```

代入の記号は `=:` です。`:` (コロン) の位置に注意しましょう。

# 基本的な操作

配列の要素数を得るには、`#` (monad) を使います。また、`{` (dyad) [^1] で要素の値を所得できます。

```j
   a
8 7 2 6 3 1 3
   #a
7
   0 { a
8
   3 { a
6
   7 { a
|index error
|   7    {a
```

インデックスは 0-オリジン (最初の要素が 0) です。範囲の外を指定すると index error が発生します。

# ベクターの計算

ここからが本題です。

例えば、配列の各要素について計算したいとき、多くの言語では

- for / for each 文
- map 関数

の いずれかに相当するコードを書くでしょう。

J では、どちらも使いません。

```j
   a + 3    NB. ベクター + 数値
11 10 5 9 6 4 6
   2 * a    NB. 数値 * ベクター
16 14 4 12 6 2 6
   -a       NB. - ベクター
_8 _7 _2 _6 _3 _1 _3
```

普通の数値の計算と**同じ書き方**で配列も計算できます。J では数値が必要な場面でベクターが使われると、**それぞれの要素に**同じ verb が適用されます。

これにより反復処理を簡潔に書けるのが、J の強みの一つです。

## ベクター同士の計算

前の例では、数値とベクターの計算をしました。ベクター同士の計算も試してみましょう。

```j
   1 2 3 + 4 5 6
5 7 9
   1 2 3 4 * 1 0 2 _1
1 0 6 _4
```

同じように、要素ごとに計算されていることが分かりますね。

要素は一対一で対応している必要があります。要素数が違うと length error になります。

```j
   1 2 3 + 4 5
|length error
|   1 2 3    +4 5
```

# リストの探索

J では単純な繰り返し以外に、要素の探索も簡単に書けます。

```j
   a
8 7 2 6 3 1 3
   a i. 3   NB. 最初の 3 のインデックス
4
   a i: 3   NB. 最後の 3 のインデックス
6
```

`i.` (dyad) は先頭から、`i:` (dyad) は末尾から探索して、はじめに見つかった所のインデックスを返します。

見つからなかった場合は、リストの長さが返ります。

```j
   #a
7
   a i. 100
7
   a i: 100
7
```

リストに値が含まれるかどうかだけ知りたい場合は、`e.` (dyad) を使います [^2]。

```j
   NB. J では true は 1, false は 0
   3 e. a
1
   100 e. a
0
```

# 連番

`i.` (monad) を使うと、0 から始まる整数のリストを作れます。よく使うので、覚えておいてください。

```j
   i.10
0 1 2 3 4 5 6 7 8 9
   1 + i.10
1 2 3 4 5 6 7 8 9 10
```

# 要素の合計

さあ、あと一息です。

ベクターの**要素を全て足し合わせる**、という処理まで短く書けてしまうのが J です。

```j
   a
8 7 2 6 3 1 3
   +/a
30
```

`/` という新しい記号が出てきました。`/` は、リストの要素と要素の間に verb (ここでは `+`) を入れて、計算を行います。例えば、以下の 2 つの式は同じ計算をしています。

```j
   +/1 2 3 4 5
15
   1 + 2 + 3 + 4 + 5
15
```

`-/` も試してみましょう。

```j
   -/1 2 3 4 5
3
```

なぜ `_13` にならないの？と思った方は、「右から」のルールを思い出してください [^3]。

```j
   1 - 2 - 3 - 4 - 5
3
   (((1 - 2) - 3) - 4) - 5
_13
```

ところで、`+/` の記号の順序について不思議に思った人がいるかもしれません。

ここまでは verb のみ紹介してきましたが、実は `/` は verb ではなく **adverb** (副詞) に分類されます。大きな違いは、adverb は verb を引数 (被演算子) にできることです [^4]。

例えば、`+/` の `+` は adverb `/` の引数になっています。

*adverb については、今は理解する必要はありません。*そういうものがある、ということだけ知っておいてください。

---

\[ 前 : [数値と計算](https://qiita.com/unsigned-wrong-wrong-int/items/45174edb69df1149386e) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [文字と文字列](https://qiita.com/unsigned-wrong-wrong-int/items/bafe9f327fe4180e0fbd) \]

[^1]: 他の言語の添え字演算子に あたります。
[^2]: `i.` と `e.` とで、引数の順番が違うことに気をつけてください。
[^3]: `/` は実質的に、リストの後ろから計算していることになります。
[^4]: 高階関数に似ています。
数値と計算 ― J 言語入門

いよいよ J 言語の説明に入ります。まずは、数値の書き方と簡単な計算を見ていきましょう。

J では、REPL のプロンプトは半角スペース 3 つです。また、コメント (行コメント) は、なんと `NB.` [^1] で始まります。最初は違和感があるかもしれませんが、すぐに慣れると思います。

# 数値リテラル

まずは整数。

```j
   0
0
   1
1
   12345
12345
```

正の数は、いたって普通の表記ですが、負の数は少し変わった書き方をします。

```j
   _1    NB. - (ハイフン) ではなく _ (アンダースコア)
_1
```

小数 (浮動小数点数) も、負の数の表現を除けば一般的な表記と同じです。

```j
   12.3
12.3
   3e18
3e18
   1.7e_9
1.7e_9
```

ただし、無限大は特殊です [^2]。

```j
   _     NB. 正の無限大
_
   __    NB. 負の無限大
__
```

# 計算してみる

さて、数値を入力するだけではつまらないので、簡単な計算を試してみましょう。

```j
   2 + 3
5
   2 - 3
_1
   2 * 3
6
   2 % 3    NB. 2 ÷ 3
0.666667
   2 | 3    NB. 3 mod 2
1
```

割り算は `/` ではなく **`%` を使う**ことに注意してください。また、剰余 `|` の**引数の順番**も他の言語と異なります。

# 計算順序

次の 2 つの式を実行して、結果を比べてみましょう。

```j
5 + 2 * 3
2 * 3 + 5
```

違う結果が表示されましたね。J には演算子の優先順位は なく、基本的に**右から**計算されます [^3]。左側を先に計算したい場合は括弧を使います。

```j
   (2 * 3) + 5
11
   2 - (8 % 4) - 7   NB. 2 - ((8 % 4) - 7)
7
```

# 単項演算子

実は、上で紹介した `+` 等の記号は全て単項演算子としても使えます。

```j
   +5
5
   -5
_5
   %5    NB. 1/5
0.2
```

`%` は逆数を表します。(`%` が割り算なのでセットで覚えましょう。)

`*` は符号を、`|` は絶対値を返します。

```j
   *5    NB. _1 (負), 0, 1 (正)
1
   *_5
_1
   |5
5
   |_5
5
```

単項演算子が混ざっても、「右から」のルールは適用されます。

```j
   2 * 3 - -5     NB. 2 * (3 - (- 5))
16
   %5 - 2         NB. % (5 - 2)
0.333333
   -|_7           NB. - (| _7)
_7
```

# 練習

下の式を、それぞれ結果を予想しながら実行してみましょう。

```j
4 + |-3
--8 % %2
1 - 2 + 3 - 4 + 5
2 * 7 - 6 * 3
1 - 4 | 9 + 1
-(5 * 3) - 2
(*(1 - 3)) % _1
```

# verb と noun

さて、ここでいくつかの用語を紹介します [^4]。J の用語の多くは文法用語から来ているので、一般的でない単語も使われます。そこで、可能な限り英語と日本語を併記することにしています。

`+` 等の演算子や他の言語の関数にあたるものを、J では **verb** (動詞) と呼びます。verb のうち、

- 単項演算子として使うものを **monad**
- 二項演算子として使うものを **dyad**

と言います [^5]。verb は常に右結合です。

verb に対して、数値等の いわゆる「値」は **noun** (名詞) と呼ばれます。

---

\[ 前 : [インストール](https://qiita.com/unsigned-wrong-wrong-int/items/eb034e9966f397355078) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [数値の配列 (ベクター)](https://qiita.com/unsigned-wrong-wrong-int/items/a9871cb5cfc34e625a67) \]

[^1]: 注釈を示す略語。ラテン語の nota bene (よく注意せよ) から。
[^2]: この他に NaN (`_.`) もありますが、J では使用頻度は低いため省きます。
[^3]: 左から右の構文も存在します。これについては後々説明しようと思います。
[^4]: 全てを暗記する必要はありません。よく使うものについては自然に覚えられると思います。
[^5]: 例えば `+` は monad かつ dyad ということになります。
インストール ― J 言語入門

# J 本体のインストール

J の公式ホームページ https://www.jsoftware.com の、Download latest と書いてあるボタンをクリックすると、最新版のページが開きます。

あとは、Download and Install の所から、プラットフォームに応じて適切なものを選んでダウンロード・インストールします。OS によっては注意点がいくつかあります:

<details><summary>Windows</summary><p>セキュリティ関連の警告が出る場合があります。公式な配布なので問題ないとは思いますが、自己責任で対応してください。</p><p>インストーラのユーザーの選択 (Choose Users) では、'Install just for me' を選ぶことをお勧めします。</p></details>
<details><summary>Android</summary><p>提供元不明のアプリなのでインストールできないという旨のメッセージが出ます。セキュリティに関わることなので、許可する場合は自己責任で行ってください。</p><p>Android 6 以降では、デバイスのファイルアクセスの許可が必要なようです。</p></details>
<details><summary>iOS</summary><p>バージョン 7.01 以降更新されていません。App Store でダウンロードは可能ですが、記事中のコードの一部が正しく動作しない可能性があります。</p></details>

# パッケージのインストール

J には、標準で配布されているパッケージがあります。インストール方法は、OS によって異なります。

## Android

JAndroid のメニューの Tools \> Package Manager から、Select All して Install を押すだけです。

## iOS

バージョンが古いため、*パッケージのインストールはできません*。

## 他の OS

jconsole を起動して、次のように入力します。(jconsole は、環境によっては **i**jconsole という名前になっているかもしれません。)

```j
load'pacman'
'install' jpkg '*'
```

インストールが完了したら、`exit 0` と入力して jconsole を終了します。

### JQt IDE の設定

JQt IDE (黄緑色のアイコン) を立ち上げます。(環境によってはかなり時間がかかります。)

設定項目は いくつも ありますが、ここでは例として、フォントの設定を行うことにします。

メニューの Edit \> Session Font でフォントの種類やサイズを指定できます。ただし、**ここでの設定は一時的なもので、次回起動時には戻ってしまいます** [^1]。次回にも反映するには、Edit \> Configure \> Qt Ide を選びます。

'config/qtide.cfg' というファイルが開かれるので、フォントの設定項目を探して書き換えます。

```
[Session]
BoxForm=0
ConfirmClose=false
ConfirmSave=false
CursorWidth=1
DebugDissect=true
EscClose=false
FontFamily=(フォント名)
FontSize=(サイズ)
FontWeight=(太さ)
...
```

保存したら、Edit ウィンドウは閉じてください。

# パッケージの更新

さて、パッケージのインストールは最初に済ませましたが、今後使っていく間に、パッケージがバージョンアップすることもあります。適宜更新を行う必要がありますね。

パッケージの更新は、基本的に GUI (JQt, JAndroid) から行います。

1. メニューの Tools \> Package Manager を開きます。
1. 左側のリストの、Upgrades / Not installed のいずれかが空でない場合は、更新が必要です。
1. 左下の対応するボタン (Updates / Not Installed) を押すと自動で選択されるので、その後 Install を押します。

## JQt の更新

JQt を使っている場合、JQt 自体 (ide/qt) の更新は GUI では**できません**。Upgrades のリストに ide/qt が含まれている場合、

1. まずは他の更新が必要なパッケージを GUI を使って更新します。
1. JQt IDE の全てのウィンドウを閉じて終了します。
1. jconsole から JQt を更新します。

```j
load'pacman'
'upgrade' jpkg 'ide/qt'
```

---

jconsole は OS によって差異があるので、記事では GUI の利用を前提として解説することにします。

---

\[ 前 : [はじめに](https://qiita.com/unsigned-wrong-wrong-int/items/2af2c832e3c534561d72) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [数値と計算](https://qiita.com/unsigned-wrong-wrong-int/items/45174edb69df1149386e) \]

[^1]: フォント以外の設定も同様です。
はじめに ― J 言語入門

# J とは

J は、APL という言語の後継で、APL を作った Kenneth E. Iverson らによって作られました。APL から引き継いだ配列処理の機能に加え、GUI プログラミングや OOP など、**実用的な機能**も兼ね備えています。

また、APL で使われていた多くの記号を ASCII 文字の範囲内で置き換えているため、現在のキーボードでも入力が容易です。

# 『J 言語入門』について

この記事は、普段他の言語でプログラミングしている人に J を紹介し、その魅力を知ってもらうことを主な目的としています。(プログラミング自体が初めてだという方は、まず他の言語を学ぶことをお勧めします。)

J は、基本的にイミュータブルな値を扱い、関数型言語に近いですが、手続き型の構文やオブジェクト指向の機能もあります。さらに、コードゴルフやメタプログラミングにも向いています。規模の大きなプログラムには向きませんが、**趣味として使うにはピッタリの言語だと思います**。

ただ、困ったことに、日本語で書かれた解説が少なく、古い情報も混ざっています。そこで、これから J を学ぶ人の足掛かりになればと思い、詳細な解説を書くことにしました。

---

\[ 前 \] \[[ 目次 ](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced)\] \[ 次 : [インストール](https://qiita.com/unsigned-wrong-wrong-int/items/eb034e9966f397355078) \]
J 言語入門 (目次)

:construction: *『J 言語入門』は、現在書きかけです。編集リクエスト・コメント等頂けると有り難いです。* :bow: 

# 目次

メインのコンテンツです。順番に読むことを想定しています。

1. [はじめに](https://qiita.com/unsigned-wrong-wrong-int/items/2af2c832e3c534561d72)
2. [インストール](https://qiita.com/unsigned-wrong-wrong-int/items/eb034e9966f397355078)
3. [数値と計算](https://qiita.com/unsigned-wrong-wrong-int/items/45174edb69df1149386e)
4. [数値の配列 (ベクター)](https://qiita.com/unsigned-wrong-wrong-int/items/a9871cb5cfc34e625a67)
5. [文字と文字列](https://qiita.com/unsigned-wrong-wrong-int/items/bafe9f327fe4180e0fbd)
6. [多次元配列](https://qiita.com/unsigned-wrong-wrong-int/items/813c4e216d60ce80e770)
7. [ボックス](https://qiita.com/unsigned-wrong-wrong-int/items/2b0825008ed95ea722ce)
8. [様々な数値](https://qiita.com/unsigned-wrong-wrong-int/items/96ed987360617667c29b)
9. [数学関数](https://qiita.com/unsigned-wrong-wrong-int/items/7be9576316e42221105a)
10. [ユニコード文字列](https://qiita.com/unsigned-wrong-wrong-int/items/399759d08f536811aeaa)
11. [シンボル](https://qiita.com/unsigned-wrong-wrong-int/items/174cab8807feb3ac5584)
12. [疎行列](https://qiita.com/unsigned-wrong-wrong-int/items/a7587ed207008e8d0a04)
13. [データ型のまとめ](https://qiita.com/unsigned-wrong-wrong-int/items/cf81b30258582f89676e)
14. [verb と引数](https://qiita.com/unsigned-wrong-wrong-int/items/4357829e274c302cfe64)
15. [高階関数](https://qiita.com/unsigned-wrong-wrong-int/items/77cb04ee82b856c52622)
16. [adverb と conjunction](https://qiita.com/unsigned-wrong-wrong-int/items/b61c2f03af3096be044f)
17. [代入](https://qiita.com/unsigned-wrong-wrong-int/items/e175f45607e407bb0973)
18. [フックとフォーク](https://qiita.com/unsigned-wrong-wrong-int/items/03f1b408fd89bdbc18ff)
19. [explicit definition](https://qiita.com/unsigned-wrong-wrong-int/items/0bc6385d4e640b097651)
20. [複数行のリテラル](https://qiita.com/unsigned-wrong-wrong-int/items/4f63903f7ae00b145ee6)
21. [define の実体](https://qiita.com/unsigned-wrong-wrong-int/items/968640fb004867c9dcce)
22. [direct definition](https://qiita.com/unsigned-wrong-wrong-int/items/6214e76feb92d7c2e756)
23. [制御構文](https://qiita.com/unsigned-wrong-wrong-int/items/c376a7ea5b58e6bdbf0f)
1. ...*執筆中*...

# コラム

本文中に書ききれなかった小ネタなど。

- [用語について](https://qiita.com/unsigned-wrong-wrong-int/items/e0eaa51710c583f0ac00)
- [データの流れ](https://qiita.com/unsigned-wrong-wrong-int/items/00180e76f5f781808ebf)
- [記号と読みやすさ](https://qiita.com/unsigned-wrong-wrong-int/items/91339ed4e4e7fa5b1ccd)

<!--
TODO: 将来的には全てのプリミティブを網羅した辞書のようなものを作りたい。今はメインの記事を優先。
-->

# 参考

- J 公式サイト: https://www.jsoftware.com
- J Wiki: https://code.jsoftware.com/wiki/Main_Page
テスト16

```vb
'桁数判定他
Sub ketasu()

'変数設定
Dim i As Long
Dim Lcount As Long
Dim snum As Long
Dim lnum As Long
Dim Hantei As Currency

'初期設定
lnum = Cells(Rows.Count, 2).End(xlUp).Row    '最終行取得
snum = 3
Hantei = 90000000000#

Set wb = ThisWorkbook.Worksheets("Sheet4")

For i = snum To lnum

    wb.Cells(i, 3).Value = Len(Cells(i, 2))
    
    If wb.Cells(i, 2).Value >= Hantei Then
    
        wb.Cells(i, 4).Value = "〇"
        wb.Cells(i, 5).Value = Hantei
        wb.Cells(i, 6).Value = wb.Cells(i, 2).Value - Hantei
        
    Else
    
        wb.Cells(i, 4).Value = "×"
    
    End If
    
    
Next i

End Sub

'メモ
ActiveSheet.PageSetup.PrintArea ="$A$1:$G$300"　　'印刷範囲設定
この行の内、　$A$2:$G$200 　の部分を必要に応じて変更。印刷の対象範囲になります。
ActiveSheet.PageSetup.PrintArea ="$A$1:$G$50"
ActiveSheet.PageSetup.PrintArea ="$A$51:$L$100"　
のように連続して記述すると、同一ワークシート内の複数の範囲を一度に印刷できます。
複数のワークシートを同時に印刷する時は、　Worksheets("Sheet1").Activate　以下を繰り返して記述。


```
【Rails】sessionによるデータの一時保持

#はじめに
sessionは「ウィザード形式」等でデータを保持させた状態で遷移先に移動する時に使用します。

###目次
1. セッションについて
2. 実装例
3. 最後に

#1. セッションについて
セッションは情報を一時的に記憶しておく仕組みです。
Railsにおいてセッションは、sessionというオブジェクトにハッシュのような形でデータが格納されます。

例えば、会員登録の際ページが切り変わって進んでいくようなサイトを想定します。
この場合、セッションを使い入力した情報を一旦sessionに格納して、次のページに遷移してそこで展開させる必要があります。


#2実装例

###前提
前提としてdeviseを用いてページを遷移しながら会員情報を保存する事を想定してます。

###開発環境
ruby 2.6.5
rails 6.0.0
devise 4.7.3




##2.1 データの保持

それでは実装してみますー

```registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController

  def new
    @user = User.new
  end

  def create
    @user = User.new(sign_up_params)
      unless @user.valid?
        render :new and return
      end
    session["devise.regist_data"] = {user: @user.attributes}
    @address = @user.build_address
    render "new_address"
  end
```

他いろいろ記述してますがsessionに注目します。

```
session["devise.regist_data"] = {user: @user.attributes} 
```

{user: @user.attributes}はsessionにハッシュオブジェクトの形で情報を保持させたい時、attributesメソッドを用いてデータを整形しています。

つまり、attributesされた@userのデータがハッシュの状態でsessionに入ってます。
これで、session["devise.regist_data"]に入力情報が代入され、保持さてた状態になります。



##2.2 展開させる
次に、データを保持した状態でページを遷移して展開します。

```registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController

#省略
 def create_address
    @user = User.new(session["devise.regist_data"]["user"])
    @address = Address.new(useraddress_params)
      if @address.valid?
        @user.build_address(@address.attributes)
        @user.save
          session["devise.regist_data"]["user"].clear
          sign_in(:user, @user)
      else
        render "new_address"
      end
  end
```

こちらもいろいろ記述してますが一番上の@userに注目。

```
@user = User.new(session["devise.regist_data"]["user"])
```

session["devise.regist_data"]["user"]について説明します。
{user: 〇〇}でデータを持すと ["user"]を使う必要がある。
また、sessionは配列で情報を入れるので以下のように情報を持す事もできます。
session["devise.regist_data"] = {user: @user.attributes, address: @user.address}


これで無事遷移先のページでsessionが展開できて@userに代入ができました。

あとは@userに代入されてるデータを使って保存などが可能です。　


#まとめ
今回は「ウィザード形式」でdeviseを用いた際のsessionの使いた方を紹介しました。

####最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜
【Swift 】通知を出す方法について


# 通知を許可しているか確認

通知を出す場合、事前に通知を許可しているか確認する必要があります。

``` Swift:
// 通知許可の取得
UNUserNotificationCenter.current().requestAuthorization(
     options: [.alert, .sound, .badge]){
     (granted, _) in
     if granted{
          UNUserNotificationCenter.current().delegate = self
     }
}
```

# 指定時間経過で通知を出す

○秒後に実行させる場合、`UNTimeIntervalNotificationTrigger(timeInterval: , repeats:)`で通知を作成させる必要があります。

```Swift:
let content = UNMutableNotificationContent()
content.sound = UNNotificationSound.default
content.title = "タイトル"
content.subtitle = "サブタイトル"
content.body = "内容"

// 指定時間後に実行
let timer = 10

// 通知リクエストを作成
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(timer), repeats: false)
let identifier = NSUUID().uuidString
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

// 通知リクエストを登録
UNUserNotificationCenter.current().add(request){ (error : Error?) in
     if let error = error {
          print(error.localizedDescription)
     }
}

```



# 指定時刻になったときに通知を出す

指定時刻に実行させる場合、`UNCalendarNotificationTrigger(dateMatching: , repeats:)`で通知を作成させる必要があります。

```Swift:
let content = UNMutableNotificationContent()
content.sound = UNNotificationSound.default
content.title = "タイトル"
content.subtitle = "サブタイトル"
content.body = "内容"
                
// 通知時刻を指定
let date = Date()
let newDate = Date(timeInterval: 60, since: date)
let component = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: newDate)
                
// リクエストを作成
let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: false)
let identifier = NSUUID().uuidString
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
                
// 通知リクエストを登録
UNUserNotificationCenter.current().add(request){ (error : Error?) in
     if let error = error {
          print(error.localizedDescription)
     }
}
```
AtCoderBeginnerContest180復習＆まとめ

# AtCoder ABC180
2020-10-17(土)に行われたAtCoderBeginnerContest180の問題をA問題から順に考察も踏まえてまとめたものとなります．
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc180)
[公式解説PDF](https://atcoder.jp/contests/abc180/editorial)

## A問題　box
> 問題文
> $N$個のボールが入っていた箱から$A$個のボールを取り出し、新たに$B$個のボールを入れました。今、箱にはボールが何個入っていますか?

```python:abc180a.py
n, a, b = map(int, input().split())
print(n - a + b)
```

## B問題　Various distances
> 問題文
> $N$次元空間内の点$(x_1,…,x_N)$が与えられます。
> 原点からこの点までの、マンハッタン距離、ユークリッド距離、チェビシェフ距離をそれぞれ求めてください。 ただし、それぞれの距離は次のように計算されます。
> 　・マンハッタン距離：$|x_1|+…+|x_N|$
> 　・ユークリッド距離：$\sqrt{|x_1|^2+…+|x_N|^2}$
チェビシェフ距離：$max(|x_1|,…,|x_N|)$

```python:abc180b.py
n = int(input())
x_list = list(map(int, input().split()))
a = 0
b = 0
c = 0
for x in x_list:
    if x < 0:
        x *= -1
    a += x
    b += x * x
    if c < x:
        c = x
print(a)
print(b**(0.5))
print(c)
```

## C問題　Cream puff
> 問題文
> $N$個のシュークリームがあります。
> シュークリームを分割することなく平等に分けることができるような人数としてあり得るものを全て求めてください。

```python:abc180c.py
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    divisors.sort()
    return divisors
n = int(input())
for x in make_divisors(n):
    print(x)
```

## D問題　Takahashi Unevolved
> 問題文
> いろはちゃんはペットを育てるゲームにはまっています。
> いろはちゃんはペットとして高橋君を飼っており、はじめ高橋君の強さは$X$、経験値は$0$です。 これらの値は次の$2$種類の特訓によって増加します。
> 　・カコモンジムに通う：強さが$A$倍になり、経験値は$1$増える。
> 　・AtCoderジムに通う：強さが$B$増え、経験値は$1$増える。
> 高橋君は強さが$Y$以上になると進化しますが、進化しない方がかわいいといろはちゃんは思っています。
> そこで、強さが$Y$以上にならないように高橋君に特訓を課すとき、経験値の最大値を求めてください。

コンテスト中は，繰り返し処理を使わないように，何回カコモンジムに通えるかを，logとか使って計算していました．
(```n = int(math.log(b / a / x, a)) + 1```みたいな感じ)
解説に書いてあった，何回カコモンジムに通えるかは制約的に$64$回以下，を見てなるほどなと思いました．
コードは解説に載っていたものです．

```python:abc180d.py
x,y,a,b=map(int,input().split())
ans=0
while a*x<=x+b and a*x<y:
  x*=a
  ans+=1
print(ans+(y-1-x)//b)
```

ここ最近，D問題までは解けても，そこまでのどこかしらの問題で時間使い過ぎて，E問題解ききれていないので，もう少し柔軟に問題が解けるようになりたいと思います．

最後まで読んでいただきありがとうございました．
Cloud9でTypeScriptの学習（環境構築から実行まで）



##【環境】

・cloud9
・tsc --version
Version 4.0.3
・npm --version
7.0.3
・nvm --version
0.33.0

#やったこと

- npm をインストールするために、Node Version Manager (nvm) をダウンロードする。

- nvmとは？ 
Node.js のバージョンをインストールして管理するために役立つ Bash シェルスクリプト

```
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
. ~/.bashrc
```

nvm の使用を開始する

```
. ~/.bashrc
```

Node.js をインストールするために、nvmコマンドを実行する (npm は Node.js に含まれている)。

```
nvm install node
```

-g オプションを指定して npm を実行し、TypeScript をインストールする。
TypeScriptがグローバルパッケージとして環境にインストールされる

```
npm install -g typescript
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/724fa399-2350-8e55-f735-a3e63fbcb23b.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/53d26e8d-9d0b-8e07-465f-676dcf2addc3.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/dc8b5057-fe3e-5b29-8ed9-aa45a8cd0b32.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/bb95a203-7ae5-d61d-9f5e-ec421f90f62f.png)

##学習内容とまとめ

・ファイルの作成
・コンパイル
・jsファイルの実行まで確認できた

参考記事
---
[AWS Cloud9 の TypeScript サンプル
](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/sample-typescript.html)
Terraformコマンド 備忘録

Terraformについて、勉強していたのでメモとして残します。
versionは0.13.2となっています。

## 作業ディレクトリの初期化
[公式](https://www.terraform.io/docs/commands/init.html)

```terminal
# 初期化
terraform init
```

## 計画実行(dry-run)
追加・更新・削除内容を確認できます。
[公式](https://www.terraform.io/docs/commands/plan.html)

ただし、terraformのdry-runであるだけで、例えばapply時に存在しないインスタンスタイプを指定して、エラーとなる場合もあります。
公式ではないが、チェックするためのツールもあるとのこと。
※[tflint](https://github.com/terraform-linters/tflint)

```terminal
# 計画実行
terraform plan

# 特定のリソースのみ
# リソースの指定
terraform plan -target=aws_security_group.ecs_cluster

# モジュールの指定
terraform plan -target=module.api_ecs_cluster
```

## リソースの追加・更新・削除
planにて出力された結果を実行。
[公式](https://www.terraform.io/docs/commands/apply.html)

```terminal
# 実行
terraform apply
```

## リソースの削除
planにて出力された結果を実行。
[公式](https://www.terraform.io/docs/commands/destroy.html)

```terminal
# 削除
terraform destroy

# コマンド実行前に確認で安心
terraform plan -destroy
```

## リソースの削除
planにて出力された結果を実行する。
[公式](https://www.terraform.io/docs/commands/destroy.html)

```terminal
# 削除
terraform destroy

# コマンド実行前に確認で安心
terraform plan -destroy
```

## モジュールの取得
実行に必要なモジュールの取得。
[公式](https://www.terraform.io/docs/commands/get.html)

```terminal
# モジュールの取得
terraform get
```


## フォーマット
.tfファイルのフォーマットをしてくれる。
[公式](https://www.terraform.io/docs/commands/fmt.html)

```terminal
# フォーマット
terraform fmt

# 再帰的にフォーマット
terraform fmt -recursive
```

## 記述チェック
.tfファイルの記述をチェックしてくれる。
[公式](https://www.terraform.io/docs/commands/validate.html)

``` terminal
# 記述チェック
terraform validate

# 例
Error: Missing newline after argument

  on main.tf line 41, in module "api_ecs_cluster":
  41:   source = "../../modules/ecs-cluster"aaa

An argument definition must end with a newline.
```

# state
Terraformのstateファイルは実際にAWS等にデプロイされているインフラと、マッピングに利用されており、メタデータを保持しているとのこと。
また、チーム開発等を行う際はAWSであればS3に配置し、直接編集を行わないようにします。
[公式](https://www.terraform.io/docs/commands/state/index.html)

```terminal
# 作成リソースのリスト表示
terraform state list

# リソースの詳細情報の表示
terraform state show <詳細情報を見たいリソース>
terraform state show aws_security_group.ecs_cluster

# S3等からstateファイルを持ってくる
terraform state pull

# ローカルのstateとリモートのStateを置き換える(※ 基本は使うべきではない)
terraform state push

# リソースをTerraform管理から外す
    terraform state rm <管理外にしたいリソース>
    terraform state rm aws_security_group.ecs_cluster
```


## import
Terraformで管理されていないリソースを管理下に置きます。
既存のリソースに対してTerrafomを導入したいときに使います。

Googleがterrafomerというツールを作成しているのでそちらを使うのもありかと。
※[terrafomer](https://github.com/GoogleCloudPlatform/terraformer)

### EC2を例にする
tfファイルの作成する

```terminal
resource "aws_instance" "test_instance" {
}
```

インスタンスIDを確認しインスタンスIDを元にコマンド実行する

```terminal
terraform import aws_instance.test_instance <インスタンスID>
```

stateコマンドの結果を元に.tfファイルを編集する

```terminal
terraform state show aws_instance.test_instance
```

planで差分がないか確認 (差分があったとしても問題なければOK)

``` terminal
terraform plan
```
Pythonの学習し直し（アルゴリズムⅠ）

Pythonをしっかりと根本面での学習をしなおそうという備忘録。
基本的な問題などに取り組んでいるものを成果として上げていこうと思う。

# FizzBuzz問題
fizz_buzz_problem
プログラマが書ける最も基本的とも言っていい問題。
###問題文
1から100までの数を順に出力するプログラムを作成しなさい。
ただし、3の倍数の時は数の代わりに「Fizz」を5の倍数の時は数の代わりに「Buzz」を、３と５の両方の倍数の場合には、「FizzBuzz」を出力するものとする。 



###作成プログラム

```python
#1から100までの数を順に出力するプログラムを作成しなさい。
#ただし、3の倍数の時は数の代わりに「Fizz」を5の倍数の時は数の代わりに「Buzz」を、３と５の両方の倍数の場合には、「FizzBuzz」を出力するものとする。
for i in range(1, 101):
    if i % 3 == 0 and i % 5 == 0:
    #if (i % 3 == 0) and (i % 5 == 0):
        print('FizzBuzz', end = ' ')
    elif i % 3 == 0:
        print('Fizz', end = ' ')
    elif i % 5 == 0:
        print('Buzz', end = ' ')
    else:
        print(i, end = ' ')
```

```terminal
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz 
Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 
Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 
Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 
FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 
92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 
```

# 自動販売機のお釣り問題
vending_machine_problem

### 問題文
1万円札まで入れることのできる自動販売機があります。この時、お釣りを最も少ない硬貨及び紙幣で出力するプログラムを作成しなさい。

### 作成したプログラム

```python
import sys


insert_price = int(input('insert:'))
product_price = int(input('product:'))
change = insert_price - product_price
if change >= 0:
    print('change:', change)
else:
    print('Not enough money.')

#=>insert:1000
#=>product:239
#=>change: 761


coin = [10000, 5000, 1000, 500 , 100, 50, 10, 5 ,1]

for i in coin:
    r = change // i
    change %= i
    print(str(i) + ':' + str(r) + 'coins')

#=> 10000:0coins
#=> 5000:0coins
#=> 1000:0coins
#=> 500:1coins
#=> 100:2coins
#=> 50:1coins
#=> 10:1coins
#=> 5:0coins
#=> 1:1coins
```

# 参考資料
[Pythonではじめるアルゴリズム入門 伝統的なアルゴリズムで学ぶ定石と計算量](https://www.amazon.co.jp/Python%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%85%A5%E9%96%80-%E4%BC%9D%E7%B5%B1%E7%9A%84%E3%81%AA%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A7%E5%AD%A6%E3%81%B6%E5%AE%9A%E7%9F%B3%E3%81%A8%E8%A8%88%E7%AE%97%E9%87%8F-%E5%A2%97%E4%BA%95-%E6%95%8F%E5%85%8B-ebook/dp/B0822N5RMS/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=38MY4D6L4UM7I&dchild=1&keywords=python+%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&qid=1603601139&sprefix=python+arugori%2Caps%2C291&sr=8-4)

[僕のgithub URL](https://github.com/jin237/algorism_python)
https://github.com/jin237/algorism_python
rubyで簡単に基本型と参照型を感じる2

[rubyで簡単に基本型と参照型を感じる](https://qiita.com/akihiro_kubota/items/1939d95b002b85a7f203) のメソッドを使わないパターンです。

macのターミナルでRubyを起動

```shell
   irb
```


## 参照型の値のもつ基本型の値を変更した場合

```ruby
temp=[1,2]
temp2=temp
temp2[0]=11
temp #[11, 2]
```
tempとtemp2の持つ値（参照値）は同じ

## 参照型の値そのものを変更した場合
```ruby
temp=[1,2]
temp2=temp
temp2=11
temp #[1, 2]
```
tempとtemp2の持つ値（参照値）は異なる
Require self-closing on Vue.js custom components (<〇〇>).の解決方法

ESLintを導入後にRequire self-closing on Vue.js custom componentsという警告が出たので解決方法を記載しておきます。

```vue:app.vue
<template>
  <v-app id="app">
    <Header></Header>
    <Todolist></Todolist>
  </v-app>
</template>
```

上記のコードで以下のような警告出ました。

```bash:警告
Require self-closing on Vue.js custom components (<Header>).
Require self-closing on Vue.js custom components (<Todolist>).
```


原因は開始タグと終了タグの間に何も記載がないのが理由ですが、
今回はタグの間に何も書く必要が無いので別の解決方法を使います。


```vue:app.vue
<template>
  <v-app id="app">
    <Header />
    <Todolist />
  </v-app>
</template>
```

このように自己終了タグを使うと警告が出なくなります。

参考
[https://kojimanotech.com/2019/09/22/187/]
Unicorn環境でRubyをアップデートする

Unicorn と capistrano を使った Railsアプリケーション で ruby を 2.3 から2.5にアップデートしたので、
その手順をまとめてみました。

## 1. rbenv の更新

updateしたい対象のrubyのバージョンをinstall し、global で対象のバージョンを指定しておく

```
$ rbenv install  2.5.8
$ rbenv global 2.5.8
```

`rbenv install --list` でアップデートしたい対象のバージョンが出てこない時は、
`rbenv install` ができないので、下記の手順でrbenvを更新すると、installできるはずです。

```
$ cd ~/.rbenv/plugins/ruby-build
$ git pull
```

###  2.  bundler の install と bundle install をしておく
デプロイ時に  bundle  install でこけないように予め bundler と 他のライブラリを install しておく

```
# gemfile.lock を確認して、同じ version の bundler を指定する
$ gem install bundler -v 1.17.3
$ bundle install
```

### 3. デプロイ
capistrano で通常通りデプロイする
しかし、この時必要なのが、 ruby のバージョンを切り替えるには、再起動が必要であり、
一度 unicorn を kill  して立ち上げ直す必要があった。

`preload_app: true` の設定をしている型は注意が必要です

```
$ kill -QUIT `cat /path/to/unicorn.pid`
$ bundle exec unicorn_rails -E production -D
```
Angularでswiperを使おうとしたが躓いた話

<h1>Angularでswiperが動いてくれない！！</h1>


Angularにて、swiperを使ってスライドショー的なやつを作成しようと、
[この記事](https://qiita.com/biga816/items/540bc88fe040ca2c4497)を参考として、実装しようと試みたが、「＜」「＞」を押しても
まったく反応してくれず、いろいろと試した結果、どうにか反応してくれたので、
その結果を残しておく。

ちなみに各バージョンは、下記の通りDeath!
Angular：10.1.6
swiper ：6.3.4

<h2>結論</h2>
swiperのslideNextメソッド呼べば動く。

```javascript:component.ts側

slideNext():void{
    this.swiper.slideNext();
  }
```
```html:html側
 <div class="swiper-button-next" (click)="slideNext()"></div>
```
<h2>やったこと</h2>
まずはHTML側にお決まりの構成を記述。

```html
 <div class="swiper-container columns is-centered">
    <div class="swiper-wrapper column is-6">
      <div class="swiper-slide">slider1</div>
      <div class="swiper-slide">slider2</div>
    </div>
    <div class="swiper-button-next" (click)="slideNext()"></div>
    <div class="swiper-button-prev" (click)="slidePrev()"></div>
  </div>
```

そしてcomponent.ts側の初期処理でswiperインスタンスの生成とプロパティ設定

```typescript
ngOnInit(): void {
    this.swiper = new swiper('.swiper-container', {
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
    });
  }
```

上記の記載で、スワイプによる切り替わりは動くものの、
「＜」「＞」ボタン押下での切り替わりがされない。。。

Google先生に質問したところ、下記サイトにたどり着く。
https://stackoverflow.com/questions/49810045/swiper-not-working-in-angular-5

先生の翻訳内容を見た限り、発生している内容が同じ。
そして、ベストアンサーには、HTMLが読み込まれる前に、swiperが初期化され、
設定が無いことになってんじゃねーの？だから、表示された後に生成しちゃえYO!
とのことらしいので、上記のngOnInit()ではなく、ngAfterViewInit()でインスタンス生成してみた。

```typescript

 ngAfterViewInit() {
    this.swiper = new swiper('.swiper-container', {
      loop: true,
      navigation: {
        nextEl:   '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
    });
}
```
うん、動かないね！デバッグで追ってみた感じ、別に初期化されてるわけでも無さそう！
てか、そもそもswiper側で何してるの？と疑問に思ったので、見てみたところ

```javascript:/node_modules/swiper/swiper-bundle.js

 onNextClick: function onNextClick(e) {
      var swiper = this;
      e.preventDefault();
      if (swiper.isEnd && !swiper.params.loop) return;
      swiper.slideNext();
    },
```
なるほどなぁ、うんうん。。。。slideNext呼べばよくね？
という事で、初めに書いた結論となります。

<h2>最後まで読んでいただき、ありがとうございます。</h2>
そんなことせんでも、もっと良いやり方あるぞ！
というご意見、アドバイス絶賛募集中です！
よろしくお願いいたします:bow_tone1:
【React】onChangeで値を取得する方法

## 開発環境
- Typescript
- React
- Material UI

## コード
onChangeの引数はevent.target.valueで取得できます。

```searchWindow.tsx
import * as React from "react";
import { useState } from "react";
import TextField from "@material-ui/core/TextField";

export default function SearchWindow() {
  const [value, setValue] = useState('default'); // valueをstateで管理

  return (
    <div>
      // 入力値をevent.target.valueで取得。setValueでvalueの値を更新
      <TextField onChange={(event) => setValue(event.target.value)} />
      <p>{value}</p>
    </div>
  );
}
```

useStateの使い方は下記を参考にしてください。
[【React】カウンターAppでuseState, useEffectを使ってみた](https://qiita.com/shungo_m/items/3e2dce0cb9efa13ba22d)


```app.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import SearchWindow from '.s earchWindow.tsx';

function App() {
  return (
    <SearchWindow />
  );
}

ReactDOM.render(<App/>, document.querySelector('#app'));

```

## 動作確認
![onChange.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497683/d063f361-765d-bd2f-4f6c-e7e27f6f888e.gif)
【実録】応用情報技術者試験の勉強の進め方

# 受験の背景
「なんで受けたの？」って聞かれることは多い。理由は2つである。
1. 経験してきたことの抽象化
2. 知識補完・補強

**まず「1. 経験してきたことの抽象化」について。**
筆者は変化が激しいIT業界の中でも、fin-tech領域の新規事業のシステム開発に新卒から３年程度関わっている。正直、過去を振り返らず、前進してきた。いい意味で機会が多く、たくさんの経験をしてきたと思っている。
一方で、その経験にレバレッジが効いているかでいうと怪しいところがあった。具体事象を多く持っていても、違う場面で応用させられるかは別の話である。
テコを効かすには、理論として抽象化する必要があると思い、体系化された理論めいたものをインプットするために受験した。

**次に「2. 知識補完・補強」について**
実践を重視するあまり、とにかく手を動かすことを優先してしまっていた。故に、ベストプラクティスへの理解や、観点を広げるために知識のインプットを怠っていきたという思いがあり、ハードウェアからプログラム、マネジメント系の知識を網羅的にインプットできると思い、受験した。

### 実際に受験してみてどうだったか？
「受験の背景」に言及した狙いは概ね達成されたかと思う。
「知っているか知っていないか」で大きな違いが生まれる領域だとも思っているので、知識補完ができたのが有意義だった。特に浅くではあるが、セキュリティ領域はリスクに対して広く触れられるため実感が強かった。

理論をインプットする際にも、過去の自身の経験と結びつけて理解することで、腹落ち度が上がるし、原理とまではいかないが、原則なるものを自己確立できた気がした。（できるかは別だけど、意識はできるようになると思う。）

# どんなことをしたのか？
難しいことはせず、以下のことをした。

- どんな試験なのかを調査
- 計画を立てた。WBSつくって、ガントチャート作って学習
- 学習する中で、PDCAを回す
- 受験

詳細/ログが、以下のスプレッドシートにあります。
よかったら、みてみてください。
https://docs.google.com/spreadsheets/d/1eq5HaneiZwLfDuBO6yx-eXXCnDw6CViq6oVpiko7qcM/edit?usp=sharing
※「Please wait...」タブがざっくりAPについてまとめており、「TaskSchedule」タブがスケジュールです。
※暇があったらQiitaかnoteに整形して転載します。
AWS S3 download, upload

# 概要  
AWSのS3に保存しているデータをdownloadまたはupload操作するときのコマンド  

## Download  
  
```
aws s3 cp s3://bucket_name/folder/ ./folder/ --recursive  
```  

## Upload  

```
aws s3 cp ./folder/ s3://bucket_name/folder/ --recursive
```  
  
## 条件に合致するファイルをUpload  
```
aws s3 cp ./folder/ s3://bucket_name/folder/ --recursive --exclude '除外する文字列' --include '含む文字列'
```
ImageMagickのコマンドラインツールで画像がモノクロかどうかを判定する（on Windows）

確実に判別できるのかまでは分かりませんが、下に記述する方法でおおむね判定できるようです。

以下のブログ記事を参考にさせてもらいました。
感謝です。
[画像がカラーか、白黒かを判別する - それマグで！](https://takuya-1st.hatenablog.jp/entry/2017/03/30/024609)


まず、
[ImageMagick - Download](https://imagemagick.org/script/download.php)
で、Windows向けの最新のバイナリをダウンロードしてきてインストールする。
インストールする際は、convertなどのレガシーなツールをインストールするか？という項目があるのでチェックする。
ffmpegをインストールするか？というオプションも必要そうなのでチェック（いらないかも）。

あとは、コマンドプロンプトを起動して以下のようにコマンドを実行。

```bash
> convert ファイルパス -colorspace HSB -separate -delete 0 -fx "u*v" -blur 2x2 -threshold 30% -format %[fx:mean] info:
0
```

モノクロだと0が出力され、そうでない場合は何も出力されません。
（参考にさせてもらったブログ記事とは挙動が異なるようですが、LinuxとWindowsでプラットフォームが違いますし、利用しているImageMagicのバージョンも違うので、そういうこともあるのでしょう。何故かまでは検証していません）

なお、jpeg画像でしか確認していないため、他の画像形式でうまくいくかは分かりませんが、上記のコマンドラインでファイル形式は指定していないので、おそらくうまくいくのではないかと思います。

以上。