OmniAICreator/Qiita-1.07M huggingface dataset:
[Rust/WinRT] クリップボード操作

Rust/WinRT でクリップボードを操作するコード例です. コードを実行した環境は以下の通りです.

* Windows 10 v1909 build 18363.836
* Rust 1.44.0 stable-x86_64-pc-windows-msvc

以下のコードのすべてで冒頭に `winrt::import` マクロによるモジュール生成および `Clipboard`, `DataPackage` の use が必要です (コード例からは省略します). なお `DataPackage` はコピー以外の操作では必要ないです.

```rust
winrt::import!(
    dependencies
        os
    types
        windows::application_model::data_transfer::*
);

use windows::application_model::data_transfer::{DataPackage, Clipboard};
```

# 基本編

## 文字列をコピー

```rust
fn main() -> winrt::Result<()> {
    let content = DataPackage::new()?;
    content.set_text("Rust🦀/WinRTによるクリップボード操作のテストです.\n改行も可能です.")?;
 
    Clipboard::set_content(content)?;
    Clipboard::flush()?;

    Ok(())
}
```

## クリップボードに保存されている文字列を取得

取得できる文字列は `winrt::HString` 型です. 理論上これで動くはずなんですが, なぜか async を `get()` する部分で止まって動きませんでした… 動作報告あるいはバグの指摘等あればぜひ教えてください.

```rust
fn main() -> winrt::Result<()> {
    let content = Clipboard::get_content()?;

    for format in content.available_formats()? {
        // 可能な出力フォーマットを表示
        println!("{}", format);
    }
    // "Text" にフォーマットできない場合エラーとなる (画像など)
    let text = content.get_text_async()?.get()?;
    println!("{}", text);

    Ok(())
}
```

## クリップボード履歴を取得

```rust
fn main() -> winrt::Result<()> {
    if !Clipboard::is_history_enabled()? {
        // クリップボード履歴機能が有効化されていない場合は以下の処理を実行せずに終了
        return Ok(());
    }

    let histories = Clipboard::get_history_items_async()?.get()?.items()?;

    for item in histories {
        // 中身の文字列 (HString 型) を取得 (async 関数だがここでブロック)
        let content = item.content()?.get_text_async()?.get()?;
        println!("{}", content);
    }

    Ok(())
}
```

# クリップボードのアイテムを削除

## 最新のアイテムを削除

```rust
fn main() -> winrt::Result<()> {
    Clipboard::clear()
}
```

## 履歴からアイテムを削除

```rust
fn main() -> winrt::Result<bool> {
    let histories = Clipboard::get_history_items_async()?.get()?.items()?;

    let item = histories.get_at(2)?;
    Clipboard::delete_item_from_history(item)
}
```

## 履歴を全削除

```rust
fn main() -> winrt::Result<bool> {
    Clipboard::clear_history()
}
```

# クリップボードを監視

コンパイルは通ったものの, 少しいじっても何も起こりませんでした. どうやって使うのでしょうか…

```rust
use windows::foundation::EventHandler;

fn main() -> winrt::Result<()> {
    Clipboard::content_changed(
        EventHandler::new(|_,_| {
            println!("Copy!");
            Ok(())
        })
    )?;
    Ok(())
}
```


# 参考文献

