OmniAICreator/Qiita-1.07M huggingface dataset:
STM32統合開発環境 STM32CubeIDE の日本語化

# はじめに
STM32CubeIDEはSTMicroelectronicsより無償で提供されている STM32統合開発環境ですが、日本語化されておらずそのまま日本語を入力すると文字化けが発生してしまいます。
本記事では、アプリUIの日本語化とソースコードの日本語が化けないようにする対策について記載します。

# 使用環境
OS:Windows 10 Pro 1903
ツール本体：[STM32CubeIDE](https://www.st.com/ja/development-tools/stm32cubeide.html) Version 1.1.0
追加プラグイン：[Pleiades 日本語化プラグイン](https://mergedoc.osdn.jp/) Ver.2019.11.29

# 手順
## STM32CubeIDEをインストール
上記リンクからツール本体をインストールします。

## Pleiades日本語化プラグインをインストール
STM32CubeIDEはeclipseベースなので、その日本語化プラグインが適用可能です。
上記リンクの「Pleiadesプラグイン・ダウンロード」をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/6ecc07a7-41ef-1720-5f48-b3c87782081e.png)
STM32CubeIDEをデフォルトパスに入れた場合、「日本語化するアプリケーション」に「C:\ST\STM32CubeIDE_1.1.0\STM32CubeIDE\stm32cubeide.exe」を指定します。

## 文字コードをUTF-8にする
最新のSTM32CubeIDEでは既にUTF-8になっていますが、一応。

1.メニューの[ウィンドウ(W)]-[設定(P)]を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/30306959-1052-27dd-c217-6726c6b43ee8.png)

2.[一般]-[ワークスペース]の[テキスト・ファイル・エンコード]がUTF-8であることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/663b1e9b-c657-0724-4012-aa3da97b81ad.png)

## 文字フォントを日本語対応にする
設定の[一般]-[外観]-[色とフォント]にて、テキストフォントを日本語対応版に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/de94a403-21ee-49fa-bf41-7ba49f810248.png)
「システム・フォントの使用」ボタンでの自動設定かMSゴシックなどの日本語対応フォントを設定すると良いでしょう。

