OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.js で Pnotify を mixin で登録して使ってみた

# 概要
アラートやメッセージの表示用のライブラリ [Pnotify](https://sciactive.com/pnotify/) をVue.jsで利用したときの設定のメモ。

メッセージ表示などはどの画面からも使うような処理だったので、mixin を使ってどの画面からも呼び出せるように定義しています。

# 環境
* Vue.js 2.6.10
* Pnotify 4.0.0

# ライブラリ導入
以下のコマンドでインストールできる

```
npm install --save pnotify
```

# mixin を使った設定

まずは呼び出したい共通メソッドを作成。
```notifyNotice```メソッドを呼び出して、通知メッセージが表示されるようにしたい。

```javascript:pnotify-custom.js
import PNotify from "../node_modules/pnotify/dist/umd/PNotify.js";
import PNotifyButtons from "../node_modules/pnotify/dist/umd/PNotifyButtons.js";

export default new class {
  constructor() {
    this.defaultOptions = {
      delay: 2000,
      modules: {
        Buttons: {
          sticker: false
        }
      }
    };
  }

  notifyNotice(title, text) {
    title ? this._notify(title, text) : this._notifyNoTitle(text);
  }
  _notify(title, text, type = "notice") {
    PNotify.alert({
      type,
      title,
      text,
      delay: this.defaultOptions.delay,
      modules: this.defaultOptions.modules
    });
  }
  _notifyNoTitle(text, type = "notice") {
    PNotify.alert({
      type,
      text,
      delay: this.defaultOptions.delay,
      modules: this.defaultOptions.modules
    });
  }
}();
```
mixinで読み込ませるファイル

```javascript:common.js
import notify from "./pnotify-custom.js";

export default {
  methods: {
    notifyNotice(title, text) {
      notify.notifyNotice(title, text);
    }
  }
};
```

Vueのインスタンス宣言箇所
mixinで先ほどの```common.js```を読み込んでいる

```javascript:main.js
import Vue from 'vue'
import App from './App.vue'
import "../node_modules/pnotify/dist/PNotifyBrightTheme.css";
import common from "./common.js";

Vue.mixin(common);

new Vue({
  render: h => h(App),
}).$mount('#app')
```

呼び出し方の例
```this.notifyNotice([タイトル],[メッセージ])```で呼び出せるようになっている

```vuejs:APP.vue
<template>
  <div id="app">
    <h1>Pnotify</h1>
    <button @click="onNotify">タイトルなし</button>
    <button @click="onNotifyTitle">タイトルあり</button>
  </div>
</template>

<script>
export default {
  name: "app",
  methods: {
    onNotify() {
      this.notifyNotice(undefined, "テスト[タイトルなし]");
    },
    onNotifyTitle() {
      this.notifyNotice("タイトル", "テスト[タイトルあり]");
    }
  }
};
</script>

<style>
</style>
```

表示はこんな感じで表示される
![pnotify1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220144/84426bbf-8e74-4831-b5d0-aaa484418599.png)
![pnotify2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220144/26339e4a-be6d-1487-9526-9244b14d1b66.png)



# まとめ
Pnotifyは簡単にリッチなメッセージダイアログを使うことができるのでお勧めのライブラリです。

こういったメッセージの表示だけでなく、共通で使える処理の定義をまとめて登録できるので、
mixinをうまく使えると開発がかなりはかどると思う。
TypeScriptで関数合成するライブラリをつくった


表題のとおりで、[fp-minimal](https://github.com/okmttdhr/fp-minimal)というライブラリを作りました。

## モチベーション

まず例として、メールアドレスとパスワードを入力するログイン機能を考えます。それはおそらく、以下のように書くことができます。

```ts
import { pipe } from 'fp-minimal';

const login = pipe(validate, getToken, responseToState, redirect)
```

このように、小さな関数(`validate`, `getToken`, `responseToState`, `redirect`)を組み合わせて機能を作る際に、可読性を上げることができます。

## 概要

`fp-minimal`のAPIは`pipe`と`curry`のみで、サイズも約1.6KBとなっています。
(`compose`をつくらなかったのは`minimal`という名を守るため)。

Ramdaのようなライブラリを入れると、全てをRamdaでなんとかしようとしてしまい、場合によっては効率の悪いコードを書いてしまうときもあるかもしれません。愚直に小さい関数を組み合わせてアプリケーションをつくりたいというだけなら、これらのAPIで十分である、というのが想いです。

## 実装

小さいので、コードの中身を紹介します。

**pipe**

```ts
export function pipe(...args: Function[]): any {
  // reduceRightにするとcomposeになる
  return (input: any) => args.reduce((result, next) => next(result), input);
}
```

**curry**

```ts
export function curry(func: Function) {
  return function curried(...args: any[]) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args2: any[]) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}
```

型は力技…。

```ts
export function curry<T1, R1>(func: (a: T1) => R1): (a: T1) => R1;
export function curry<T1, T2, R1>(func: (a: T1, b: T2) => R1): (a: T1) => (b: T2) => R1;
export function curry<T1, T2, T3, R1>(func: (a: T1, b: T2, c: T3) => R1): (a: T1) => (b: T2) => (c: T3) => R1;
export function curry<T1, T2, T3, T4, R1>(func: (a: T1, b: T2, c: T3, d: T4) => R1): (a: T1) => (b: T2) => (c: T3) => (d: T4) => R1;
export function curry<T1, T2, T3, T4, T5, R1>(func: (a: T1, b: T2, c: T3, d: T4, e: T5) => R1): (a: T1) => (b: T2) => (c: T3) => (d: T4) => (e: T5) => R1;
```

## 使用例

使う時はこのように

```ts
import { pipe } from 'fp-minimal';

const double = (x: number) => x * 2;
const addOne = (x: number) => x + 1;
const square = (x: number) => x * x;

pipe(double, addOne, square)(2) // 25
```

```ts
import { curry } from 'fp-minimal';

const add = (x: number, y: number) => x + y;
const addOne = curry(add)(1);

addOne(2); // 3
[1, 2, 3].map(addOne); // [2, 3, 4]
```

型も推論されています。

<img width="695" alt="スクリーンショット 2019-12-13 23.29.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22875/e8db1e0a-e2ae-725f-13ff-f1258495f3e0.png">

返り値の型が変わる場合

<img width="695" alt="スクリーンショット 2019-12-13 23.32.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22875/e4f8992f-267f-833e-51f4-057ac1164a95.png">

curry

<img width="602" alt="スクリーンショット 2019-12-13 23.35.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22875/d02e7fd1-8d3b-60e9-7f93-4670f19328f5.png">

curry化した関数で新しい関数を作った場合

<img width="340" alt="スクリーンショット 2019-12-13 23.33.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22875/c1740f15-ce55-cddb-d83c-359a92ef74e9.png">


## おわりに

小さいパーツつなぎあわせてソフトウェアを動かすのは楽しいですね。

- [Support proposed ES Next "|>" pipeline operator · Issue #17718 · microsoft/TypeScript](https://github.com/microsoft/TypeScript/issues/17718)
- [TypeScriptでもpipeline operator(もどき) | Studio Andy](https://blog.andoshin11.me/posts/pipeline-operator-like-helper)
フレームワークを理解するために自作PHPフレームワーク作ってみた

この記事は[2019新卒 エンジニア Advent Calendar 2019](https://qiita.com/advent-calendar/2019/2019-graduates)の1日目の記事です。
(参加しようと思ったのが13日でしたが、空いている枠が1日しかありませんでしたので1日目の記事として投稿しました。すみません。)

# 動機
仕事でフレームワークを使ってWebアプリを開発しています。
自作でフレームワークを作ることで、

* プログラマとしてのスキルアップ
* フレームワークが何をしているのか理解できるようになり、バグの原因発見が容易になる
* 機能追加の際にフレームワークの動きも加味していいコードが書けるようになる

以上のメリットがあると考えたためです。

# どのように作ったか
[パーフェクトPHP](https://www.amazon.co.jp/dp/B00P0UDWQY/)の第7~8章を参考にしました。

# 得られた知見(大きなもの一部抜粋)
スクラッチでフレームワークを作ることで以下のような知見を得られました。

### PHPがどのようにレスポンスを返すか

```php
header('HTTP/1.1 200 OK') #HTTP header
echo $content; #HTTP body
```
恥ずかしいことにechoでresponsebodyを返していることすら理解していませんでした...
HTTPRequest/Responseを追えるようになったのは大きな成長だと思います。

### リクエストURLからコントローラへの橋渡し
```php
$tokens = explode('/', ltrim($url, '/'));
foreach ($tokens as $i => $token) {
   if (0 === strpos($token, ':')) {
      $name = substr($token, 1);
      $token = '(?P<' . $name . '>[^/]+)';
   }
   $tokens[$i] = $token;
}
$pattern = '/' . implode('/', $tokens);
$routes[$pattern] = $params;
```
urlを分割し、controller名とaction名に分ける処理です
この後ルーティングを参照し、controller名を使って目的のphpをrequireします
普段投げているリクエストURLがどのようにcontrollerと結びついているのかを知ることができました

# まとめ
普段意識せずにviewとcontrollerを配置してwebアプリを実装していました。
今回のようにスクラッチでフレームワークを実装してみると大小様々に得られるものが多く、特に

- PHPの言語的な理解
- フレームワーク内の処理に関する理解

が深まって良いのではないかと思います。
Chromeのユーザー機能によってAWSマネジメントコンソールで複数のアカウントを使い分ける方法


運用するサービスやデプロイする環境ごとにAWSアカウントを分けるのは、よくある手法かと思います。
そこで問題となるのが、AWSマネジメントコンソールで同時に複数のアカウントにログインできないことです。
この制約を回避すべく、ブラウザのシークレットモードを使ったり、別のブラウザを起動したりしている人も多いのではないでしょうか。
その問題、Chromeなら解決できます。

## ユーザー管理機能を使う
Chromeには、ユーザー管理機能が存在します。
ほとんどの人はGoogleアカウントと紐づけているかと思いますが、同じデバイス上で複数のユーザーを作成して使い分けることも可能です。

## Chromeのユーザーを作成
Chromeのウインドウ上部にあるユーザーのアイコンをクリックすると、次のようなメニューが表示されます。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/02a2a96b-e284-63c2-68e0-768fc83f73c0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/02a2a96b-e284-63c2-68e0-768fc83f73c0.png)

「ユーザーを管理」をクリックすると、ユーザー管理画面が開きます。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/7bc667f1-48bf-6405-02a1-c6b27b0fe63c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/7bc667f1-48bf-6405-02a1-c6b27b0fe63c.png)

さらに「ユーザーを追加」ボタンをクリックすると、ユーザー追加画面が開きます。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/6ef52659-5914-8c27-b951-ea4b36b073a8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/6ef52659-5914-8c27-b951-ea4b36b073a8.png)

ここでは、作成するユーザーの名前とアイコンを設定します。
名前には、AWSのアカウント名を入れるといいでしょう。
アイコンはデフォルトで用意されたものの中から選ぶ必要がありますが、どうしても独自の画像を使いたい場合は設定ファイルを直接書き換える方法もあるようです。[^1]

## ユーザーごとに設定をカスタマイズ
そのまま使い始めてもいいのですが、せっかくなのでユーザーごとに設定をカスタマイズしましょう。

### テーマを変更
アイコンだけでは区別がつきづらいので、ユーザーごとに異なるテーマを設定しましょう。
手前味噌ですが、癖がないマテリアルデザインカラーのテーマをThemeBetaで公開しているのでよければお使いください。

- [Chrome Themes by Munieru - ThemeBeta](https://www.themebeta.com/chrome/user/768148)

僕は開発環境は青、ステージング環境は緑、本番環境は赤のように使い分けています。

### 起動時にログイン画面を開く
今回作成したユーザーはAWS用なので、起動時にログイン画面を開くようにしておきましょう。
AWSマネジメントコンソールのログイン画面のURLは、次のような形式になっています（実際にアクセスするとアカウント名が入力された状態のログイン画面にリダイレクトされます）。

```
https://<アカウント名>.signin.aws.amazon.com/console
```

SSO環境を構築している場合は、よしなに置き換えてください。

## 参考リンク
- [Chrome を他のユーザーと共有する - パソコン - Google Chrome ヘルプ](https://support.google.com/chrome/answer/2364824)

[^1]: [Chromeのユーザー画像変更 - Qiita](https://qiita.com/yuki0n0/items/ef7b922688580a4a8e7b)
fishでmkcdコマンドを作る

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の十三日目の記事です。

fishでmkcdコマンドを作った解説記事です。

## じっそー

```fish
function mkcd
  set dirname $argv[1]
  mkdir -p $dirname
  eval "cd" $dirname
end
```
1行目は関数の宣言ですね。
2行目でdirnameという変数にコマンドライン引数の1つめを代入しています。
3行目で変数dirnameに対してまずはmkdirコマンドを実行し
4行目でevalを使ってcdコマンドを同様にdirnameに対して行っています。

## 注意事項

- mkdir の -p は複数階層を一度につくるため
- evalせずにcdをすると、終了後にパスが戻る
サイバー攻撃(サイバーテロ)は人を殺しえるか？

# 自己紹介
どうもはじめまして。
oxlunaxoと申します。
普段は他人の記事を見るのが中心ですが、
いい加減に記事の一つや二つ書かないと深夜にフィッシングサイトのリンクを貼るスパマーや、怪しい製品の宣伝をするスパムアカウントと同類かなと思い、自分の低レベルのスキルでかける記事がなにか無いかと考えながらと、日課のセキュリティブログを流し見してたときに思いついた記事になります。
内容としては実際の攻撃手法とか説明するのでは無く実際にあった事件等を交え、自身に知識とか還元する目的を兼ねて書いているのでどちらかというと初心者向けになるかと思います。

結構タイトルは危ないですが、ガチガチの説明口調ではなく砕いてフランクに書く予定なので身構えなくてもいいです。
その代わり主観も結構入ると思うので、そういうのが苦手な方は戻るボタンが懸命かもしれません。
※コメント等での指摘やこういう事例があるよというリンク等は歓迎します。(記事への反映には時間がかかります。)

## キッカケ
まずはこの動画(リンク先youtube)を見ていただきたいです。
[Hacknet - Project Junebug - No Commentary](https://www.youtube.com/watch?v=vbuzbCo4_vE)

これはHackNetと呼ばれるゲームで主人公はハッカーとしてPortHack.exeの開発者であるプログラマーの死を追っていくというゲームになります。
ゲーム自体はLinuxっぽいコマンドを使いコマンドラインに様々なコマンドを打ち込んでいきながら様々なサーバ、PC、スマートフォンの脆弱性をついて侵入し、データを抜き出し(または削除や改ざん)て次の攻撃対象への足がかりを掴んでいく内容になります。
基本的な攻撃は実行ファイルのコマンドを叩くだけ(スクリプトキディ)なのでこの手のゲームとしてはかなり簡単な難易度だと思います。
何より定期的にSteamとかでほぼタダに近いディスカウントがされるので手を出しやすいです。
(これは布教なので宣伝扱いになりませんよね？)
ゲーム的にあえて演出されているところもありますが、結構操作としてはリアルな方です。
(セーブデータへのアクセスがユーザーIDとパスワードを打ち込んで実際にログインさせてくれるのでIDとパスワードを忘れたら詰みます)
何よりこの手のゲームで逆探知されてもセーブデータ消されないのがうれしい。

その中で主人公はとある医療機器メーカーのペースメーカにリモートアクセスし、管理者権限で機器を停止させることでとある患者を安楽死させてほしいという依頼を受けるか問われることになります。


###クラッキングでを殺せるの？
いきなり結論から言っちゃうと**理論上可能**だったりします。

最近でも米食品医薬品局(FDA)が注意喚起するくらいです。
[FDAが医療機器へのハッキングリスクを注意喚起](https://www.yakuji.co.jp/entry75195.html)

過去には何度もペースメーカーの攻撃実証実験が公開されているのに関わらず製造元が認めてなかったり、直してなかったりしている状況が続いていたみたいですね。コワイ！(医療機器メーカーが認めない姿勢とか一番ヤバい)

[心臓のペースメーカーはハッキングできる？ エンジニアたちが示した脆弱性の「証拠」](https://wired.jp/2018/09/18/pacemaker-hack-malware/)

###ロシアでは実際に子供が殺されかけた事例が起きている
ペースメーカーが攻撃されていなくても手術中に医療機器に攻撃があったら・・・？
[ロシアのハッカーが子供の脳の手術中に医療機器を切断](https://jp.rbth.com/science/80494-hakka-ga-kodomo-no-no-shujutsu-chu-ni-iryo-kiki-wo-setsudan)

上記の事件では[Purgen]と呼ばれるマルウェアを使用して手術中に医療機器類を軒並み停止されました。
※犯罪者の要求はのまず、何とか医療機器無しで脳手術を乗り切ったみたいです。

[Purgen]について調べてみましたが、詳細はつかめませんでした。ランサムウェアの類でしょうか？
(ご存じの方がいらっしゃったらご一報お願いいたします)

###今後、人命を狙ったクラックは増加していく・・・かも。
現在のクラッカーのトレンドとしてはスピアフィッシングやAIを用いたなりすましによる金銭の搾取がIPAによる情報セキュリティ2019年度版でわかってきました。
[情報セキュリティ10大脅威 2019](https://www.ipa.go.jp/security/vuln/10threats2019.html)
[IPAが「情報セキュリティ10大脅威2019」を公開！初ランクインの脅威とは？](https://www.secure-sketch.com/blog/ipa-10-major-threats)

ですが過去に病院等の人命が関わるインフラを狙った大規模なランサムウェアの攻撃があったことを忘れてはいけないと思います。
理論上可能であれば、個人情報より人命の方が金銭を脅し取る為の人質として最適だからです。


趣味レベルでの調査なので割と雑なところが大きいですが、
人の命を狙ったサイバー攻撃というのは
Watchdogsやhitman等といったフィクション上の話ではなく、徐々に実現しつつあるという危機感を持ち、
人命に関わる攻撃の知識、情報をもっと人々(特に一般の人達)は知っていくべきなのではないかと思います。

次はテーマは異なるでしょうがソースコードの提示が含まれた記事が書きたいな・・・

###2020/1/14追記
[てんかん発作の誘発を狙ったTwitter上での攻撃、その影響(Kaspersky blog)](https://blog.kaspersky.co.jp/twitter-epilepsy-attack-aftermath/26516/)
人命を狙った攻撃が去年11月のtwitter上で行われていたみたいですね。
内容としてはtwitterの自動再生機能の設定を受けないapng形式でポケモンフラッシュのような画像を、てんかんに関連するハッシュタグをつけて米国のNational Epilepsy Awareness Month（てんかん月間）に投稿しまくるという殺意の高いものでした。

その攻撃に対して、twitterはapng形式のファイル投稿が出来なくし、seizure（発作）というキーワード検索結果に画像を表示させないようにすることで対応した模様です。
M5StackでGrove超音波距離センサの値を画面表示


[1]:https://m5stack.com/
[2]:http://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/
[3]:https://www.arduino.cc/en/main/software
[4]:https://www.switch-science.com/catalog/3648/
[5]:https://www.switch-science.com/catalog/1383/

[6]:https://github.com/m5stack
[7]:https://github.com/Seeed-Studio/Grove_Ultrasonic_Ranger/

#1. はじめに
この記事では, **[M5Stack][1]**の画面に**[GROVE超音波距離センサモジュール][2]**の値を表示します.
[注意] **Grove超音波距離センサモジュール**専用のライブラリを使っているので, 
他の超音波距離センサを使う場合は, プログラムの改良が必要です.

↓↓完成画像
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279324/58be9e51-b5b3-dd5e-81e9-4e9fc5df7742.jpeg" width=50%>


#2. 開発環境
M5StackとGrove超音波距離センサモジュールは,こちらのリンクから入手可能です.
(1) [M5Stack Gray][4]
(2) [Grove超音波距離センサ][5]
(3) [Arduino IDE 1.8.10][3]

#3. Arduino IDE ライブラリ
Arduino IDE ライブラリを2つ使っています.
ライブラリは, Gitからインクルードしています(以下リンクから各Gitライブラリにアクセス可).
(1) [M5Stackライブラリ][6]
(2) [Grove超音波距離センサの制御用ライブラリ][7]

M5StackをArduino IDEで使うための初期設定(環境設定)は,本記事では終わっている段階です.

#4. プログラム
Arduino IDEのシリアルモニタとM5Stackの画面両方で, 超音波距離センサの値が確認できます.
本プログラムでは, 黒画面に黄色文字で表示しています.
超音波距離センサはcm, 整数表示です.


```c++
#include "Ultrasonic.h"
#include <M5Stack.h>

Ultrasonic ultrasonic(22);

void setup()
{
  M5.begin();
  Serial.begin(115200);

  delay(500);

  M5.Lcd.setTextFont(2);
  M5.Lcd.setCursor(10, 10);

  
}
void loop()
{
  long RangeInCentimeters;
  
  Serial.println("The distance to obstacles in front is: ");
	
  RangeInCentimeters = ultrasonic.MeasureInCentimeters(); // two measurements should keep an interval
  
  M5.Lcd.clear();
  
  M5.Lcd.setCursor(10, 10);
  M5.Lcd.setTextColor(YELLOW);
  M5.Lcd.setTextSize(2);
  M5.Lcd.printf("Ultrasonic distance\n");
  
  M5.Lcd.setCursor(50, 50);
  M5.Lcd.setTextColor(YELLOW);
  M5.Lcd.setTextSize(2);
  M5.Lcd.printf("%d cm\n", RangeInCentimeters);
  delay(500);

  Serial.print(RangeInCentimeters);//0~400cm
  Serial.println(" cm");
  delay(500);

  M5.update();
}
```

#5. 感想
今回は, 超音波距離センサの値を表示するところまでできたので, 次回はこれを使ってIoT通信に挑戦したいです!!:grinning:
闇の絵文字😈に対する防衛術

# はじめに
この記事は[闇の魔術に対する防衛術 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/yaminomajutu)の15日目の記事です。
# ♰闇の絵文字♰
絵文字というものはとても便利なもので、自らの感情を言葉ではなく1文字分の絵🖼で表現することができます。
しかし......🤔🤔🤔

**文章を解析する時に邪魔**😡

なんです。

# どゆこと❓
Python🐍などを利用して文章解析をする場合、前処理という文章📝を使いやすい形に整える作業をする必要があります。

解析の際に文章中に絵文字があるとあの忌々しい🤢Errorが降臨してしまいます😈

以前擬似[しゅうまい](https://twitter.com/shuumai)🍽のようなものを作った際にはこのエラーに大変悩まされました😱

# 世界🌎を滅ぼさんとする絵文字から身を守る術👊

この世界を破壊💣し滅ぼそうとする絵文字たちから身を守る術はひとつ☝️


![bouryoku.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269896/151af037-4f96-c935-bf53-4598d13d1bae.jpeg)


 **"力"** です👊👊👊
絵文字をちぎっては投げちぎっては投げを繰り返せるほどの力を手に入れましょう💪💪💪

# 力🤜🤛で絵文字を制する
もしかして感情分析📈などでは絵文字からも感情❤️を読み取れ、利用できるかもしれません。
しかし、今回はそのような場合を無視🐝し絵文字を徹底的に文章から消し去ります。

# 闇の絵文字を消し去る呪文

```python
# -*- coding: utf-8 -*-
text = '😈あいうえおabcde😈'

def emoji_killer(string):
    return ''.join(tar for tar in string\
                   if tar.encode('unicode-escape').decode('utf-8')[0] != '\\'\
                   or tar.encode('unicode-escape').decode('utf-8')[1] != 'U')

if __name__ == '__main__':
    print(emoji_killer(string)) >>'あいうえおabcde'
```
これだけで多くの絵文字は消し去ることができます......

しかし😱
# 強敵👾現る
☹️⛳️⚾️⌨️<効かないよ

こいつらを含めた数多くの絵文字たちに僕は勝つことができませんでした.......

原因は

```python
'☹️'.encode('unicode-escape')　 >>b'\\u2639\\ufe0f'
'⛳️'.encode('unicode-escape')  >>b'\\u26f3\\ufe0f'
'⚾️'.encode('unicode-escape')  >>b'\\u26be\\ufe0f'
'⌨️'.encode('unicode-escape')  >>b'\\u2328\\ufe0f'
```

この絵文字たちは2文字以上の絵文字の組み合わせから出来ているのです😨(よく見たら二文字目同じコードだけど)

# ✝️神✝️の力を借りる
幸いなことにPythonには絵文字用のライブラリが存在しています。

```python
# -*- coding: utf-8 -*-
import emoji

def emoji_kill_tool(text):
    return ''.join(tar for tar in text if tar not in emoji.UNICODE_EMOJI)

if __name__ == '__main__':
    text = 'あ☹️い⛳️う⚾️え⌨️お'
    print(emoji_kill_tool(text)) >> 'あいうえお'
```

つよい。

# まとめ
結局自らの力💪では絵文字を倒しきることはできませんでしたが、神👼の力を借りることで憎き絵文字たちを消し去ることができました🙆‍♂️。
しかし、車輪🚕の再発明は学習においては無駄なことではありません🙅‍♂️。適当に流していた部分を勉強📚しなおすことができるのでとても身🍎になりました。

# さいごに
今回は、前々から考えていた絵文字への対策を再学習＆アウトプット📤してみました（不完全だったけど😅）。
[闇の魔術に対する防衛術 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/yaminomajutu)にはまだまだ面白い記事がありますので是非見てみてください😘。
Maplat Coreで古地図上を進行方向に視点を変えながら走り回ってみる

Maplat Advent Calendar 13日目ですが、Maplat Coreで古地図上を進行方向に視点を変えながら走り回ってみます。
今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 13](https://codesandbox.io/s/maplat-advent-calendar-day-13-g52z6)

昨日までは設定した経路の上をPOIピンを走らせてみましたが、今回は地図の中心点を経路の上を辿らせつつ、その進行方向が常に地図の上方向になるように視点を動かす（いわゆる「ヘッドアップ」というやつです）ことを実現してみます。

今回は経路に沿った方角を計算しないといけないということで、`turf.js`の`@turf/bearing`というモジュールを依存に加えます。
それを使って、`@turf/line-chunk`で細切りにした線分の第一ノードと第二ノードの間の方角（北を0度として時計回りの度数表示）を、`@turf/bearing`で計算しています。
それの逆回転を`direction`引数で`app.setViewpoint`に与えることで、ヘッドアップを実現しています。
現在位置の移動は、`app.setViewpoint`に一緒に経緯度を`latitude`、`longitude`引数で与えてやることで、移動を実現しています。

```app.js
import "@maplat/core/dist/maplat_core.css";
import { MaplatApp } from "@maplat/core";
import { lineString } from "@turf/helpers";
import length from "@turf/length";
import lineChunk from "@turf/line-chunk";
import explode from "@turf/explode";
import bearing from "@turf/bearing";

var option = {
  appid: "maplat_ac_day13"
};

var app = new MaplatApp(option);
app.waitReady.then(function() {
  var ring = [
    [139.53184, 36.251013],
    [139.534322, 36.249581],
    [139.533853, 36.24814],
    [139.530729, 36.248649],
    [139.53184, 36.251013]
  ];
  app.addLine({
    lnglats: ring,
    stroke: {
      color: "#ffcc33",
      width: 2
    }
  });
  document.getElementById("gsi").addEventListener("click", function(e) {
    app.changeMap("gsi");
  });
  document.getElementById("osm").addEventListener("click", function(e) {
    app.changeMap("osm");
  });
  document.getElementById("ojo").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_ojozu");
  });
  document.getElementById("aki").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_castle_akimoto");
  });

  var ringFeature = lineString(ring);
  var ringLength = length(ringFeature, { units: "meters" });
  var divLength = ringLength / 20;
  var chunk = lineChunk(ringFeature, divLength, { units: "meters" });
  var points = chunk.features.map(function(line) {
    var nodes = explode(line);
    var start = nodes.features[0];
    var startPoint = start.geometry.coordinates;
    var end = nodes.features[1];
    var direction = bearing(start, end);
    return [startPoint[0], startPoint[1], direction];
  });
  app.setViewpoint({
    latitude: points[0][1],
    longitude: points[0][0],
    direction: -points[0][2]
  });
  console.log(points);
  var index = 0;
  var regularRun = function() {
    var point = points[index];
    app.setViewpoint({
      latitude: point[1],
      longitude: point[0],
      direction: -point[2]
    });
    index = index + 1;
    if (index > 19) index = 0;
    setTimeout(regularRun, 1000);
  };
  regularRun();
});
```

動作している状況は以下のような感じになります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/9184e4ab-bfb5-da67-0f46-e2e6e3204a35.gif)

このAdvent Calendar連載記事、Maplatだけでなく何気に`turf.js`の活用法紹介記事にもなってますね...

さて、明日もネタがない...何にしようか。
YugabyteDBのround()の話

先日、PostgreSQLのround関数の挙動について[記事](https://qiita.com/fujii_masao/items/c79575fb57827f658063)を書きました。この記事を参考に、本記事では、PostgreSQL互換をうたっている[YugabyteDB](https://www.yugabyte.com/)のround関数の挙動について確認します。

# YugabyteDBのインストール

インストールは、[Get started](https://download.yugabyte.com/)に従って進めます。

```bash
$ wget https://downloads.yugabyte.com/yugabyte-2.0.7.0-darwin.tar.gz
$ tar xvfz yugabyte-2.0.7.0-darwin.tar.gz && cd yugabyte-2.0.7.0/
$ ./bin/yb-ctl create
```
# round関数の挙動の確認

クライアントツールのysqlshを使ってYugabyteDBにアクセスし、round関数を実行します。まずは、1.0から3.0までのNUMERIC型及びDOUBLE PRECISIONの値を0.1刻みでround()に渡します。

```bash
$ bin/ysqlsh -c "SELECT num, round(num::NUMERIC) \"NUMERIC\", round(num::DOUBLE PRECISION) \"DOUBLE\" FROM generate_series(1.0, 3.0, 0.1) num"
Null display is "(null)".
 num | NUMERIC | DOUBLE 
-----+---------+--------
 1.0 |       1 |      1
 1.1 |       1 |      1
 1.2 |       1 |      1
 1.3 |       1 |      1
 1.4 |       1 |      1
 1.5 |       2 |      2
 1.6 |       2 |      2
 1.7 |       2 |      2
 1.8 |       2 |      2
 1.9 |       2 |      2
 2.0 |       2 |      2
 2.1 |       2 |      2
 2.2 |       2 |      2
 2.3 |       2 |      2
 2.4 |       2 |      2
 2.5 |       3 |      2
 2.6 |       3 |      3
 2.7 |       3 |      3
 2.8 |       3 |      3
 2.9 |       3 |      3
 3.0 |       3 |      3
(21 rows)
```

次に、1.5、2.5、3.5、…をNUMERIC型とDOUBLE PRECISION型でround()に渡します。

```bash
$ bin/ysqlsh -c "SELECT num, round(num::NUMERIC) \"NUMERIC\", round(num::DOUBLE PRECISION) \"DOUBLE\" FROM generate_series(1.5, 10.5, 1.0) num"
Null display is "(null)".
 num  | NUMERIC | DOUBLE 
------+---------+--------
  1.5 |       2 |      2
  2.5 |       3 |      2
  3.5 |       4 |      4
  4.5 |       5 |      4
  5.5 |       6 |      6
  6.5 |       7 |      6
  7.5 |       8 |      8
  8.5 |       9 |      8
  9.5 |      10 |     10
 10.5 |      11 |     10
(10 rows)
```

以上のとおり、YugabyteDBでも、PostgreSQLと同様に、引数のデータ型によりround関数の挙動が異なり、round(NUMERIC)は四捨五入、round(DOUBLE PRECISION)は銀行丸めを行います。
Chromedriverのバージョンが合わない事によってseleniumでchromeが開けない

# 概要
seleniumでchromeを開こうとしたら、一瞬だけ画面に表示され、すぐ消えた。
ChromeDriverと、Chromeバージョンが違うとエラー出された。
なんで...

# エラー文
"selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 76"
ここでどうしたらよいかわからなかった。

# 解決策
https://qiita.com/umaruskie/items/f2b4c11b50b34508b64f
ここで紹介されているように、自分が今使っているChromeのバージョンを確認し、そのバージョンをサポートしているChromedriverをダウンロードしないと、seleniumからchromeを開くことができなかった。

解決、解決、めでたしめでたし
Armadillo-G3で「usb 2-1: USB disconnect, device number **」によりモバイル通信切断

usb 2-1: USB disconnect, device numberというログメッセージが出力されて、モバイル通信が切断された場合に、発生したと思われる事象を記載する。

※ 下記の内容は、メーカーからの公式見解ではなく、ユーザフォーラムから推測した内容である。

* モバイル通信が切断され、再接続のため、3G/LTEモジュールが再起動している

* 本体温度の上昇により、サーマルシャットダウンが発生し、3G/LTEモジュールが再起動している

https://users.atmark-techno.com/node/2743
https://users.atmark-techno.com/forum/armadillo/2743

* 端末の電源に何らかの異常が発生し、3G/LTEモジュールが再起動している

https://users.atmark-techno.com/forum/armadillo/2743

---

## 参考

[FAQ : Armadillo-IoT G3: 3Gモジュールで通信できないときには？
](https://armadillo.atmark-techno.com/faq/aiotg-g3-3g-doesnt-work)
pythonからGPUの枚数を知る方法〜multiprocessingをpytorchで使う際の注意点〜

# はじめに

pytorchでmultiprocessingを利用するとCUDAの初期化で怒られることがあります．

```
RuntimeError: cuda runtime error (3) : initialization error at /pytorch/aten/src/THC/THCGeneral.cpp:50
THCudaCheck FAIL file=/pytorch/aten/src/THC/THCGeneral.cpp line=50 error=3 : initialization error
```

# なぜ怒られたか

色々調査すると，spawnがどうとか，様々な文献が見当たりましたが，自分の場合は`torch.cuda.device_count()`を利用していたことが原因だったようです．

ということで，GPUの枚数を`torch.cuda.device_count()`抜きで知りたい．

# GPUの枚数をpythonから取得

`nvidia-smi`に頼ります．
linuxの場合は以下の通り．


```
import subprocess
msg = subprocess.check_output("nvidia-smi --query-gpu=index --format=csv", shell=True)
n_devices = max(0, len(msg.decode().split("\n")) - 2)
```

pytorchのCUDA初期化問題には皆様も気をつけてください．
JAWS-UG初心者支部#16

###JAWS-UG初心者支部

初めて参加させていただいたMeetUpで参考にさせていただいた（印象に残った）プレゼン資料です。何が参考になったか年末の時期に思い起こすと、AWSの基本的なことを理解することで数珠繋ぎの様に知らないことを知る有意義さに気づかせていただいたことだと思います。またプレゼンの自由さみたいな感覚を掴ませていただきました。備忘録として引用させていただきます:bow_tone2:

[EC2 つまずきやすいCPUクレジット](https://jawsug-bgnr.connpass.com/event/118619/presentation/?utm_campaign=new_event_links_to_group_member&utm_source=notifications&utm_medium=email&utm_content=detail_btn)

:apple::apple:
【画像処理100本ノックに挑戦】Q.4. 大津の二値化

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

# Q.4. 大津の二値化
> 大津の二値化を実装せよ。 大津の二値化とは判別分析法と呼ばれ、二値化における分離の閾値を自動決定する手法である。 

分離度という指標を最大化すればよいのですが、分離度というものがいまいちピンときません。分離度を最大化することは

```math
w_0\sigma_0^2 + w_1\sigma_1^2
```

を最小化することと同じことのようです。ただし$w$はそれぞれのクラスの割合です。うーん、わかるようなわからんような・・・。
もう少し調べてみると、元画像と二値画像の二乗誤差を小さくする閾値を求めるのと同じという説明があります。式による詳細な説明は見つからなかったのですが、これが一番納得出来そうな気がします。
次のような二値化を考えます。

```math
g_i =   \left\{
    \begin{array}{ll}
      \mu_0 & i<t\\
      \mu_1 & i\geq t
    \end{array}
  \right.
```

ただし、$\mu$はそれぞれのクラスの平均値です。元画像の画素値を$\{f_i\}$とすれば、二乗誤差は

```math
\begin{eqnarray}
\sum_i(f_i-g_i)^2 &=& \sum_{\rm class0}(f_i-\mu_0)^2 + \sum_{\rm class1}(f_i-\mu_1)^2 \\
&=& n_0\sigma_0^2+n_1\sigma_1^2\\
&\propto& w_0\sigma_0^2 + w_1\sigma_1^2
\end{eqnarray}
```

となり、大津の方法の式と同じ式が出てきます。ただし$n$はそれぞれのクラスに属する画素数です。

コードは次の通り。

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

	std::vector<int> x;
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			x.push_back(y);
		}

	double maxeval = 0;
	double T;
	for (int t = 1; t < 255; t++)
	{
		int n[2] = {0};
		double mu[2] = { 0 };
		for (int i = 0; i < width*height; i++)
		{
			if (x[i] < t)
			{
				n[0]++;
				mu[0] += x[i];
			}
			else
			{
				n[1]++;
				mu[1] += x[i];
			}
		}
		mu[0] /= (double)n[0];
		mu[1] /= (double)n[1];
		double w0 = n[0] / (double)(width * height);
		double w1 = n[1] / (double)(width * height);
		double eval = w0 * w1 * (mu[0] - mu[1]) * (mu[0] - mu[1]);
		if (eval > maxeval)
		{
			maxeval = eval;
			T = t;
		}
		
	}

	for(int j=0; j<height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			y = (y < T ? 0 : 255);
			ppm2(i, j, 'r') = y;
			ppm2(i, j, 'g') = y;
			ppm2(i, j, 'b') = y;
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```
![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/072a0d7a-13df-e34b-c9eb-ea44ac53f382.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/18304426-7511-7395-86e7-bb3e003ef5a3.png)
Raspberry Pi のOSインストール時に無意味にフォーマットするのは止めよう

# きっかけ
最近pi4が日本発売されたのをきっかけにネット上を検索していると不思議なことに気が付きました。「ラズパイ　インストール」などで検索しているとヒットした上位サイトの多くが「無意味なフォーマット」をする手順になっているのです。
Qiita内の記事にも「無意味なフォーマット」をしているものがあります。

# なにが無意味なのか？
公式OSのRaspbianのインストールには2つの方法が有ります。
1. インストーラの「Noobs」を使う。
2. Raspbian のディスクイメージを直接sdカードに書き込む。

1のNOOBSを使う場合にはSDカードがfat16またはfat32でフォーマットされている必要があります。普通購入時にfat32でフォーマットされているので再フォーマットの必要はありません。64GB以上の場合には購入時にexFATになっているのでfat32で再フォーマットすることが必要になります。

さて、2のRaspbianのディスクイメージをSDカードに書き込む場合にフォーマットは必要でしょうか？
**「もちろん必要ありません」**
なぜならばディスクイメージにはパーティションやフォーマット、ラベルなどの情報をすべてが含まれているからです。つまりSDカードがどんなフォーマットになっていても（フォーマットされていなくても）関係なくディスクイメージどおりのパーティション、フォーマットになるのです。

# 公式サイト(英文)はどうなっているか
https://www.raspberrypi.org/documentation/installation/installing-images/README.md
もちろんSDカードをフォーマットする手順はどこにもありません。

# 結論
RaspbianをNOOBSを使わずにディスクイメージからインストールする場合にはSDカードを予めフォーマットする必要はありません。balenaEtcherやWin32DiskImagerを使って直接イメージを書き込みましょう。

# 蛇足
私も公式サイトが英語の場合にはつい日本語情報だけ見てしまいます。ラズパイ初心者が初めてインストールする場合ならなおさらです。今回の例は無駄な手順というだけで大きな害はないのですが、間違った情報があちこちに引用されて誤りが再生産されてしまうこともあるので気をつけましょう。
Qiita はAPNGファイルにも対応されていた！

GIFアニメ
![ac8530f9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/50175249-2460-d9c7-6581-efa4b798df3d.gif)


APNG test どうせ対応してないんだろうなぁ～～と思ったら！！！時代は進化しているなぁ。
音は入んないのかな？

APNG
![elephant_apng_zopfli.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/c060b898-b3c4-361c-b231-b0dba720006b.png)


https://ics.media/entry/2441/
Xamarin.Androidでクライアント証明書を使った認証をしようとした話

# まだ解決してません
同じことで躓く人がいなくなりますように書き残します。

# 要件
Azureサーバーへの通信は特定多数のPC、android端末からのみを許可したい

# １番目に試したこと
設定からクライアント証明書をandroid端末にインストールし、
プログラムで参照して、リクエストヘッダに載せたかった

### できなった原因
http://dsas.blog.klab.org/archives/51995232.html
サイトを要約すると、設定から証明書をインストールした場合、
アプリから参照する方法がない。
アプリからインストールさせればできる。

# ２番目に試したこと
アプリから証明書をインストールさせる。
パスワードはユーザーに入力させ、証明書はファイルアプリ内のフォルダに置き、
初回パスワード入力で、証明書をインストールしたら、証明書を削除する想定。

２回目以降は証明書ストアから取得するよう書きました。

実際にインストールも、取り出しもできたのですが、問題がありました。

証明書を端末から取り出した場合のみ、証明書についている秘密鍵がnullになってしまい、サーバーで認証が通りません。

```C#
private getCert() 
{
    X509Certificate2Collection findResult;
    using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
    {
        store.Open(OpenFlags.MaxAllowed);
        findResult = store.Certificates.Find(X509FindType.FindBySubjectName, "subjectname", false);
        store.Close();
    }
    X509Certificate2 cert;
    if (findResult.Count == 1)
    {
        cert = findResult[0];
    }
    else
    {
        X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable;
        Stream fis = Android.App.Application.Context.Assets.Open("certfilename.pfx");
        cert = new X509Certificate2(GetByteArrayFromStream(fis), "password",flags);

        using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
        {
            store.Open(OpenFlags.ReadWrite);
            store.Add(cert);
            store.Close();
        } 
    }
    return cert;
}
```

# 解決案あったら教えてください

X509Certificate2.PriveteKeyは明示的に値いれようとすると、エラーになります。
Android特有の権限回りの問題なのか、ソースで解決できる問題なのかもわかってません。
Xamarin.Android触って２日目なので、実はもっと簡単だったりするかもですが、解決したら追記します。
Zenkit使い方備忘録

Zenkit
https://zenkit.com/

検索しても出てこなかったので自分用に。
「なんか使いづらいけど○○ってできないのかな...」って人用にも。

個人で使っているので、Member系はよくわからないです...

ざっくり導入検討は前回記事です
https://qiita.com/samotie/items/ab24d70816858634f75f

何かわかったら随時足します。



#外部連携
###Googleカレンダーと連携したい
Zapierとか使わなくてもできます。
同期なので、Googleカレンダー側のアイテムもZenkitに読み込まれるらしいです（やったことない）

1. 連携したいコレクションを開く
- 左上のコレクション名をクリック
- メニューの「Manage Add-Ons」
- 「Calendar Synchronization」を「Add」
- Providerを「Google Calendar」にする（2019年現在これしか選べない）
- 別窓でGoogleアカウント認証
- 同期先のGoogleのカレンダーを選ぶ。1コレクションに1カレンダーしか紐付かないので、コレクションが複数ある時はGoogle側のカレンダーがどんどん増える
- 同期する内容を選ぶ。「Title:Title」「Date:Due Date」「Description:Description」とかでいいと思います。
- 「Connect」で同期！

「Zenkit → Google」はすぐだけど、「Google → Zenkit」は時間がかかるらしい。
設定した内容は、コレクション設定画面の「Magage Add-Ons」の下に「Calendar Synchronization」が追加されているので、そこから確認できる。
確認するだけなので、設定を変更したい時は「Remove Add-On from Collection」で一度削除してから再登録。

Zenkit公式 Knowledge Base（英語）
https://zenkit.com/documentation#/lists/HJQBQ1Hw/sections/BkPFGISFZ/entries/BJZU9LHtZ?_k=8a8pkb


#表示系
###タスク詳細の表示を変更（スライド / ポップアップ）

1. アイテムを開いて右上メニューボタン（3点マーク）
- 「Show as popup / sidepanel」

###カレンダー表示ボタンがない / マインドマップ画面は？

1. Collection画面で右上のビューボタン（KanbanとかListになってるはず）
- 「+ New view」で「Calendar」とか「Mindmap」とか

###日付の表記が気に入らない

1. 画面右上のアカウント情報を開く
- 「Date Format」で変更。その下で時間表記も変更できる。


#アイテムの入力内容
###アーカイブしたアイテムを確認したい / 復帰したい

1. 左上のコレクション名をクリック
- メニューの「Archive」

###日付じゃなくて期間で設定したい

1. 「Due Date」の日付設定画面を下にスクロール
- 「End Date」をオンにして終了期日を設定
- または「Duration」をオンにして、開始日からの経過時間で表示

###テキストフィールドで見出しとかリストとか使えないの？

1. 左上のコレクション名をクリック
- 左メニューの「Fields」を表示して「Description」を開く
- Defaultsの「Editor Type」をクリックして「Plain」から「HTML」か「Markdown」に
- 「Fields」画面に戻ったら右上の「Done」を忘れずに

コレクション内の全てのアイテムが変更されるので注意

または

1. アイテム詳細を開く
- 入力欄のタイトル（Description)をクリック

で個別設定ができます。

###Tagの色や並び順を変えたい
*2020/2/26追記*

1. 左上のコレクション名をクリック
- 左メニューの「Fields」を表示
- タグのブロックをクリック
- 名前の変更や入れ替え、削除など。
- 色は左の丸いカラー部分をクリックすると選べる
- 終わったらFields一覧に戻って右上のDone

##アイテムの入力項目のデフォルト表示を追加したい/編集したい
1. 左上のコレクション名をクリック
- 左メニューの「Fields」を表示して「+ Add Custom Field」

Name: 入力フィールドの名前
Type: 項目のタイプ

これ以下はTypeによって項目が変わる
Checklistだけ「+ Add Custom Field」の外に出てる

####Checklist
チェックリスト。デフォルトでチェック済が非表示にならないのが良い。

####Text
テキストフィールド。「Editor Type」でプレーンテキスト、HTML、Markdownを選べる。

####Number
数値の入力フィールド。管理番号とか工数とか。
Integer:整数
Decimal:小数
Currency:通貨。円もあります。数値入力で接頭辞追加。例：180 → ¥180.00

####Date
日付。

####Checkbox
チェックボックス。チェックリストとは別。

####Labels
ラベル。タグ付けできる。

####Formula
他の入力フィールドの数値を使って計算する。~~関数がかなり用意されているので~~、用途はあるかも
よく見たら基本的なやつでした。
sqrt()：平方根
abs()：絶対値
min()：最小値
max()：最大値
exp()：指数関数
sum()：合計
avg()：平均
count()：個数

ここは時間があったら別記事書くかもしれません。

####Members
担当者。複数担当の可/不可も選べる

####Files
ファイルをアップロードしてアイテムに添付する。無課金プランは1GBのアップロード空間。
ローカルからアップロードの他、Dropbox、Google Drive、Boxも利用可。

####Reference to other items
他のアイテムへのリンクを指定する。他コレクションも選べる。

####Subitems
子アイテムを指定できる。
「Hierarchy」ビューで操作しても同じ。

####Aggregation
他のアイテムの数値を使って集計できるらしいが不明。
追加しようとすると「参照できるフィールドがないんですが」と言われる

####Dependencies
依存関係。アイテム同士の依存関係を指定します。
シェルスクリプト $0 パラメータ

$0 パラメータ には、起動中のシェルスクリプト名がセットされています。

##### bash のコンソール上の場合
/bin/bash がセットされています。

```bash:example1
$ echo "$0"
/bin/bash
```

##### シェルスクリプト内の場合
その実行したシェルスクリプト名がセットされています。

```bash:example2.sh
#!/bin/bash
echo "$0"
```

```bash:result2
$ ./example2.sh
./example2.sh
```

##### basename コマンドを使ってスクリプト名だけ取り出す
bash のコンソール上の場合

```bash:example3
$ basename "$0"
bash
```

シェルスクリプト内の場合

```bash:example4.sh
#!/bin/bash
basename "$0"
```

```bash:result4
$ ./example4.sh
example4.sh
```

##### シェルの -c オプション
man bash で調べると、-c オプションに関して以下のような記述があります。

```
-c   If the -c option is present, then commands are read from the first non-option argument command_string.
If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters.
The assignment to $0 sets the name of the shell, which is used in warning and error messages.
```

つまり、以下のように記述すると、\$0 に test、\$1 に hello がセットされます。

```bash:example5
$ /bin/bash -c 'echo "$0"; echo "$1"' test hello
test
hello
```
Systemd環境でシスログに同一メッセージが2重出力される問題へ対処

## はじめに

Systemd環境では、journald → systemdの順に、journaldが書き込んだSYSLOGソケット (/run/systemd/journal/syslog)から、rsyslogdがシスログに出力するようになっている。

journaldの設定状態によっては、systemdのメッセージがシスログに重複して出力されてしまうケースがある。

本記事では、CetnOS7のSystemd環境において、journaldを経由せず、/dev/logから直接ログを受け取ることで、メッセージが重複する問題へ対処する方法を記載する。

## journald

   systemdの環境で、標準的に提供されるログ管理のサービス

---

## /dev/log

  シスログが書き込まれる「UNIXドメインソケットファイル」 

---

## 設定変更

以下のファイルを下記のように変更する。

* /usr/lib/systemd/system/systemd-journald.socket

```sh
    [Socket]
    ListenStream=/run/systemd/journal/stdout
    ListenDatagram=/run/systemd/journal/socket

    #コメントアウト
    #ListenDatagram=/dev/log
```

* /etc/rsyslog.d/listen.conf

```sh

    # journaldが書き込んだSYSLOGソケットからの読み取りをコメントアウト
    #$SystemLogSocketName /run/systemd/journal/syslog

   # UNIXソケット(/dev/log)経由でのログを受け付ける設定
    $SystemLogSocketName /dev/log       
```
               
* /etc/rsyslog.conf

```sh
   # UNIXソケット(/dev/log)経由でのログを受け付ける設定
   $ModLoad imuxsock

   # rsyslogdがjournaldからログを受け取る設定を無効化させるため、コメントアウト                
   #$ModLoad imjournal   
 
    # onの場合: /run/systemd/journal/syslogからの入力を受け付けない
    # offの場合: ローカルSYSLOGソケット(CentOSの場合、/run/systemd/journal/syslog)からの入力を無視する  
   $OmitLocalLogging off

   # imjournalモジュールをロードしていない場合、利用できないオプションなので、コメントアウト                
   #$IMJournalStateFile imjournal.state

```

---

## 参考

https://qiita.com/suzukit14/items/7bc05d1422c4bce5485b


http://www.asahi-net.or.jp/~aa4t-nngk/journald.html
個人でタスク管理するならZenkit派

初投稿です。

タスク管理ツール、何使ってますか？
私はBacklogで育ったのでBacklogが一番だと思うんですが、個人で導入するにはちょっと無理があります。

ここ２ヶ月、仕事もプライベートも「Zenkit」でタスク管理しているので、その備忘録も兼ねて記事を書くに至りました。
Zenkitユーザー増えて欲しい。そして日本語対応してほしい。（本音）

導入後のあれこれはこちら
https://qiita.com/samotie/items/251435153db84327903a

以下は特筆のない限りMac、Chrome、iPhoneでの環境です。

#結論

触ってみたのはTrello、Zenkit、ClickUp（とBacklog）ですが、
**Trelloで慣れているならTrelloの方がいいと思います。**

- 日本語対応している
- 動作が軽い
- 誤動作が少ない

やはりこの辺がクリアされているのは強いです。

ただ「なんか肌に合わないな・・・」って人は他のも使ってみるといいかもしれません。

Zenkitについては

**メリット**

- デフォルトでカレンダー表示が使える
- デフォルトでマインドマップが使える
- アイテムを入れ子にできる（親子関係）
- 期限表示が「Today」とかじゃなくて「YYYY-MM-DD」と年月日で表示してくれる。期限過ぎても赤くならない。（設定で変えられる？）
- そこそこ動作が安定している

**デメリット**

- 日本語化されていない（入力は日本語可能）
- 公式がネイティブアプリ開発を諦めたらしく、スマホアプリでカレンダー表示にするとちょっと見辛い
- たまに誤動作

という個人的感想です。そんなに不便してないです。
公式がTrelloからの乗り換えを狙っているからか、最初にTrelloのアイテムやコレクションを引き継ぐことができます。~~露骨~~親切。

デフォルトでカレンダー表示が使えるのはすばらしいです。
カレンダー横のパネルに期限未設定のアイテムがずらーっと並ぶので、カレンダー上にひょいひょい移動してスケジューリングできます。要件だけ先に立てて後で日程調整、とかに便利です。

ちなみにClickUpは

- 超多機能
- 超使いづらいUI
- 不具合多め
- 動作重め
- 日本語化されていない

でした。
提供されている機能はどれも魅力的ですが、スマホアプリで入力するたびに内容が消えるのはきつすぎる...
UIって大事だなぁと再認識したい人向け。
海外だと人気あるらしいので、そのうち改善されるかも？

あと気になりがちなガントチャートですが、

Trello:外部サービスやプラグインで対応
Zenkit:未実装（運営の公開やることリストに上がってる。2020年以降対応予定）
ClickUp:有料ユーザー限定

です。
チーム開発ならともかく、個人なら無くてもなんとかなるかな...

###その他

Zenkitってドイツ製なんですね。調べてて初めて知りました。
応援してます。（課金するか...）

Zenkit
https://zenkit.com/

Trello
https://trello.com/
ClickUp
https://clickup.com/
LookMLにおける ％表記についてメモ

Lookerで小数点以下の数値(%表記など）を可視化する場合、フォーマットはLookMLで指定が必要です。

その際に、エンジニア向け(`value_format`)と、非エンジニア向け(`value_format_name`)で２種類のやり方があります。
→自分は勝手に上記のように解釈しちゃってますが違ったらごめんなさい。


## サンプルデータの準備
・日付別での契約率のデータを準備
　↓

```
target_date,contract_rate
2019-12-01,7.86
2019-12-02,6.37
2019-12-03,9.70
```

## lookMLへの記載方法
１）エンジニア向け：`value_format` 
　　→フォーマット形式を自分で指定する。

```yaml

  measure: contract_rate_value_format {
    type: number
    value_format: "0.00\%"   ##　value_formatへ左のように指定することで%表記をさせる
    sql: ${TABLE}.contract_rate ;;
  }
```

２）非エンジニア向け：`value_format_name`
　　→フォーマットは名称指定で大丈夫。ただし、1.0=100%と解釈される為、sql内で調整必要。

```yaml

  measure: contract_rate_value_format_name {
    type: number
    value_format_name: percent_2   ##　value_format_nameへ「percent_2」を指定することで%表記をさせる
    sql: ${TABLE}.contract_rate / 100.0  ;;  ##注意点：value_format_nameを使うと1.0=100%になるので100で割る必要がある
  }
```

## 上記１）、２）の実行結果（同じ結果になる）

```
target_date,contract_rate
2019-12-01,7.86%
2019-12-02,6.37%
2019-12-03,9.70%
```

こんな感じで、
１）の場合は、**プログラムチック**な対応なので、エンジニア向け、
２）の場合は、**フォーマットに指定名称**(percent_2:小数点第２位を四捨五入して％表記する）で対応可能な為、非エンジニア向けかなと思いました。

出力結果は同じなので、どちらを使うかは好み次第と思いますが、両方のコードがシステムの中に混在すると結構気持ち悪い。と思う方もいるかもしれませんので、あらかじめ**LookMLの開発ルールでどちらかを使うか定義しておく**のがオススメと思います。


## value_format と value_format_name のコード内容と表記例

|  表記内容            | value_format | value_format_name | 表記イメージ | 
|--------------------:|:-------------|:-----------|-------------:
|　小数点第１位を四捨五入 | "0\%"        | percent_0  |    12%       
|　小数点第２位を四捨五入 | "0.0\%"      | percent_1  |   12.3%      
|　小数点第３位を四捨五入 | "0.00\%"     | percent_2  |   12.34%     
|　小数点第４位を四捨五入 | "0.000\%"    | percent_3  |   12.345%    



`value_format` と `value_format_name` の仕様詳細はLookerの公式マニュアルに記載あります（2019/12/13時点では英語マニュアルのみ対応）

↓value_format
https://docs.looker.com/ja/reference/field-params/value_format

↓value_format_name
https://docs.looker.com/reference/field-params/value_format_name
YugaByteDB(4) YugaByteDBが活きるユースケースとは

この記事は「[RookだらけのAdvent Calender](https://qiita.com/advent-calendar/2019/rook)」13日目の記事です。

昨日はRookで展開したYugaByteDBを使いながら、2つのAPIやデータ分散のアーキテクチャなどを学びました。
今日はRookによるYugaByteDB編の最終回として、この構成がどのようなユースケースにフィットするのかを検討したいと思います。

# YugaByteDBに適したユースケース

まず、Productionな環境で必要なデータベース構成を、フロントのサービス規模に応じて3つに分類してみましょう。

1. 可用性は必要だが、スケールは不要なケース
2. 可用性は当然必要で、Readクエリに対してスケールが必要なケース
3. 可用性は当然必要で、<font color="red">Read/Writeともにスケールしたいケース</font>

1.はAmazon RDSでいうところのMulti-AZ構成のようなものを想定して下さい。
基本的にはシングルインスタンスですが、DBMSまたはストレージの部分でデータが冗長化され、障害時には別ノードにフェイルオーバすることでサービスを継続します。

2.は上記のMulti-AZにReadレプリカも付いた構成となります。
可用性は担保しつつ、データのレプリカでReadクエリのみ実行を許可することでスケールアウトが可能です。Writeクエリを処理できるのは1インスタンスのみですので、Writeはスケール不可です。
そして、レプリカも親－子－孫のような構成が作れますが、多くても10数インスタンスというのがこの構成の特徴です。

3.はいわゆるマルチマスターなデータベースとなります。
複数のデータベース・インスタンスが、ReadもWriteも処理しながらお互いにデータを同期し続けます。全インスタンスの役割は基本的に同一で、台数を増やせば増やすほどスケールするため、100台以上の規模でデータベース・クラスタを構築することが可能です。

この3.のアーキテクチャでは色々な実装方法がありますが、クラウドベンダがManaged Serviceとして提供しているものでは、以下の2つの仕組みに分かれているように見えます。

**（マルチマスター・データベースの2つの類型）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54853/71249cf8-3c4b-7efc-5513-4f89b28b03e6.png)

このうち、YugaByteDBは左側の「**RDB on 分散KVS**」の一つで、YQLとDocDBに分かれた階層構造（[昨日説明したもの](https://qiita.com/tzkoba/items/a2d4596f5c805ef9d1bf#yugabytedb%E3%81%AE2%E3%81%A4%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)）からもそのことは明らかです。

ここまでの話から、分かることは以下です。

- Readレプリカで対応できるケースで、可用性担保のためにYugaByteDBを採用するのは不適です。
- Spannerを使うようなWrite負荷も非常に高いケースで、正しいキー設計の下でYugaByteDBを運用することで、他にない性能を達成できる可能性があります。

# Rookから見た分散データベース
上記のように、YugaByteDBを「RDB on 分散KVS」として捉え、Write負荷の高いユースケースで運用が可能なことは理解して頂けたのではないでしょうか。

それをRook、つまり**Kubernetes Operator**で運用する意味はどこにあるのでしょうか。

これは分散データベースの構築要件に由来すると考えています。

先ほどあげた**2.**のケース、10数台のレプリケーション構成を正しく構築し、障害時のリカバリも含めた運用を行うことは簡単ではありません。しかし、これは実現している企業もあるかと思います。

一方で100台単位にスケールするデータベース・クラスタを構築し、データのバックアップや障害復旧などをきちんとやり切るにはどの程度の管理負荷がかかるでしょうか。

これは間違いなく、膨大なものになるでしょう。
そのようなステートフルなワークロードの運用を助けるために開発が進められているのが、Kubernetes Operatorです。

現在のRook-YugaButeDBは構築を担うだけの非常にシンプルな機能しかありません。しかし、そこにバックアップ/リカバリなどの運用機能が搭載されれば、現在はニッチにしか受けていないYugaByteDBのブレークスルーとなりえます。

# まとめ
本日はYugaByteDB編の最後ということで、どのようなユースケースに適しているか、そしてRookを用いてそれを構築する意味などを少し考えてみました。

Rookだらけのアドベントカレンダーの本筋からは外れるため、YugaByteDB自身の機能や性能などについては今回検証を行っていませんが、そちらも時間を見て行いたいと思っています。

よろしくお願いします。
スマホを使っている気分になれるかもしれないCSS3つ

こんにちは。Media Do Advent Calendar 2019 14日目担当の@hrk02です。
今回はフロントエンド初心者の私が、「CSSってこんなことできるのね！」と感動した技術を3つ紹介します。
少なくてすみません・・・・・


(大変申し訳ないことに、超特急で書き上げたメモです....図解や実装例は今後追加していきたいと思います！)


> 注意書きとなりますが、ブラウザやブラウザバージョンによっては動作しないものももちろんあります。
> 基本的にはGoogleChromeやSafariで動くものを紹介しております。

## スクロール後にピタッと止まる
スクロールスナップ(scroll-snap)というらしいですね！
調べて初めて知りました。

`scroll-snap-type` でどの方向にスライドするか、`scroll-snap-align`でどこでピタっと止めるかを指定します。
この技術があれば、よくあるランキングなどの横スライドもいい感じにできますね！

```css
.container {
  scroll-snap-type: x;
}

.area {
  scroll-snap-align: start;
}
```

## スムーズにスクロール(慣性スクロール)
よくあるはみ出ているバーなどを横にスクロールさせる際に、指でスーッと移動させることができます(語彙力)
これはあとでイメージ図を挿入する必要がありそうですね・・・・

```css
.area {
  -webkit-overflow-scrolling: touch;
}
```

## 長い文章(複数行)を3点リーダーで省略
よくある3点リーダーで省略する実装です。
すごーく昔にやったときは面倒だった記憶があったのですが、今はこんなに便利なのかと驚きました。

もはやスマホ関係ないやんって感じですが、結構思い出に残っているので、メモとして残します。

`-webkit-line-clamp` で、何行まで表示したいか指定します。

```css
.text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
```

この`-webkit-line-clamp`は`-webkit-box-orient`が`vertical`の場合のみに適用されます。
ただ、私はAngularでこれを使おうとして結構つまりました。
しっかりと`-webkit-box-orient: vertical;`をつけているのに、なぜか `-webkit-box-orient` が効かないのです・・・・

どうして・・・・(´；д；｀)
と泣いていたところ、こんな記事をみつけました。

https://github.com/angular/angular-cli/issues/14393
https://qiita.com/watanabejunya/items/40b6c915639be5fa943f

WAO!!!!!!!びっくり!!!!
Autoprefixerのせいなのね・・・・！！！
> Autoprefixer
> 必要なベンダプレフィックスを自動で付けてくれる便利なツール

ということで、下記のように書くことで解決。

```css
.text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  /* autoprefixer: ignore next */
  -webkit-line-clamp: 2;
  overflow: hidden;
}
```

## おわりに
普段フロントエンド開発を行っている方からすると当たり前なことでも、初心者の私にとっては新鮮な出会いばかりです.....
他の人にとっては当たり前でありふれた内容でも、自分の言葉でちゃんと説明できるようにQiita記事などでアウトプットする習慣をつけたいですね。
現場からは、以上です。
Redis-SentinelのSDOWNとODOWNについて

## ダウン (ノード停止)

Redis Sentinelでは、ノード停止に関して、ダウンという概念が2つ定義されている。

## 主観的ダウン（SDOWN）

自身が他のSentinelを停止したと判断した状態。
is-master-down-after-millisecondsに指定された秒数分、
PING要求に対する有効な応答を受信しない場合、SDOWNになる。

## 客観的なダウン (ODOWN)

Sentinelがクォーラムに設定した数以上のSDOWNを検出すると、ODOWNになる。

## クォーラム

マスターが停止したと判断するために、同意する必要があるSentinelの数。

---

## ダウンに関連する設定オプション

### parallel-syncs

SlaveをMasterに昇格させた後、同時に同期をSlave取るスレーブの数
値が小さいと1回辺りの同期台数が少ないので、フェイルオーバーの完了に時間がかかる
レプリカが古いデータを提供するように構成されている場合、
すべてのレプリカを同時にマスターと再同期させたくないに設定する。

---

### is-master-down-after-milliseconds

is-master-down-after-millisecondsに指定された秒数分、
PING要求に対する有効な応答を受信しない場合、SDOWNになる。


---
朝会やミーティングをちょっとだけ楽しくする方法: いろんなハイタッチのパターンを考えた

この記事は私が働いている[LIFULLのアドベントカレンダー](https://qiita.com/advent-calendar/2019/lifull)その3の13日目の記事となります。

私のチームでは朝会の最後に毎回ハイタッチをしています。
ハイタッチをすることで気分を盛り上げたり、楽しい雰囲気でそれぞれの業務を始めてもらおうという意図があります。
ただ、ハイタッチをずーっと続けていてもマンネリ化してきてしまうので、いくつかハイタッチのパターンを考えました。
今回はその一部をご紹介したいと思います。

今回一緒に撮影に協力してくれたのは弊社の新卒1年目の井上くんです！
（動画の撮影してくれたのは新卒2年目の志賀くんです）
快く協力してくれてありがとう:blush:

## 入門編
### 普通のハイタッチ
![01_high_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/9954f48e-f382-1504-188d-9bdce7f358d7.gif)
一番オーソドックスで簡単なハイタッチ。

### 片手ハイタッチ
![02_onehand_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/64d48ac6-b1ca-bc96-aa1d-2460dea605e4.gif)
勢いよくパーンってやると気持ちいい。

### グータッチ
![03_goo_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/2ec22b24-0990-efb1-c172-90d0fec564bc.gif)
原監督の気分で。

### 片手グータッチ
![04_one_hand_goo_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/3358940f-ae1e-144c-6002-be3187582d16.gif)
ちょっと痛いから気をつけて。

### 握手
![05_handshake.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/48715ba6-9461-4e66-4b94-49f7a9f6c443.gif)
両手で握手するとより心理的安全性が高まる(握らない方の手を添える)。
ハイタッチが恥ずかしかったらとりあえずこれ。

## ちょっと変わったやつ
ここからは自分たちで考えて出てきたやつです。

### 片手グータッチ→片手ハイタッチ
![10_onehand_goo_touch_and_hightouch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/daa2c255-ecca-b7ae-a981-ca36f228f19f.gif)
景気がいい。

### 片手トントンタッチ
![06_onehand_tonton.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/ea5f46b2-9dd0-ebe6-3457-f6c4f4cb201b.gif)
小気味よい。

### 両手トントン→ハイタッチ
![11_bothhand_tonton_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/47b9d0bf-593f-7349-c601-536cb8779fdf.gif)
どっちが上になるか難しいから楽しい。
「トントン・タッチ」と声に出してやるとリズムが合うので良い。

### 2本指タッチ
![07_twofinter_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/2ed373d5-3637-0ca3-60b5-78433cdcfc87.gif)
結構難しい。

### 3本指タッチ
![08_threefinger_touch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/0c710428-167d-8ce2-34ef-384f17a803a2.gif)
結構難しい。
やりたければ1本指でも4本指でも。
ちなみにこの辺のシリーズは娘とハイタッチするときに編み出したもの。

### 体当たり
![09_body_attack.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237077/823926f9-0b55-e9d5-4482-ee610a9f3434.gif)
激しめのが好きな人はどうぞ。
うまくやらないと痛いので気をつけて:sweat_smile:

## ポイント
* 必ず全員とやる
* 「よろしくお願いしまーす」とか、声を出しながらやる
* タッチのパターンに名前をつける。そうすると「今日は片手トントンタッチでいきまーす」と言えば、どれをやるのかが伝わる。
* いろんなメンバーに「今日はどのハイタッチする？」と聞いて決めてもらう。人気のタッチ分かる。
* いろんなタッチのやり方をみんなで編み出す
* 朝会だけじゃなくてミーティングの終わりにやっても良い
* キックオフとかリリース直前ミーティングとか、特別に結束力を上げたいときにおすすめ

## どう導入していいか分からなかったら
やってみたいけど恥ずかしいから言い出しにくいという声をたまに聞きます。
そういうときは何も考えず、何も相談せず、朝会の終わりに
「じゃあハイタッチしまーす。両手出してくださーい」って言ってやっちゃえばいい。

「え？何、急に」みたいな空気になるかもしれませんが
気にせず上がった手に向かって「パーン」と景気よくやりましょう。
みんなしぶしぶ恥ずかしそうにやるはずです。
そしてちゃんとみんな笑っているはずです。

「なんで急にハイタッチ始めたんですか」とか聞かれたら
「なんとなく」とでも返しておけばいいのです。

どうしても難しかったらまず握手から始めてみると良いかもしれませんね。
C＃のできることできないこと

#C#その２アドベンドカレンダー13日目です。
##今日はC#できることできないことを書いていきたいと思います。
実は去年C#に触れるということがありました。
Javaがわかる人C＋＋がわかる人なら簡単にできます。
ただ気をつけないといけないのはクラス呼び出しの書き方です。

```C#
using クラス名
```
になります。

##利点は
正直言うとコンストラクタデコンストラクタが使えるということと簡単にかけるといったところですね。
下手したらPython並に簡単にかけます。
Javaみたいに仕様やライセンスに振り回されることもなくなりました。
最近はクロスプラットフォームでも使えます。
それはxamarinとmonoと.net coreの存在です。
これらが増えたおかげで簡単にいろんなプラットフォームにプログラムが提供できるようになりました。
<storing>実は我社にはC#大好き人間がいますがxamarinのこと知りません。</storing>
今の自分だったらXamarinかPWA(Riot利用の）を考えてしまいますね。
それほどC＃は進化したと思っていますb。
##弱点
実は去年データベースライブラリを自分で作ったのですが。
思ったより使えませんでした。
それは実はPostgreSQLとLINQの組み合わせの相性が最悪でした。
今後頑張って開発していってくれると思っていますが。
オープンオース系データベースとC#の組み合わせが相性悪いです。
これができたら最強な武器の登場になると自分は思っています。

##今後やってみたいこと
特にほしいといえばMySQLとMongo用のLINQができてくれればすぐにでも使いたいです。
と言うか作ってくださいマイクロソフトさん。
PHPも好きですがC#も大分好きになりました。
去年使うまでは食わず嫌いでしたが本当に好きな言語の一つになってくれました。
PHP・Python・Riot・jQueryと同じくらい好きな言語の一つになってくれました。
いろんな複合技を使わなければいけないときには使いたいと思っています。

なんか文書だけになってしまい申し訳ございませんが。
13日目のアドベンドカレンダーといたします。
using を忘れたときの楽な方法


C# で あ～using XXXXXX なんだっけな～

とりあえず書いて、左端のマークをクリック

これで安心。楽でいいよな

----MCK9595さんからアドバイスで追記＆検証＆説明追加----------

もっと簡単な入力方法がありました。**マウス操作なし方法！**

例えば、List と文字を打ち込んだら、**　ctrl + .  enter 　** をすればいいだけ。
マウス操作すら不要。
この場合、Listに相当する using System.Collections.Generic;
が自動追記されます。

これはすごく楽！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/9dea7f78-ae3e-3f34-18cc-395420e9143c.png)

C++のインクルードとは違う。

C#は引き出しを選ぶだけだから意味合いは微妙に違うけど、
作業的には、プログラムの冒頭に何のキーワードを置くか？だけ。
この自動化をやってくれるのはいい。
Vue.jsで使える日付選択ライブラリ（vuejs-datepicker）

# 概要
Vue.js で開発しているときに、日付選択のライブラリで使いやすいのがないかなと
探していた時に出会ったライブラリ。


# 環境
* Vue.js 2.6.10
* vuejs-datepicker 1.6.2

# ライブラリ導入
以下のコマンドでインストールできる

```
npm install vuejs-datepicker --save
```

使い方はこんな感じ

```vuejs
<template>
  <div id="app">
    <h1>vuejs-datepicker</h1>
    <vuejs-datepicker :language="ja"></vuejs-datepicker>
  </div>
</template>

<script>
import vuejsDatepicker from "vuejs-datepicker";
import { en, ja } from "vuejs-datepicker/dist/locale";

export default {
  name: "app",
  components: {
    vuejsDatepicker
  },
  data() {
    return {
      en,
      ja
    };
  }
};
</script>

<style>
</style>
```

見た目はこんな感じ
![vuejs-datepicker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220144/ff3dcd1f-0ad3-4842-496f-3c4f776ba29f.png)

表示言語はpropsの指定で変更することができる（上記の例は日本語版を利用）

# まとめ
Vue.js に特化した日付選択ライブラリの紹介でした。
探しているときに思ったのが、こういったライブラリはやっぱり jQuery を使っているライブラリが多いなと感じました。