* [Clipboard Class (Windows.ApplicationModel.DataTransfer) - Windows UWP applications | Microsoft Docs](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.clipboard?view=winrt-19041)
* [how to use Clipboard.GetContent in winrt-rs #187](https://github.com/microsoft/winrt-rs/issues/187)
* [C++/WinRTの始め方](https://qiita.com/yottui/items/390bf7582fa1abb42766)
IE11対応は、多分core-jsだけじゃ無理そう

TypeScriptなり、JSXやSFCなりを使ってトランスパイルして、Webpackを使ってビルド、babel-loaderをかましていい感じに動いているのをChromeで確認して、本番にあげる。すると、聞こえてくる悲鳴は、**IEでは死んでいる**。
そう、僕たちはいつもIEをないがしろにして、Chromeを基準に物事を考てしまう。リッチなブラウザをたよりに、ちゃんと動いていると信じ込んでしまう。そして、原因はbabelのpluginが足りなかったり、core-jsを読み込んでいなかったりといった原因を探り出し、ようやく解決して本番に再pushする。そうすれば解決すると信じて...。

## core-jsを利用する、しかし...

> @babel/polyfill
> 🚨 As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions):
>
> import "core-js/stable";
> import "regenerator-runtime/runtime";

なるほど、`@babel/polyfill` は非推奨であり、イマドキのような設定をする必要があるようだ。上記を参考にして、ビルドを行ってみる。

しかし。

`SCRIPT5022: catch ステートメントでは適用されますが、throw ステートメントでは適用されません。` のエラー。
エラーが発生した部分を整形して、解析してみる。
**なるほど、わからん。**

```bundle.js
// ...
t.exports = {
        set: n, get: a, has: i, enforce: function (t) {
            return i(t) ? a(t) : n(t, {})
        }, getterFor: function (t) {
            return function (e) {
                var r;
                // 以下の行ではTry-Catchが行われていないため、IEではエラーとなる...??
                if (!s(e) || (r = a(e)).type !== t) throw TypeError("Incompatible receiver, " + t + " required");
                return r
            }
        }
    }
//...
```

ビルドした成果物が悪ければどうしようもないし、ではcore-jsのせいなのか、あるいはプラグインの不足なのかを探り、探る。しかし原因を探し当てることが難しい。3日ほど溶かしちゃうのではないか。3日ほど溶かすといえば、これを思い出した。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">すでに3日悩んだことがあるからだよ。 <a href="https://t.co/xBLF6oGJ4T">https://t.co/xBLF6oGJ4T</a></p>&mdash; えいや (@aya_eiya) <a href="https://twitter.com/aya_eiya/status/1269881996798357510?ref_src=twsrc%5Etfw">June 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## core-jsだけでは問題は解決しない

さて、結論から言えば、 `core-js` と `regenerator-runtime` を読み込むだけでは**解決しない場合**がある。ある程度はIEでもcore-jsを利用したビルドが功を奏することもあるが、そうでない場合もあることは教訓として覚えておく必要がある。ではどのように解決していけばよいか悩んでいたなかで、以下の記事にたどり着いた。

[最新版で学ぶwebpack 4入門 - Babel 7でES2020環境の構築(React, Vue, Three.js, jQueryのサンプル付き)](https://ics.media/entry/16028/#webpack-babel-esnext)

> ※最新版のBabelでは@babel/polyfillではなく、core-jsを利用する方法を推奨されています。しかし、2020年1月現在、core-jsを組み込む方法は注意する点が多くあります（特にIE11で利用可能にするのは難しい）。本記事では@babel/polyfillでの方法でしばらく継続して掲載します。

そう、`@babel/polyfill`は非推奨ではあるが、読み込んでしまえというものである。
さて、これで解決したのかといえば、残念ながら解決はしなかった。次は`SCRIPT438: オブジェクトは 'assign' プロパティまたはメソッドをサポートしていません。`に遭遇した。Object.assignが使えない、それはわかるが、、、もうつらい、、、もう面倒くさい...。

ではどうしたのか。

**polyfill.ioでよくないか？**

## 最終兵器、polyfill.io

以下のコードをHTMLに差し込むだけで解決した。

```index.html
<html>
<head>
  ...
  <script src="https://polyfill.io/v3/polyfill.min.js?features=Object.assign"></script>
</head>
...
```


## IEとの対決
上記のような、polyfill.ioを用いた方法が最善だとは思えない。しかしそういう**逃げ方**もできるということを知っておくべきだと思う。本来的な手順としては、

1. `core-js` + `regenerator-runtime` を用いる
2. 1が正常に動かない場合、非推奨となっている `@babel/polyfill` を導入して様子を見てみる
3. 2が正常に動かず、一般的なメソッドの定義が欠損しているだけであれば、polyfill.ioを利用して、うまいこと逃げる
4. 3でも動かない場合は、es5で書かれていないコードを見直し、適宜es5に変更していく

という戦略で望むのがよいかと思う。
IEを切り捨てられる未来はまだまだ遠い。
node_modulesをインストールして死にかけた話

## node_modulesをインストールして死にかけた話

React学習のため

```ruby:ターミナル
$ npm install
```

npmをインストールしてwebpackやreactをインストールしたいとコマンドを実行。

無事`node_modules`をインストール完了！これからパッケージのインストールしていくぞ！！

一旦Githubにコミットしておこう。

##### ところが。。

差分があまりにも大きすぎてGithubにコミットできないようになっていた。

エラー文を読解して理解した。

どうすればいいんだろう。初学者の私は必死で解決策を考えました。

##### あっ、そういえば`gitignore`なるものがあったな


```ruby:gitignore
node_modules
```

こちらを追加してgit commit

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575665/8dda78fe-be9b-a347-5f16-26bbc20f5c09.png)


これでコミットできました。これからnode_modulesインストールする人は気をつけてください。Gitが潰れます。
webpackのproductionモードで自動minyfyされなかった

webpack4のproductionモードのとき、
コードが自動でminifyされると思ってましたが、場合によってはそうでもないみたいです:rolling_eyes:

# はまったパターン
CSSをminifyするため`OptimizeCSSAssetsPlugin`を設定

```js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
  // メインとなるJavaScriptファイル（エントリーポイント）
  entry: ["./src/js/index.js"],
  output: {
    filename: "js/main.js",
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({filename: 'style/[name].css'}),
  ],
  optimization: {
    minimizer: [new OptimizeCSSAssetsPlugin({})],
  },
}
```

↓build
cssのminifyはされたけどjsのminifyがされない…

```js
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
:
:

```

# 原因
調べてみると、`optimization.minimizer`を設定すると既存の設定が全て上書きされるので、minifyの設定は自分でしなきゃいけないようです。

>If you decide to try another minification plugin, just make sure your new choice also drops dead code as described in the tree shaking guide and provide it as the optimization.minimizer.


[公式](https://webpack.js.org/guides/production/ "公式")


#解決

公式で紹介されてる`terser-webpack-plugin`を使用しました。

`$ npm install terser-webpack-plugin --save-dev`

```js
const TerserPlugin = require("terser-webpack-plugin");
:
optimization: {
 minimizer: [
   new TerserPlugin(),
   new OptimizeCSSAssetsPlugin() // CSS の minify を行う
 ]
},

```
↓build

```js
!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};..
```

無事minifyされました。

公式に思いっきり書いてたのに…
反省と共に投稿です:skull:


webpackがあればgulpとかタスクランナーいらないぜ！ってのをネットで良く聞くのですが、
書いてみて結構長くなって読み辛くなってしまったと感じます。

webpackとタスクランナー併用で使って、わかりやすいの欲しいなーと思ったので、次はそれ作ってみます:eyes:
ApolloGraphQLで特定のExceptionをハンドリングする

# 背景

graphQLは基本onFailureとなった場合、ApolloExceptionが返る
しかし、特定のExceptionを指定して何か別途処理をしたい場合どうするか

# 実装

例えば[SocketTimeoutException](https://docs.oracle.com/javase/jp/6/api/java/net/SocketTimeoutException.html)のみ何か処理を変えたい場合

```kotlin

fun mutateHoge() {
    val clinet = ApolloClient.builder()
              .serverUrl("適当なURL")
              .okHttpClient("適当なokHttpClient")
              .build()

    // queryでもok 中のmutationは適当です
    client.mutate(
        HogeHogeMutation.Builder().build()
    ).enqueue(
        override fun onResponse(response: Response<HogeHogeMutation.Data>) {
            // 成功時の処理
        }

        override fun onFailure(e: ApolloException) {
            if (e.cause is SocketTimeoutException) {
                // 特別な処理
            } else {
                // 通常の失敗処理
            }
        }             
    )
}
```

こんな感じで`onFailure`側に`e.cause`で判定することで特定が可能になります

参考になれば幸いです
SeaserのBeans.copyと存在しないプロパティ

# 主旨

業務で
`org.seasar.framework.beans.util.Beans#copy`
を使うことがたまにあります。

便利なのですが、頻繁には使わないので、使うたびに以下に２点が不安になります。

- コピー元にはあって、コピー先にないプロパティがあるとエラーになる？
- コピー元になくて、コピー先にあるプロパティがあるとエラーになる？

[Javadocもこんな感じ](http://s2container.seasar.org/2.4/s2-tiger/ja/apidocs/org/seasar/framework/beans/util/Copy.html#execute())で上記のことについては書いていないので、テストしてみました。

# 結論

- いずれもエラーにはならない。
- コピー元になくてコピー先にあるプロパティは、影響を受けない（事前に代入された値のまま）。

# 実行したコード

```Java

import org.seasar.framework.beans.util.Beans;

public class BeansTest {

  /** 　コピー元のクラス */
  public static class Src {
    public String name;
    public String hobby; // Destにないプロパティ
  }

  /** コピー先のクラス */
  public static class Dest {
    public String name;
    public String address; // Srcにないプロパティ

    @Override
    public String toString() {
      return String.format("name=%s, address=%s", name, address);
    }
  }

  public static void main(String[] args) {
    Src src = new Src();
    src.name = "コズレ花子";
    src.hobby = "自転車";

    Dest dest = new Dest();
    dest.address = "東京都千代田区";

    // コピー実行
    Beans.copy(src, dest).execute();
    System.out.println(dest); // -> name=コズレ花子, address=東京都千代田区
  }
}
```

# おまけ

ちなみに、 `src` がnullだとNullPointerExceptionになります。
Create React App で作成したアプリを GitHub Pages で PWA として公開する

# プロジェクトを作成する

### 前提
この投稿では typescript を使用しています。
そうでない場合は読み替えてください

## プロジェクト作成
```
npx create-react-app [YOUR_APP] --typescript
cd [YOUR_APP]
```

## 動作を確認する
``` yarn start```

## モジュールをバラす
``` yarn eject```

このあたりで GitHub にリポジトリ作って commit & push しておく

## GitHub Pages で公開する
前提として、すでにリポジトリがある事
色々やり方ありますが、一番手っ取り早いと感じてる方法
### ```gh-pages``` ブランチを作成する
これは GitHub Pages で公開するブランチです。
このブランチ名は後の gh-pagesモジュールが使用します

![2020-06-09_17h54_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70983/0ab8a2c6-08bd-b74b-ea0d-49cdfe855920.png)

### gh-pagesモジュールを追加する
```yarn add gh-pages -d```
#### package.json にスクリプトを書き加える
ビルドして gh-pages ブランチに push して GitHub Pages で公開する一連のフロー

```package.json
  ...
  "scripts": {
    ...
    "preghpages": "yarn build",
    "ghpages": "gh-pages -d build"
    ...
  },
  ..
  "homepage": "./"
```

### GitHub Pages で公開する
```yarn run ghpages```

setting > GitHub Pages のセクションで URL を確認
![2020-06-09_18h10_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70983/d14133d8-c041-4c15-7491-e62c027fabba.png)

## manifest.js を変更する
``` src/manifest.js
　...
  "start_url": "[GitHub Pages のURL]",
  "url": "[GitHub Pages のURL]",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "screenshots": [],
  "orientation": "portrait",
  "lang":"ja"
}
```

## Serviceworker を有効にする
``` src/index.tsx
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
// serviceWorker.unregister();

serviceWorker.register()
```

### 再度公開・確認
```yarn run ghpages```

インストール可能なPWAならば、アドレスバーに + が付きます
![2020-06-09_18h27_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70983/07df3780-a6e4-3633-f74e-8480ecf7d75d.png)
AWS EC2 AmazonLinux2 Apache 設定ファイルの場所

# 目的

- Apacheの設定ファイルの場所分からず若干迷子になったため設定ファイルの場所を記載する。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| AWS EC2インスタンス | AmazonLinux2 | こちらの方法を用いてイメージからインスタンスを作成→[AWS EC2 をMacで使ってみよう!](https://qiita.com/miriwo/items/a1ab84c098008e43d042) |
| Apache バージョン | 2.4.43 | `$ sudo yum install httpd`にてパッケージをダウンロード |

# 設定ファイルの場所

- 下記に設定ファイルの場所を記載する。
     - `/etc/httpd/conf/httpd.conf`
     - 「# Further relax access to the default document root:」にドキュメントルートディレクトリの記載がある。
Nuxt.jsでFortAwesomeを導入する方法【nuxt-fontawesomeを使用】

Nuxt.js(Vue.js)でFortAwesomeを導入する方法についてまとめました。
CDNで取り込む方法もありますが、今回は【nuxt-fontawesome】を使用します。
[nuxt-fontawesome](https://www.npmjs.com/package/nuxt-fontawesome)はFortAwesomeを使用できるコンポーネントです。

## プロジェクトにnuxt-fontawesomeを導入する

まずはnuxt-fontawesomeをインストールします。

```terminal
npm i nuxt-fontawesome

#明示的にインストールする必要があるとエラーが出た場合は下記も実行
npm i --save @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons
```

yarnでインストールする場合は下記を実行します。

```
yarn add nuxt-fontawesome

#明示的にインストールする必要があるとエラーが出た場合は下記も実行
yarn add  @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome @fortawesome/free-solid-svg-icons
```
## nuxt.config.jsで設定
インストールが完了したらnuxt.config.jsファイルで読み込みます。

```js:nuxt.config.js

module.exports = {

  modules: [
    'nuxt-fontawesome'
  ],
  fontawesome: {
    imports: [
      {
        set: '@fortawesome/free-solid-svg-icons',
        icons: ['fas']
      }
    ]
  }
}

```
これで各ファイルでFortAwesomeのコンポーネントが使用できます。

## nuxt-fontawesomeを使用する
icon属性に使用したいアイコンを指定することで使用できます。

```vue
<template>
  <div>
    <font-awesome-icon icon="user" />
    <font-awesome-icon icon="times" />
    <font-awesome-icon icon="caret-down" />
  </div>
</template>
```
属性で指定できるので、v-bindを使えばクリックしてアイコンを変更するなども容易にできます。

## 番外編：CDNでFortAwesomeを読み込む場合
CDNでFortAwesomeを読み込む場合はheadタグで読み込みます。

```js:nuxt.config.js
export default {
  head: {
    link: [
      { rel: 'stylesheet', href: 'https://use.fontawesome.com/releases/v5.6.1/css/all.css' }
    ]
  },
}
```

##終わりに
今回はnuxt-fontawesomeを使用しNuxt.jsにFortAwesomeを導入しました。
コンポーネントなので使いやすくとても便利です。
クラウド・インフラ技術を学んでいくためにAWSを始めてみた（その２：MySQLによるRDSの構築）

#はじめに

　　インフラ・クラウド関連の勉強を兼ねて`AWS`を使ってみたのでまとめます。下記、`udemy`のレッスンを元に作りました。

　前回は、`VPC`設定についてでした。今回は`RDS`についてまとめます。

>AWS：ゼロから実践するAmazon Web Services。
https://www.udemy.com/course/aws-and-infra/


##RDSとは
　
 `RDS`(Relational Database Service)の略称で、`Amazon`のフルマネージド型データベースサービスのことです。そして、リレーショナル型であることが特徴となっています。

　フルマネージド型とは、運用保守管理を全て代行してもらえるということです。下記図にオンプレミス、EC2（AWSのサービス）とRDSについて簡単に表にまとめました。


　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/3759d204-3d89-3cea-79e7-ecd41c266520.png)

　基本的にフルマネージド型だと、自身で行うべきところはアプリの機能について対応すれば良いことが分かります。

　従来のオンプレミス型に比べて、クラウド型の便利なところを詰め合わせたサービスがフルマネージド型と理解しました。

　また、リレーショナル型とは行と列の２軸で表されるデータベースのことです。`Excel`のようなものでしょう。

　この`RDS`上にデータベースのサービス(`RDBMS`Relational DataBase Management System)を導入することで実際にデータベースを構築させることができます。


+ Amazon Aurora
+ Postgre SQL
+ MySQL
+ Maria DB
+ Oracle
+ SQL Server

以上のデータベースが`RDS`にて利用可能です。

 `RDS`の特徴としては下記です。

+ オンプレミスと比較して物理的な運用が容易
+ スケーラビリティが高い
+ データベース管理費用が節約可能
+ 運用負荷の軽減

　サービスのデータベース量に応じて自在にストレージ量やコンピューティング容量を変えることができます（≒スケーラビリティが高い）。また、その自在な変更によりデータベース管理費用を抑えられたり、サーバーの物理的な運用が楽であるメリットがあります。

　最後の運用負荷の軽減についてですが、自動的にバックアップ（スナップショット）やソフトウェアメンテナンスを行ってくれるメリットがあります。
　これにより、運用が楽であることがいえます。

##RDSの構築について

　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/41f60ee1-298c-e748-b045-7b436779ff8a.png)



　今回は、プライベートサブネットを二つに増やします。そして`RDS`にて二つのプライベートサブネットをDB化させます。

　その二つ目のプライベートサブネットを構築する際のポイントとして、別のアベイラビリティゾーンにプライベートサブネットを構築することが挙げられます。
　
　これは、冗長化が目的で一つのサブネットが障害が起きても別のサブネットで代替させることができます。

###RLogin上でMySQLをインストール

　`RLogin`上から`MySQL`をインストールさせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/fd2a9da2-73d2-7eda-7ccc-a94ad2d1fa8f.png)


次に、`MySQL`コマンドでデータベースの接続先（エンドポイント）を探します。`RDS`上の中から探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/3e10fc8c-55ec-79e3-040b-75d698bfe9a3.png)

そして、見つけたエンドポイントアドレスを含むコマンドでアクセスします。

` mysql -h 'エンドポイントアドレス' -u root -p`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/ecdd9312-6d93-2686-e5d0-5ecb6eee14e3.png)

これでつなげることができました！あとはお好きなデータベースを実際に構築していくフェーズに移ります。


#終わりに

　`RDS`について学ぶことができました。データベースの設置を行いました。そしてWebサーバーからデータベースにアクセスすることができました。
　基本的なWebサービスに必要なことができたと思います。
一般的な企業・家庭のファイアウォールで許可されるポート番号の一覧

# 1. 要約（3行まとめ）
- **環境によらず必要不可欠なサービスは、Web、DNS、NTPの3種類。**
- **企業の場合、上記に加え、Mail、VPN、VoIPなど、業務に必要なサービスを追加する。**
- **家庭の場合、OutboundはAll Allow、InboundはAll Denyとしてしまうことも多い。**

# 2. 概要
- 自宅等でファイアウォールの設定をする際に、「あれ？何許可しとけばいいんだっけ？」となることがあるので、一般的な企業や家庭で許可されることの多い（と思われる）ポート番号を整理してみました。
- 本記事の内容は経験則（主観）に基づくものなので、まあ普通こんな感じだよね、くらいのニュアンスで読んでいただけると幸いです。
- 使い方としては、後述の表をベースに、個別の要件を加味してカスタムする、という想定になります。

# 3. 凡例
　〇・・・許可
　－・・・拒否
　Outbound・・・From 内部、To 外部
　Inbound・・・From 外部、To 内部

# 4. 企業（エンタープライズネットワーク）
### 4-1. Outbound
| Port | Service | TCP | UDP |
|:-:|:-:|:-:|:-:|
| 25 | SMTP | 〇 | - |
| 53 | DNS | - | 〇 |
| 80 | HTTP | 〇 | - |
| 123 | NTP | - | 〇 |
| 443 | HTTPS | 〇 | - |

- Outboundは、Web Proxyサーバ、Mailサーバ、DNSサーバ、NTPサーバを立てて、クライアントからの通信を集約するのが一般的かと思います。
- Web Proxyサーバとは別に、Windows UpdateのためにWSUSサーバを立てる場合もありますが、ポート番号はWeb Proxyサーバと同じになります。
- Mailサーバについては、クラウドサービス（Office 365等）を利用している場合は、不要になります。
- DNSサーバ＋NTPサーバ＝Active Directoryサーバとすることも可能です。
- その他、最近だとビデオ会議（VoIPを含む）に必要なポート等を、追加で許可する必要があるかもしれません。
- ポート番号ではないですが、PINGの可否はお好みで。

### 4-2. Inobound
| Port | Service | TCP | UDP |
|:-:|:-:|:-:|:-:|
| 25 | SMTP | 〇 | - |
| 53 | DNS | - | 〇 |
| 80 | HTTP | 〇 | - |
| 443 | HTTPS | 〇 | - |

- Inboundは、「外部公開サーバ＝必要なポート」になりますので、非常に分かり易いと思います。
- WebサーバとMailサーバについては、クラウドサービスを利用している場合は、不要になります。
- DNSサーバについては、クラウドサービスやISPのサービスを利用している場合は、不要になります。
- その他、管理やVPN（IPsecを含む）に必要なポート等を、追加で許可する必要があるかもしれません。

# 5. 家庭（ホームネットワーク）
### 5-1. Outbound
| Port | Service | TCP| UDP |
|:-:|:-:|:-:|:-:|
| 53 | DNS | - | 〇 |
| 80 | HTTP | 〇 | - |
| 123 | NTP | - | 〇 |
| 443 | HTTPS | 〇 | - |

- 一般家庭では、Outboundの通信（とその戻り）は制限しないことが多いと思いますが、あえて制限するとすれば、最低限上記サービスは必要になります。
- DNSとNTPについては、ファイアウォール（≒ルータ）に機能があれば、集約するのもアリです。
- ポート番号ではないですが、PINGは許可しておいたほうが便利ですね。（そもそも制限できないことも多い）

### 5-2. Inbound
なし

- オンラインゲームをする、自宅にサーバを立てて外部に公開する、IoT機器を設置して外部から操作する、等がなければ特にInboundの通信を許可する必要はありません。
- むしろIPv6も含めてすべての着信パケットをDropしてしまったほうが安全です。

# 6. 雑記
- [WSUS サーバーとインターネットの間にファイアウォールを構成する](https://docs.microsoft.com/ja-jp/security-updates/windowsupdateservices/18128308#:~:text=%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF&text=Microsoft%20Update%20%E3%81%8B%E3%82%89%E6%9B%B4%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0,443%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
- [【Switch】オンラインゲームをおこなうとき、ルーターのどのポートを開放すればよいですか？](https://support.nintendo.co.jp/app/answers/detail/a_id/36082) → ガバガバやん。

# 7. 更新履歴
- 2020/06/09：初版投稿
- 2020/06/11：オンラインゲームに関する内容を追記
RailsでJsonカラムのvalidationしてないエンジニアいますかっていねーか、はは

Railsで[json-schema](https://github.com/ruby-json-schema/json-schema)を使ったJsonカラムのバリデーションについての記事です。

## まえがき
MySQLにJsonカラムが追加されて久しいですよね。

**Railsのデフォルトだと無さそうだけど、Jsonのバリデーションをちゃんとやりたい！**
でも、カスタムメソッドで愚直に書こうとすると…

### 愚直なカスタムメソッドの例

```ruby:some_model.rb
class SomeModel < ApplicationRecord
  validate :verify_timetable

  private

  def verify_timetable
    errors.add(:timetable, '配列ではありません') && return unless timetable.is_a?(Array)

    timetable.each do |el|
      errors.add(:timetable, '要素がHashではありません') && next unless el.is_a?(Hash)
      errors.add(:timetable, 'Hashのkeyが不正です') && next unless el.keys.sort == %w[end_at start_at]

      %w[start_at end_at].each do |key|
        DateTime.parse(el[key])
      rescue ArgumentError
        errors.add(:timetable, "#{key}の値が不正です")
      end
    end
  end
end
```
- かなりの分量になる…
- 「keyの過不足を許すか？」等の細かいチューニングの管理が難しい…

そんなお客様も多いのではないでしょうか？
逆に思ってないお客様は、アプリケーション側のバリデーションちゃんとやってますか？

今回は[json-schema](https://github.com/ruby-json-schema/json-schema)を使って、私がちょっと考えた中では一番クールなJsonバリデーション方法をご紹介します。

## どんな感じになるか

```ruby:some_model.rb
class SomeModel < ApplicationRecord
  TIMETABLE_SCHEMA = {
    type: 'array',
    items: {
      type: 'object',
      properties: {
        start_at: { type: 'string', format: :datetime },
        end_at: { type: 'string', format: :datetime },
      },
    },
  }.freeze
  validates :timetable, json: { schema: TIMETABLE_SCHEMA }
end
```

かなり直感的ですよね。
schemaを置く場所はお好きに。
自分はバリデーションはバリデーションでまとめたいので、validatesの直前に定義しています。

## 使い方

### gemのインストール

```ruby:Gemfile
gem 'json-schema'
```

### カスタムバリデータの定義
`validates :hoge, json: { schema: fuga }`で呼べるようにするための設定です。
自分は`app/validators`に置いています。

```ruby:app/validators/json_validator.rb
class JsonValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    JSON::Validator.validate!(options[:schema], value, strict: true)
  rescue JSON::Schema::ValidationError => e
    record.errors[attribute] << (options[:message] || e.message)
  end
end
```

この時点で、通常のJson Schemaに則ったvalidation（正規表現によるパターンマッチングやminLength,maxLengthの定義など）は可能です。
Json Schemaの仕様をググりつつ、[GemのReadme](https://github.com/ruby-json-schema/json-schema)を読んで色々試してみて下さい。
（例えば、`strict: true`はrequiredの内容を無視して、keyの過不足を許さない設定です）
Rubyのハッシュで書けるので気が楽ですよね。

### DateTime用バリデータの追加
Jsonの型定義にはdate型がありません。
でも、とりあえず日時情報をJsonにぶち込みたいケースって発生しますよね。
ここでは、この[issue](https://github.com/ruby-json-schema/json-schema/issues/427)を参考に、JSON::ValidatorにDateTime用バリデータを追加しています。

```ruby:config/initializers/json_validator.rb
datetime = -> value {
  begin
    DateTime.parse(value)
  rescue ArgumentError
    raise JSON::Schema::CustomFormatError.new('not datetime format')
  end
}
JSON::Validator.register_format_validator(:datetime, datetime)
```
「このカスタムフォーマットが欲しい！」等あれば、ここに追記していけば良いわけですね。

## 締め
いかがでしたか？
これで属人的なバリデーション記述から開放されそうですよね。
今までJsonのバリデーションをおざなりにしてきたエンジニアも、これを機にアプリケーション側のバリデーションを充実させて、健康的なRails生活を送りましょう！
Gitでcommitするbranchを間違えたときの対処まとめ

コードを書いていてよくやらかしがちなのが、branch切り替えわすれたままcommitしてしまうケース。  

特に`master` で直接書いてしまって「やっべやらかした」はおそらく結構な人たちが経験することと思われる。

本エントリではその修正法をおおまかに２つに分けて紹介する。

ただし、pushしてしまった場合はもう無かったことにはできない場合が多い(CIをやらせている場合はまず不可能)ので、大人しくRevertするかReposのメンテナに相談すること。

# commitが1つだけの場合

cherry-pickすると結構面倒なので、commitがまだ1つで済んでいる場合はSoftResetしてからcheckoutするのが一番簡単かつ速い。と思う。

ちなみにSoftResetとはファイルの変更を保持したままcommit直前の状態に戻すことを指す。

```bash
# HEADの1つ前の状態に変更を保持したまま戻す
$ git reset --soft HEAD\^

# 正しいbranchにcheckout
$ git checkout hogefuga#846

# 同じ内容でcommit
$ git commit -m 'hogefuga'
```

# commitが複数の場合

この場合は再度commitし直すのが非常に手間なので、cherry-pickで正しいbranchにcommitを持ってくるのが一番最適。でも多少面倒である。

そしてcherry-pick時におけるハッシュの指定について気をつけないといけないところがある。

![Screen Shot 2020-06-09 at 17.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320738/83c8854f-1d09-702c-e21e-f17a2dc3423a.png)


例えば上のスクリーンショットのピンクの範囲を正しいbranchに持ってきたい時だが、始点として指定するハッシュは**コピーする1つ前**を指定しないといけない。(終点は範囲中の最後でOK)

スクショの例で言えば`439c2cd..f30759b`で指定すれば良い。  
これをしくじるとconflictが起きるが、慌てずにスタート地点にHardResetしてやり直せばOK。

```bash
# `git log --oneline` などを使ってcommitのハッシュを調べる
$ git log --oneline

# 今回は間違ってcommitしたbranchを `master`
# 作業する前の位置を `origin/master` と仮定し、まずは作業前のポジションにcheckoutする
$ git checkout origin/master

# commitするはずだったbranchを作る
$ git checkout -b hogefuga#846

# 調べた始点と終点のcommitハッシュでcherry-pickする
$ git cherry-pick START_POINT..END_POINT

# 正常にコピーできたら間違ってcommitしたものを消す
$ git checkout master
$ git reset --hard origin/master
```
# まとめ
1つだけならまだいいが、複数に渡ると非常に面倒なのでcommitする前にbranchは確認したほうがいいです。
記載内容が間違っていたらコメントで指摘してもらえるとうれしいです。
Ruby と Python で解く AtCoder Tenka1 Programmer Contest C 累積和

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[Tenka1 Programmer Contest C - Stones](https://atcoder.jp/contests/tenka1-2019-beginner/tasks/tenka1_2019_c)*
<font color="green">Difficulty: 946</font>

今回のテーマ、累積和

問題より最終的な石の並びは、すべてが白`........`、全てが黒`########`、もしくは左白右黒`.....###`のいずれかに変更します。
少々厄介なのは`.#....#.#.`の様なパターンで、左の`.#.`は`...`に、右の`#.#.`は`####`に変更するのが最小値となります。
そこで、左から右に`.`及び`#`の累積和を取り、その位置での変更個数を調べて最小値を求めます。
# Ruby
```ruby.rb
n = gets.to_i
s = gets.chomp.bytes
dot = '.'.ord
a = Array.new(n){Array.new(2, 0)}
if s[0] == dot
  a[0][0] = 1
else
  a[0][1] = 1
end
1.upto(n - 1) do |i|
  if s[i] == dot
    a[i][0] = a[i - 1][0] + 1
    a[i][1] = a[i - 1][1]
  else
    a[i][0] = a[i - 1][0]
    a[i][1] = a[i - 1][1] + 1
  end
end
min = [a[-1][0], a[-1][1]].min
n.times do |i|
  min = a[-1][0] - a[i][0] + a[i][1] if min > a[-1][0] - a[i][0] + a[i][1]
end
puts min
```
```rui.rb
1.upto(n - 1) do |i|
  if s[i] == dot
    a[i][0] = a[i - 1][0] + 1
    a[i][1] = a[i - 1][1]
  else
    a[i][0] = a[i - 1][0]
    a[i][1] = a[i - 1][1] + 1
  end
end
```
変則的ですが、累積和を取っています。

```bw.rb
min = [a[-1][0], a[-1][1]].min
```
まずは、全部白にした場合と全部黒にした場合の個数を調べます。

```tugi.rb
  min = a[-1][0] - a[i][0] + a[i][1] if min > a[-1][0] - a[i][0] + a[i][1]
```
次に、それぞれの位置で左白右黒に変更した場合の個数を調べます。

```ord.rb
dot = '.'.ord

  if s[i] == dot
```
char値で比較した方が、若干速くなる様です。
# Python
```python.py
from sys import stdin

def main():
    input = stdin.readline

    n = int(input())
    s = input()
    a = [[0, 0] for _ in range(n)]
    if s[0] == '.':
        a[0][0] = 1
    else:
        a[0][1] = 1
    for i in range(1, n):
        if s[i] == '.':
            a[i][0] = a[i - 1][0] + 1
            a[i][1] = a[i - 1][1]
        else:
            a[i][0] = a[i - 1][0]
            a[i][1] = a[i - 1][1] + 1
    min = a[-1][0] if a[-1][0] < a[-1][1] else a[-1][1]
    for i in range(n):
        if min > a[-1][0] - a[i][0] + a[i][1]:
            min = a[-1][0] - a[i][0] + a[i][1]
    print(min)
main()
```

||Ruby|Python|
|:--:|:--:|:--:|
|コード長 (Byte)|457|631|
|実行時間 (ms)|175|186|
|メモリ (KB)|16208|30024|
# まとめ
+ Tenka1 C を解いた
+ Ruby に詳しくなった
+ Python に詳しくなった
Mac の docker 上の Ubuntu で nvvp (NVIDIA Visual Profiler) を GUI として起動する

あまり詳しくないのですが、 最新の MacOS (Catalina, 10.15.5) では cuda toolkit のサポートがされていないようで、 nvvp のインストールができないようです。
そこで、docker 上の Ubuntu で nvvp を起動し、その GUI をホストに飛ばして表示することを試みます。

# ホスト側 (MacOS 側) の準備

https://qiita.com/ryoya-s/items/ee1daf9cab18c100c990
この記事に従い、 `socat` および `xquartz` を導入します。
(コメントにもある通り、 `socat` を起動する際に指定する DISPLAY 環境変数がインストール直後だとセットされておらず、 Mac の再起動が必要でした。)

# Docker image/container の準備

以下の Dockerfile を build します。

```dockerfile
FROM ubuntu:18.04

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update \
  && apt-get -y install wget ubuntu-desktop

# https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal
# に従い、cuda toolkit の install を試みる
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin \
  && mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 \
  && wget http://developer.download.nvidia.com/compute/cuda/11.0.1/local_installers/cuda-repo-ubuntu1804-11-0-local_11.0.1-450.36.06-1_amd64.deb \
  && dpkg -i cuda-repo-ubuntu1804-11-0-local_11.0.1-450.36.06-1_amd64.deb \
  && apt-key add /var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub \
  && apt-get update \
  && apt-get -y install cuda
# nvvp にパスを通しておく
ENV PATH /usr/local/cuda-11.0/bin:$PATH

# Java8 が必要そうなので install
RUN apt-get install openjdk-8-jre

# nvvp に java8 を使ってもらえるようにしとく
RUN echo "-vm" >> /usr/local/cuda-11.0/libnvvp/nvvp.ini \
  && echo "/usr/lib/jvm/java-8-openjdk-amd64/bin/java" >> /usr/local/cuda-11.0/libnvvp/nvvp.ini
```

これを適当な名前、例えば `nvvp.Dockerfile` などとして保存し、

```bash
docker build -t nvvp -f nvvp.Dockerfile .
```

でビルド。

その後、 `socat` と `xquartz` を起動します：

```bash
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
```

```bash
open -a XQuartz
```

# Docker container の起動

`ifconfig en0 | grep inet | awk '$1=="inet" {print $2}'` でホストの IP アドレスを調べて、

```bash
# xxx.xxx.xxx.xxx は調べたアドレス
# /host/dir は、採取したプロファイルを配置しているディレクトリ (docker 起動後に docker cp とかで送っても OK)
docker run -it -e DISPLAY="xxx.xxx.xxx.xxx:0" -v /host/dir:/mnt nvvp
```

として起動する。
起動した docker container 上で

```bash
# (hoge.nvvp を採取したプロファイルとして)
nvvp /mnt/hoge.nvvp
```

とすると、XQuartz 経由で nvvp を触ることができるはず。 (`docker run` のオプションとして `nvvp` を指定して直接起動もできるかもしれないですが、試してないです)

最初に起動したときだけ workspace はどうしますか？とか聞かれますが、適当に設定して、「二度と表示しない」で大丈夫です。

無事、採取したプロファイルの読み込みに成功したら、Visual Profiler が立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62450/f49ff60a-6ecf-0284-b45b-0fa7134d0067.png)
高位合成言語Polyphony (windowsでiverilog その17）

#概要

windowsでiverilogやってみた。
polyphony、やってみた。
Lチカ、書いてみた。
テストベンチを書いてみた。

#サンプルコード


```
from polyphony import testbench, module, is_worker_running
from polyphony.io import Port
from polyphony.typing import bit

@module
class ltika:
	def __init__(self):
		self.led2 = Port(bit, 'out')
		#self.interval = 10
		self.append_worker(self.worker)
	def worker(self):
		led:bit = 1
		while is_worker_running():
			self.led2(led)
			led = ~led

m = ltika()

```

#テストベンチ


```
module test();
	reg clk;
	reg rst;
	wire led2;
	ltika_m m(.clk(clk), .rst(rst), .led2(led2));
	initial
	begin
		$monitor("%d %d %d", clk, rst, led2);
		rst = 1;
		#5
			rst = 0;
		#5
			rst = 1;
		#100
			$finish;
	end
	always
	begin
		#5
			clk = 1;
		#5
			clk = 0;
	end
endmodule
```

#実行結果


```


x 1 0
1 0 0
0 1 0
1 1 0
0 1 0
1 1 1
0 1 1
1 1 0
0 1 0
1 1 1
0 1 1
1 1 0
0 1 0
1 1 1
0 1 1
1 1 0
0 1 0
1 1 1
0 1 1
1 1 0
0 1 0
1 1 1
0 1 1

```

以上。
Cloud Functions(Python) で Cloud StorageにアップロードしたファイルをExcelで文字化けしないよう変換する

# 背景
BigQueryのクエリ結果をGCSに吐き出したものを社内に展開してエクセルで閲覧してほしい状況。
BigQuery -> GCS はutf8で結果を吐き出すので、エクセルで開くと日本語が文字化けしてしまう。
そこで、バケットにファイルを入れたら勝手にbom付きutf8に変換される cloud functionsを実装する。

# Cloud Function with Python
初めて触る場合はこのあたりを読んで触っておくと良さげ

[Python クイックスタート](https://cloud.google.com/functions/docs/quickstart-python?hl=ja)
[最初の関数: Python](https://cloud.google.com/functions/docs/first-python?hl=ja)

# Cloud Storageで発火する関数
Cloud Storageにオブジェクトが作成されたら発火する関数とかが作れる

[Cloud Storageのチュートリアル#オブジェクトのファイナライズ](https://cloud.google.com/functions/docs/tutorials/storage?hl=ja#object_finalize)

# サンプル

bucketに上がったファイルをbom付きutf8に変換し、prefixに `bom_` をつけてuploadする関数

```main.py
from google.cloud import storage


def convert_to_bom(data, context):
    bucket_name = data['bucket']
    file_path = data['name']
    prefix = 'bom_'

    file_path_arr = file_path.split('/')
    file_name = file_path_arr[-1]

    if file_name.startswith(prefix):
        return 'skipping of bom file.'

    dir_arr = file_path_arr[:-1]
    dir_path = '/'.join(dir_arr) + '/'
    local_file_path = '/tmp/' + file_name

    if(len(file_path_arr) == 1):
        new_file_path = prefix + file_path
    else:
        new_file_path = dir_path + prefix + file_name

    client = storage.Client()
    bucket = client.get_bucket(bucket_name)
    dl_blob = bucket.get_blob(file_path)
    up_blob = bucket.blob(new_file_path)

    with open(local_file_path, 'w', newline='', encoding='utf_8_sig', errors='ignore') as f:
        f.write(dl_blob.download_as_string().decode('utf8'))

    up_blob.upload_from_filename(local_file_path)

    return 'success'
```

```requirements.txt
-i https://pypi.org/simple
cachetools==4.1.0
certifi==2020.4.5.1
chardet==3.0.4
google-api-core==1.19.0
google-auth==1.16.1
google-cloud-core==1.3.0
google-cloud-storage==1.28.1
google-resumable-media==0.5.1
googleapis-common-protos==1.52.0
idna==2.9
protobuf==3.12.2
pyasn1-modules==0.2.8
pyasn1==0.4.8
pytz==2020.1
requests==2.23.0
rsa==4.0
six==1.15.0
urllib3==1.25.9
```

# デプロイ

```sh
gcloud functions deploy convert_to_bom --runtime python37 --trigger-resource ${YOUR_BUCKET} --trigger-event google.storage.object.finalize
```

# ファイル書き込み時の注意点

`/tmp` 以外のディレクトリには書き込みできないので気をつける。書き込もうとすると関数がcrashして静かに死ぬ。

> ファイル システムで書き込み可能な部分は /tmp ディレクトリだけです。このディレクトリは、関数インスタンスの一時ファイルの保存先として使用できます。

[Cloud Functions 実行環境#ファイルシステム](https://cloud.google.com/functions/docs/concepts/exec?hl=ja#file_system)

 

# 参考
[Python Client for Google Cloud Storage](Python Client for Google Cloud Storage)
[[GoogleCloudStorage] GCSのPythonAPIの使い方 [備忘]](https://qiita.com/Hyperion13fleet/items/594c15ac24f149ab73c9)
turbolinksを停止する方法

今回、Ajaxを手作業で導入した。デフォルトでgamに導入されているturbolinksは、Ajaxと同じような機能のため、競合してしまい、うまく作動しない可能性がある。そこで、turbolinksを停止させたい。

# 1. GemfileからTurbolinksを削除
Gemfileの中に、以下のような記述があるので、コメントアウトにする。

```
gem 'turbolinks', '~> 5'
```

# 2. bundle install
ターミナルで、`bundle install`をする。

# 3. application.html.haml から turbolinks の関連部分を削除する
```
< 省略 >
= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' 
= javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
< 省略 >
```
上記の記述の後半部分を、下記のように削除する

```
< 省略 >
= stylesheet_link_tag    'application', media: 'all'
= javascript_include_tag 'application'
< 省略 >
```

# 4. application.js から turbolinks の関連部分を削除する
```
< 省略 >
//= require jquery
//= require jquery_ujs
//= require turbolinks 　← この記述を削除
//= require_tree .
```

# 5. formを編集
`form_with`を使って作成したformがある場合、全てのformに`local: true`オプションをつける。これがないと、フォームがうまく動作しない。



## 参照
[Railsにおけるturbolinksの無効化の手順](https://kossy-web-engineer.hatenablog.com/entry/2018/11/29/093958)
[【Rails】turbolinksを無効化する](https://qiita.com/d0ne1s/items/5a4122d2972be3812986)
MQTTについて調べたのでまとめました

MQTTについて調べる機会があり、せっかくなのでまとめてみました。

MQTTとは、二者間の非同期通信をサポートするプロトコルであり、メッセージの送信側と受信側を空間という点でも、時間という点でも切り離すことができるプロトコルである。
そのために、信頼できないネットワーク環境内でスケーラブルな性質を発揮する。
パブリッシュ/サブスクライブ・モデルに従っており、ブローカーで仲介して、送信、受信どちらにも一対多の通信を確立することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/0397072b-9a75-1399-8ff7-00295da44e94.png)
MQTTのシーケンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/94e0de86-a4f5-825d-978f-8d9b6c8a7d30.png)


### MQTTの特徴
・固定ヘッダが最小2バイトと軽量プロトコルも簡易である
・Pub/Subモデルにより、一対多・多対多でメッセージのやり取りが可能
・階層型トピックとワイルドカードにより柔軟に通信相手を選定できる
・通信の切断をトリガーにしてメッセージ(will)を送信できる
・必要な到達可能性（QoS)を設定できる
・最後に送られたメッセージを受け取ることができる(Retain)
最後の切断中に送られたメッセージを後から受けとれる(pesistent Session)

という特徴があり、以上のことから

・クライアントが低い計算能力しか持たない場合でも実装できる
・通信の際の消費電力も少なくて済む（軽量なので）
・非同期でのメッセージのやり取りが可能
・サーバー側からのプッシュ通信が可能
・コネクションが切断されたことを検知できる

というのが利点があることがわかる
### HTTPとの比較
一般に使用されることが多いプロトコルHTTPと比較したとき
HTTP通信は、最初に3ウェイハンドシェイクを実行してコネクションを確立する必要がある。その後GET,POST等を使ってデータを送り、コネクションを閉じる。このためセンサーデータなど短いデータを送る場合はオーバーヘッドが目立ってしまう等の特徴があり、IoTでは使用する場面が限定されることが予想できる

下図はHTTPのシーケンスのイメージである
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/1bec5dc7-0491-a852-067b-77a3337ad178.png)
データの送信と受信が切り離されていないことや、通信に手間がかかることがわかる
これと比較してMQTT通信は
~~・3ウェイハンドシェイクをしないため通信開始までの時間が短い~~
(TCP/IP上に実装されていますので、3ウェイハンドシェイクを行っています)
・サーバー側からのプッシュ通信が可能
・コネクションが切断されたことを検知できる
等のメリットがある。
### Topicの階層
MQTTはTopicと呼ばれるキーを用いてメッセージングを行っており、Topicは「/」で区切られた階層構造になっている
つまりTopicはメッセージの送り先を示す文字列になっている。さらにTopicは＋と＃というワイルドーカードを使用することができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/16dd49f9-dbfe-6ad7-1206-7e8296f4ebc3.png)
＋でその階層のすべて、＃でその以下の階層のすべてを指定する
（例）foo/+/foobar

### QoSについて
Quality of Serviceの略でメッセージの到達可能性を明示している
メッセージごとの到達可能性を3種類のQoSから選択することができる

QoS1 : 最高1回、届くかは保証しない
QoS2 : 少なくとも1回、重複可能性がある
QoS3 : 正確に1回

QoS3が一番正確だがサーバーとクライアントどちらの処理も重くなり、負荷がかかる。処理が多くなるために遅くなるので状況に応じて使い分ける必要が出てくる

### セキュリティについて
クライアントの接続時にユーザー名とパスワードを指定することが多いが、
そのままで送信するとパスワードが平文で送られること、ペイロードの暗号化については仕様で定義していないことが多いのでTLSと組み合わせ使用することが多い

TLS(Transport Layer Security)
TLSとはTCP/IPを使った様々なサーバーとクライアントの通信で、セキュアなチャンネル（通信路）を使用できるようにする仕組みで以前はSSLと呼んでいた

### ライブラリ
ライブラリはweb上に情報がたくさんあるので使用するときに調べるとよいと思われる
phao-MQTTが有名である。

### 使用例
IoT,M2M,人工衛星、FacebookMessengerなどに使用されている
###まとめと感想
MQTTはヘッダーが軽量なこと、通信が不安定なところでもスケールすることができるのでIoTの通信に向いていると考えられる。だがセキュリティに関しては深く考える必要があり、特に何かを操作しようと考えている際にはしっかりとリスクを把握したうえで使用する必要があると考えられる。
　実験に使用する程度であれば実装は簡単なので実装する際はこちらのサイトも参考にしてみてください
http://blog.shinrinakamura.jp/dgh34280/2018/11/02/environment1/

### 参考情報
Web+DB PRESS vol88　2015年9月25日　初版第一刷発行　株式会社技術評論社

日経ITエンジニアスクール　IoT最高の指南書　2018年5月21日発行　日経BP社
 
[IBMチュートリアル](![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/1f312cd4-ee45-bd07-8a16-fab64059c4e3.png)
)
[さきぶろぐ](https://sakiot.com/what-is-qos-of-mqtt/)
Django の QuerySet が発行する SQL を確認する

query を使う。

```
>>> query_set = Site.objects.all()
>>> query_set.query
<django.db.models.sql.query.Query object at 0x7f87f31a8f10>
>>> str(query_set.query)
'SELECT "django_site"."id", "django_site"."domain", "django_site"."name" FROM "django_site" ORDER BY "django_site"."domain" ASC'
```

`django.db.models.sql.query.Query` は dunder method `__str__` が定義されているので、 `str()` を呼び出せばSQLが確認できる。
Python pickle の使い方サンプル

```python

import pickle

sample_dic = {'key1': 1, 'key2': 2, 'key3': 3}
sample_dic['key4'] = 4
f = open('sample.binaryfile','wb')
pickle.dump(sample_dic,f)
f.close


f = open('sample.binaryfile','rb')

new_dic = pickle.load(f)

print(new_dic)
print(new_dic['key4'])
Azureに関するサービス更新情報の監視をLogic Appsで簡単に実現する

パブリッククラウドの保有するサービスは変化が早く更新情報についてはアンテナを張り巡らせる必要があります。
私が利用しているMicrosoftのAzureに関しても以下のサイトで不定期にサービスの更新や新しい機能の追加に関する情報が発信されており、人力で更新情報を追い続けることは少しばかり骨が折れます。。。
https://azure.microsoft.com/ja-jp/updates/

しかし、このサイトには幸運なことにもRSSフィードが設けられており、これを利用することで更新情報の有無を確認出来そうな気がしていました。
そこで今回はUpdate情報のRSSフィードを監視する仕組みを作成することにしました。

#実現する構想
今回の仕組みを構築する方法としてプログラムでの実現も考えましたが、AzureのPaaSを用いて簡単に実現できないかと思い、今回はLogic Appsを試してみることにしました。
また、実際に通知を受ける方法も必要なので、Teamsのチャネルに投稿する形で構築します。

#構築手順
まず、Azure上でLogic Appsのリソースを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/45bdb3c9-bcab-24f4-18cc-8934958f73dc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/e94164bc-df25-24d7-1866-f992201fbf33.png)

次に構築したリソースに移動し、トリガーとアクションの詳細を設定します。
Logic Appsはコネクタを用いて視覚的にデータフローを構築できるので、プログラミングレスで実現することができます。
今回はテンプレートにないシナリオなので、「空のロジックアプリ」から作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/43c3b2a6-94a1-77ba-f506-a64c950813e5.png)

Logic Appsのデータフローを構成するコネクタの種類はサービスを開始する**トリガー**と、サービスの内容となる**アクション**の2種類あります。
構築手順として先にトリガーとなるコネクタを設定します。今回はRSSを検知するので検索バーから「RSS」と検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/0d986fd2-17c6-fd22-6709-cd1eb9adcaf0.png)

今回のトリガーの設定については以下のように入力しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/8b5b10b4-1de8-00a5-b70f-a53951582439.png)
設定値としては、「RSSフィードのURL」が今回RSSフィードを取得するURL、「項目を確認する頻度」はなるべくすぐに検知できるように1時間に一度更新の有無を確認するような設定をしています。
また、タイムゾーンについてはどこまで起因しているか公開情報から確認出来ていないのですが、念のため、日本のタイムゾーンを設定しています。

トリガーが設定できたので、アクションとなるコネクタを追加していきます。
作成したトリガー用のコネクタの下部にある「新しいステップ」を選択し、コネクタを追加していきます。
今回のアクションはTeamsへ投稿することを検討していますので、検索バーから「Teams」と検索し、「Microsoft Teams」を見つけます。
アクションの内容としては対象のチャネルへの投稿を実施します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/b6775960-11c4-0db6-7395-5587c28e01c7.png)
Teamsのコネクタを利用する場合にはOffice365を利用できるユーザーで認証する必要があります。
アクションの投稿内容について、チームとチャネルについては任意のものなので、説明を省きます。
投稿するメッセージの内容についてですが、RSSフィードから取得した内容を投稿に反映させます。
メッセージの記入の際にポップアップで「動的コンテンツ」が表示されますので、そこから前のコネクタで取得したデータを利用します。以下の画像のように項目が表示されない場合は、「もっと見る」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/caa30884-04cd-6fb7-b6dc-a599c2149b71.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/8e8cb721-d7db-02b8-735d-5dbf2b882f88.png)

今回の投稿内容としては「フィードの公開日付」、「フィードタイトル」、「フィードリンク」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482426/eab1b5f6-2ca6-f2e8-13b9-1bf51e6c4b32.png)

以上でRSSフィードの更新を検知して内容をTeamsへ投稿する設定は完了です。最後に保存を選択し、Logic Appsのデザイナー画面を終了します。
あとはAzureに関するアップデート情報が案内されるのを待つだけです。

#まとめ
プログラミングの知識等がほとんどない状態でも視覚的に設定ができ、かつ少ないアクションで実現できるので、衝撃的です。。。

やってみて思ったことは、Azureの最新情報については公開時は、ほとんどが英語で案内されるので、タイトルや概要については日本語にする方法を探ります。
また、Logic AppsのMicrosoft社公式の情報がかなりすくないので、コネクタの詳細などは実際に動かしてみないといけない部分もあり、ちょっと不便でした。。。

今回作成したものについてはちょこちょこアップデートしていくので、その際の備忘録として記事にしていく予定です。
【Nuxt.js】Nuxt文法編：v-show

# 前置き

初心者向けの文法編です✨👏
今回はv-show

**❓どんな時に使うか**
要素の表示/非表示に使います！
あれ、なんか見たことあるような…🤔
そうです！！！
v-ifとほとんど一緒です！
なので主にv-ifとの違いを解説します🙋‍♀️
v-ifの解説記事はこちら
https://note.com/aliz/n/n76280a0e3a02

# v-show

前置きに書いた通り、
v-ifと使い方はほとんど同じです！
式が真の時に表示されます👀

```index.vue
<template>
 <div class="page">
   // h1タグの表示をokの真偽値で切り替え
   <h1 v-show="ok">Hello!</h1>
 </div>
</template>

<script>
export default {
 data () {
   return {
     ok: true,
   }
 },
}
</script>
```

【表示】
**🌷true🌷**
h1タグが表示されます。
<img width="875" alt="スクリーンショット 2020-06-05 14.38.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/08c14fe6-0bac-02ff-dcef-c6dfd2ca6de4.png">
**🌷false🌷**
h1タグがdisplay: none;
非表示になります。
<img width="883" alt="スクリーンショット 2020-06-05 14.26.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/9c38afad-801d-5dc0-227e-4b2079f0595e.png">

# v-ifとの違い(表示)

検証を見れば分かります👀
**・v-show**
　ex) サイト内検索用モーダル
　└常に描写をしcssで切り替え
　　　＝頻繁に切り替える場合に⭕️
　└描写は1度きり
　　　＝非表示でもdataを保持する場合に⭕️
**・v-if**
　ex) 最初の訪問時に1回だけ出る広告modal 
　└条件式がtrueになるまで描写しない
　　　＝ほとんど切り替えない場合に⭕️
　└その都度描写される
　　　＝非表示でも
　　　　dataを保持しなくて良い場合に⭕️

【表示】

**🌷v-show🌷**
h1タグが描写されDOMには残っています。
display: none;で見えなくなっていますね👀
<img width="883" alt="スクリーンショット 2020-06-05 14.26.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/262e9961-9866-866a-b225-878bef1d23a8.png">

**🌷v-if🌷**
<! ---->
そもそも描写されません！
![v-if.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/3be857f7-cc02-9a1f-0cab-a38edb1a2cad.png)

# v-ifとの違い(コード)

**・v-show**
　単体でのみ使用可能
　v-else-if, v-elseとセット❌
**・v-if**
　単体でも組み合わせでも使用可能
　v-else-if, v-elseとセット⭕️　

**【index.vue】**
v-showとv-elseを使ってみます。

```index.vue
<template>
 <div class="page">
   <h1 v-show="ok">
     Hello!
   </h1>
   <h1 v-else>
     falseの場合に表示させたい
   </h1>
 </div>
</template>

<script>
export default {
 data () {
   return {
     ok :false,
   }
 },
}
</script>
```

**【表示】**
v-elseを使っていますが
対応するv-ifがないですよ
とエラーが出ます👀
<img width="626" alt="スクリーンショット 2020-06-05 17.48.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/83a9efb6-6880-0e81-ab90-6ce2a54fde3d.png">

**【index.vue】**
v-ifに変更してみましょう！

```index.vue
<template>
 <div class="page">
   <h1 v-if="ok">
     Hello!
   </h1>
   <h1 v-else>
     else
   </h1>
 </div>
</template>

<script>
export default {
 data () {
   return {
     ok :false,
   }
 },
}
</script>
```

**【表示】**
きちんとelseの方が表示されますね🌟
<img width="801" alt="スクリーンショット 2020-06-05 17.52.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469755/b4b06d08-7449-09f5-1e5a-f0c9184a5c18.png">

# 次回予告

【Nuxt.js】firebase基礎編(Auth版)：
facebookログインをできるようにしよう
6/12(金)公開です🌟

**記事が公開したときにわかる様、
フォローをお願いします😀💕**
https://twitter.com/aLizlab
Chromium Edge おすすめ機能

#Chromium Edge とは
Microsoft のブラウザと言えば IE（Internet Explorer）が有名ですが、今回は Chromium Edge のおすすめ機能を紹介したいと思います。
[ダウンロードはこちら](https://support.microsoft.com/ja-jp/help/4501095/download-the-new-microsoft-edge-based-on-chromium)

##設定編
設定画面へのアクセスは画像を参考にしてください。
![コメント 2020-06-09 170925.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539633/45988d0e-6bcd-4a4e-a2eb-43efc01c25fa.jpeg)

- 設定 > 起動時 > 中断したところから続行する
    - 前回開いていたタブを復帰できるので便利
- 設定 > ダウンロード 
    - ダウンロード先を違うところにしたい人向け
- 設定 > プライバシーとサービス > アドレスバー（一番下）
    - アドレスバーの検索エンジン変更
    - 個人的には 新しいタブを開いたときに bing を使えるようにして、アドレスバーでは google とかにしてます。

##ショートカットキー編
- Ctrl + Shift + B → お気に入りバーの表示の有無
- Ctrl + T → 新しいタブ
- Ctrl + Shift + T → 消したタブの復帰
- Ctrl + P → 印刷
    - プリンターの種類を変えると pdf に出力とかもここからできます
- Ctrl + Tab → タブの移動、Shift をつけると逆回り
- Ctrl + shift + K → タブの複製
- Ctrl + W → タブを閉じる
- Ctrl + N → 新しいウィンドウを開く
- Alt + 左右矢印 → 進む / 戻る

##マウス操作編
- マウスのホイールでリンクをクリック → 別タブで開く
- マウスのホイールでタブをクリック → タブを閉じる（x を押さなくても閉じれます）

##拡張機能編
Chrome で使うことができた拡張機能が使えるので、ここは他の記事などを参考にしてください。
初心者　Spring bootでMySQL接続

# Spring bootでMySQL接続


Spring bootでMySQL接続をしてみようと思いいろんなサイトをみて実行していたら、
最初につまずいた箇所です。

###①application.propertiesにソースを追加する。

application.propertiesに以下のように設定します

```
spring.datasource.url=jdbc:mysql://127.0.0.1:33060/mikandb?serverTimezone=JST
spring.datasource.username=docker
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
```
ああこれコピーして使えばいいんだなと思ってたら
自分のに変え忘れていました・・・


###②依存性の指定
build.gradleに記載

```
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.session:spring-session-core'
    implementation'org.springframework.boot:spring-boot-starter-data-jdbc'
    implementation'org.springframework.boot:spring-boot-starter-web'
    implementation'org.springframework.boot:spring-boot-starter-web-services'
    implementation'org.springframework.boot:spring-boot-starter-test'
    runtimeOnly 'mysql:mysql-connector-java'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
```


###③ist内でsql文を指定
DbController.javaに記載する

```
package com.example.mikan;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;
import java.util.Map;


<!--だいたい上は自分のがあるのでここから記載-->
@RestController
public class HelloController {
    @Autowired
    JdbcTemplate jdbcTemplate;

    @RequestMapping(path = "/friends", method = RequestMethod.GET)
    public String index() {
        List<Map<String, Object>> list;
        list = jdbcTemplate.queryForList("select * from friends");
        System.out.println("動きました");
        return list.toString();
    }

    @RequestMapping(path = "/friends/{id}", method = RequestMethod.GET)
    public String read(@PathVariable String id) {
        List<Map<String, Object>> list;
        list = jdbcTemplate.queryForList("select * from friends where id = ?", id);
        return list.toString();
    }
}
```
Google colabで実行が終わったら音で通知させたい時．

# 結論
```python
def beep():
  from google.colab import output
  output.eval_js('new Audio(\
"https://upload.wikimedia.org/wikipedia/commons/0/05/Beep-09.ogg")\
.play()') 
beep()
```
これで`beep()`が実行されれば音が鳴ります．

もっといろんな音を出したいときは，`"https://...`の引数を変えればいいんだろうけど，見つからなかった．（教えてください).

###参考
https://stackoverflow.com/questions/54293537/is-there-a-way-to-make-colab-give-an-audio-notification-when-cell-has-finished-r
turbolinksとは

# turbolinksとは
- TurbolinksはRails4.0からデフォルトで導入されたgem

- ajaxとhistoryAPI(popState, pushState)を利用して画面遷移

- js, cssの読み込みを初回時に行い次回以降の読み込み処理を省略することで高速化する。


# 主なTurbolinksの動作は2つ
####fetchReplacement
- `<a>`タグのリンクをクリックした時の遷移をajax化して画面遷移なしにページ遷移する。

- clickイベントの挙動を変えている

####fetchHistory
- 戻るボタンなどを押した時のイベントを書き換えている

- fetchReplacement時にpushStateでキャッシュしたページをpopStateで復元する。


# 参照
[Turbolinksを調べてみた](https://gist.github.com/saboyutaka/8727377#fetchreplacement)
MySQLのエラーログを確認できるディレクトリを作る

Mac環境：macOS Catalina 10.15.5

個人開発の環境構築でMySQLを導入。(全然うまくいかず)
その際にエラーログを確認できるディレクトリを作成した。

##mysqlのログには4つの種類がある

**実行エラーログ**
起動、停止及び実行時のエラーが保存されます。
MySQLで障害発生時に障害特定の情報を得ることが出来ます。

**クエリログ**
全てのSQL文(接続を含む)が保存されます。
クエリログはクエリを受け取った時点でログを書き込みます。
サーバ負荷の問題があるので、開発時またはデバッグ時に使用します。

**スロークエリログ**
指定した時間(秒)に処理が終了しなかったSQL文とINDEXを使用しなかったSQL文が保存されます。

**トランザクションログ**
MySQLに対する全てのデータベースの更新情報が保存されます。
サーバのパフォーマンスが約1%程度低下することがあります。

#実行ログを見れるようにする
mysqlのエラーを吐き出すディレクトリを作成する。

```
$ sudo vi /etc/my.cnf
```


次に、このファイルの中身を編集します。

```
[mysqld]
socket  = /tmp/mysql.sock

[mysqld_safe]
log-error=/var/log/mysqld.log
~
~
~
~
(編集後 :wq で退出)
```

mysqlの起動にはこのsocketファイルが必要なので、そのパスの記述。 また、エラーログをパスも同時に設定します。

```
$sudo touch /var/log/mysqld.log
```

次に上記を実施することで、実際のエラーログが記述されるファイルを作成できます。

ただ、これだけだとこのファイルやディレクトリを閲覧する怪訝が付与されていません。

```
$sudo chown ユーザー名:wheel /var/log/mysqld.log
```

これを行うことで、権限の付与を行うことができます。
ここまで出来たらmysqlを起動してみる。

```
$mysql.server start
```

起動に失敗していたら、、

```
$sudo cat /var/log/mysqld.log
```

このコマンドでmysqld.logを開き、エラーを確認する。