参考：[Eclipseでコメントの前の方だけ文字化けする](https://qiita.com/segur/items/60b3711c0c9207d23b2f)

## 自動生成ソースコードの文字コードをUTF-8にする
拡張子がiocのファイルから各種ペリフェラルの初期化コードを自動(再)生成することが出来ますが、その際に既に入力していた日本語が文字化けすることへの対策です。
（コメ欄でのご指摘を頂いた内容を反映しました）

以下ファイルに項目を追記します。
C:\ST\STM32CubeIDE_1.3.0\STM32CubeIDE\stm32cubeide.ini
追記：
-Dfile.encoding=UTF-8

## 既存のソースファイルをインポートする
インポート前、もしくはインポート直後に、Shift-JISなどのソースはUTF-8に変換しておきます。(BOM無しでOK)
AWKコマンドで正規表現にマッチした行だけを抽出

AWKマスターへの道のり アドベントカレンダーの4日目
https://qiita.com/advent-calendar/2019/awker

## 環境

```bash
$ awk -V
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)
```

## やりたいこと
特定の正規表現にマッチした行を抽出する。

## コード

```bash
// 行全体で行う場合
$ cat target.tsv | awk -F'\t' '/<正規表現>/'

// 特定のカラム(列)で行う場合
$ cat target.tsv | awk -F'\t' '$1=/<正規表現>/'
```

// ← で囲った部分が正規表現として評価されます。
基本的な正規表現はもちろん使えますが、気になる方は[正規表現で使える文字列]((http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_5.html))を参考にしてみてください。

※awkコマンドでは、パターンのみを書いてアクションを書かない場合には、tureの時にprint $0が実行されます。

## 最後に
awkコマンド何でもできるなぁー。

私もなんでもできるようになりたいなぁー。。。
Ubuntu 18.04/19.10にcoq-jupyterをインストールする

# 1. 概要

Ubuntu 18.04, Ubuntu 19.10にcoq-jupyterをインストールする手順を示します。

# 2. Ubuntuパッケージのアップデート

最初にパッケージのアップデートを実施します。

```
sudo apt update
sudo apt upgrade -y
```

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

続いてパッケージのインストールです。

```
sudo apt install -y python3-pip jupyter git coq
```

## 3-1. Ubuntu 19.10のパッケージ操作

Ubuntu 18.04ではこの操作は不要です。

Ubuntu 19.10では、aptでインストールしたCoqパッケージでは、JupyterからCoqの呼び出しするとエラーが発生します。そのため、gitでCoqのソースコードをcloneしてビルドします。
以下の手順では、先ほどインストールしたCoqパッケージをremoveしています。これは、install時に一緒にインストールされるOCaml環境が、Coqビルド時に必要なためです。Coqパッケージをremoveしても、OCaml環境は削除されません。

```
sudo apt remove -y coq
git clone https://github.com/coq/coq.git
cd coq
./configure
（質問はデフォルトでOKなので、全部Enterキーを押す）
make
sudo make install
vi ~/.bashrc
（以下の行を最後に追加する）
export PATH=/usr/local/bin:$PATH
（viを抜ける）
source ~/.bashrc
```

# 4. Pythonパッケージをインストールする

coq-jupyterパッケージをインストールします。

```
pip3 install coq-jupyter
```

## 4-1. Ubuntu 18.04のPythonパッケージ操作

Ubuntu 19.10ではこの操作は不要です。

Ubuntu 18.04では、一緒にインストールされるtornadoのバージョンを4.5.3に落とす必要があります。

```
pip3 uninstall -y tornado
pip3 install tornado==4.5.3
```

## 4-2. coq_jupyterモジュールのインストール

以下の操作を行います。

```
python3 -m coq_jupyter.install
```

# 5. Jupyter notebookの起動

せっかくなので、マルレク提供のcoq-tutorialをcloneしてから、Jupyterを起動してみます。

```
git clone https://github.com/maruyama097/coq-tutorial.git
jupyter notebook
```

以上
VueのエラーハンドラーとAxiosで快適な例外処理を行う

こんなことありませんか？

- 例外処理忘れてて、コンソールに流れていた:scream_cat:
- 例外発生時にアラートを表示するだけで4行も余分にコードを書かないといけなくて辛い:crying_cat_face:

``` XXX.vue
methods: {
  onClick() {
    try {
      this.something();
    } catch (error) {
      alert(error.message);
    }
  },
},
```

## Vueのエラーハンドラーについて

[Vue.config.errorHandler](https://jp.vuejs.org/v2/api/index.html#errorHandler)を使えばVueで発生するエラーをほぼキャッチできます。非同期処理内で発生したエラーはキャッチできないため、残りは`addEventListener`でキャッチします。

``` main.ts
// ほとんどのエラーをキャッチ
Vue.config.errorHandler = function (err, vm, info) {
  // 2.2.0 以降で使用できます。
  alert(err);
}
// 残りのエラーをキャッチ
window.addEventListener("error", event => {
  alert(event.error);
});
window.addEventListener("unhandledrejection", event => {
  alert(event.reason);
});
```

以下の説明にあるようにバージョンごとに仕様が異なるので注意。

![スクリーンショット 2019-12-16 23.11.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/fb2ba2ca-3de6-6642-dc9c-b47f8c40c05b.png)

[Vue.config.errorHandlerはどこで発生したエラーをキャプチャできるのか - Qiita](https://qiita.com/clomie/items/73fa1e9f61e5b88826bc)が分かりやすくまとまってて参考になりました。

## Axiosの共通処理について

Axiosの共通の処理は[Interceptors](https://github.com/axios/axios#interceptors)を使うと綺麗にかけます。
全てのリクエストヘッダーにX-Request-Id: uuidを付けた例です。

``` Repository.ts
client.interceptors.request.use((config: AxiosRequestConfig) => {
  config.headers['X-Request-Id'] = uuidv4();
  return config;
});
```

次の例ではrequestとresponseの時間を計測し、APIの通信に何ミリ秒かかったのかを毎回コンソールに出力します。Sentryを使うことで時間のかかってるAPIをフロント側から計測することも出来ますね。

[Vueのエラー監視にSentryを使ってみた - Qiita](https://qiita.com/kitanote/items/b47e634c4c89e366f348)

``` Repository.ts
import axios from 'axios';

const repository = axios.create({
  baseURL: 'http://localhost:8080',
});
repository.interceptors.request.use(request => {
  performance.mark('start');
  return request;
});
repository.interceptors.response.use(
  // 2XX範囲内のステータスコード
  (response) => {
    performance.mark('finish');
    performance.measure('request-to-response', 'start', 'finish');
    const message = `${performance.getEntriesByName('request-to-response')[0].duration}`;
    console.log(message);
    // Sentryでログを残すもよし
    // Sentry.captureMessage(message, Sentry.Severity.Debug);
    return response;
  },
  // 2XX範囲外のステータスコード
  (error) => {
      return Promise.reject(error);
  }
);
export default repository;
```

## 結果

- 例外処理忘れても確実にアラートで表示してくれる:smirk_cat:
- 共通の例外処理については機械的なtry,catchを書かなくてよくなった:smiley_cat:


``` XXX.vue
methods: {
  onClick() {
    this.something();
  },
},
```
Railsでiframeを使いたい

#やりたいこと
・Railsでiframeからのリクエストを許可して外部のサイトで表示させたい
・すべて許可するとなにかと怖いので特定のURLに絞りたい

#ということで
Railsでは

```ruby
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
```
が設定されていて自身のドメインしかiframeで表示出来ないそう

今回は特定のURLのみ許可したいので以下のように実装

```ruby
class HogeController < ApplicationController
    after_action :allow_iframe, only: [:hoge]

    def hoge
        render "hoges/index", layout: false
    end

    private
    def allow_iframe
        url = "https://hoge.com"
        response.headers['X-Frame-Options'] = "ALLOW-FROM #{url}"
        response.headers['Content-Security-Policy'] = "frame-ancestors #{url}"
    end
end
```

#注意点
なんと皆がよく使ってるであろうChrome、Safariなど多くのブラウザが
`X-Frame-Options ALLOW-FROM`
に対応していません[^1]

なので合わせて
`Content-Security-Policy frame-ancestors`
も記述してやりましょう[^2]

調べてみた感じIE以外対応してたので安心です[^3]

#効いてるか確認
Chrome DevToolsの`Network` パネルで確認できます
<img width="500" alt="C__でなにができるの？おススメ案件！___ITフリーランスエンジニアのためのコラム【at-engineer】.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178509/013c0005-e4c1-8daa-7f32-206ae7a8b8c7.png">


[^1]: [X-Frame-Options ブラウザ対応表](https://developer.mozilla.org/ja/docs/Web/HTTP/X-Frame-Options#Browser_compatibility)
[^2]: `X-Frame-Options ALLOW-FROM`だけ設定してしまうと未対応ブラウザですべてのURLを許可する状態になってしまいます
[^3]: [Content-Security-Policyブラウザ対応表](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy#Browser_compatibility)
新規アプリケーションをGithubで管理する(Rails)

# はじめに
Railsを使ってプログラミングの学習をしているのですが、新規アプリケーションを作成する際、Githubで管理する方法を忘れてしまうので、定着させる意味でも残したいと思います。

# 環境
OS: Mac
Rails 5.0.7.2
Ruby 2.5.1
MySQL
Github Desktop

# 手順
### １,新規アプリケーションを作成

```terminal:ターミナル
$ cd myapp #作成したいディレクトリへ移動
$ rails _5.0.7.2_ new my-blog -d mysql #Railsのバージョンを指定、DBはMySQLを指定する。
$ cd my-blog #作成したアプリケーションのディレクトリへ移動
$ rails db:create #データベース作成
```

### 2,Github Desktopからローカルリポジトリにする
<img width="961" alt="スクリーンショット 2019-12-18 1.24.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/6ad69531-ca74-eb67-6bd4-9b4a3bd25896.png">
Github Desktop左上の`Current Repository`をクリック→`Add`→`Add Existing Repository`を選択。

<img width="961" alt="スクリーンショット 2019-12-18 1.29.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/45b5dcb5-039c-ff3e-f4a3-6c1f7e518295.png">
選択画面が出てくるので、作成したアプリを選択。

**Add Repositoryできない場合**
ターミナルにて、作成したアプリのリポジトリ→`git init`のコマンドを打てば解消されます。

<img width="961" alt="スクリーンショット 2019-12-18 1.32.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/469d7200-88d4-55b7-df65-6c54f89bb4dd.png">
左下から最初のコミットをする。<img width="961" alt="スクリーンショット 2019-12-18 1.34.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/211bf584-e408-a44b-19de-77263513f6db.png">
`Publish repository`をクリック。
<img width="961" alt="スクリーンショット 2019-12-18 1.35.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/049db55d-22a2-0969-8c65-bf819507ea64.png">
公開してもいいなら`Keep this code private`のチェックを外し、`Publish Repository`をクリック。

### 3,Githubのリモートリポジトリが作成される
<img width="1012" alt="スクリーンショット 2019-12-18 1.40.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433361/3fc0b8d4-e263-a594-918f-00065228df34.png">
Githubの`Your Repositories`に作成したアプリが登録されていれば完了です。
JavaScriptで配列内の文字列から最も文字数の小さい要素を取得する方法。

# はじめに
短く書くにはどうすればいいか調べたのでまとめたよ。

# ゴール
```javascript:index.js
const string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";

function findShortWord(s){
    return Math.min(...s.split(" ").map (s => s.length));
}

console.log(findShortWord(string));
```


# 概要
## Math.min()
* 引数に渡された一番小さい値を返す。
* [MDN Web Docs - Math.min()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/min)

## スプレッド構文（...）
* 配列・関数の引数・オブジェクトを個々に展開できる。
* [MDN Web Docs - スプレッド構文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)

## String.prototype.split()
* 文字列を、引数で指定した区切り文字で分割して、配列で返す。
* [MDN Web Docs - String.prototype.split()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)

## Array.prototype.map()
* 配列の各要素に関して、コールバック関数を実行して配列で返す。
*  [MDN Web Docs - Array.prototype.map()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

# さいごに
* スプレッド構文（...）をちゃんと勉強したけど、こんなに便利だと思わなかった。
AWKコマンドで重複をなくす(ユニークにする)

AWKマスターへの道のり アドベントカレンダーの3日目
https://qiita.com/advent-calendar/2019/awker

## 環境

```bash
$ awk -V
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)
```

## やりたいこと
重複した行をユニークにする。(uniqコマンドを使わないで)

## コード

```bash
// uniqコマンドを使う場合
$ cat target.tsv | sort | uniq
```


```bash
// awkをのみを使ったバージョン
$ cat target.tsv | awk -F'\t' '!a[$0]++'
```

### 何をしているのか??
a[$0]は、つまりその行すべてをキーにした配列です。
それを評価した後にインクリメントします。

つまり、
1回目 > 0
2回目 > 1
3回目 > 2
...

と評価されるわけです。

awkでは0以外の値はすべてtrueなので、一回目だけfalseで後はすべてtrueということになります。
これを「!」で逆の評価にしているので、一回目の出力のときだけtrueで、後はすべてfalseになり、最初の一回目だけ出力されるというわけです。

※awkコマンドでは、パターンのみを書いてアクションを書かない場合には、tureの時にprint $0が実行されます。

### sort | uniq　よりも早い
sortの後にuniqを実行すると、一度すべての行をなめて整列させた後に、再びすべての行に対して重複のチェックを行うので二度手間です。

なお、上記のawkコマンドでは並べ替えはしませんが、順番まで正しくしたいのであれば、awkコマンドで重複なくした後にsortしたほうが処理が少なくなるのでおすすめです。

## 最後に
awkコマンドすげー。
Node.jsのバージョンを上げた際のnode-sassのビルドエラー


ほんとにどうってこと無いメモです。

久々に開発しようとしたNuxtJSプロジェクトで、node-sassがコケました。
[node-sass](https://github.com/sass/node-sass)はv4.13.0です。

```bash
$ yarn dev

・
・
・

● Client █████████████████████████ building (61%) 431/466 modules 35 active
 node_modules/markdown-it/lib/rules_core/state_core.js

✖ Server
  Compiled with some errors in 9.34s


✖ Client
  Compiled with some errors in 13.93s

✖ Server
  Compiled with some errors in 9.34s


 ERROR  Failed to compile with 1 errors                                            friendly-errors 23:04:34


 ERROR  in ./layouts/blog.vue?vue&type=style&index=0&lang=scss&                    friendly-errors 23:04:34

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):                 friendly-errors 23:04:34
Error: Missing binding /Users/n0bisuke/dotstudio/1_protooutstudio/node_modules/node-sass/vendor/darwin-x64-79/binding.node
Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 13.x

Found bindings for the following environments:
  - OS X 64-bit with Node.js 12.x

・
・
・
```

みたいなコケかたをしました。

```
Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 13.x
```

この`64-bit`をみると一瞬カタリナにmacOSをアップデートしたから怒られるやつかと思いましたが、

```
Found bindings for the following environments:
  - OS X 64-bit with Node.js 12.x
```

こちらを見ると既に64bit Node.js v12でnode-sassが紐付けされてたみたいですね。
> <img src="https://i.gyazo.com/dac73062873f171ced5f80c81c371234.png" width="400px">

それにしてもエラー表示がすごい。

## これで解決

```
yarn add node-sass
```

npmの人も入れ直せばOK。
【Vue.js】タブ切り替えが出来る単一ファイルコンポーネントサンプル

## はじめに
Vue.jsでタブ切り替えが出来る**単一ファイルコンポーネント**のサンプルを作成してみました。

`v-for`
`v-bind`
`v-show`
Vue.jsの基本機能である上記3点を活用しています。

![スクリーンショット 2019-12-18 23.02.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/bfce1f67-63f2-5fff-6083-e19315f9ada8.png)

## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
vue-cli: 4.1.1
```
## サンプル確認用リンク

こちらから動きの確認ができます。
[JSfiddle（外部サイト）へのリンク](https://jsfiddle.net/terufumi1122/r3ky47gb/4/)

※動きの確認用のため、若干下記ソースコードと書き換えているところがあります。

<script async src="//jsfiddle.net/terufumi1122/r3ky47gb/3/embed/js,html,css,result/dark/"></script>

## ソースコード

```vue:Tab.vue
<template>
  <div class="tabs">
    <div class="btn-container">
      <button v-for="(tab, index) in tabs"
              :key="tab.id"
              :class="{ active: currentTab === index }"
              @click="currentTab = index">{{ tab.tabName }}</button>
    </div>
    <div class="tab-content">
      <div v-show="currentTab === 0">
        <h1>Tab1 content</h1>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
      </div>
      <div v-show="currentTab === 1">
        <h1>Tab2 content</h1>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
      </div>
      <div v-show="currentTab === 2">
        <h1>Tab3 content</h1>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'tabs',
  data () {
    return {
      currentTab: 0,
      id: 0,
      tabName: "",
      tabs: [
        {id: 1, tabName: 'Tab1'},
        {id: 2, tabName: 'Tab2'},
        {id: 3, tabName: 'Tab3'}
      ],
    }
  }
}  
</script>

<style lang="scss" scoped>
.tabs {
  margin: 10px auto;
  padding: 10px;
  width: 80%;
  height: 80%;
  background: rgb(242, 242, 242);
  border-radius: 10px;
}
h1 p{
  font-family: 'Courier New', Courier, monospace;
}
h1 {
  font-size: 20px;
}
p {
  font-size: 8px;
}
.btn-container {
  display: flex;
  justify-content: center;
}
button {
  width: 20%;
  font-size: 20px;
  text-align: center;
  margin: 10px;
  padding: 3px 10px;
  background: rgb(186, 214, 238);
  border-radius: 10px;
}
button.active{
  background: lightcoral;
}
.tab-content div {
  padding: 30px;
  background: #ffffff;
  width: 80%;
  margin: 0 auto;
}
</style>
```

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

コンポーネント単位で作成出来ると、機能が同じならスタイルを変えて流用出来ていいですね。
やっとVue.jsの良さを実感出来てきました:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
[リストレンダリング — Vue.js](https://jp.vuejs.org/v2/guide/list.html)
Pythonはじめました： SQL結果で取得した値の配列をリスト型への値入れ替えて別のクエリーの IN で使う

## まずあるSQL結果の値配列をリスト型への値入れ替えていく

サンプルクエリー

```
users_id_query = '''
SELECT CAST(user_id as char) as user_id FROM users_table;
'''
``` 

※前提として user_id がint であるという点が重要。リスト型にしたかったらこれを変換しないとエラーになってしまう。

Python で上記のクエリー実行すておく。

```
users_ids = execute_query('my_database', users_id_query)
```

結果は「111,222,333」みたいにしたいわけ：

```
users_result = [str(x['user_id']) for x in users_ids['rows']]
users_ids_string = ','.join(users_result)
```

users_ids_string にはほしいような、カンマ区切りの値が見事に入ってくれる。

## 用意したリストを別のクエリーの IN で使う

サンプルSQL

```
users_login_query = '''
SELECT count(0) FROM login_log_table where user_id in (user_ids_string)
'''
```

「user_ids_string」は次で実際の値と置き換えるパラメータ。

```
entry_users_ids = execute_query('my_database', users_login_query.replace('user_ids_string', entry_users_ids_string))    
```

実行先を指定しながら値も同時にリプレイス。
java 実践編 その1

今日はjavaの簡単な扱いかたについて
書きます。

なお先日の投稿であるJDKについて終わっている前提で書いて行きます。

# 基本手順
少しjavaはrubyと比べて手間がいるコードなので
手順を書いて行きます。

1,.javaファイルを作成してjacaコードを書く
2,上記のファイルをjavacコマンドでclassファイルを作成する
3,クラスファイルを実行する。

これが簡単な流れです。
基本コードを書いてもコンパイルしてクラスファイルを作らないと
javaは使えないのでjavacコマンドでクラスファイルに変換作成するわけです。

## 基本書式
まず基本的な書式を書いて行きます。
他の言語と比べ前準備のコードがかなり長いです。

```java:基本書式.java
class ファイル名（クラス名）{
   public static void main(String[] args){
    （処理内容）
  } 
}
```

例はこちら

```java:HelloJava.java
class HelloJava {
	public static void main(String args[]){
		System.out.println("Hello!");
	}
} 
```

これでHello!と出力するコマンドがかけました。

## クラスファイルの作成

次に実行ファイルに当たるクラスファイルを作成します。

```bash:ターミナル
javac javaファイル名.java
```
例として

```bash:ターミナル
javac HelloJava.java
```

これでHelloJava.classが作成されました。

## ファイルの実行
次にクラスファイルを実行します。
例で使われているHelloJava.classを実行します。

```bash:ターミナル
 java クラスファイル名
```

```bash:ターミナル
 java HelloJava
```

これでHello!と出力されました。

# 名前の注意点
名前は同じにするなど注意点があります。

## ファイル名とクラス名を同じ名前にする
ファイル名とクラス名は同じにしなければいけないというJavaの決まりごとがあリます。

## 大文字、小文字を意識する
また、Javaでは大文字、小文字を認識するため、
「classsample」と「ClassSample」は違うものとして扱われます。
実はFirefoxにはWebページの翻訳機能がある

# はじめに

先月、MozillaがFirefoxにオフラインで利用できる、Webページの翻訳機能の実装を進めている、というニュース記事を読みました。調べてみると、Firefoxにはすでに、Webページのクラウド翻訳機能が実装されていたことを知りました。

そんで、その機能を使うための日本語の情報が全く無かったため、この記事を書きました。（ちなみにqiita初投稿）

※今回使用した`Firefox`のバージョンは`71.0`です。

# 翻訳機能について

翻訳機能を使う設定をすると、外国語のページを閲覧したとき、翻訳ツールバーが上部に表示されます。こんな感じ。

![翻訳ツールバー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536524/7c8348dc-9dbf-ffbd-8734-8fb4005b9b06.png)

**ただし、FirefoxのWebページの翻訳機能を使うには、`about:config`での設定と、利用する翻訳APIへの登録とそのAPIキーが必要です。**

# 設定方法

Firefoxの`about:config`で設定を行います。

まずは、翻訳ツールバーを表示する設定です。下記の設定を`true`に変更します。真偽値はダブルクリックで切り替えが可能です。

`browser.translation.detectLanguage`<br>`browser.translation.ui.show`

次に、翻訳エンジンの名前を文字列で設定します。下記の設定に`Google`, `Yandex`のどれかをセットします。（今回、試したところ`Bing`は動作せず）

`browser.translation.engine`

最後に、APIキーの設定を追加します。設定値はもちろん文字列ですが、先ほど設定した翻訳エンジンにより、設定名が異なります。

| browser.translation.engine の値 | APIキーの設定名                           |
| ------------------------------- | ----------------------------------------- |
| Google                          | browser.translation.google.apiKey         |
| Yandex                          | browser.translation.yandex.apiKeyOverride |
| Bing                            | browser.translation.bing.apiKeyOverride   |

**APIキーは各自で発行して設定してください。**

以上で設定完了です。

# 今回使った翻訳APIの比較

| API                                  | 翻訳精度 | 料金                                                                                                               | APIキーを発行するページ                                                     |
| ------------------------------------ | :------: | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| Google(Google Cloud Translation API) |    ◎     | 月50万文字まで無料（[詳細](https://cloud.google.com/translate/pricing)）                                           | https://console.cloud.google.com/apis/credentials                           |
| Yandex(Yandex.Translate API)         |    △     | 月100万文字まで無料（[詳細](https://translate.yandex.com/developers/offer/prices))<br>クレカ登録不要で使える       | https://translate.yandex.com/developers/keys                                |
| Bing(Microsoft Translator Text API)  |    ◎     | 月200万文字まで無料（[詳細](https://azure.microsoft.com/pricing/details/cognitive-services/translator-text-api/)） | https://portal.azure.com/#create/Microsoft.CognitiveServicesTextTranslation |

# さいごに

・設定名を[Searchfox](https://searchfox.org/mozilla-central/source/browser/components/translation)で検索すれば、どこのコードで使われているのかが見れます。

・Webページは文字数が多いので、翻訳APIの無料利用枠を超過する恐れがあるので注意しよう。~~（素直にChromiumを使え）~~
[ReactNative] expoのAppAuthでOAuthを実装してみる

# What
expoの[AppAuth](https://docs.expo.io/versions/latest/sdk/app-auth/?redirected)の登場で、イジェクトなしでOAuth実装が非常に簡単になりました。
マイナーなSNSとの連携が必要な場合に非常に重宝しますね。

実装手順は以下
グーグルログインの場合

```react

import * as AppAuth from "expo-app-auth";

 const config = {
    issuer: "https://accounts.google.com",
    clientId: "クライアント識別子"      
    scopes: ["profile"]
  };
 const tokenResponse = async () => {
   try {
     const authState = await AppAuth.authAsync(config);
     console.log(authState);
   } catch ({ message }) {
     alert(`${message}`); 
   } 
 };
```

これだけの手順でOAuthが実装できます。非常に簡単ですね。
※`AppAuth.authAsync()`はtoken情報のみを返します。
$_POST は万能じゃなかった！（困って学ぶ日々の備忘録）

痛い目に合いつつ学んだ内容をただ残していくだけの記事ですが、調べて日本語の記事があんまりなかったのでまずは簡単な内容でも助かる方がいるかも！と思い、公開。

タイトル通りですが、GET/POST で送られてくるデータを受け取る時は何もかも ```$_POST``` や ```$_GET``` で受け取ってしまえばいい、わけではないのです。
長い前書きは抜きにして、今日は「PHP ```php://input``` と ```$_GET / $_POST``` の違い、使い分け」について最近ちょっと困った結果学んだ情報を軽く整理してみました。

## ```$_POST``` は万能じゃない

受け取れる情報の量の許容範囲が ```$_GET``` よりあるからといって便利に思われがちですが、そうではにないことを最近実感した。
なんと・・・受信する殆どのデータが問題なのに、たま～にだけなぜか文字列が変なところで途切れたりして、構造が壊れ化けてしまうという・・・

ちょっと調べたら：
- XMLの受信
- JQueryからのAjaxリクエスト

には向いていないという。
今まであんまり意識せずにフレームワークのInputクラス（つまり、さらなる$_POSTラッパー）を使ったりしていましたが、本来は用途に応じて使い分ける必要があるとわかりました。

## $_POSTを使って良いケース

以下のコンテンツタイプのみ、phpのラッパーである $_POST は良い仕事をするという大前提があるようです。これは「すべてのユーザーエージェントによってサポート対象であるコンテンツタイプだから」であって、それらのみが保証されているということのようです。

- application/x-www-form-urlencoded
- multipart/form-data

HTMLフォームで送信できる内容に限って使うイメージを持てば安全かなと思います。
ちなみに、私の場合はヘッダーが「application/x-www-form-urlencoded」で送られてきていた xml も化けてしまったので、ヘッダーのみで安心するのもちょっと厳しい気がします。

## $_POSTを避けたほうがいいケース

- JSON を送信するとき（コンテンツタイプが application/json ）
- xml を送信するとき（コンテンツタイプが application/xml ）
- YAML を送信するとき（コンテンツタイプが application/yaml ）

上記（というか、使って良いケース以外！）の場合 $_POST に格納されたデータが壊れるケースが多いようです。壊れからも様々で、最初はただ「うまくURLデコードできないかな？」と思ってしまうレベルだったりします。
他順なデータでテストしても問題ないのに、ちょっと特殊な文字が含まれ送られてきた分だけ文字化けして、結局形式が壊れて例えば XML としてパースできないデータになってしまう場合がります。

## $_POST が使えない場合は？

```php://input``` から生のデータを引っ張り出す。
ただし、この場合は $_POST の恩恵（データをURLデコードしてくれちゃったり、配列にしてくれるあたり）が受けない分、全部自分で実装しないといけない。
送られてくるデータは、ただの（おそらくURLエンコードまたはRAW URLエンコードされた） string になるので、ある意味「自由に何でもできる状態」ではあります。


## 今回参考になった記事

https://stackoverflow.com/questions/8893574/php-php-input-vs-post
AWKコマンドで●回以上重複した行のみを抽出

AWKマスターへの道のり アドベントカレンダーの19日目
https://qiita.com/advent-calendar/2019/awker

## 環境

```bash
$ awk -V
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)
```


## やりたいこと
特定の回数以上出現する行のみを抽出する。

## コード

```bash
// テンプレ
$ cat target.tsv | awk -F'\t' '++a[$0]==<重複回数>'

// 例) 2回以上重複する行のみ
$ cat target.tsv | awk -F'\t' '++a[$0] == 2'
```

## 最後に
次回はちょうど●回重複した行のみの抽出を書きます。
mockmockでmockの状態遷移をしてみる(中級編)

こんにちは、mockmockチームエンジニアのジホです。

## この記事は
mockmockアドベントカレンダー 19日目の記事です。
mockmockでmockの多様な状態遷移方法をまとめます。

## やりたいこと
`指定時刻による遷移`、`指定時間経過による遷移`、`受信データによる遷移`、`確率による遷移`の例を紹介します。


## 手順
### プロジェクトを作成は[mockmockでmockの状態遷移をしてみる(初級編)](https://qiita.com/cheekykorkind/items/d26551b60109b78d1cdd)参考お願いします！
- プロジェクト設定を作成します
- データテンプレートを作成します
- mockグループを作成します
- mockステータスを作成します
- mockを作成します


### mockステータスを設定してみます
#### mockステータスを`指定時刻による遷移`を設定してみます
ユーザーの指定した時刻になる前まで状態を維持します。指定した時刻になると指定した状態に遷移します。
- イメージの設定は21時まで現状態を維持し、21時になった瞬間terminate状態に遷移させます。
- `指定時間`の書き方は[`秒 cronの時間書き方 `]になります。
![selctedTime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/dcea508a-9d85-d878-a632-00f6f16d75ab.png)


#### mockステータスを`指定時間経過による遷移`を設定してみます
- ユーザーが指定した時間が過ぎたら状態遷移させます。
- イメージでは20秒過ぎたらterminate状態に遷移させます。
![timeTrigger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/8db8b9b7-fab8-73c9-8604-4dafd128f063.png)


#### mockステータスを`受信データによる遷移`を設定してみます
- 送信先やブローカーとの通信によって得られたデータによって遷移を行います。
また、得られたデータの指定箇所をmock変数に格納することも可能です。
HTTP(S) : レスポンスの内容に応じて遷移を行います。
MQTT(S) : 特定のトピックをサブスクライブし、送られてきたメッセージの内容に応じて遷移を行います。
- イメージの設定はHTTPのレスポンスコードが200だったら、状態遷移させることを意味します。
![byReceive.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/573a19ef-8cdd-e81f-0136-f857852959f4.png)



#### mockステータスを`確率による遷移`を設定してみます
- イメージでは30%確率でterminate状態に遷移させてます。
![byPersentage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/ad2aabb1-3674-9e66-f8e5-edba951b9d7a.png)




## まとめ
本記事では、mockmockでmockの多様な状態遷移方法を作成しました。
mockの状態をいろいろ設定して、ぜひお試しください。

明日も私、 @cheekykorkind  が `mockmockでmockの状態遷移をしてみる(上級編)` をご紹介します。


## 参考
https://console.mock-mock.com/docs/tutorials/simple_data
https://qiita.com/cheekykorkind/items/d26551b60109b78d1cdd
SQLで重複しているレコードだけ抽出する

## 環境
MySQL
※多分他のやつでも同じように動くはず

## やりたいこと
タイトルの通り、SQLの適当なテーブルから、特定のカラムの値が重複しているレコードだけを抽出。

## コード

```sql
SELECT * FROM <テーブル> GROUP BY <カラム...> HAVING COUNT(*) >= 2;
```

ちなみに、カラムを複数対象にしたい場合には、GROUP BYに複数のカラム(「,」区切り)を書くことができます。

### 例) users テーブル(id,name_sei,name_mei,age,sex)

同姓同名がテーブルにいるアカウントのみ抽出

```sql
SELECT * FROM users GROUP BY name_sei,name_mei HAVING COUNT(*) >= 2;
```
## 最後に
SQLで全件検索した後にawkを使って無理やりやろうとしてましたが、冷静に考えてみたらSQLの方が素直に書けて良いですね。

SQLでかけるようなときは、AWK自重します。
【画像処理100本ノックに挑戦】Q.23. ヒストグラム平坦化

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.23. ヒストグラム平坦化
>ヒストグラム平坦化を実装せよ。
ヒストグラム平坦化とはヒストグラムを平坦に変更する操作であり、上記の平均値や標準偏差などを必要とせず、ヒストグラム値を均衡にする操作である。

画素値$z\to z'$の変換は

```math
z' = \frac{z_{\rm max}}{S} \sum_{i=0}^z h(i)
```

で与えられるらしい。なんだこの式。

# 式の意味を考えてみる
式を少し書き換えてみます。$\sum_{i=0}^z h(i)/S$は累積分布関数なので

```math
\sum_{i=0}^z h(i)/S \equiv p(z)
```

と定義します。するとヒストグラム平坦化の式は

```math
z' = z_{\rm max}p(z)
```

と書けます。累積分布関数からアプローチするのが見通しがよさそうです。

目的はヒストグラムを平坦化することでした。完全に平坦なヒストグラムの場合、累積分布関数は$z/z_{\rm max}$となります。なので、$z$をうまく変換して理想に近づけることを考えます。

ここでイメージをつかむため$f(x)=x^2$の線形化を考えます。そのためには、$f(x)=X$なる変数$X$を考えます。このような変数変換を行えば線形化が出来ます。

累積分布関数$p(z)$の話に戻ります。$p(z)$は一般に線形ではありませんが、先程の例に倣って

```math
p(z) \equiv z'/z_{\rm max}
```

を満たす変数$z'$を考えます。これは元の式そのものですね。離散変数なので厳密な平坦化は一般には出来ませんが、さてどの程度効果があるかやってみます。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();

	int N = 256;
	std::vector<int> hist(N);
	std::vector<double> p(N);
	for (int n = 0; n < N; n++)
	{
		hist[n] = 0;
		p[n] = 0;
	}

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			hist[ppm(i, j, 'r')]++;
			hist[ppm(i, j, 'g')]++;
			hist[ppm(i, j, 'b')]++;
		}
	
	for (int n = 0; n < N; n++)
		for(int m=0; m<n+1; m++)
		{
				p[n] += hist[m]/(double)(3.*width*height);
		}
	std::ofstream ofs("p0.txt");
	for (int n = 0; n < N; n++)
	{
		ofs << p[n] << std::endl;
	}
	int zmax = 255;

	PPM ppm2(width, height);
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = zmax * p[ppm(i, j, 'r')];
			ppm2(i, j, 'g') = zmax * p[ppm(i, j, 'g')];
			ppm2(i, j, 'b') = zmax * p[ppm(i, j, 'b')];

		}
	for (int n = 0; n < N; n++)
	{
		hist[n] = 0;
		p[n] = 0;
	}
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			hist[ppm2(i, j, 'r')]++;
			hist[ppm2(i, j, 'g')]++;
			hist[ppm2(i, j, 'b')]++;
		}

	for (int n = 0; n < N; n++)
		for (int m = 0; m < n + 1; m++)
		{
			p[n] += hist[m] / (double)(3. * width * height);
		}
	ppm2.Flush("out.ppm");

	std::ofstream ofs2("p.txt");
	for (int n = 0; n < N; n++)
	{
		ofs2 << p[n] << std::endl;
	}
	



	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/97cffd2d-2e7b-f8e1-9d5a-72f9ceed993c.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/592950fd-613f-a535-3c24-4250c59f9ab1.png)

累積分布関数は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/1b30f38c-23e3-3d1c-a2d7-b3570202f83f.png)
おお！思ったよりも平坦に！
MaplatEditorで不正確な古地図をマッピングする（３）マッピング作業

Maplat Advent Calendar 18日目です。
今日は昨日、MaplatEditorに登録した画像に、マッピングを施してみます。

昨日までの作業をやった状態で、MaplatEditorを起動すると、こんな感じになっているはずです。
<img width="1312" alt="スクリーンショット 2019-12-18 21.44.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/0b8b0a4d-ae9a-52ad-0226-3cb44d3505b4.png">
この、「地形生成ツールの成果地図」ボタンを押して、地図編集画面に移ります。

編集画面には「メタデータ」タブと「対応点設定」タブがありますが、このうち「対応点設定」タブを選びます。
すると、下の動画のような画面になりますが、左の絵地図の方でも、右の正確な地図の方でもいいので、マウスを右クリックします。
![マッピング手順](https://t.tilemap.jp/maplat/mapping_procedure.gif)
すると、「マーカー追加」コンテクストメニューが出るので、そこでマーカー追加を選ぶと、その場所に番号がついた薄ピンク色のマーカーが追加されます。
続いて、もう一方の地図（絵地図から始めた場合は正確な地図、正確な地図から始めた場合は絵地図）に移って、同じように右クリック=>マーカー追加で、こちらにも同じ番号のマーカーが置かれ、マーカーの色は薄黄色になります。
これで、両方の地図に「対応点」が設定されたことになります。
マーカーはドラッグで動かせるので、対応位置を動かして微調整することもできます。
対応点を3点以上追加すると、地図の上に三角形が表示され、位置変換ができるようになります。

位置変換のテストは、どちらの地図でもいいので、地図面上で左クリックすると、黄色い菱形のマーカーが出て、変換結果がテストできます。
![変換テスト](https://t.tilemap.jp/maplat/convert_test.gif)

対応点を追加していくと、時に三角形が交差して、エラーが生じることがあります。
地図を正確に変換するには、このエラーは解消したほうがいいのですが、しかしそんなに正確に変換する必要がなければ、このエラーを無視する方法があります。
エディタの下の方の「エラーモード」と書かれている選択ボタンを、「厳格」から「自動」にしてみましょう。
すると、エラーが発生している時は自動的にルーズな変換モードに切り替えて、エラーを解消してくれます（その代わり、ルーズな変換なので変換の正確さは犠牲になります）。
本当のサービス用地図をマッピングするなら、エラーは解消したほうが良いでしょうが、今回の例はどうせデタラメな地図画像なので、ルーズモードでも全く問題ないでしょう。
![エラー解消](https://t.tilemap.jp/maplat/error_ignore.gif)
こうやってマッピングを完了すると、右上の「保存」ボタンでセーブできます。
下記がマッピングが完了した様子です。
<img width="1312" alt="スクリーンショット 2019-12-18 22.42.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/f6b19053-c4fb-9768-cb55-165198270f4b.png">
とりあえず、これをMaplat Coreで読み込む方法を明日以降触れますが、その前に、私の方でマッピングしたデータをクラウドにアップロードしておきます。

https://t.tilemap.jp/maplat/maplat_advent_2019_18day.zip

このzipファイルを展開すると、`maps`、`compiled`、`originals`、`tiles`の4つのフォルダが含まれています。
この4つのフォルダの中身を、`[OSのドキュメントフォルダ]/MaplatEditor`フォルダの下にある同名の4つのフォルダの中に移します。
その後、MaplatEditorを再起動すると、私がマッピングした内容を手元で共有できます。
ARMベースのEC2インスタンスを利用する

この記事は、[ニフティグループ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nifty) の18日目の記事です。
昨日は @fuku710 さんのハッカソンのハックためになりましたね！
私は今月 AWS re:Invent 2019 に参加してきたのですが、同イベント中にも Hackathons and Jams というハッカソンが開催されていたので、次の機会があれば、@fuku710 さんの記事を参考にしながら参加したいですね！

残念ながら、ハッカソンには参加できませんでしたが、たくさんのセッションやワークショップに参加したので、その中から ARM ベースのEC2インスタンスを利用するワークショップ [CMP306 - Getting started with Arm-based Amazon EC2 instances]
(https://www.portal.reinvent.awsevents.com/connect/sessionDetail.ww?SESSION_ID=95746) を紹介したいと思います。


## はじめに

AWS の ARM への取り組みは 2004年 [Amazon Lab126](https://amazon.jobs/en/teams/lab126/) (Kindle などを作っているチーム) から始まったそうです。その後、ネットワークのオフロードや Nitro システムの構築など、カスタムシリコンの開発に情熱的に取り組んできたようです。
今年は Graviton2 を採用した次世代の ARM インスタンス（M6g/R6g/C6g）も発表されました。

Graviton と比べると性能も7倍に上がったようですし、コストも20%程度は削減できるということで、是非一度使ってみたい！と思いワークショップに参加しました。

## ワークショップの内容

### 1. arm64 で Java を動かす

Amazon Corretto を使用したアプリを A1インスタンスで動作させます。

* インスタンスの作成（AMI は Amazon Linux 2 を選択し、アーキテクチャに 64-bit Arm を選ぶこと）
* SSH でログインし Amazon Corretto 8 を `amazon-linux-extras` でインストールします
* 同様に `amazon-linux-extras` で `tomcat8.5` もインストールし簡単のJSPを用意します
* セキュリティグループで 8080 を開けて結果が表示されれば成功です！簡単ですね！

### 2. x86 と arm64 インスタンス混在でコンテナを動かす

* ELB のバックエンドに x86 と arm64 インスタンスを作成する（t3.small を追加）
* `docker buildx` を実行して x86 と arm64 のコンテナを同時に作成する
* 

### 3.arm64 で CodeBuild を実行し BB を動かす


参考資料（※ワークショップで使ったURLなので1ヶ月程度で消えるかも）
https://arthurpt-public-ui.s3-eu-west-1.amazonaws.com/reInvent2019-cmp306-arm-instances/index.html
pytubeで Getting KeyError: 'length_seconds' が出る方へ

# 引用元
https://github.com/nficano/pytube/issues/497

こちらの内容を元に作成しております。

#変更内容
＿main＿.py のソースコード修正
length(self)
の戻り値修正

変更前
return self.player_config_args['length_seconds']

変更後
return self.player_config_args['player_response']['videoDetails']['lengthSeconds']

# 変更前
```__main__.py

    @property
    def length(self):
        """Get the video length in seconds.
        :rtype: str
        """
        return self.player_config_args['length_seconds']
```
# 変更後


```__main__.py

  @property
    def length(self):
        """Get the video length in seconds.
        :rtype: str
        """
        return self.player_config_args["player_response"]["videoDetails"]['lengthSeconds']
```
Vue初級者がPropsとv-Slotをどう使い分けるかを考えた話

#はじめに
**Vue.js**をある程度やり、**props**で子コンポーネントにデータの受け渡しをできるようになった…。
ところで**Slot**てあるけど、どういうシチュエーションで使っていくのだろうか、ってのを考えていきましょう。
ついでに**Props**とどう使い分けていくのかも。
#おさらい
まずは**Props**と**Slot**は何なのかのおさらいをしていきましょう。
###Propsとは
[Props - Vue.js](https://jp.vuejs.org/v2/guide/components.html#%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%B8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%8F%97%E3%81%91%E6%B8%A1%E3%81%97)

Vue.jsでコンポーネント間のデータの受け渡しをする上で最も基本的な機能ですね。
親側で**v-bind**や子側の**Props**名でデータを紐付けて、子側は**Props**内にプロパティで型とか状態を指定してって使い方。

```parent.vue
<div>
  <child title="Qiita!"></child>
  <child :title="Vue"></child>
<div>
//*省略
data() {
  return {
    Vue: "Vue.js!"
  };
},
```

```javascript:child.vue
props:{
  title:{
    type:String,
    required: true
  }
}
```

上の`title="Qiita!"`は文字列を受け渡し、下の`:title="Vue"`は`Vue`というインスタンス変数などをv-bindで受け渡ししています。

###Slotとは
[Slot - Vue.js](https://jp.vuejs.org/v2/guide/components-slots.html)

コンポーネントの開始タグと終了タグの間に、何かしらの要素があった時に、それを子側で`<slot></slot>`と置換する機能ですね。
子側に`<slot></slot>`がないと、親側でタグの間に要素があってもそれは表示されないので、表示させたい場合は子側に`<slot></slot>`を指定してあげる必要があります。

```parent.vue
<template>
  <child>
    Qiita!
  </child>
</template>
```

```child.vue
<template>
  <slot></slot>
</template>
```
``<child>``に囲まれた**Qiita!**の文字列が、子の``<slot></slot>``と置換され、**Qiita!**が表示されます。
なお、これは文字列だけではなく他のタグ要素に囲まれた物も置換されます。

```parent.vue
<template>
  <child>
    <h1>Vue.js!</h1>
    <span>YES!Vue!</span>
  </child>
</template>
```

```child.vue
<template>
  <slot></slot>
</template>
```
``<h1>``タグと``<span>``タグも、子の``<slot></slot>``と置換されます。
主に親コンポーネントの要素を子要素に差し込みたいってときに使うと思います。

#使い分けを考える
###値を渡すだけならProps
文字列なり数値なり、単にデータを受け渡すのなら**slot**でやるよりも**Props**でやるべきです。

###状態で中の要素が変わるならslot
**v-if**などで中の要素の構成が動的に変わる事があり、それを子側で挟み込んでやりたい。
という場合には**slot**を使ったほうが、子側に**props**を使い状態を渡してやるよりも依存関係が薄くなり、
子側のコンポーネントの再利用性が上がるので、このような場合は**slot**を使いましょう。

```parent.vue
<template>
  <child>
    <template v-if="flag">
      <h1>Vue.js!</h1>
      <span>YES!Vue!</span>
    </template>
    <template v-else>
      <p>Error!!!</p>
    </template>
  </child>
</template>
```

```child.vue
<template>
  <slot></slot>
</template>
```
**flag**の値が**true**の時は上の要素が、**false**の時は下の``Error``とかかれた要素が表示されます。
また、置換したい親側の要素を**Vueコンポーネント**にしても、それを子側の**slot**で置換することができます。

####AtomicDesignで使ってみよう

**AtomicDesign**を使ってコンポーネント設計を行っていた場合にでも、**Atom**や**Molecules**など、コンポーネントの粒度が細かい箇所でよく使う機能になります。
特に**Atom**レベルのコンポーネントは、それ以上機能として分けれない、親との疎結合性を保つ必要がある、
などの必要があるのと、なによりも**Atom**コンポーネントの中に他の要素を入れる事は**AtomicDesign**の考えから離れてしまいます。
なので、**AtomicDesign**でも要素の子に別の要素を入れたい…！という時には、**slot**を使って置換させる、などの手法が特に有効と思います。

#おわり
作成中のプロジェクトで**slot**を使う機会が出てきたので、今回は記事にしてみました。
**props**も**slot**もどちらも子に何かしらの値や要素を受け渡す便利な機能ですが、
どちらも使い方によってはアンチパターンとなるので、しっかりとコンポーネントの設計を考えていく必要がありますね。
新入社員に適当にNode.jsのアプリ入門教えたら意外とウケたのでメモ

# はじめに
細かいことは気にせずにNode.jsでwebアプリケーションを作る手順をまとめました。
新入社員の教育につかってみたら思ったより理解してくれて、開発の一歩目になってもらえたのでメモがてら置いておきます。
これから開発をする方がこの記事にたどり着いて少しでも開発への苦手意識などがなくなれば嬉しいです。

![スクリーンショット 2019-12-18 22.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143517/337074ec-2cc1-fedc-a373-3c847d16b761.png)


SlideShareはこちら👇
https://www.slideshare.net/SoheiUchino1/nodejs-beginner
railsでSQLログをapplicationログとは別に出力する

# railsでSQLログをapplicationログとは別に出力する

applicationログはinfoで出したいけど、別途SQLログも出したい時など

```config/application.rb:ruby
  ActiveRecord::Base.logger = Logger.new('log/sql.log')
  ActiveRecord::Base.logger.formatter = proc do |severity, timestamp, progname, msg|
    {
      timestamp: timestamp.iso8601,
      LOG_LEVEL: severity,
      message: msg
    }.to_json << "\n"
  end
```

# 動作環境

rails 6.0.2
ruby 2.6.3
ソケット通信

###ソケット通信
https://pc-karuma.net/windows-10-firewall-open-port/
https://memo.saitodev.com/home/python_network_programing/#id3

UDP
##送信側
```
from __future__ import print_function
import socket
import time
from contextlib import closing

def main():
  host = 'XXX.XXX.XXX.XXX' #受信側のipv4
  port = 4000
  count = 0
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  with closing(sock):
    while True:
      message = 'Hello world : {0}'.format(count).encode('utf-8')
      print(message)
      sock.sendto(message, (host, port))
      count += 1
      
  return

if __name__ == '__main__':
  main()
```

##受信側
```
from __future__ import print_function
import socket
from contextlib import closing

def main():
  host = 'XXX.XXX.XXX.XXX'  #受信側のipv4
  port = 4000
  bufsize = 4096

  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  with closing(sock):
    sock.bind((host, port))
    while True:
      print(sock.recv(bufsize))
  return

if __name__ == '__main__':
  main()
```

##変換re
```
b = "b'19929717,168780'"
import re
regex = re.compile('\d+')
match = regex.findall(b)
print(match) #['19929717', '168780']
int(match[0]), int(match[1]) # (19929717, 168780)
```
##動的更新
```
#!/usr/bin/env python
# -*- coding: utf8 -*-
import tkinter as tk
import random
def read_current_Temperature():
    return random.randint(1, 100)
def update():
    aktTemp.config(text=str(read_current_Temperature())+"°C")
    aktTemp.after(1000, update)
HEIGHT = 300
WIDTH = 500
root = tk.Tk()
canvas = tk.Canvas(root, height = HEIGHT, width = WIDTH)
canvas.pack()
aktTemp = tk.Label(root, text=str(read_current_Temperature())+"°C", fg="red") 
aktTemp.pack()
update()
root.mainloop()
```
NHK番組表APIの使い方

# はじめに

ちょっとマイナーなAPIを使ってみたい...ということで、NHKの番組表APIを利用した時のメモ書きをまとめてみました。
登録があれこれ面倒ではないかと心配したのですが、意外と簡単に登録→利用まで進めることができました。

# ユーザーの登録

1. [NHK番組表APIのページ](http://api-portal.nhk.or.jp/ja)にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/9e07af64-708d-7afa-1934-16047567074a.png)
2. ［ユーザー登録がお済でない方はこちら］をクリックして、ユーザー登録画面に入ります。
3. ［アカウントの作成］タブを選択して、以下の事項を記入して［アカウントの作成］をクリックします。
 * ユーザー名
 * メールアドレス：このアドレス宛に登録確認のメールが送信されます。
 * 利用規約に同意します：チェックを忘れずに...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/12167f6b-11bd-abb7-2e00-574bc64d39ee.png)
4. 上記のメールアドレスに5分程度で仮登録完了のメールが届きます。
 * 確認のメールが届くまで少しタイムラグがあるので、メールアドレスの指定を間違えたかと思ったほどです。
5. メールに記載されたURLに遷移して、パスワードを変更（設定）すれば登録完了となります。

# アプリの登録

以下の手順は、NHK番組表APIのページにログインしていることが前提となります。

1. NHK番組表APIのページにアクセスして、［登録済みアプリはこちら］をクリックします。
2. ［My Apps］タブを選択して、［新規アプリ登録］をクリックします。
3. 以下の事項を記入して、［Create App］をクリックしてアプリを登録します。
 * App Name：アプリ名を記入します。
 * アプリのURL：任意入力項目です。
 * プロダクト：デフォルト値の［NHK Program Guide API］しか選べません...

# APIキーの取得

以下の手順は、NHK番組表APIのページにログインしていることが前提となります。

1. NHK番組表APIのページにアクセスして、［登録済みアプリはこちら］をクリックします。
2. ［My Apps］タブを選択して、先程に登録したアプリ名をクリックします。
3. 遷移した先のページで、［キー］タブを選択するとAPIキーを取得できます。

# APIの利用例

* `curl`コマンドで「[現在提供している番組](http://api-portal.nhk.or.jp/doc_now-v1_con)」のJSONファイルを取得して、その結果を`jq`コマンドで解析して表示しています。
 * `curl`コマンドと`jq`コマンドについては、[こちらの記事](https://qiita.com/nkojima/items/e893ef1489c803e29be8)もご覧ください。
* JSON中の文字列はダブルクォートで囲まれているため、`sed`コマンドを使って不要なダブルクォートを除去しています。

```bash:nhk_api.sh
#!/bin/bash
​
json=$(curl -s http://api.nhk.or.jp/v2/pg/now/130/g1.json?key={あなたのAPIキー})
​
echo '[現在放送中の番組]'
echo 'チャンネル：'$(echo ${json} | jq '.nowonair_list.g1.present.service.name' | sed 's/\"//g')
echo '番組名：'$(echo ${json} | jq '.nowonair_list.g1.present.title' | sed 's/\"//g')
echo 'サブタイトル：'$(echo ${json} | jq '.nowonair_list.g1.present.subtitle' | sed 's/\"//g')
```

```text:出力結果
[現在放送中の番組]
チャンネル：ＮＨＫ総合１
番組名：ニュースウオッチ９▽かんぽ生命　不適切販売１万２８００件余　その実態は…
サブタイトル：▽通知表が年明けに？全国５３自治体でシステム障害▽ジャパンライフ債権者集会　首相に説明求める声明▽ガンダム・富野監督　若者へのメッセージ▽羽生・紀平　全日本へ
```

# 注意点

* 画面上では複数の「アプリ」を登録できそうな雰囲気ですが、「アプリ」は「APIキー」と不可分な存在となっています。
* そのため、「アプリ」を既に登録した状態で［新規アプリ登録］をクリックすると、以下のようにエラーとなってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/87958204-aac2-bc7a-c411-932dd8d96000.png)
ECS(Fargate)へssh接続してみた

# はじめに
この記事はコンテナ勉強用として試したことまとめたものです。
ECS（Fargate）にsshログインする要件があったので実施したものをまとめました。

# Fargateについて
* Fargateにssh接続はできない。
* sshdをインストールして接続する必要がある。

# テンプレート取得
* 以下リンクにsshd設定をしてdockerイメージ作成をしてくれるのでgit cloneする。
* https://github.com/sawanoboly/amazonlinux-sshd

```shell
git clone https://github.com/sawanoboly/amazonlinux-sshd
```

# イメージの作成
* 以下コマンドを実行してイメージを作成する。
* Dockerfileにsshdやawscliなどのインストール設定が書かれています。

```shell
docker build -t amazonlinux-sshd:latest .
```

# ECRにプッシュ
* ECRにログインする。

```shell
$(aws ecr get-login --no-include-email --region ap-northeast-1)
```

* タグ付けをする。

```shell
docker tag amazonlinux-sshd:latest 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/test-ecr-repo:latest
```

* プッシュする。

```shell
docker push 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/test-ecr-repo:latest
```

# ECSデプロイの実施
* サービスを設定する。
<img width="524" alt="ECSサービス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466400/b2321100-a799-0d86-7ccf-963797d1cc93.png">

* タスクを設定する。
<img width="523" alt="ECSタスク.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466400/7738aa6b-9a76-95ac-a851-50514b650b92.png">

# ssh接続する
* 以下のような形でログイン確認ができる。

```ssh
Last failed login: Wed Dec 18 12:44:50 UTC 2019 from kd111111111111.au-net.ne.jp on ssh:notty
There was 1 failed login attempt since the last successful login.
debug1: PAM: reinitializing credentials
debug1: permanently_set_uid: 0/0
Environment:
  USER=root
  LOGNAME=root
  HOME=/root
  PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/aws/bin
  MAIL=/var/mail/root
  SHELL=/bin/bash
  SSH_CLIENT=100.100.100.100 56702 22
  SSH_CONNECTION=100.100.100.100 56702 101.101.101.101 22
  SSH_TTY=/dev/pts/0
  TERM=xterm
  AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/1e23t01a-7a1e-3761-bc27-fa4b8473938373
  AWS_EXECUTION_ENV=AWS_ECS_FARGATE
  AWS_DEFAULT_REGION=ap-northeast-1
  AWS_REGION=ap-northeast-1
-bash-4.2#
```
* ロールにS3へのアクセス権限を付与すればS3からファイルをダウンロードすることもできる。
* 既存設定だとssh切断した際にコンテナが停止されてしまうので必要に応じて設定する必要あり。

# まとめ
* Fargateだとsshできないかと思っていたが、やろうと思えばできる。
* sshdをインストールする必要があるのに気付けなかった。

# 参考
* https://qiita.com/sawanoboly/items/2766c8b0760ad9f9be99
ssh接続する際に、yes/noを尋ねられないようにする(can't be established)

未知のホスト鍵の際に尋ねられる。

```
Are you sure you want to continue connecting (yes/no)?
```

自動化したいなどで聞かれたくない場合、オプションをつける(-oStrictHostKeyChecking=no)

```
ssh -l ユーザー名 -p ポート番号 -oStrictHostKeyChecking=no IPアドレス
パスワードを効かれたら入力する。
```

##参考にさせていただいたサイト
https://www.turbolinux.co.jp/products/server/11s/user_guide/sshconnect.html
https://www.softel.co.jp/blogs/tech/archives/1414
LeetCode: 374. Guess Number Higher or Lower

# 問題の要約
- 1 から n の範囲で、予め１つだけ選択された数字を当てる
- 用意されたAPI=guess(int n) に数値を指定すると、数値は n より大きい/小さいのヒント or 正解が返却される

## 問題
[問題へのリンク](https://leetcode.com/problems/guess-number-higher-or-lower/description/)

## 回答　その１　全探索

- まずはブルート・フォースを作成。
- 1～n を 総当たりで guess関数に問い合わせる。

```cpp
class Solution {
public:
    int guessNumber(int n) {
        int i=0;
        for(;i<n;i++){
            if(guess(i)==0) break;
        }
        return i;
    }
};
```
```math
時間計算量は O(N)
```
提出すると当然 Time Limit Exceeded。14/25 テストケースまでPassした所で拒否されました。


## 回答　その２　二分探索

- 次に「二分探索」で計算量を削減しました。
- 「二分探索」は英語で「バイナリーサーチ」

```cpp
class Solution {
public:
    int guessNumber(int n) {
        long int low=1, high=n, ans=1;
        while(low<=high){
            int mid=(int)((low+high)/2);
            int ans=guess(mid);
            if(ans==0) return mid;
            if(ans==1) low=mid+1;
            else high=mid-1;
        }
        return -1;
    }
};
```
````math
時間計算量は O(logN)
````
提出すると、Accepted。Runtime=0 ms、Memory=8.1 MB。Runtime=0msって 1ms以下ってことですかね。

※ low+high が int型の範囲を越えるので、long int型で計算してからint型にキャストしました。
　 int mid=low+(high-low)/2; の方が int型の範囲を超えず、良かったかもしれません。
エラーハンドリングについて考えてみた

# はじめに
今回は、外部APIからデータを取得して表示する際のエラーハンドリングについて考えてみます。

# 方法1
[ERROR HANDLING WITH ANGULAR`S ASYNC PIPE](https://sebastian-holstein.de/post/error-handling-angular-async-pipe/) でも紹介されている方法です。
エラーを通知する先としてSubjectを用意してそれをビューテンプレートで表示します。

## Service
テスト用のモックを作成します。（実際に外部APIと通信は行いません。）

```typescript
get(id: number): Observable<User> {
  return new Observable((subscriber) => {
    setTimeout(() => {
      if (!id) {
        subscriber.error('id is required');
        return
      }
      subscriber.next(new User(id, "hello"))
      subscriber.complete();
    }, 1000);
  })
}
```

## Component

```typescript
user$: Observable<User> | null = null;
error$ = new Subject<Error>();

get(id: number) {
    this.error$.next()
    this.user$ = this.userService.get(id).pipe(
      catchError(err => {
        this.error$.next(err);
        return throwError(err);
      })
    );
}
```

## View
asyncでuserオブジェクトを取得できない場合は、ローディング中もしくは、エラーが発生している可能性があります。
その場合は loadingOrErrorTemp を表示して、その中で、エラーが出ている場合とローディング中の場合を、`error$`の値を参照して判定します。

```typescript
<ng-container *ngIf="user$">
    <div *ngIf="user$ | async as user; else loadingOrErrorTemp">{{user | json}}</div>
</ng-container>
<ng-template #loadingOrErrorTemp>
    <div *ngIf="error$ | async as err; else loadingTemp">{{err}}</div>
    <ng-template #loadingTemp>loading</ng-template>
</ng-template>
```

# 方法2
次の方法は、Go言語のエラーハンドリングからヒントを得た方法です。
Goでは、以下のように、メソッドの戻り値として、エラーを受け取りハンドリングを行います。

```go
value, err := get(id)
if err != nil {
    log.Println(err)
    return
}
```

これをAngularのエラーハンドリングに適応すると以下のようになります。

## Object
userオブジェクトをラップして、エラーの値もサービスから返すようにします。

```typescript
export class UserResponse {
    user?: User;
    errorMsg?: string;
}
```

## Service
userResponseオブジェクトを返すサービスを作成します。

```typescript
getUserResponse(id: number): Observable<UserResponse> {
  return new Observable((subscriber) => {
    setTimeout(() => {
      const userResponse = new UserResponse();

      if (!id) {
        const errMsg = 'id is required';
        userResponse.errorMsg = errMsg
        subscriber.next(userResponse);
        subscriber.complete();
        return
      }

      userResponse.user = new User(id, "hello");
      subscriber.next(userResponse);
      subscriber.complete();
    }, 1000);
  })
}
```

## Component

```typescript
getUserResponse(id: number) :Observable<UserResponse>{
    this.userResponse$ = this.userService.getUserResponse(id);
}
```

## Template
前回の方法と異なり、asyncで値を取得できていない状態はローディングの時のみとなります。

```typescript
<ng-container *ngIf="userResponse$">
    <div *ngIf="userResponse$ | async as userResponse; else loadingTemp">
        <ng-container *ngIf="userResponse.errorMsg as err">{{err}}</ng-container>
        <ng-container *ngIf="userResponse.user as user">{{user?.id}}</ng-container>
    </div>
    <ng-template #loadingTemp>loading</ng-template>
</ng-container>
```

# まとめ
どちらの方法が良いかは好みかと思いますが、個人的には方法2の方が直感的でコードの見通しも良いのではと思いました。