OmniAICreator/Qiita-1.07M huggingface dataset:
Vuex用語整理(個人メモ)

### 目的
nuxt.jsでVuexでデータを扱いたいときに、すぐに忘れてしまうためメモとして残しておきたい



### 参考リンク

https://reffect.co.jp/vue/understaind-vue-basic
https://ja.nuxtjs.org/guide/vuex-store/



## 基礎

### なぜ使うと便利？

複数コンポーネントからデータを一元管理するときにpropsやemitから解放されるためvueファイル内のdataプロパティで扱うより容易になるケースがある。



### $store

データを格納する場所

```js
export const state = () => ({
  name: value
})
```



### getters

computedプロパティと同じ。複数コンポーネントでフィルターの条件など使いまわせる分DRYになる

```js
export const getters = () => ({
  getValue(state) {
    return state.value
  },
})
```

使い方

```js
return this.$store.getters.getValue;
```



### mutations

stateの中身を編集することだけに使う。それ以外の複雑な処理はactionsに記述

```js
export const mutations = {
  changeState(state) {
    state.value = ??
  },
}
```

使うときはcommitを使う。

```js
methods: {
  chnageState(){
  	this.$store.commit('chnageState')
  }
 },
```



payloadでmutationに引数を渡す。

```js
export const mutations = {
  chnageState(state, payload) {
    state.value = state.value = payload
  },
}
```

```js
methods: {
  changeState() {
    this.$store.commit('chnageState', 'value')
  },
},
```



### actions

mutationsを経由してcommitする。非同期処理が可能。

```js
export const actions = {
  changeStateAction(context) {
    context.commit('chnageStateActoin')
  }
}

// or (context内でcommitしか使わない場合)

export const actions = {
  changeStateAction({commit}) {
    commit('chnageStateActoin')
  }
}
```

contextというstoreインスタンスが引数に入る

実行するには

```js
methods: {
  changeStateAction() {
    this.$store.dispatch('chnageStateAction')
  },
},
```

非同期処理を書くには(axios)

```js
export const state = () => ({
  data: [],
})

export const mutations = {
    setData(state, data) {
        state.data = data
    }
}

export const actions = {
  getData({commit}) {
    return axios.get(url).then(res => {
        commit('setData', res.data)
    })
  }
}
```

つかうときは

```js
this.$store.dispatch('getData')
```
エンジニアらしいツイートをする技術

お仕事に疲れたので息抜きに書こうと思います。
深夜テンションで行きましょう。

こんにちはいぬっくすです。

## 世界観

インターネットに「ヌルポガッ」が溢れ始め早数年…
今回はそんなヌルポに変わる次の流行を作りたい人のために、新しいExceptionの作り方をご説明します。

## ルール説明

ルールは簡単。2つ覚えるだけです。

- 単語をつなげ、先頭を大文字にする
- 最後はExceptionで終わる

さぁ、やっていきましょう。

## 事例紹介

### ToiletPaperNotFoundException

まさに地獄。今すぐ右隣の壁にノックしてトイレットペーパーをもらってください。

### DontSyusyaException

会社に出社しない時に使ってください。
「出社したくない」ではなく「出社しない」わけですから、これを使うことで上司は何時間でも待ってくれます。

### NanimoShitenaiException

何もしていない時に急にPCが動かなくなったら、会社のシステム管理の方にこれを伝えてください。
あなたは何もしていないはずですから、何も問題はありません。

### CantMoveMyBodyException

夜中に金縛りにあって体が動かなくなったらツイートしてください。
TwitterがWiFiの力を借りて霊を爆散してくれるはずです。

### BoyMeetGirlExceptoin

制服の男女が出会って何か物語が始まりそうな場面に出会ったおじさんが、その証拠写真とともに呟ける言葉です。

### NeedTo128MemoryException

PCのメモリは128G必要だ、という強い意思が必要です。
なぜなら僕たちはChromeを使うからです。

### CrashMyEyesByMorningLightException

朝の光によって目が潰れた時に使ってください。
徹夜したらカーテンを開けてはいけません。

### LoveDogLoveCatException

犬好きと猫好きは争ってはいけません。
心が赴くままに愛でるのです。


## 終わりに

それでは今日もお疲れ様でした。

一応真面目な投稿もしてます。

https://qiita.com/koma2hiroki/items/487c4e48909558a0623c
Active Record のアソシエーション（has_many, belongs_to）に条件を付けるときは一番最初の引数に lambda を渡さなければならない

# 概要
Active Record のアソシエーション（has_many, belongs_to）に条件付けをしたはずなのに、その条件が動作しない場合があるので共有です。

# 方法
下記のように lambda を最後に記載すると where は動作しないが

```ruby
has_many :comments, { class_name: 'Comment' }, -> { order(id: :asc) }
```

一番最初に記載すると正常に動作します。

```ruby
has_many :comments, -> { order(id: :asc) }, { class_name: 'Comment' }
```
様々なJavaScriptの資格を紹介する

# はじめに
JavaScriptは多くの人に愛され、現在も急成長を遂げている言語です。
2020年も更に活躍してくれると期待しています。

今日はそんなJavaScriptの実力を証明できる資格を紹介します。

# JavaScript Certification

[JavaScript Certification](https://www.w3schools.com/cert/cert_javascript.asp)

W3Schoolsという学習プログラミングサービスが提供している
JavaScript開発者向けの認定試験です。
合格するとJavaScript開発者証明書がもらえます。

英語のみの受験となり受験料は95ドルです。

# JAVASCRIPT CERTIFICATION

[JAVASCRIPT CERTIFICATION](https://www.javascriptinstitute.org/javascript-certification/)

International JavaScript Institute、別名IJSIによる認定プログラムです。
前述した資格と名前は同じですが、こちらの認定試験では、JSの能力だけでなく、Webの一般的な知識に関しても出題される傾向があるようです。

英語のみの受験となり受験料は70ユーロです。

# Exam 98-382: Introduction to Programming Using JavaScript

[Exam 98-382: Introduction to Programming Using JavaScript](https://docs.microsoft.com/en-us/learn/certifications/exams/98-382)

天下のマイクロソフト様が実施しているJavaScript開発者向けの認定プログラムです。
Microsoft Technology Associate（MTA）認定は、プログラミングからデータベース管理、セキュリティに至るまで、Webを開発する上で必要な基本的な知識と必要なスキルを候補者が持っていることを確認するプログラムになります。
紹介したのはその一部であり、受験者は様々な試験の中から選択してMTA証明書を取得することができます。

英語を初め、中国語や日本語など様々な言語で受験することができ、受験料は127ドルです。

#CIW JavaScript Specialist

[CIW JavaScript Specialist](https://www.ciwcertified.com/ciw-certifications/web-development-series/javascript-specialist)

CIWはCertified Internet Web Professionalの略であり、これは米国のCertification Partner社によって運営されているインターネット技術者の技術者認定資格です。

CIWの実施するJavaScript認定は、JSコードのデバッグと修正のためのツールと手法、およびJavaScriptフレームワークとライブラリ、AJAXを使用した高度なインタラクティブWebアプリケーション、WebAPIなどの多岐にわたるJSの知識を問う試験内容となっています。

英語のみの受験となり、受験料は150ドルです。

#OpenJS Node.js Application Developer (JSNAD)

[OpenJS Node.js Application Developer (JSNAD)](https://training.linuxfoundation.org/certification/jsnad/)

OpenJS Node.js Application Developer（JSNAD）認定テストでは、Node.jsを使用してWebベースのアプリケーションを作成する際の候補者のスキルをテストおよび検証します。

JSNAD認定は、Node.jsでの作業に2年以上の経験があるNode.js開発者が対象です。
Node.jsコアAPIの知識に重点を置いて、あらゆる種類のアプリケーションを作成するNode.jsの能力を実証するための認定資格であり、Node.jsのデバッグから非同期操作の管理、プロセスの制御まで、様々なスキルをテストします。

英語のみの受験となり、受験料は300ドルです。

#OpenJS Node.js Services Developer (JSNSD)

[OpenJS Node.js Services Developer (JSNSD)](https://training.linuxfoundation.org/certification/jsnsd/)

OpenJS Node.js Services Developer（JSNSD）認定は、セキュリティ慣行に特に重点を置いたRESTful Node.jsサーバーおよびサービス（またはマイクロサービス）の作成における候補者のスキルをテストおよび検証します。

JSNSDは、Node.jsを使用したRESTfulサーバーおよびサービスの作成に2年以上の経験を持つNode.js開発者が対象です。
RESTful Node.jsサーバーおよびサービス（またはマイクロサービス）を作成する能力を実証するために、特にセキュリティの実践に重点を置いており、サービス、サーバー、セキュリティの分野での様々なスキルをテストします。

英語のみの受験となり、受験料は300ドルです。

# おわりに
プログラマにとって資格が必要かどうかは別として、資格に向けて学ぶということは大きなモチベーションに繋がりますし、書類審査などでも実力を証明できる大きな武器になると思います。

JSの実力を証明したいと考えている人の参考になれば嬉しいです。
Wio Teriminalでネコ走らせてみた🐈

# 謝辞

@Kyome さんの[『Windowsのタスクバーでもネコ走らせてみた🐈』](https://qiita.com/Kyome/items/47aac4979933dac12263)
という記事を読ませて頂き、Wio Terminalでも飼いたくなりました。

# はじめに

1. IoT的な事をやって遊んでみるか？という事で[Wio Terminal](https://wiki.seeedstudio.com/jp/Wio-Terminal-Getting-Started/)を入手。
2. [LovyanGFX](https://github.com/lovyan03/LovyanGFX)という描画ライブラリに出会う。最高!!
3. @Kyome さんの記事に出会う。カワイイ!!

という事でWio Terminal用のスケッチを作成しました。

# 完成品

単純な拡大なのでガクガクです...

![small.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147526/e5a626a6-bbaf-b395-9cc0-4fa45322ba04.jpeg)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Wio Terminalで猫を表示してみた。<br><br>多謝<a href="https://t.co/bpN3HNXtwb">https://t.co/bpN3HNXtwb</a><a href="https://t.co/0QT9kqtZ3I">https://t.co/0QT9kqtZ3I</a> <a href="https://t.co/Iv03kiocLr">pic.twitter.com/Iv03kiocLr</a></p>&mdash; たかよひ (@TKawamorita) <a href="https://twitter.com/TKawamorita/status/1296480551566823424?ref_src=twsrc%5Etfw">August 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ソース

https://github.com/t-kawamorita/RunCat_for_WioTerminal

# レシピ (所要時間60分)

1. RunCat for windowsのソースコードを取得する。
2. リソースディレクトリ内のアイコンをPNGに変換する。
3. PNGをPGM(ASCII)に変換する。
4. PGM(ASCII)からヘッダを削除して、C言語の配列に書き換える。
5. C言語の勉強を開始して1週間位で作れそうなソースを書く

# 現状...

CPUの稼働率を収集する処理を作成していないので、まったり走り続けるだけです。
サーバーと通信をして稼働率を表示する事は出来そうだが....

# Wio Terminalについて

**盛り沢山の内容で4000円でお釣りくるんだから最高！**と思ってはいるが苦戦中。

1. WiFiでHTTP GETすると10回でそれ以上のconnectできなくなる。
→ サンプルの通りにソースを書き換えると改善した。

2. WiFiでHTTP POSTすると10回でそれ以上のconnectできなくなる。
→ サンプルがないのでサーバー側をGETで処理するようにお茶を濁す。

Seeedさんのソースを解析して問題を調べようかと着手するも、本来やりたい事が進まないので
Seeedさんのサンプル充実を期待して待ことにしている。。。
[Semantic MediaWikiの使い方①] MediaWikiでの記事の作成方法

# What is this?
* [Semantic MediaWiki](https://www.semantic-mediawiki.org/wiki/Semantic_MediaWiki)の導入にあたり必要な知識のまとめ記事
* まず前提としてのMediaWiki使い方を知るためのまとめ
    * Semantic MediaWikiはMediaWikiの拡張機能の１つ

# 新規ページ作成
* 標準のMediaWikiには「新規記事作成ボタン」はない
* 何かしらの方法で**未作成の記事ページ**に飛ぶ必要がある
* 未作成の記事ページに飛ぶ方法は３つ

## ①ウィキリンクから
* 他のページから存在しないページに[ウィキリンク](#"リンク")が貼られている場合、オレンジ色で表示される
* そのリンクを選択することで、ページが存在しない場合は新規作成ページに飛ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/3511d58a-e47a-0ad3-0eea-add221868ee3.png)
    
## ②検索から
1. **右上の検索欄**から作成したいページ名を検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/11c7e3dc-4943-f08c-ce59-5c7364616fd2.png)

2. ページが見つからないが、生成された新規作成リンクを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/9397a056-2431-53a0-452b-b59bcd0ae9fa.png)

## ③URLから
1. MediaWikiではページ名称＝URLとなるため、以下のようなURLに直接飛ぶことで新規作成ページにアクセスできる
    * `http://www.example.net/index.php/*ARTICLE*` or
    * `http://www.example.net/wiki/*ARTICLE*`
2. アクセスした先のページで新規作成リンクを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/92c6d34e-b99e-435e-77b8-6a4305291e04.png)

参考：https://www.mediawiki.org/wiki/Help:Starting_a_new_page/ja

# 既存ページの編集
ページを開いた状態で右側の**編集タブ**を開くことで編集ページに移動できる。[^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/17374f1a-8c99-ef46-d39b-bc7fd400dd31.png)


# 記法
* できることはMarkdownとほとんど同じだが、記法は全然異なる
    * 公式ヘルプ：https://www.mediawiki.org/wiki/Help:Starting_a_new_page/ja
    * [こちらのチートシート](https://colo-ri.jp/develop/2008/03/mediawiki.html)がわかりやすい

# リンク
Wikiの使用目的上、リンクを多用する。特にWiki内の他のページへリンクを貼る内部リンクをMediaWikiでは特に**ウィキリンク**という。基本的にリンクは`[[リンク先]]`で記述。[^2]
参考：https://www.mediawiki.org/wiki/Help:Links/ja

# カテゴリ
MediaWikiの標準機能として**カテゴリ**をつけることができる。カテゴリを設定することで、ページ下部にボックスが出現し、カテゴリページへのリンクが貼られる。[^3]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214822/742af0a2-5186-8f04-4a97-abdcfed442cc.png)

カテゴリの設定方法は、記事文章中に`[[カテゴリ:テスト]]`と記述する。記事内のどこに記述しても、ページ最下部に上記のようなボックスが表示される。

参考：https://www.mediawiki.org/wiki/Help:Categories/ja

[^1]: タブの位置は「個人設定」の「外装設定」での設定による。本記事は「ベクター」でのデザイン。
[^2]: ウィキリンク以外にもさまざまなリンク種類があるが、ナレッジグラフ構築では器用に使い分ける必要はなさそう。
[^3]: カテゴリ以外のページ分類の方法は他にも、「名前空間」「サブページ」がある（[参考](http://blog.livedoor.jp/lionkid/archives/3096475.html)）。これらはあくまでMediaWiki標準の機能であり、次回以降に説明するSemantic MediaWikiでのアノテーションとは別に併存する。
【Swift】Codableを用いてCloud FirestoreのドキュメントをEncode&Decodeする実装

## はじめに
Webサーバなどを経由せずに、クライアントサイドから直接データを登録できるのがFirestoreの強みですが、データを保存するには下記のコードのようにkey:value形式のデータを作成する必要があります。([公式ドキュメント参照](https://firebase.google.com/docs/firestore/quickstart?hl=ja#swift_1))

``` .swift
// usersコレクションにデータを追加する
var ref: DocumentReference? = nil
ref = db.collection("users").addDocument(data: [
    "first": "Ada",
    "last": "Lovelace",
    "born": 1815
]) { err in
    if let err = err {
        print("Error adding document: \(err)")
    } else {
        print("Document added with ID: \(ref!.documentID)")
    }
}
```

しかし、いかんせん値の指定がkey:value形式なので、key名をハードコーディングする必要があります。
せっかくSwiftを使っているならデータをEncode&DecodeしてClassやStructで扱いたいですよね？
今回はCodableを用いてFirestoreのドキュメントのデータをEncode&Decodeする実装を書きたいと思います。

## 環境構築
まずは[公式ドキュメント](https://firebase.google.com/docs/ios/setup?hl=ja)を参考に、Firebaseのプロジェクトを作成しましょう。
そのあとはまたまた[こちらの公式ドキュメント](https://firebase.google.com/docs/firestore/quickstart?hl=ja#ios)を参考にCloud Firestore データベースを作成しましょう。
ドキュメントの**Cloud Firestore を初期化する**まで進めたら環境構築は十分です。Podfileは下記のようになっています。

``` Podfile
pod 'Firebase/Core'
pod 'Firebase/Firestore'

# Optionally, include the Swift extensions if you're using Swift.
pod 'FirebaseFirestoreSwift'

```

## 実装
### Encode処理
冒頭のusersコレクションにドキュメントを追加する処理を、Encodeしたデータを使った実装に置き換えてみます。
usersコレクションには**first**、**last**、**born**の三つのデータを追加していたのでそれをクラスで定義します。

``` User.swift
class User: Codable {
    internal let first: String
    internal let last: String
    internal let born: Int
    
    init(first: String, last: String, born: Int) {
        self.first = first
        self.last = last
        self.born = born
    }
}
```

定義したUserクラスをEncodeして、そのデータをusersコレクションに追加します。

``` .swift
import Firebase

// UserのEntity作成
let user: User = User(first: "Ada", last: "Lovelace", born: 1815)
var encodedUserData: [String: Any]!
do {
    // エンコード処理
    encodedUserData = try Firestore.Encoder().encode(user)
}
catch let e {
    fatalError(e.localizedDescription)
}
// usersコレクションにエンコードしたデータを追加する
var ref: DocumentReference? = nil
ref = Firestore.firestore().collection("users").addDocument(data: encodedUserData) { err in
    if let err = err {
        print("Error adding document: \(err)")
    } else {
        print("Document added with ID: \(ref!.documentID)")
    }
}

```

これでkey名をハードコーディングする必要がなく、追加したいデータをクラスで管理することができました。

## Decode
上記でEncodeしたデータをusersコレクションに追加できたので、それらのデータ一覧を取得してDecodeする処理を実装したいと思います。

``` .swift
// usersコレクションから、userのデータのドキュメントの一覧を取得する
Firestore.firestore().collection("users").getDocuments { (snapshot, error) in
    if let error: Error = error {
        print(error.localizedDescription)
        return
    }
    guard let snapshot: QuerySnapshot = snapshot else {
        return
    }
    var users: [User] = []
    do {
        for document in snapshot.documents {
            // key:value形式のデータをDecodeする
            let user: User = try Firestore.Decoder().decode(User.self, from: document.data())
            users.append(user)
        }
        // usersの一覧取得成功!!
    }
    catch let e {
        fatalError(e.localizedDescription)
    }
}
```

以上。
「削除」なんて架空じゃないんかい？

プログラミングを40年やって来たけど、StorageとかDatabaseとか、要らんと思う。
コンピュータって結局、メインメモリを保存できて、再現できれば良いんにゃないの？
って事は、Register > Memory > Storage(Include Database)って事で、全てはキャッシュって事じゃないかなぁ。
そう考えると、全てはGarbageCollectionで、Objectに「忘れないでねフラグ」を付けとけば、勝手に記録してくれれば良いんじゃね？

逆に忘れて良い事なんて何一つ無いので、「忘れてくださいフラグ」だよね。
だって世の中で生きて来て、「恥ずかしいから忘れてください」って思っても、みんな忘れてくれないもんね。

「酔っ払って覚えてないです」って言ったって、大抵後から「あの時は...」って蒸し返されるもんね。
そうなると、「削除」って概念自体、実現不可能じゃないのかな？
恥ずかしい事も覚えてくれた方が、AIが「ちょっと待って」って提言してくれて便利じゃないのかな？
CSSの文字を指定するときの単位について

#CSS文字を指定するときの単位について
CSSの単位には<strong>絶対単位</strong>と<strong>相対単位</strong>と言うものが存在する。
CSSの大きさを指定する単位は非常に重要なのでこれを機にあまり使われない単位も紹介できたらと思う。
##絶対単位と相対単位
<strong>絶対単位</strong>
表示される環境に一切左右されずに同じ大きさで表示させる時に使う単位である。基本これを使って単位を指定することはあまりない。

<strong>相対単位</strong>
表示される環境や条件に応じて変動される単位のことである。基本はこっちを使うので正直覚えておくのはこっちだけで十分。

##絶対単位の種類
| 単位 | 数値|
|---|---|
|*mm*|*10mm = 1cm*|
|*cm*|*1cm = 10mm*|
|*in*|*1in = 2,54cm*|
|*pt*|*72pt = 1in*|
|*pc*|*1pc = 12pt*|

##相対単位の種類
| 単位 | 数値 |
|---|---|
|*em*|*親要素の高さに対する倍率で長さ、高さを指定*|
|*ex*|*親要素の高さに対する倍率で長さ、高さを指定*|
|*px*|*画面を構成する点に対する倍率で長さ、高さを指定*|
|*%*|*親要素を基準にしてサイズを指定*|

##最後に
先ほども記述したが、単位は基本的には<strong>相対単位</strong>を使うので相対単位は覚えた方がいい。
【React Hooks】useReducerを使う時、dispatchのtypeには変数で与えた方がいい理由

こんにちは！

今回はReact Hooksについてお伝えしたいと思います。
中でも、「useReducerを使う時、dispatchのaction.typeには変数で与えた方がいい理由」について触れていきます。


### dispatchのaction.typeをハードコーディングすると、エラーにきづかない！？
※useReducerに絡む部分以外は省略して書いています。

```javascript
const [state, dispatch] = useReducer(reducer, initialState);

// Reducer
const reducer = (state = [], action) => {
    switch(action.type) {
        // action.type ： 'CREATE_EVENT'
        case CREATE_EVENT:
            const event = {title: action.title, body: action.body};
            const length = state.length;
            let id;
            if (length === 0) {
                id = 1;
            } else {
                id = state[length - 1].id + 1;
            }
            return [...state, {id: id, ...event}];
        default:
            return state;
    }
}

const EventForm = () => {
    const initialState = {
        events: [],
    };

    // Reducerを呼び出す
    const [state, dispatch] = useReducer(reducer, initialState);

    // dispatchを呼び出す
    const addButtonClickEvent = () => {
        dispatch({
          type: 'CREATE_EV', // <-スペルミスしたとします
          title,
          body,
```

**`dispatch`の`action.type`をスペルミスした状態で、`EventForm`コンポーネントを呼び出すとどうなるか。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/63e0d86f-0fe6-e5ed-df70-77c85767165a.png)

console上はエラーになりません。
Reducerの定義の部分で、`action.type`の`switch`文で`default`の場合何もしないと定義しているためです。
しかし、このままですと、**エラーに気づかないので、バグ対応にコストを要してしまいます。**

### dispatchのtype名は変数で与えると、どうなるか？
```javascript


// actionのtype名は一箇所で定義し、各ファイルで読み込む
// const CREATE_EVENT = 'CREATE_EVENT';
import {CREATE_EVENT} from '../actions/index';

// ・・・・（省略）

    // dispatchを呼び出す
    const addButtonClickEvent = () => {
        dispatch({
          type: CREATE_EVE, // <-スペルミスしたとします
          title,
          body,
```
結果は・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/38e739cf-e370-6b34-fa71-8bec901d255b.png)

エラーになりましたね。
予め`action.type`は変数で設定することをルール化しておくことで、エラーを検知しやすくなると思います。

### 参考文献
【udemy】React Hooks 入門 - Hooksと Redux を組み合わせて最新のフロントエンド状態管理手法を習得しよう！
https://www.udemy.com/course/react-hooks-101/
はむさん、ありがとうございます！
PHPマニュアルのコード例をJavaScirptで再現してみる--無名関数編--

##はじめに
PHPとJavaScript両方の勉強ができる方法はないものか考えてみたのですが、PHPマニュアルのコード例をJavaScriptで再現してみるのはどうか？と思い立ち、実際にやってみました。

##今回の題材
記念すべき(？)第１回目の題材は、無名関数のところに記載されていたコード例としました。以下はコード例の引用です。
[PHPマニュアル 無名関数](https://www.php.net/manual/ja/functions.anonymous.php)

```php

<?php
// 基本的なショッピングカートで、追加した商品の一覧や各商品の
// 数量を表示します。カート内の商品の合計金額を計算するメソッド
// では、クロージャをコールバックとして使用します。
class Cart
{
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.00;
    const PRICE_EGGS    = 6.95;

    protected $products = array();
    
    public function add($product, $quantity)
    {
        $this->products[$product] = $quantity;
    }
    
    public function getTotal($tax)
    {
        $total = 0.00;
        
        $callback =
            function ($quantity, $product) use ($tax, &$total)
            {
                $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                    strtoupper($product));
                $total += ($pricePerItem * $quantity) * ($tax + 1.0);
            };
        
        array_walk($this->products, $callback);
        return round($total, 2);
    }
}

$my_cart = new Cart;

// カートに商品を追加します
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// 合計に消費税 5% を付加した金額を表示します
print $my_cart->getTotal(0.05) . "\n";
// 結果は 54.29 です
?>

```

消費税５％とは良い時代ですね・・・
色々勉強になりましたが、大切なのは変数のスコープでしょうか。

PHPのスコープにはスーパーグローバル、グローバル、ローカルの３種類があります。スーパーグローバルはここでは置いておいて、関数の外で定義された変数がグローバルスコープ、関数の中で定義された変数がローカルスコープとなります。グローバルスコープの変数は、何もなしには関数の中では使えません。

で、クロージャについては親スコープから変数を引き継ぐことができます(useを使用)。
親スコープから引き継いだ変数の値は、関数が呼び出された時の値ではなく、関数が定義された時点のものになるというのが注意点です。

また、今回登場している$totalは、金額の合計値を算出するために、クロージャに対し値渡しではなく参照渡しで渡します。


##JavaScriptで再現

では、早速JavaScriptで再現してみます。

```javascript

class Cart {
  static price = {
    'butter': 1,
    'milk': 3,
    'eggs': 6.95
  };

  constructor() {
    this.products = {};
  }

  add(product, quantity) {
    this.products[product] = quantity;
  }

  getTotal(tax) {
    let total = 0;

    const callback = function(product, quantity) {
      const pricePerItem = Cart.price[product];
      total += (pricePerItem * quantity) * (tax + 1);
    }

    Object.keys(this.products).forEach((key) => {
      callback(key, this.products[key]);
    });
    return Math.round( total * 100 ) / 100;
  }
}

const my_cart = new Cart;

my_cart.add('butter', 1);
my_cart.add('milk', 3);
my_cart.add('eggs', 6);

console.log(my_cart.getTotal(0.05));
```

クラス定数はstaticキーワードを使い、オブジェクトとしてまとめました。
連想配列$productsは、JavaScriptのオブジェクトに対応するのでそのようにします。addメソッドはほぼ一緒の書き方でOKですね。

最後に、getTotalメソッドですが、PHPのクロージャははuseを使わないと\$tax、$totalを使用できませんでしたが、JavaScriptでは関数内に変数が見つからない場合、親の関数に変数を探しにいくため、そういった必要がありません。

PHPのarray_walk()は、JavaScriptではmap()やforEach()に対応しているのでは？と思いました。ですが、これらのメソッドは配列に対してしか使えません。そこで、Object.keys()を使用してオブジェクトからプロパティ名(キー)を取り出して配列にします。

##まとめ
なかなか良い学習法を見つけたかもしれません。
DockerでMySQLのコンテナをサクっと構築する

趣味でMySQL8.0を使って、業務で5.7を使って...とローカルのMySQLの再インストールを繰り返していて、アホらしくなったのでコンテナでサクッと確認できる環境を作る。
(docker-compose で各環境は用意されていたが、お試し的に使う環境が欲しかった)

## Dockerコンテナ、ボリュームの作成

```shell-session
$ docker volume create db_storage
$ docker run -d --name db_container -e MYSQL_DATABASE=db_name -e MYSQL_ROOT_PASSWORD=root -v db_storage:/var/lib/mysql -p 3305:3306 mysql:5.7
```

MySQL8.0を使いたい時は最後のイメージ名の指定を `mysql:8.0` に変える
ポート番号はデフォルトだと何かと被るのであえて変えてます。

## Dockerコンテナ、ボリュームの確認

```shell-session
$ docker volume ls
DRIVER              VOLUME NAME
local               db_storage

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
8f4893883bd6        mysql               "docker-entrypoint.s…"   4 seconds ago       Up 3 seconds        33060/tcp, 0.0.0.0:3305->3306/tcp   db_container
```

作成したコンテナとボリュームが表示されればok。
表示されない場合は、コンテナの起動時にエラーになってると思うのでコンテナログを確認してみてください。

```shell-session
$ docker logs db_container
```

## MySQL接続

Sequel Ace を使うのがお手軽感あります。
https://apps.apple.com/us/app/sequel-ace/id1518036000

- Host: `127.0.0.1`
- Username: `root`
- Passwor: `root`
- Database: `db_name`
- Port: `3305`

## Dockerコンテナ、ボリュームの破棄

使わなくなったら、下記のコマンドで簡単に削除できます。

```shell-session
$ docker rm -f db_container
$ docker volume rm db_storage
```

何度も再インストールを繰り返してローカルDBが起動しない問題に悩まされなくなって快適です🥰

## 参考

- [ついにSequel Proの後継アプリ登場！Sequel AceでMySQLに接続する](https://qiita.com/ucan-lab/items/b1304eee2157dbef7774)
EGitでマージとマージの取り消しをやってみた

###マージ
masterブランチにdevAブランチのマージを行う。
現在masterブランチにはMain.javaファイルが作成されている状態。
![スクリーンショット 2020-08-20 23.20.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/3e9e0fa1-e204-b691-5de0-aeda533759c0.png)

devAブランチはmasterブランチから作成したブランチ。
ブランチ作成後、DevAMake.javaファイルを作成した状態。
![スクリーンショット 2020-08-20 23.22.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/dfd70243-0604-3db1-f57d-0ebbf80a22a5.png)


カレントディレクトリをマージされる側(master)にし、「チーム」→「マージ」
マージ対象のdevAを選択し、「マージ」

マージを行うとmasterブランチはdevAで行った変更が取り込まれDevAMake.javaが追加された状態となる。
![スクリーンショット 2020-08-20 23.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/58a93138-f02e-b369-b421-45c1d11cdd02.png)

マージを行ったヒストリーが追加される。
![スクリーンショット 2020-08-20 23.31.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/54412578-f9de-9216-08c6-3141b263d88d.png)

###マージの取り消し(Revert)
先ほど行ったマージを取り消してみる。
現在マージはプッシュしていない状態。
ヒストリータブで取り消したいマージを選択し右クリック→「コミットを戻す」。
マージが取り消され、先ほどのマージで取り込まれたDevAMake.javaがいなくなった。
ヒストリーにはRevertコミットが追加される。
これでマージを行う前の状態に戻すことができた。
![スクリーンショット 2020-08-20 23.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/f7293159-782c-40f7-da33-bf0bbe1940af.png)

###プッシュしたマージをRevertで取り消す
先ほどはプッシュしていない状態でマージの取り消しを行ったが、
次はプッシュしたマージの取り消しをしてみる。
まずはマージを行おうとしたが、問題が発生。
先ほどと同じ手順でマージを行うとdevAの変更が取り込まれない。
特にエラーも出ていない…。
調べてみるとこの場合マージをRevertしたコミットをRevertすると良いようだ。
以下に整理してみた。

1.マージした
2.マージをRevertした // こいつをRevertする

上記2のコミットをRevertすると1の状態(devAをマージした状態)となった。
![スクリーンショット 2020-08-20 23.53.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/83033660-29b8-83fb-5aef-807cacf08fc4.png)

やっとマージした状態となったためpush。
![スクリーンショット 2020-08-21 0.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/ed08ecd3-0ac7-ef9b-e327-7a514f8e0ca0.png)

まずは先ほどと同じ手順で(「コミットを戻す」)でRevertしてみる。
マージでの変更は取り消された。
この状態でpushすると成功した。
![スクリーンショット 2020-08-21 0.13.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/5a5df4bf-9f8c-6654-d5b3-f213ef467863.png)

###マージをしなかったことにしたい(reset)
Revertは打ち消しのコミットであり、ヒストリーに履歴が残る。
resetを使うと、マージの変更点がなくなり、かつヒストリーからも
マージを行ったという履歴が消える。

まずマージを行った状態にする。
![スクリーンショット 2020-08-23 14.18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/e1f8308e-ca0d-7c5b-6043-de7730f4691c.png)

id:b8733b1のマージコミットにより、masterブランチにはDevAMake.javaが追加されている。
このマージの変更をresetを使ったなかったことにする。
現在戻りたいコミットはid:39cd904
ヒストリータブで行を選択した状態で右クリック→「リセット」→「ハード」

マージを行ったことで追加されたファイルがなくなり、ヒストリーからもマージコミットを行った履歴が消えた。

![スクリーンショット 2020-08-23 14.24.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/5119acd9-44f6-c3a2-7031-ba8da5cd95ff.png)
ごく単純な IE 除け

~~~html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />

        <!-- ここから -->
        <style>
            @media all\0{
                body{display:none}
                html:after{content:"現在お使いのブラウザではご利用いただけません"}
            }
        </style>
        <script>
            document.documentMode&&document.execCommand("Stop")
        </script>
        <!-- ここまで -->

        <script>
            alert("IE では実行されない")
        </script>
    </head>
    <body>
        IE では表示されない
    </body>
</html>
~~~

> まず "Internet Explorer" という言葉を思い浮かべる。
> そしてゆっくりこう唱えるんだ。
> "存在しない"と。
WSL2とAndroidエミュレータの共存

# Windows Home + WSL2 + Androidエミュレータ

この環境で色々ハマったので備忘録として書いておきます。

# WSL2とHyper-VとAndroidエミュレータ
まず、WSL2とHyper-Vの関係
https://qiita.com/matarillo/items/ca1eecf8f9a3cd76f9ce
ここを見てもらうのがいいのですが、WSL2はHyper-Vハイパーバイザーの上で動いています。Windows Pro にある Hyper-V とは別です。また、Windowsハイパーバイザープラットフォームを有効化することで、他の仮想化技術と共存させることができるようです。似た用語で紛らわしいのですが、「Hyper-Vハイパーバイザー」、「Hyper-V」、「Windowsハイパーバイザープラットフォーム」はそれぞれ別物のようです。

で、WSL2をインストールした状態でAndroidエミュレータを起動しようとするとHyper-Vが有効化されているので起動できないので、Hyper-VをOffにするコマンドを実行してね、というメッセージが表示されます。この時点で何も分かっていなかった、そのコマンドを実行しました。すると、WSL2が起動しないではないですか！「BIOSの仮想化設定を確認してください」のメッセージが表示されていますが、すでに有効済みです。

# Hyper-Vの On Off
普通にHyper-Vの有効無効について調べると、PowerShellのコマンドか「Windowsの機能の有効化または無効化」を使った方法が見つかるのですが、Windows Homeだとこれらの方法で有効無効を切り替えられません。（そもそもHomeにはHyper-Vが無いので）
コマンドプロンプトのコマンドだとWindows Homeでも有効無効を切り替えられました。
https://qiita.com/dodonki1223/items/75bd5171e2f2193c9977
Androidエミュレータを起動できなかったときに実行したコマンドと同じです。

# WSL2とAndroidエミュレータを共存させるには
Hyper-Vと共存させる方法は公式ドキュメントに書いてありました。
https://developer.android.com/studio/run/emulator-acceleration?hl=ja#vm-windows-whpx
「Windowsハイパーバイザープラットフォーム」を有効にすればいいそうです。

# 結論
Home、Pro関係なく、WSL2とAndroidエミュレータを共存させる場合は「Windowsハイパーバイザープラットフォーム」を有効にしましょう。
WSL2をインストールした環境はHomeであってもHyper-Vが有効になっているものとみなすみたいです。
ログメッセージ監視シェル

# メッセージ監視シェル

メッセージ監視シェルのメモを残す
１．シェル作成
２．systemd登録

## １．シェル作成
```log-monitor.sh
#!/bin/bash
########################################################
# ログメッセージ監視シェル
#
########################################################
#--- 共通設定 ------------------------------
HOME=`dirname $0`
CONF=${HOME}/_conf
SHELLNAME=`basename $0`

#--- 変数初期値代入 ------------------------
MONITOR_FILE=/var/log/messages
RESULT_FILE=/var/log/messages.result
MATCH_FILE=${CONF}/match.list
EXCLUSTION_FILE=${CONF}/exclustion.list

#--- 内部関数定義 --------------------------
_CHECK_ACTION () {
while IFS= read -r LINE
do
  egrep -f ${MATCH_FILE} <(echo "${LINE}") \
   | egrep -vf ${EXCLUSTION_FILE} >> ${RESULT_FILE}
done
}

#--- メイン処理 ---------------------------
# メッセージ監視処理
tail -n 0 -F ${MONITOR_FILE} | _CHECK_ACTION

exit
```

## ２．systemd登録
```/etc/systemd/system/log-monitor.service
[Unit]
Description = Log Monitor File:/var/log/tstlog

[Service]
ExecStart = /path/to/file/log-monitor.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

```cmd.result
# systemctl enable log-monitor.service
# systemctl start log-monitor.service
```
App Store Connect プロモーションコードの生成 (に潜む罠)

# 前提
- 2020/08/21時点のコンソール
- リリース済みのiOSアプリ

# 手順
- App Store Connect で App を選択します。
- 「機能」を選択します。
- 「プロモーションコード」を選択します。
![コメント 2020-08-20 235251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365845/0efc9328-0588-34b4-e462-2244b76858d2.png)
- 必要なアプリまたはアイテムの各「数量」欄に必要数を入力します。
    - 制限内で複数種類をまとめて生成できます。
- 「コードを生成」を押します。
- 表示された文章を読み、「上記の規定を読み、理解しました。」にチェックして「コードを生成」を押します。
- 回転する「生成中」の標示をしばらくぼーっと眺めて待ちます。
    - 待っても終わらないようなら、「キャンセル」を押します。

### 注意
- 生成中の標示はいつまで待っても終わらないように見えます。
    - OSやブラウザを変えて試したけど、変化なかったです。
    - 終わらなくてキャンセルしても、生成できています。(罠)
        - 「失敗した」と早とちりしてやり直さないこと。(失敗した…)
        - まずは、後述する「生成状況の確認」をしましょう。
- 生成できても「残りのコード数」は減りません。
    - 「残りのコード数」を見て生成状況を判断することはできません。(罠)
- コードの有効期限は、コードが要求されてから4週間後の23時59分です。期限内であっても、ライセンス契約の期限が切れると無効になります。
    - 必ず、コードに添えて期限について告知しましょう。

# 生成状況の確認
- 「生成 / 履歴」タブを「履歴」へ切り替えます。
- 生成済みコードはここで閲覧・ダウンロードできます。
[Rails] いいね数順でランキング

今回はいいね数の多い順(いいね数が0も含む)に投稿を表示させるランキング機能の実装方法についてです。
ランキング機能の実装方法は他でもあったのですが、いいねが0の投稿も表示させている記事が見当たらなかったので実装してみました。

# 前提
- 投稿のテーブルは `posts`、 ユーザーのテーブルは `users` とする。
- いいね機能に必要な中間テーブルは `likes` とする。
- `posts`・`users`・`likes` それぞれのテーブルはいずれも作成済みとする。

# 手順

## モデルにアソシエーションを定義

```post.rb
class Post < ApplicationRecord
    belongs_to :user
    has_many :likes, dependent: :destroy
    has_many :liked_users, through: :likes, source: :user
end
```

```user.rb
class User < ApplicationRecord
  has_many :posts,dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_posts, through: :likes, source: :post
end
```

```like.rb
class Like < ApplicationRecord
  belongs_to :post
  belongs_to :user
end
```


## コントローラーをいじる

```app/controller/posts_controller.rb
def index
  @posts = Post.includes(:liked_users).sort {|a,b| b.liked_users.size <=> a.liked_users.size}
end
```

ここでは `sort` というrubyのメソッドを使って順序を操作している。
=> [sortに関してはこちらを参照](https://docs.ruby-lang.org/ja/latest/method/Array/i/sort.html)

`a.liked_users.size`、`b.liked_users.size` が表しているのはそれぞれ各投稿のいいね数。
すなわち、各投稿のいいね数を比較して昇順で並び替えている。



## ビューで表示させる
あとはビューで表示させるだけ。

```app/view/posts/index.html
<% @posts.each do |post| %>

  #省略

<% end %>
```
まだまだ知らないメソッドたちはたくさんあるなぁ。

# 参考
- [Array#sort (Ruby 2.7.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Array/i/sort.html)
Strapiのユーザーログイン時に処理を追加する

Strapiの`strapi-plugin-users-permissions`の`ID/PASS`でのログイン時の処理に,
ビジネスロジックを入れ込むことをしたのでやり方の共有

strapiは`3.1.4`で検証

[strapi/packages/strapi-plugin-users-permissions at master · strapi/strapi](https://github.com/strapi/strapi/tree/master/packages/strapi-plugin-users-permissions)

## 新規に`Policies`を作成をする
https://strapi.io/documentation/v3.x/concepts/policies.html#concept

ドキュメント通りに`Policies`を作ると、Strapiの`strapi-plugin-users-permissions/config/routes.json`を書き換える必要が出てくる.
Strapiのアップデートが辛くなるので, この方法はやりたくない...

ので、`estenstions/users-permissions/config/policies/`までフォルダをく作って、その中に新規にPoliciesを作成をする.

```javascript
// パス
// extensions/users-permissions/config/policies/send-mail-on-login-notify.js

'use strict';

module.exports = async (ctx, next) => {
  console.log('In sendMailOnLoginNotify policy.');

  await next();

  if (ctx.status === 200) {
    // ログイン成功時の処理
    console.log("success login.");
  } else {
    // ログイン失敗時の処理
    console.log("fail login.");
  }
};
```


## ログイン時の`auth/callback`に`Policies`を追加する
GUIから動的に変更ができる.

`ロールと権限` -> `Publicロール`を編集する
![Strapi_-_Roles___Permissions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661975/e1652e74-aa89-4a24-4b31-9c6ef32b13f9.png)

`USERS-PERMISSIONS`の`callback`の設定ボタンをタップすると, 
高度な設定が設定できるので、そこから`新規で作成をしたPlicies`を選択する.
![貼り付けた画像_2020_08_20_23_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661975/45c195cf-a916-72ca-bffa-3034eebfba70.png)

## ログインをしてみる

### ログイン成功時
```bash
strapi_1   | [2020-08-20T14:58:56.710Z] debug OPTIONS /auth/local (0 ms) 204
strapi_1   | In sendMailOnLoginNotify policy.
strapi_1   | success login.
strapi_1   | [2020-08-20T14:58:59.765Z] debug POST /auth/local (3051 ms) 200
```

### ログイン失敗時
```bash
strapi_1   | [2020-08-20T15:00:24.445Z] debug OPTIONS /auth/local (1 ms) 204
strapi_1   | In sendMailOnLoginNotify policy.
strapi_1   | fail login.
strapi_1   | [2020-08-20T15:00:24.554Z] debug POST /auth/local (106 ms) 400
```  



(๑•̀ㅂ•́)و✧ ﾖｯｼ!

## おまけ

起動時に動的に`/auth/callback`のPoliciesを変更する方法
`bootstrap`に処理に追加をすれば, 共同開発者も幸せになれる.

```javascript
// パス
// strapi/config/functions/bootstrap.js

module.exports = async () => {
  const role = await strapi.query('role', 'users-permissions')
    .findOne({type: 'public'});
  await strapi.query('permission', 'users-permissions')
    .update(
      {
        role: role.id,
        controller: 'auth',
        action: 'callback',
      },
      {
        policy: "send-mail-on-login-notify"
      });
};
```
大量の画像を集めたいから「google image download」を使ってみた

#初めに
Photomosaic generatorのを使ってモザイク画像やモザイク動画を作りたい
https://github.com/uvipen/Photomosaic-generator

上記のサンプルを動かクスのgit cloneして”video2video.py” "image2image.py"を動かせば簡単にサンプルが動きます。
何も環境を入れてない人は、opencvを入れないといけませんので下記をたたきます。
$pip install opencv-python

ただ、自分の好きな画像でモザイク絵を作りたい！！！って事で

##google-images-downloadで大量の画像ダウンロード

google image downloadが動かなかったのでその対応
https://qiita.com/taedookim/items/63759e79426514c8a729

この記事を書いているのが2020/08/20で、最新のGoogle画像検索の仕様変更で
ツールが動かないみたいです。で上記のqiitaの中にも書いてありますが、
パッチバージョンてDL出来るバージョンをクローンして使いました。
URL
https://github.com/Joeclinton1/google-images-download/tree/patch-1

qiitaの記事の中で100件以上の画像は取得できない。。それは困った。。

###google-images-downloadで100件以上の大量の画像を

これも、qiitaに書いてありました。
機械学習用の画像集めに便利な「google-images-download」の使い方
https://qiita.com/tomokin966/items/fdf14f4bfaa8bf97eed6

上記のqiitaの[記事][link-1]にかいてありました。
[chromedriver][link-2]をダウンロードしてください。
ここで大事なのchromedriverのexeと今PCにインストールしているchromeのバージョンを合わせる事です。
今私のPCではバージョン: 84.0.4147.125なので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/23dde0f7-27ed-5c5c-59f4-e574972afecc.png)

chromedriverのページ行くと一番新しいのは85なので84のバージョンにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/222afe0d-edc5-b16f-1f70-fc1624d2022d.png)



[link-1]:https://qiita.com/tomokin966/items/fdf14f4bfaa8bf97eed6#100%E4%BB%B6%E4%BB%A5%E4%B8%8A%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%AB%E3%81%AFchromedriver%E3%81%8C%E5%BF%85%E8%A6%81

[link-2]:http://chromedriver.chromium.org/downloads

###パッチを当てたgoogle-images-downloadでchromedriverを使って100以上のの画像ダウンロードする。
dogを200件DLする

```python
python google_images_download\google_images_download.py -k "dog" -l 200 -cd "chromedriver.exe"

```

さ、好きなキャラでモザイク画像つくろ～
htmlにJavaScriptを埋め込んで動かそう！！

#この記事の対象読者
・**JavaScript**を始めて見たいけど、どうにコードを書いてどうやって実行するか分からない人
・**JavaScript**をhtmlとは別のファイルから読み込める様にしたい人
・ウェブ開発をやった事は無いけど興味がある暇な人
#JavaScriptとは
ざっくり言うと、環境構築がいらずで開発を始められて**ウェブサイト**、**アプリ**、**サーバー**など多岐に渡って色々な事が出来るプログラミング言語だと思っていたら大丈夫だと思います。
※本当はもっと細かく説明した方が良いと思うが今回やる事に関してだったらこれくらいで十分だと思います。詳しく知りたい人は[wiki](https://ja.wikipedia.org/wiki/JavaScript)を見て下さい。
#下準備
ここからはBracketsを使って行きますが、コードを貼り付けますので無くても大丈夫です。もしBracketsを入れたい人は[こちら](https://qiita.com/lot-uni/items/8d621d4f80bc5cf17f15)を参考にしてくれたら嬉しいです。(ちなみに動作環境はfirefoxです。)

始めにfinderを使って、書類のフォルダーに**JavaScript_test**とフォルダーを新規で作って置いて下さい名前は正直どうでも良いです。次にbracketsを開いて新しいファイルを2つ開きそれぞれ**index.htmlとtest.js**と言う名前で保存して下さい。それではindex.htmlの方から編集をして行きます。**!**と入力してからtobキーを押したら下準備は完成です。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```
本来なら**lang**をjaに変更したり、**title**を変えたりしますが今回はあくまでテストなので放って置きます。

#htmlに埋め込み
始めは、超簡単な**JavaScript**を直接埋め込む事をやって見ます。これは単にスクリプトタグで囲んで、その中にプログラムを書くだけです。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
    document.write(1+1);
    </script>
</body>
</html>
```
次に**JavaScript**を別で読み込むコードです。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="test.js">
</script>
</body>
</html>
```

```javascript
 document.write("<h1>Hello World</h1>");
```
jsで**document.write**を使うときはh1の様にタグを付ける事でcssに対応させる事が出来るので、cssでHello Worldの色を変える事も出来ます。![スクリーンショット 2020-08-21 0.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/4ff8d7e0-63cf-845e-26e6-2f58889fb101.png)
#終わりに
JavaScriptは今までやった事があまりなかったので間違っている所はコメントで教えてくれると憂しいです。
参考にしたサイト
https://www.javadrive.jp/javascript/before/index4.html
ターミナルエミュレータについて


#ターミナルとは

- ユーザがコンピュータへ入出力する際に利用する専用のハードウェアのこと。

- 入力装置：キーボード
  出力装置：ディスプレイ

#ターミナルエミュレータとは

- 単にターミナルでターミナルエミュレータのことを指す場合が多い。

- OSごとに多くのターミナルエミュレータが開発されている。


#主なターミナルエミュレータの種類

| OS | ターミナルエミュレータ
|:-----------:|:------------:|
| Windows       | PuTTY、TeraTerm |
| Mac OSX     | ターミナル、iTerm2 |
| Linux       | GNOME端末（GNOMETerminal）、Konsole |


####※ 「ターミナルエミュレータ」と「シェル」は、どちらも直接ユーザが操作するソフトウェアではあるが、全く違うソフトウェアなので注意！
JavaScript（未経験者向け）

# JavaScriptとは
ウェブサイトを操作して表示を変化させたいときや、画面を更新せずにサーバと通信したい時に使用します。
*ex.いいね機能など*

## Javaとは全く違うよ
Javaというプログラミング言語がありますが、JavaScriptは全くの別言語です。名前が似てるだけで全く別物なので注意です！

## 基礎文法

#####●アラートの表示

```script.js
window.alert('こんにちは');
```
テキストはシングルクォート（'）かダブルクオート（"）で囲みます。

 **※window.alert()**
 ブラウザでアラートを表示させるメソッドです。引数としてアラートに表示させる情報を渡します。

#####●コンソールにテキストを表示させる
ブラウザ上で二本指クリック→「検証」を選択→Consoleを選択でコンソールを開く
↓
index.htmlを開いているブラウザをリロード
↓
コンソールにテキストが表示されたら成功！

 **※console.log()**
 ブラウザのコンソールにテキストを表示させるメソッドです。引数としてコンソールに表示させる情報を渡します。 
 window.alertと同様に変数を引数に渡すこともできます。Rubyにおけるputsメソッドと同様に使えます。

#####●変数を宣言する

```ruby:script.js
var name = 'harada';
console.log(name + 'さん、こんにちは');
```
修正ができたら、もう一度ブラウザをリロードして、「haradaさん、こんにちは」と
表示されていれば成功です。

#####●ES2015(ES6)バージョン以降の変数宣言
ES2015(ES6)バージョン以降は、letとconstを使います。
letの場合

```script.js
let name = 'mitsui';
console.log(name + 'さん、こんばんは');
```

**letは、後で書き換えることができる**
**constは、後で書き換えることができません**


## 条件分岐
if文を使います。

```
if (条件式1) {
  // 条件式1がtrueのときの処理
} else if (条件式2) {
  // 条件式1がfalseで条件式2がtrueのときの処理
} else {
  // 条件式1も条件式2もfalseのときの処理
}
```

☆条件式は()でくくること
☆条件式の後に続く波括弧{}内の処理が実行されること
☆複数条件を指定する場合は、elseのあとに続けてif文を記述すること

**Rubyではelsifですが、JavaScriptではelse ifと書くことを注意です！**

```
num = 36

if num % 15 == 0
  puts num.to_s + 'は2と4の倍数です'
elsif num % 3 == 0
  puts num.to_s + 'は2の倍数です'
elsif num % 5 == 0
  puts num.to_s + 'は4の倍数です'
else
  puts num.to_s + 'は2の倍数でも、4の倍数でもありません'
end
```

## 配列
JavaScriptにおいても配列の概念があります。

```script.js
let list = ['Ruby', 'Ruby on Rails', 'JavaScript', 'HTML', 'CSS'];
console.log(list);
```

ブラウザをリロードすると、配列の中身を確認することができます。

1.要素を取得
取り出したい文字列の番号を記述
2.要素数を取得
lengthメソッドが利用できます
3.要素を追加
Pushメソッドが利用できます
4.要素を削除
popメソッドが利用できます
配列の最後の要素を取り除きます。Rubyの場合はpopメソッドの引数に数字を渡すことで「何個分要素を取り除くか」という数を指定できるが、JavaScriptのpopメソッドではそれができません。

**先頭の要素を取り除くためにshiftメソッドが利用できます**

## オブジェクト
データのまとまりのこと。オブジェクトは名前と値をセットにしてデータを管理します！
オブジェクトを作成するには波括弧を使用します。

オブジェクトの定義

```
let hoge = { name: 'harada' };
```

```script.js
let obj = { name: 'harada', age: 18, address: 'nagoya' };
console.log(obj);
```

変数hogeはnameプロパティを持っています。
プロパティは必ず属性名である*「プロパティ名」*とデータである*「値」*をセットで持ちます。
つまり、nameはプロパティ名、'harada'は対応する値です。

1.プロパティの値を取得する

```
let obj = { name: 'mita', age: 30, address: 'tokyo' };
console.log(obj.name);
```

2.プロパティの値を変更する

```
let obj = { name: 'mita', age: 30, address: 'tokyo' };
obj.name = 'tanaka';
console.log(obj.name);
```

# 繰り返し処理を実装

#####for文

```
for (let i = 0; i < 繰り返す回数; i = i + 1) {
  // 繰り返す処理の内容
}
```

#関数を定義

#####function文

```
function 関数名(引数) {
  // 処理の内容
}
```

#####関数の戻り値

returnを使う
JavaScriptではreturnを用います！

```
function calc(num1,num2){
  return num1*num2;
}

let num1 = 3;
let num2 = 4;
console.log(calc(num1,num2));
```

##### 無名関数を定義
JavaScriptにおける関数の定義には2種類で、
一つが関数宣言
二つ目が無名関数を用いたものです。

```
// 関数宣言
function hello(){
  console.log('hello');
}

// 関数式（無名関数）
let hello = function(){
    console.log('hello');
}
```

##### 基本編は以上になります。ここまで読んでいただきありがとうございます＾＾
座標系での向きの変わる移動 Python3編やってみた

#はじめに
例によってまたpaizaのBランクレベルアップセット。
一応公式でコード公開オッケーされてる問題なのであしからず。


今回はBランクの本ちゃんのスキルチェックにもあった鼠小僧とほぼ同じ問題。
どっち向いてる時に座標がどう動くかだけ間違わなければ簡単に解ける。

```python:zahyo_muki.py
x,y,n = [int(i) for i in input().split()]

direction = "N"


for i in range(n):
    a = input()
    
    if direction == "N":
        if a == "R":
            x += 1
            direction = "E"
        
        else:
            x -= 1
            direction = "W"
            
    
    elif direction == "E":
        if a == "R":
            y += 1
            direction = "S"
        
        else:
            y -= 1
            direction= "N"
    
    elif direction == "S":
        if a == "R":
            x -= 1
            direction = "W"
        
        else:
            x += 1
            direction = "E"
          
    
    else:
        if a == "R":
            y -= 1
            direction = "N"
        
        else:
            y += 1
            direction = "S"
    print(x,y)

```



#感想
特になし。
強いて言えば初期位置でどっちの方角向いてるのかが明記されておらず、テストケースの出力で判断するしかなかったのが困った。
この問題解けれるレベル感ならBランクの鼠小僧は解けると思う。


#それよりも、、、



この問題の一個手前（これより簡単なはずの位置付け）の問題に手も足も出せず完封された。。。


![スクリーンショット 2020-08-20 23.50.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682059/7e50853d-d115-2c88-2b17-768d209a2545.png)

この時計回りの動きをどうしてもコードに落とし込めず。
とりあえず現実逃避してタイトルの問題に挑んだものの簡単すぎて拍子抜け。
まじでわからん。。。白旗:bow_tone4:
pythonのimaplib調査

# はじめに
エンジニアとしてのアウトプット習慣をつけるため、なるべく毎日なにかしらの記事を投稿していこうと思います。

業務で使うわけではないですが、興味があったためpythonでメールを扱う方法を調べることにしました。
`python` の`imaplib`についていくらか自分で調べた内容をまとめようと思います。
まとめるとは言えど、公式ドキュメントのほぼそのまんまを記事になるのかも…

# IMAPクライアントインスタンスの作成

ほかの[Qiita記事](https://qiita.com/takey/items/1498af9e1113eeb7bb21 "Qiita記事")にもあるが、`imaplib.IMAP4_SSL`を使いIMAPクライアントインスタンスをつくる。
このときの引数には`host='', port=IMAP4_PORT,ssl_context=`を指定する必要があり、Yahooメールの場合

```
host = "imap.mail.yahoo.co.jp"
port = ("ssl", 993)
ssl_context = ssl.create_default_context()
```
となる。なんでかは調べてません。

# ライブラリオブジェクト

受信メールの基本操作をしようとするとき使用しそうなオブジェクトをざっと調べました。


| オブジェクト名 | 説明 | 使用例 |
|:--|:--|:--|
| login(user,password)  | ログイン。メールのアカウント情報を入力すればOK  |  IMAP4.login('AAAA@yahoo.co.jp','password') |
| logout()  | ログアウト。引数なし  |  IMAP4.logout() |
|  select(mailbox='INBOX', readonly=False) | メールボックスを選択。ReadonlyをTrueにすると変更をかけられなくなる  | IMAP4.select(mailbox='onlyfive')  |
| fetch(message_set, message_parts)  | メッセージの一部を取り寄せる。message_setはバイト型の数字、message_partsはッセージパートの名前を表す文字列を丸括弧で囲ったもの。  |  IMAP4.fetch(b'1', '(RFC822)') |

短いですが、今日はここまで。
TWELITE で Lチカの続き(シリアルUART出力)


「TWELITE で Lチカ」
https://qiita.com/nanbuwks/items/b9b5c16838d5d4626639

ではスクラッチビルドでミニマムプログラムを作成しました。
今回はその続きで、TWELITE からシリアルUART出力を行います。

無線通信などは行わず、先のLチカプログラムにシリアルUART出力に必要な最低限の記述のみ加えます。

「tsSerialPortSetup」「SERIAL_vInit()」を見て、シリアルポートをセットアップします。
https://sdk.twelite.info/hw-api-rifurensu/perifuraru/uart/serial-raiburari/tsserialportsetup
https://sdk.twelite.info/hw-api-rifurensu/perifuraru/uart/serial-raiburari/serial_vinit

```

#include <AppHardwareApi.h>
#include "utils.h"
#include "ToCoNet.h"
#include "ToCoNet_mod_prototype.h"
#include "serial.h" 
#include "fprintf.h"
#define LED 12

tsFILE sSerial0Stream;
static tsSerialPortSetup sSerial0;


static void vProcessEvCore(tsEvent *pEv, teEvent eEvent, uint32 u32evarg)
{
    static int counter=0;
    if (eEvent == E_EVENT_TICK_TIMER) {      // 4ms timer
        counter++;
        if (  0 == counter % 500 ) {
            vPortSetHi(LED);
            vfPrintf(&sSerial0Stream, "LED High\n\r");
        }
        if ( 250 == counter % 500 ) {
            vPortSetLo(LED);
            vfPrintf(&sSerial0Stream, "LED Low\n\r");
        }
    }
}


void cbAppColdStart(bool_t bStart)
{
    if (!bStart) {
    } else {
        vPortAsOutput(LED);  // GPIO set
        ToCoNet_Event_Register_State_Machine(vProcessEvCore); // add Event handler
        // serial init

        static uint8 au8SerialBuffTx[32];
        static uint8 au8SerialBuffRx[16];

        sSerial0.pu8SerialRxQueueBuffer = au8SerialBuffRx;
        sSerial0.pu8SerialTxQueueBuffer = au8SerialBuffTx;
        sSerial0.u32BaudRate = 115200;
        sSerial0.u16AHI_UART_RTS_LOW = 0xffff;
        sSerial0.u16AHI_UART_RTS_HIGH = 0xffff;
        sSerial0.u16SerialRxQueueSize = sizeof(au8SerialBuffRx);
        sSerial0.u16SerialTxQueueSize = sizeof(au8SerialBuffTx);
        sSerial0.u8SerialPort = E_AHI_UART_0;
        sSerial0.u8RX_FIFO_LEVEL = E_AHI_UART_FIFO_LEVEL_1;
        SERIAL_vInit(&sSerial0);

        sSerial0Stream.bPutChar = SERIAL_bTxChar;
        sSerial0Stream.u8Device = E_AHI_UART_0;

        vfPrintf(&sSerial0Stream, "Hello World!\n\r");
    }
}

void cbAppWarmStart(bool_t bStart) { return; }
void cbToCoNet_vRxEvent(tsRxDataApp *psRx) { return; }
void cbToCoNet_vTxEvent(uint8 u8CbId, uint8 bStatus) { return; }
void cbToCoNet_vNwkEvent(teEvent eEvent, uint32 u32arg) { return; }
void cbToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) {	return; }
uint8 cbToCoNet_u8HwInt(uint32 u32DeviceId, uint32 u32ItemBitmap) {	return FALSE; }
void cbToCoNet_vMain(void) { return; }


```


# 実行結果


```

Hello World!
LED Low
LED High
LED Low
LED High
LED Low
・
・
・
```

-
閾値処理(アダプティブスレッショナルド)

#実行環境
[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)

#Google Colaboratoryで画像を読み込む為の準備
```python:
from google.colab import files
from google.colab import drive
drive.mount('/content/drive')
```

#必要なライブラリの読み込み
```python:
import cv2 #opencv
import matplotlib.pyplot as plt 
%matplotlib inline
```

#画像準備
```python:
img = plt.imread("/content/drive/My Drive/Colab Notebooks/img/Lenna.bmp")
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
```
#アダプティブスレッショルド処理

近傍から閾値を求めて変換する。

```python:
plt.figure(figsize=(9, 6), dpi=100,
           facecolor='w', linewidth=0, edgecolor='w')

plt.gray()

#オリジナル画像
plt.subplot(2,2,1)
plt.axis('off') 
plt.imshow(gray)

henkango = 255 #閾値を超えたものの数値をどう変換するか
blocksize = 11 #閾値算出の為の近傍領域サイズ(3以降の奇数)
c = 16 #減算値


#アダプティブスレッショナルド処理：MEAN
plt.subplot(2,2,3)
plt.title("MEAN", fontsize=10)
dst = cv2.adaptiveThreshold(gray, henkango, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blocksize, c)
plt.axis('off') 
plt.imshow(dst)

#アダプティブスレッショナルド処理：GAUSSIAN_C
plt.subplot(2,2,4)
plt.title("GAUSSIAN", fontsize=10)
dst = cv2.adaptiveThreshold(gray, henkango, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, blocksize, c)
plt.axis('off') 
plt.imshow(dst)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610285/ec596b55-eb82-4e89-66c4-9106c179ad4a.png)
jsf.ajax.request: Method must be called within a formとなった時の対応方法

- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
    - openjdk version "11.0.7" 2020-04-14 LTS
    - JSF 2.3.9

# 事象 : f:ajaxを使った処理を実行したら怒られた
なんか動かないと思ったら、Chromeの開発ツールのConsoleにエラーが出ていた

```bash:Chromeの開発ツールのConsoleに出たエラー
jsf.js.jsf?ln=javax.faces:1 Uncaught Error: jsf.ajax.request: Method must be called within a form
    at Object.request (jsf.js.jsf?ln=javax.faces:1)
    at Object.ab (jsf.js.jsf?ln=javax.faces:1)
    at HTMLInputElement.onclick (upload.jsf:12)
```

# 原因 : formタグがないから
うっかりformタグを忘れていた。

```xml:xhtml
<body>
<!--省略-->
    <h:commandButton value="閉じる" action="#{uploadBean.close}">
      <f:ajax onevent="windowClose" />
    </h:commandButton>
  </div>
</body>
```

```html:出力されたhtml
<input id="j_idt11:j_idt14" type="submit" name="j_idt11:j_idt14" value="閉じる" onclick="mojarra.ab(this,event,'action',0,0,{'onevent':windowClose});return false">
```

## 対応 : formタグの中にf:ajaxを配置する
```xml:xhtml
<body>
  <h:form>
<!--省略-->
      <h:commandButton value="閉じる" action="#{uploadBean.close}">
        <f:ajax onevent="windowClose" />
      </h:commandButton>
    </div>
  </h:form>
</body>
```
Git for Windows（2.25以降）でファイル名に禁則文字を含むリポジトリを Clone する方法

Linux での利用を前提としたリポジトリには、ファイル名に Windows の禁則文字が含まれている場合があります。[^2] しかし、Git for Windows ではファイル名に禁則文字を含むリポジトリを Clone できません。[^1] とはいえ、禁則文字を含まないファイルまで Clone できないのでは不便です。どうにかできないものか。


[^2]: [一例](https://github.com/aquasecurity/vuln-list/blob/master/oval/redhat/6/2010/)です。
[^1]: Windows 10 の場合、「\」「/」「:」「*」「?」「"」「<」「>」「|」がファイル名に利用できません。

## 「まばらに」 Clone して問題を回避する

[protectNTFS](https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreprotectNTFS) をオフにした状態で、[sparse-checkout](https://www.git-scm.com/docs/git-sparse-checkout) を活用すれば無事に Clone できます。

```powershell
# 空のリポジトリを作成する
mkdir <リポジトリ名>
Set-Location <リポジトリ名>
git init
git remote add origin <リポジトリのURL>

# 禁則文字を含むファイルをチェックアウトするとエラーになる機能を無効化
git config core.protectNTFS false
# sparse-checkout を有効化
git config core.sparsecheckout true

# .git\info\sparse-checkout にクローン対象とするパスを記述する
# このとき、エンコードが UTF-8（BOMなし）であることに注意する
[System.IO.File]::WriteAllLines("${PWD}\.git\info\sparse-checkout", @("クローン対象1";"クローン対象2";...), (New-Object "System.Text.UTF8Encoding" -ArgumentList $false))

# 「まばらに」 Clone
git pull origin master
```

protectNTFS が有効な状態では、sparse-checkout でクローン対象とするパスを限定しても、 禁則文字を含むファイルがあると問答無用でエラーになってしまいます。なお、protectNTFS は [Git for Windows 2.25.0](https://github.com/git-for-windows/git/releases/tag/v2.25.0.windows.1) から含まれており、以前のバージョンでは sparse-checkout するだけで問題を回避できていました。

## 参考リンク

* [Git for Windows now fails as expected when trying to check out files with illegal characters in their file names.](https://github.com/git-for-windows/git/releases/tag/v2.25.0.windows.1)
* [git sparse checkout で clone せずに一部のサブディレクトリだけを pull/checkout する](https://mseeeen.msen.jp/git-sparse-checkout/)
* [Git pullエラー：ファイルを作成できません（無効な引数）](https://www.it-swarm.dev/ja/windows/git-pull%E3%82%A8%E3%83%A9%E3%83%BC%EF%BC%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%EF%BC%88%E7%84%A1%E5%8A%B9%E3%81%AA%E5%BC%95%E6%95%B0%EF%BC%89/1049291468/)
* [Partial Clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html)
Firebase CLI を global install したのに、firebase: command not found と怒られるときの対処法。

# SUGOI USUI
```sh:terminal
yarn global add firebase-tools
export PATH="$(yarn global bin):$PATH"

// npm 使いなら
npm install -g　firebase-tools
export PATH="$(npm bin -g):$PATH"
```
と、path を通してあげる良い。

## 補足
下で bin の場所を確認している。

```sh:terminal
yarn global bin
npm bin -g
```

短い投稿で申し訳ない。さっき firebase を触ろうとして初っ端から躓いたので。