OmniAICreator/Qiita-1.07M huggingface dataset:
Nuxt.jsのプロジェクトにESLint + JavaScript Standard Style + Prettierを導入する方法

Nuxt.jsのプロジェクトに、[ESLint](https://eslint.org/)、[JavaScript Standard Style](https://standardjs.com/)、[Prettier](https://prettier.io/)を導入する方法を紹介します。

## create-nuxt-appを使用する場合
プロジェクトの作成に[create-nuxt-app](https://github.com/nuxt/create-nuxt-app)を使用する場合、リントツールのオプションでESLintとPrettierを選択するだけで導入することができます。

## create-nuxt-appを使用しない場合
### ESLintを導入
[create-nuxt-app](https://github.com/nuxt/create-nuxt-app)でESLintを使用する設定でプロジェクトを作成した場合や、Nuxt.jsの[スターターテンプレート](https://github.com/nuxt-community/starter-template)を使用した場合は、あらかじめESLintが組み込まれています。

`.eslintrc.js`ファイルには、Vue.jsのための設定が記載されています。

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    'plugin:vue/essential'
  ],
  plugins: [
    'vue'
  ],
  rules: {}
}
```

`nuxt.config.js`ファイルには、ソースコードの更新時に自動でリントを実行するための設定が記載されています。

```js:nuxt.config.js
module.exports = {
  build: {
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}
```

スクラッチからプロジェクトを作っている場合、これらのファイルをプロジェクトに追加することで同じ構成にすることができます。

### JavaScript Standard Style + Prettierを導入
#### パッケージをインストール
普通の方法ではJavaScript Standard StyleとPrettierのルールが競合してしまうので、両者を併用するためのパッケージである[eslint-config-prettier-standard](https://www.npmjs.com/package/eslint-config-prettier-standard)をインストールします。

```sh
$ npm i -D eslint-config-prettier-standard eslint-config-prettier eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard eslint-plugin-prettier prettier
```

#### ESLintに設定を追加
`.eslintrc.js`ファイルの`extends`に、`prettier-standard`を追加します。

```diff:.eslintrc.js
  module.exports = {
    root: true,
    env: {
      browser: true,
      node: true
    },
    parserOptions: {
      parser: 'babel-eslint'
    },
    extends: [
-     'plugin:vue/essential'
+     'plugin:vue/essential',
+     'prettier-standard'
    ],
    plugins: [
      'vue'
    ],
    rules: {}
  }
```

このとき、`prettier-standard`は`extends`内の最後に書く必要があります。

>Make sure to put it last, so that it gets the chance to override other configs.

出典：[eslint-config-prettier-standard - npm](https://www.npmjs.com/package/eslint-config-prettier-standard)

## 注意
JavaScript Standard StyleとPrettierでは、関数宣言の括弧の前にスペースを入れるルール（[space-before-function-paren](https://eslint.org/docs/rules/space-before-function-paren)）の扱いが異なるため、eslint-config-prettier-standardを用いてリントしたソースコードはJavaScript Standard Styleに完全に準拠しているとは言えません。[^1]
Prettierr Flavored JavaScript Standard Styleとでも呼ぶべきでしょう。

## 参考リンク
* [開発ツール - Nuxt.js](https://ja.nuxtjs.org/guide/development-tools/#eslint)
* [Integrating with ESLint · Prettier](https://prettier.io/docs/en/eslint.html)

## 関連記事
* [Nuxt.jsのプロジェクトにESLint + JavaScript Standard Styleを導入する方法](https://qiita.com/munieru_jp/items/22ad3a5d0919e423b447)

[^1]: [JavaScriptの書式と整形についてあれこれ - Hachirog](http://blog.hachiro.info/entry/2018/02/25/154414)
Nuxt.jsのプロジェクトにESLint + JavaScript Standard Styleを導入する方法

Nuxt.jsのプロジェクトに、[ESLint](https://eslint.org/)、[JavaScript Standard Style](https://standardjs.com/)を導入する方法を紹介します。

## create-nuxt-appを使用する場合
プロジェクトの作成に[create-nuxt-app](https://github.com/nuxt/create-nuxt-app)を使用する場合、リントツールのオプションでESLintを選択するだけで導入することができます。

## create-nuxt-appを使用しない場合
Nuxt.jsの[スターターテンプレート](https://github.com/nuxt-community/starter-template)や、スクラッチからプロジェクトを作っている場合は、自分で導入する必要があります。

### ESLintを導入
[create-nuxt-app](https://github.com/nuxt/create-nuxt-app)でESLintを使用する設定でプロジェクトを作成した場合や、Nuxt.jsの[スターターテンプレート](https://github.com/nuxt-community/starter-template)を使用した場合は、あらかじめESLintが組み込まれています。

`.eslintrc.js`ファイルには、Vue.jsのための設定が記載されています。

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    'plugin:vue/essential'
  ],
  plugins: [
    'vue'
  ],
  rules: {}
}
```

`nuxt.config.js`ファイルには、ソースコードの更新時に自動でリントを実行するための設定が記載されています。

```js:nuxt.config.js
module.exports = {
  build: {
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}
```

スクラッチからプロジェクトを作っている場合、これらのファイルをプロジェクトに追加することで同じ構成にすることができます。

### JavaScript Standard Styleを導入
#### パッケージをインストール
ESLintでJavaScript Standard Styleを使用するためのパッケージ群をインストールします。[^1]

```sh
$ npm i -D eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
```

#### ESLintに設定を追加
`.eslintrc.js`ファイルの`extends`に、`standard`を追加します。

```diff:.eslintrc.js
  module.exports = {
    root: true,
    env: {
      browser: true,
      node: true
    },
    parserOptions: {
      parser: 'babel-eslint'
    },
    extends: [
+     'standard',
      'plugin:vue/essential'
    ],
    plugins: [
      'vue'
    ],
    rules: {}
  }
```

このとき、`standard`は`plugin:vue/essential`よりも前に書く必要があります。[^2]

## 参考リンク
* [開発ツール - Nuxt.js](https://ja.nuxtjs.org/guide/development-tools/#eslint)

## 関連記事
* [Nuxt.jsのプロジェクトにESLint + JavaScript Standard Style + Prettierを導入する方法](https://qiita.com/munieru_jp/items/b90fee4d39536f2ee22f)

[^1]: [eslint-config-standard - npm](https://www.npmjs.com/package/eslint-config-standard)
[^2]: [eslint-plugin-vue - npm](https://www.npmjs.com/package/eslint-plugin-vue)
jqualy よく使うやつ

http://semooh.jp/jquery/api/manipulation/clone/true/

##　.clone()  

```
<button>Clone Me!</button>

jq
$("button").click(function(){
  $(this).clone(true).insertAfter(this);
});

```

##　.find()  
全てのp要素からfindを用いてspan要素を捜し、色を赤くします。これは$(“p span”)と同じ意味である。

```
<p><span>Hello</span>, how are you?</p>

<p>Me? I'm <span>good</span>.</p>
$("p").find("span").css('color','red');
```

##　.uniqueId()

配列中から重複している値を除去し、ユニークになったものを返します。


##　.val() 
全ての要素のvalue属性を返す。


##　.replace() 
 

##　.split()
.split()

##　.pop() 
.pop()  

##　.filter()
.filter()  

##　.append() 
.append() 

##　.hide() 
.hide() 

##　.show()  
.show()  

##　.on()  off 
on発動　　off解除
```
$('button').on('click', function() {
  alert('クリックされました');
});

$('button').click(function() {
  alert('クリックされました');
});

$('img').on({
  'mouseenter': function() {
    // マウスオーバー時の処理
  },
  'mouseleave': function() {
    // マウスアウト時の処理
  }
});

記事
http://js.studio-kingdom.com/jquery/events/off
```


##　.parents()
.parents()  

##　.each()  
.each()  

##　.change()  
.change()  

##　.iCheck()
.iCheck()    

##　.css()
.css()   

##　.positon()
.positon() 

##　.width()
.width()  

##　.data()  

### カスタムデータ

値を適切な型にパースしてくれる

```
参照
JavaScriptで実際に必要な情報を取り出すためにデータをパースするのが難しくなる
https://www.webprofessional.jp/how-why-use-html5-custom-data-attributes/
```

データ属性得られる

```
<body>
<p data-name="taro" data-age="30" data-tel="080-1234-5678">私は太郎です</p>
 
<script>
    var result = $('p').data();
 
    console.log( result );
</script>
</body>
```

結果
```
{tel: "080-1234-5678", age: 30, name: "taro"}
```

##　.addClass() 
.addClass()  

##　.clear_up_form()
.clear_up_form()  

##　.not()
.not() 

##　.removeClass()  


##　.clear_up_form()   


##　.colorpicker()    


##　.bootstrapToggle()     

##　.text() 

##　.attr()  

##　.closest() 


##　.get()  

##　.prop()

##　.modal()


##　.sortable()

##　.disableSelection()


##　e.preventDefault()
SwiftのDictionary生成時のデータの並び順はランタイムで変わる

# 概要

SwiftのDictionaryは順番が保証されないですが、それでトラブったので調べたことを書きます。

# 事の発端

Xcodeをアップデートした後にiOS側で生成したJSON文字列の並びが毎回違うことが発覚。
その後調査したところアプリの起動毎にDictionary型のデータの並び順が変わっていたのでJSONのデータの並び順が変わっていた事がわかりました。

# 何が起こってたのか？

Dictionary生成時に記載した順番と生成されたデータの順番が変わってました。
<img width="1036" alt="スクリーンショット 2018-10-21 14.58.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/161845/b51cfbb4-aa3c-9160-f399-8ead65383d6d.png">

以前は順番が変わらなかったのですが、
ランタイムで生成されたDictionaryの順番が変わるみたいです。

# いつ頃から起こってたか？

おそらくXcode9.4あたり...?

コマンドラインツールなど環境が根本原因なのか古いXcodeを入れ直しても再現できませんでした。

恥ずかしながらXcodeのアップデートを怠っていたのでXcode10で発覚。
Xcode9.3だと問題が発覚しなかったのと、古い別のMacに残ってたXcode9.4.1で検証しても起きてたのでこのあたりが怪しそうです。

ただDictionaryで順番担保しないのは知ってたので、これはコードを書いた側のミスですね...
環境再現ができなかったのでわからずじまいですが、型推論で別の型になってたりなんてのもありえるのかもしれません。

# Dictionaryおさらい

`Dictionaryは変更を加える際には順番は保証できるけどそれ以外はできない`とのこと。
たぶんremoveとかのmutationでは順番は変更されないとかですかね。

```
The order of key-value pairs in a dictionary is stable between mutations but is otherwise unpredictable.
```

[Dictionary - Swift Standard Library | Apple Developer Documentation](https://developer.apple.com/documentation/swift/dictionary)

# 解決策

## JSONの生成時に順番が保証されてればいい場合

`JSONSerialization.WritingOptions`の`sortedKeys`を使いましょう。
key順番でソートしてくれます。

[sortedKeys - JSONSerialization.WritingOptions | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/jsonserialization/writingoptions/2888322-sortedkeys)

ただiOS11からなのでiOS10は爆発するしかない。

## Dictionaryで順番も担保したい場合

`順番を担保したいなら実行速度が遅いけどDictionaryLiteralってのがあるよ`だそうです。

```
 If you need an ordered collection of key-value pairs and don’t need the fast key lookup that Dictionary provides, see the DictionaryLiteral type for an alternative.
```

[DictionaryLiteral - Swift Standard Library | Apple Developer Documentation](https://developer.apple.com/documentation/swift/dictionaryliteral)

使ってみたところkey-valueのtupleをArrayにしたみたいな感じで使い勝手が悪いので役に立たなそう。
当然ながらJSONにできないです。

<img width="1216" alt="スクリーンショット 2018-10-21 15.22.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/161845/a9bd3b8c-1f12-5027-6903-66396780faa6.png">

使い所が思い浮かばないのでうまい使い方があるのか知りたいです。

# まとめ

* ドキュメントはちゃんと読んでから開発しましょう
* JSONの文字列生成時にはオプションでsortedKeysをつけると順番を固定できます
GitHubで複数ユーザーを使い分ける場合の Permission-denied 403 の対処方法

GitHubで複数ユーザーを使い分ける場合の Permission-denied 403 の対処方法
==============================================================================

GitHubで複数ユーザーを使い分けている場合において、gitでpushするときに以下のエラーが出る場合の解決方法について記述します。

```bash
remote: Permission to ユーザー名1/リポジトリ名 denied to ユーザー名2.
```
git pushでpermission deniedされ403エラーになりました。
解決方法は以下の通りです。

# Mac版の解決方法
以下の情報が参考になりました。  
[gitでpushするときに"remote: Permission to ユーザー名1/リポジトリ名 denied to ユーザー名2\."と表示され、pushできないときの対処法。 \- Qiita](https://qiita.com/mzkii/items/d47c37964c435a981114)

# Windows版の解決方法
以下の方法で解決しました。
1. Windowsの「コントロールパネル→ユーザーアカウント→資格情報マネージャー」
2. 「汎用資格情報/Windows資格情報」の項目にある`git:https://github.com`の項目を削除
JavaScriptの非同期処理をキャッシュする場合の注意点

# 概要

「サーバーのAPIを叩くHTTPクライアントでも書くか」
(**※Angularなのでfunctionが要らない・TypeScriptなので型を指定できることに注意**)

```sample1.ts
// Angularを知らない人向けの説明：
// AngularにはHttpClientクラスがあり、それを使うことでGETなどのHTTPリクエストが実行できる。
// また、コンストラクタの引数にするだけでDI(依存性の注入)できる
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) {}

private async getHoge(): Promise<string> {
    return await this.http.get<string>(url).toPromise();
}
```

「でもこれじゃ2回目以降のgetHoge()でもHTTPリクエストしてしまう……キャッシュ化しよう」
(**※GETリクエストが冪等なのはRESTの常識なので**)

```sample2.ts
// 簡単なキャッシュ
cache: {[key: string]: string} = {};

private async getHoge(): Promise<string> {
    // キャッシュにあればそちらを返す
    if ("getHoge" in this.cache){
        return this.cache["getHoge"];
    }

    // キャッシュに無いのでHTTPリクエストし、その結果をキャッシュする
    const result = await this.http.get<string>(url).toPromise();
    this.cache["getHoge"] = result;
    return result;
}
```

「……あれ、キャッシュしたはずなのに何度もHTTPリクエストしてしまうぞ！？」

# 原因

　上記処理はasync/awaitを用いた非同期処理です。
　このことから、getHoge()の1回目の処理(当然キャッシュ化されていない)の途中で別のgetHoge()が走ると、「その段階ではキャッシュにデータが無い」ことから、**そちらについても律儀にHTTPリクエストしてしまいます**。
　具体的には、「Angularで複数配置した同コンポーネントが、配置時に一斉にリクエストする場合」などにこういったミスが起きてしまいます。

# 対策

　**セマフォでHTTPリクエストを待たせます**。
　[本質的にJavaScriptの処理はシングルスレッド](https://qiita.com/klme_u6/items/ea155f82cbe44d6f5d88)であり、非同期処理によって別スレッドと並行処理しているように見えるだけです。なので変数に値を入れる際も、変数に対してロックだのなんだのと考える必要はありません。

```sample3.ts
// 簡単なキャッシュ
cache: {[key: string]: string} = {};

// セマフォ
semaphore: boolean = false;

private async getHoge(): Promise<string> {
    // キャッシュにあればそちらを返す
    if ("getHoge" in this.cache){
        return this.cache["getHoge"];
    }

    // セマフォが立っている際は通信中なので、読み込みを待機する
    if (this.semaphore) {
      // 適当な時間(今回は100ミリ秒)待機する
      await new Promise(resolve => setTimeout(resolve, 100));

      // 再帰的に処理を呼び出す
      return this.getHoge();
    }

    // キャッシュに無いのでHTTPリクエストし、その結果をキャッシュする
    this.semaphore = true;
    const result = await this.http.get<string>(url).toPromise();
    this.cache["getHoge"] = result;
    this.semaphore = false;

    return result;
}
```

# 参考資料

- [JavascriptでAJAXで取得した値を変数にキャッシュして使う - 何度やっても同じ](http://xfan.hateblo.jp/entry/20110311/1299852204)
Rspecのbeforeとitではどのくらい時差があるのか？

#環境
rails 5.1.4
ruby 2.5.0
mysql 5.7.20

#背景
Railsでモデルを作っている時に時間に依存するバリデーションをかける必要がありました。

具体的には、とあるモデルのカラムにdatetime型でデータを保存し、update時に、そのカラムのDBの値と保存しようとしている値が異なる場合は、エラーをあげるというバリデーションをかけようとしていました。

つまり時刻を記録するためのカラムのため、誤って上書きがされないようにしたいということですね。その際に最初は、下記のようにRspecでテストを書いていたのですが、落ちてしまいました。

```ruby
describe 'validations' do
  subject { hoge.update!(store_time: Time.zone.now) }
  let(:hoge) { create(:hoge, store_time: nil) }

  context 'first time' do
    it { expect{ subject }.not_to raise_error }
  end

  context 'second time' do
    before { hoge.update!(store_time: Time.zone.now) }

    it { expect{ subject }.to raise_error(ActiveRecord::RecordInvalid) }
    # ここでエラーが出ない…
  end
end
```

時間依存のバリデーションに対して、このようなテストを書いていた自分が安易ではあるのですが、1秒でも違えば、`ActiveRecord::RecordInvalid`が出るはずではあるので、`before`と`it`の実行時間に1秒も差異がないのだと理解しました。

その後、テストはリファクタして、通したのですが、結局どのくらいの時間差があるのか、気になったので実験してみることにしました。

# 実験
まず最初に時間単位の確認です。
保存しようとするデータとDBのデータは何秒まで記録しているのか見ていきましょう。

```ruby
pry(main)> Hoge.first.created_at
=> Tue, 05 Jun 2018 23:44:57 JST +09:00
pry(main)> Hoge.first.created_at.nsec
=> 0
```

ということはDB上ではnsecでは保存していないという事になります。つまり1秒以上ズレがないと、異なる値とは見なされないということですね。

それではRspecで`before`と`it`の中でどのくらい時間にズレがあるか確かめてみましょう。下記のようにRspecを書きます。

```ruby
describe 'test time' do
  before { puts 'before: ' + Time.zone.now.iso8601(6) }
  it { puts 'it:     ' + Time.zone.now.iso8601(6) }
end
```

そして実行してみると下記のようになりました。

```ruby
  test time
before: 2018-10-21T16:14:10.802145+09:00
it:     2018-10-21T16:14:10.803911+09:00
```

つまり、約0.001秒程度しか差がないということですね…これでは同じ秒と見なされてしまいますし、ごくごく稀に通ってしまう可能性もあるので、かなり悪いテストを書いていたことになりますね…

反省です…

# 結論

`before`と`it`の実行時の時間差は1秒にも満たないので、時間依存のテストを描く場合は、その点を留意して、テストを書く必要がある。
大量の日本語文字の3DモデルをBlenderで効率よく作成する

3Dモデル作成ツールの[Blender](https://www.blender.org/)を利用すれば、3Dモデルを簡単に作成することができます。ただ大量にモデルを作成する場合、手動では時間がかかることがあります。

今回、日本語文字の3Dモデルを大量に作成する必要があったので、色々調べてみたところ、BlenderはPythonスクリプトを利用して、3Dモデルの作成が可能のようです。

## スクリプト

- テキストオブジェクトを作成
- 日本語フォント設定
- 大きさなど設定
- メッシュに変換する

```python

def add_text():
		# フォント読み込み(mac)
        fnt = bpy.data.fonts.load('/System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc')
        # テキストオブジェクトをシーンに追加
        bpy.ops.object.text_add()
        
        ob=bpy.context.object
        ob.data.name = "A"		# テキストオブジェクトの名前設定
        ob.data.body = "ア"			# テキストオブジェクトのテキスト設定
        ob.data.font = fnt				# テキストオブジェクトのフォント設定
        
        s=bpy.context.scene.objects.active
        s.name = "A"
        s.rotation_euler[0]=math.radians(90)		# 角度指定
        # 大きさ指定
        s.scale[0] = 0.2		
        s.scale[1] = 0.2
        s.scale[2] = 0.2
        # 太さなどを指定
        s.data.offset=0.010
        s.data.extrude=0.050
        s.data.bevel_depth=0.020
        s.data.bevel_resolution=1
        # メッシュに変換
        bpy.ops.object.convert(target='MESH')
        bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN')
        bpy.ops.object.transform_apply(rotation=True, scale=True)

```

ループ処理などを追加すれば、大量に作成できると思います。

<img width="655" alt="スクリーンショット 2018-10-21 15.42.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/30218/aa088e45-6913-b41f-9b2c-d980eb3318aa.png">
【Django】複数アプリで共通のテーブルを使いたいケース


とあるWeb予約システムをつくる際にひっかかった、

**複数アプリで共通のテーブルを使いたい**

場合のフォルダ構成アイデアです。

詳細はブログも参照ください。

[【Django】Webアプリのフォルダ構成のアイデア〜違うアプリで同じテーブルを使いたい！
](http://coinbaby8.com/django-folder-structure-idea.html)

## ViewとModelを同じ階層でつくればOK

Pythonの仕様で、import元は同階層か下の階層にある必要があるようです。
(裏技もあるようですが非推奨と思われます。)


ModelはViewから呼ばれるので、
ModelとViewが同階層か、Modelが下階層にあればOKです。



```
(venv) django_project$ tree
.
├── config     #プロジェクト作成時の設定フォルダ
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── newapp   #アプリフォルダ(共通)
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── urls.py   #新規作成
    ├── migrations
    │   └── __init__.py
    ├── models           #モデルフォルダ作って  
    │   └── __init__.py
    │   └──reserve.py    #それぞれモデルファイル作成
    │   └──manage.py     #こっちもモデルファイル
    ├── tests.py
    └── views_reserve.py # views.pyファイルの名前を変更
    └── views_manage.py # 新しくファイルを作成
```

newapp/urls.py 内のルーティングで2つのviewsファイルを指定。

```python:urls.py
from django.urls import path
from . import views_reserve, views_manage  #ファイル名指定
 urlpatterns = [ 
     path('reserve', views_reserve.xxx, name='reserve'), 
     path('manage', views_manage.xxx, name='manage'), 
```

modelsフォルダ内のinit.py に下記の記載をします。

```python:init.py
from newapp.models.reserve import *
from newapp.models.manage import *
```
これでいくつでもファイル分けられます。
(View側もフォルダつくってわけられますが階層が下がっちゃうので今回のケースではNG)

## おわりに

わかってみれば簡単なんですが数日悩んだので誰かの役にたてれば幸いです。

## 2018/10/22 追記

コメント頂きまして、INSTALLED_APPS に追記でもいけるようです。


INSTALLED_APPSを

```
INSTALLED_APPS = [
    ... < 略 > ...    
    'reserve.apps.ReserveConfig',
    'manage.apps.ManageConfig',
    ... < 略 > ...        
]
```

としてあげれば、

```
from reserve.models import *
from manage.models import *
```

でお互い相互にモデルのクラスを持ってくることはできるはずです。
リレーションも、

```
hogehoge = models.ForeignKey('reserve.FOO', on_delete=models.CASCADE)
```

とかでいけます。（ベストプラクティスかどうかはさておき）
[Command Line]基礎編

はじめまして、プログラミングの初心者です。
こちらで簡単な学習メモを残していきたいと思います。
よろしくお願いします。
#ファイルの構造
・ホームディレクトリ；作業をするときに起点にするディレクトリ。「~」で表される。
・ルートディレクトリ；1番親のディレクトリ。「/」で表される。
・カレントディレクトリ：自分が今いるディレクトリ。
***ディレクトリの移動***
`cd ディレクトリ名`
***一つの親ディレクトリの移動***
`cd ..`
***ホームディレクトリの移動***
`cd`
***カレントディレクトリの確認***
`pwd`
print working directoryの略。
***ディレクトリの中身を表示する***
`ls`
listの略。
#ファイルやディレクトリの操作
***ファイルの作成***
`touch ファイル名`
***ファイルの中身を表示する***
`cat ファイル名`
***ディレクトリを作成する***
`mkdir ディレクトリ名`
make directoryの略。
***ファイルとディレクトリの移動***
`mv ファイル名 ディレクトリ名`
`mv ディレクトリ名 移動先のディレクトリ名`
moveの略。
***ファイル名の変更***
`mv ファイル名 新しいファイル名`
***ファイル名とディレクトリのコピー***
`cp コピーするファイル名 新しいファイル名`
`cp -r コピーするディレクトリ名 新しいディレクトリ名`
copyの略。
***ファイル名とディレクトリ名の削除***
`rm ファイル名`
`rm -r ディレクトリ`
removeの略。
チャットボット作成中

こんにちは。

本日はチャットボットのサンプルをせっせと作っています。

それではコードです。

```PHP
<!doctype html>
<head>
<title>
Sample
</title>
</head>
<body>
<form method="POST">
<textarea type="text" name="comment" placeholder="自由に入力してください"></textarea>
<input type="submit">
</form>
<?php
$data = htmlspecialchars($_POST['comment'],ENT_QUOTES,'UTF-8'); 
$arr = array('おはようございます','こんにちは','こんばんは','こまりましたね');
echo $data.'<br>';

foreach($arr as $val){
	if($data == $val){
		echo $val.'<br>';
		
	}elseif($data = 'こんにちは' == $val = 'こんにちは'){
		echo $val.'<br>';
		
	}elseif($data = 'こんばんは' == $val = 'こんばんは'){
		echo $val.'<br>';
	}elseif($data = 'お金がありません' == $val = 'こまりましたね'){
	echo $val;
	}
	
		break;
}
```
本当にチャットボットというか、チャットボットもどきというか・・・

これだと、おはようございますと入力しSubmitすると

おはようございますと返してくれます。

これは個人的に思っていたことと同じなので、正解。

問題はその後です。

こんにちはとうってこんばんはと出たり

こんにちはと返してきたりとなります。

これは恐らくelseifの書き方が悪いんだろうな

という印象を受けています。

PHP Data objectもやってみていますが

foreachが動かないという所から

foreachや配列への理解が足りていない

というところから路線を変えて

こういう風に、基礎的な内容だけでチャットボット

の作成をしてみようと思った次第です。

foreachとswitch文を組み合わせて

やってみたりもしてみようと思います★
CSSを書いてgoogleの検索結果に順位を表示させる方法

SEOを仕事にしている方なら、共感していただけると思うのですが、

<img width="685" alt="スクリーンショット 2018-10-21 16.00.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/14191/1ee208fb-9813-a697-7885-00dfbc9b071b.png">

ある検索結果に対して、この記事は何位だっけ？というのを一番上から数えて...
という経験はないですか？

そんな時に、サクッと何位かわかる方法を紹介します。

# やり方

まず、chromeの拡張機能「[stylus](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne)」をインストールします。これは、お気に入りのWebサイトのスタイル（CSS）を任意のCSSに変えてしまうアドオンです。

そして、詳細設定で、下記の通りに設定を行ってください。

stylusを選択して、「管理」を選択

<img width="248" alt="スクリーンショット 2018-10-21 15.42.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/14191/45e965d0-002f-b222-3cc0-16eb6f99df43.png">

すると、　色々なメニューが出力されます。そこから「新スタイルを作成」を選びます。

<img width="233" alt="スクリーンショット 2018-10-21 15.39.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/14191/91603209-fa58-ff29-3666-07a430531b1d.png">

次に、

- 指定のCSSを貼り付けます
- 指定のURLを貼り付けます「https://www.google.co」
- 任意の名前を入力（参考:google_rank） ← google検索した時のみこのスタイルを適用させる
- 保存

<img width="849" alt="スクリーンショット 2018-10-21 15.51.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/14191/72e98884-c663-2ac0-b4f1-ab3382faf8c9.png">

指定のCSSを下記に貼り付けます。

```css
body {
    counter-reset: result !important;
}

h3.LC20lb:before {
    content: counter(result) ". " !important;
    counter-increment: result !important;
    display: inline-block;
    background: #fbe4c2;
    margin-right: 1em;
}
```

ポイントは、CSSのプロパティである`counter-increment`を使って、任意のクラス（`h3.LC20lb`）を要素回数ごとに連番をつけているところです。

ここまで設定できたら、google検索した際にランクが表示されています。

<img width="729" alt="スクリーンショット 2018-10-21 15.58.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/14191/d4835101-1820-2e82-7e22-eb0131c3ff0a.png">

これで、サクッと何位かわかるようになりましたね。

# 改善ポイント

2ページ目からも1から表示されてしまうところですね。ここ、なんとかできる方、コメント待ってます。もちろん、GRCとか使えば指定キーワードの順位は定期的に取れるんですが、今回はサクッとわかるやり方を紹介しました。ありがとうございました！
EC2のAMIはベースOSの種類でログインユーザー名が異なる

wordpressのサイトをEC2で作りたいと思い、AMIからbitnami-wordpresのイメージを使ってデプロイを行いました。作成方法は以下の通りです。

+ インスタンス作成時にAMIカスタムイメージを選択(bitnami-wordpress)
- 既存で作成していたpemファイルを選択
- インスタンス起動

これでログインすると以下のようなエラーが出ました。

```
[hogenoMacBook-ea:~/.ssh $ ssh wordpress-aws01
ec2-user@ec2-52-68-14-142.ap-northeast-1.compute.amazonaws.com: Permission denied (publickey).
```

ssh接続はconfigファイルで管理しており、こちらの設定はこんな感じです。

```
#wordpress-aws01
  Host         wordpress-aws01
  HostName     ec2-52-68-14-142.ap-northeast-1.compute.amazonaws.com
  User         ec2-user
  IdentityFile ~/.ssh/authorized_keys/test-aws01.pem
```

今までの経験上あるあるの間違いは

- ディレクトリ、pemファイルのパーミッション
- 異なるpemファイルを利用している

なので今回も確認してみました。

```
[hogenoMacBook-ea:~/.ssh $ ls -la
total 16
drwx------   5 hoge  staff  160 Oct 21 15:12 .
drwxr-xr-x+ 26 hoge  staff  832 Oct 21 15:12 ..
drwx------   3 hoge  staff   96 Jul 21 12:39 authorized_keys
```
authorized_keysのディレクトリは700になっているので所有者にリード、ライト、実行権限があるので問題ないです。

```
[hogenoMacBook-ea:~/.ssh/authorized_keys $ ls -la
-rw-------  1 hoge  staff  1692 Jul 21 12:39 test-aws01.pem
```

pemファイルのほうも問題なさそうです。
他のEC2も同じpemファイルで接続しているので、異なるpemを使用している線はないです。

そんな中いろいろ探しているとまずEC2でsshエラーが出たときはAWSのこのサイトを見ましょうということが書いてありました。

[インスタンスへの接続に関するトラブルシューティング
](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html#TroubleshootingInstancesConnectingMindTerm)

スクロールしていくとAMIによって標準のユーザー名が異なると書いてありました。

> Amazon Linux 2 または Amazon Linux AMI の場合は、ユーザー名は ec2-user です。
> Centos AMI の場合、ユーザー名は centos です。
> Debian AMI の場合は、ユーザー名は admin または root です。
> Fedora AMI の場合、ユーザー名は ec2-user または fedora です。
> RHEL AMI の場合は、ユーザー名は ec2-user または root のどちらかです。
> SUSE AMI の場合は、ユーザー名は ec2-user または root のどちらかです。
> Ubuntu AMI の場合は、ユーザー名は ubuntu です。

なるほど、原因はこれですね。bitnami-wordpressのAMIを調べてみるとubuntuになっていたので、configファイルを修正します。

```
#wordpress-aws01
  Host         wordpress-aws01
  HostName     ec2-52-68-14-142.ap-northeast-1.compute.amazonaws.com
  User         ubuntu          //es2-userからubuntuへ変更  
  IdentityFile ~/.ssh/authorized_keys/test-aws01.pem
```

変更してからsshしてみます。

```
[hogenoMacBook-ea:~/.ssh $ ssh wordpress-aws01
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1065-aws x86_64)
*** System restart required ***
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|

  *** Welcome to the Bitnami WordPress 4.9.8-0 ***
  *** Documentation:  https://docs.bitnami.com/aws/apps/wordpress/ ***
  ***                 https://docs.bitnami.com/aws/ ***
  *** Bitnami Forums: https://community.bitnami.com/ ***
Last login: Sun Oct 21 06:12:21 2018 from 150.249.202.145
bitnami@ip-172-31-35-129:~$
```

AMIのログインユーザーは全部ec2-userだと思ってました。OS種別毎にユーザー名が異なるみたいなのでこれからは気をつけたいと思います。
AWSおよびAmazon FreeRtos

アマゾンWeb Serviceの現状を分析し、どのようなサービスを今後提案するかの記録です。

#AWS(amazon web service)現状確認
https://aws.amazon.com/jp/

##APIで自動化

## 他者と差別化する領域（競争力）に焦点

##革新を加速

##安心を強化

###security 
certification 14項目

AWSの中身を見ない。

暗号化

#技術
##Amazon Robotics
　川崎full fill center
##Amazon Dash button
500円。
### amazon dash replenishment service
dashボタンの自動化

##amazon alexa

##amazon Go
シアトル。アプリで入る。
IoTと機械学習。
computer vision 
deep learning


##amazon primeair

##amazon echo

#IoT
##AWSIoT 3年前。安全かつ簡単に

身元証明。UIなしに認証。
大量のデバイスを接続するサーバ。数百万台が接続。
クラウドからデバイスを制御。双方向の通信。httpより軽いもの。

## AWSIoT new
### AWS IoT Care

### AWS IoT Device Management
firmware遠隔更新。
更新の監視。何台済みか。未更新を網から切断。

### AWS IoT Device Defender
認証情報が出た情報を検知。
他への接続を検知。

### AWS IoT analytics
ネットにデータがあがっていない
ネットに上がったデータが
前処理：クレンジング

機械学習。

##
3つ

Rock inされたくない。

全部amazon.
暗号鍵は工場で。
CA自前

##FreeRtos

https://aws.amazon.com/jp/freertos/

http://monoist.atmarkit.co.jp/mn/articles/1712/28/news011.html

あとから更新できるように作る。
何が障壁になっているか。

権利を買い取る。Richard Vari。その人に依存。


### AWSIoT Device SDK
python, javascript, C++, embedded C
通信層をライブラリ。

####ライブラリ
ローカル接続（Edgeコンピュータ、Wifi)
クラウド接続（AWSおよびそれ以外）

セキュリティ
OTA &署名

MQTT クラウドに依存していない。
セキュアソケット　クラウドに依存していない。

接続
25MHz以上
64KB以上のRAM
アーキテクチャは40以上。
暗号化のハードがあれば、10MHzで16KBでも可能。

###スマートデバイス
アプリケーション開発
OTA update
状態管理
証明書埋め込み
TLS対応
MQTTクライアント対応


セルラー提供していない。ユーザ対応。

##Amazon FreeRtos 認定プログラム
Micro chip
NXP
ST
TI
XX
infineon

Test Suiteを用意。
モジュールごとに試験。

Enduserも Test Suiteを使える。

ARM, IAR, MIPS, SEGGER


##
チップが対応しているか

NXPの例。
Wifiはチップベンダが作っている。

HTTPを使うなら別に作らないと。


###
2枚のピザを共有できる人数。

### OTA agent
別タスク。

### update
検索してgroup作成
狙い撃ち

###Edge, mini。Raspberry PI以上。

### use case
B2C：顧客
B2B：商業
B2B：産業

speed, cost, complexityを下げる。

### Reference.
車：同様のライブラリを。

### Alexa連携
移行対応。cloud対応。接続。

#### Alexa connect kit

##Greengrass

オフラインになったとき、異常検知ができないと困る。
Edge computing。デバイス側でも動く。Proxyも動く。



##デバイス




#顧客中心
低価格を実現するためのサイクル
##　顧客体験
##　顧客数
日本で10万、世界で数百万
中央大学、広島大学、近畿大学

##　出展社
##　品揃え
##　成長
##　低費用
##　低価格
66回の値下げ
Laravel artisan generate系コマンドのメモ


### Controller

```
php artisan make:controller XyzController
```

namespace付きの場合

```
php artisan make:controller Abc\\XyzController
```


### Model

```
php artisan make:model Xyz
```


### Resource 

※ Resource ・・・ レンダリング用に出力を整形するクラス

* 単体

```
php artisan make:resource XyzResource
```

* コレクション

```
php artisan make:resource XyzResourceCollection
```


### Policy

※ Policy ・・・ レンダリング用に出力を整形するクラス

```
php artisan make:policy XyzPolicy
```
mac でavr-gccのinstallに失敗する(qmk_firmware関連の作業)

## 結論
依存libを削除してからインストールする

```
brew remove GMP MPFR MPC
brew install avr-gcc@7
```
(警告が出た場合はよしなにそれを付加して実行)


## 環境(コンテキスト)
こんなような表示がでてinstallに失敗している状況

```
http://gcc.gnu.org/install/prerequisites.html for additional info.  Ifyou obtained GMP, MPFR and/or MPC from a vendor distribution package,make sure that you have installed both the libraries and the headerfiles.  They may be located in separate packages.
```

macOS Mojave 10.14
fish shell

## 上記解決までは以下の方法で対応していた。(qmk_firmware)
hex fileのbuild(dockerを利用)
keybordはよしなに自分の使っているものを選択
(fish用に改変しているので、よしな変えてください。)

```
docker run -e keymap=default -e keyboard=crkbd --rm -v ('pwd'):/qmk:rw edasque/qmk_firmware
```

読み込ませる
$リセットボタンを押してから$、以下コマンドを実行([こちら](https://buty4649.hatenablog.com/entry/2018/02/07/215300)を参考にさせていただきました。)

```
sudo avrdude -p atmega32u4 -c avr109 -P /dev/tty.usbmodem* -U flash:w:.build/crkbd_rev1_default.hex
```

この方法だと別途キーボードがもう一つ必要でしんどい。

## 余談
自作キーボードのファームウェア周り情報が少なくて、ニッチな問題に当たると疲弊してしんどいです。
この情報が同士の役に立つことを祈って:innocent:
英語  会話編　

## 話の入り始め

```
切り出し
How’s it going? 調子どう？
What’s going on? どうしたの？
What’s the matter? どうしたの?
Just between us. ここだけの話だよ。
Where was I? 私、何の話をしてたっけ？
Where were we? 私たち何の話してたっけ？
It’s my turn. 私の番だよ。
```

気分を

## ネタを作る

```
自己紹介


近況
How have you been?どうしてた？
How have you been recently?最近どんな感じ？
```

## 共感

```
I hope so. そうだと良いなぁ。
So do I. 私もそうです。
Neither do I. 私もそうじゃないんです。
That is true. それは正しいです。
You are right. あなたは正しいです。
That’s for sure. それは確かです。
```

## 否定

```
Of course not.もちろん違うよ。
That’s not ture. それは違うよ。
You’re kidding. 冗談でしょ！
I know that. そんなことわかってるよ。

i am afraid to say
```

## 確認

```
Is that right? それって確かなの？
Are you serious? 本気なの？
Are you sure? 自信があるの？
What’s your point? 何が言いたいんですか？
```

## 会話を広げる

```
And you?君は？
What about you?君はどうなの？
How about you?君はどう？
speaking of it
```

## 意見をいう

自分の意見を伝えたい時
```
I think …（〜と思います。）
I don't think …（〜とは思いません。）
In my opinion, …（私の意見では〜です。）
As far as I know …（私の知る限り〜です。）
In my view/from my point of view, …（私から見れば〜です。）
I believe that …（〜と信じます。）
I don't believe that …（〜とは信じられません。）
If you want my honest opinion …（私の率直な意見を述べれば〜です。）
```

人の話を遮る

```
I'm sorry, but …
Sorry to interrupt, but …
遮ってごめんなさい、でも・・・

と言う方がベターです。相手の話に関連して、捕捉を入れたい時には、

May I add something here?
ちょっと捕捉して良いですか？
```

相手の意見を聞きたい時

```
What do you think?
What's your opinion?
あなたはどう思う？

と言えばOKです。
相手の言っている事がわかりにくく、明確化して欲しい時などには、

What do you mean by A?
What are you trying to say by A?
Aってどういう意味？
```
英語　MTG　流れ

## 流れ
1. はじめの挨拶

```
– Thank you for your time. （お時間をいただき、ありがとうございます）

スタンダード中のスタンダードですが、最初の一言で緊張してしまうという方はこうした簡単なフレーズからはじめると、いくらか不安がとりのぞけるでしょう。

＜中上級者向け＞

– Thank you for joining me/us today. （本日はご参加いただきありがとうございます）

– It is a great pleasure to have you all today. （本日皆様にお集まりいただいたことを光栄に思います）
```

2. 自己紹介


3. 本題に入る

```
– Today, I am going to talk about…（今日は・・・についてお話ししましょう）

– Today, I’m here to…（今日は・・・するためにお集まりいただきました）

- Today, I would like to talk to you about (product innovation).

＜中上級者向け＞

– The main objective of this meeting is to…（このミーティングの目的は・・・です）
```

4. 前提の確認

```

– As you may know…（ご存知かと思いますが・・・）

– As we discussed via email…（Eメールでもお伝えしましたが・・・）

概要の説明

-　There are three things I’d like to cover today. Firstly, I will talk about (our new technology). Then I will explain (new product features). Finally, I will describe (our new pricing system). 

- This presentation will take about one hour.
＜中上級者向け＞

– I assume you are aware of …（・・・についてはすでに把握してらっしゃるかと思いますが）

– I believe we could all agree that…（・・・だということは周知の事実でしょう）
```


5. 資料・パワポを引用する

```
– Let’s look at …（・・・をご覧ください）

– As you can see…（ご覧の通り・・・）


```

6. 起承転結

```
Introduction（序章）自己紹介、プレゼンの目的、アウトライン（所要時間含む）等
Body（本論）プレゼンの目的に合わせ、複数にわたるトピックで話を展開しましょう。。
Conclusion (結論) 
```

7.　まとめる

```
＜初心者向け＞

– In conclusion…（結論としては・・・）

＜中上級者向け＞

– To summarize my main points…（私の言いたいことをまとめると・・・）

– This brings me to my conclusion, which is…（こういったことから私は・・・という結論に至りました）


```

8.　質疑応答

質問を受け付ける
```
– Any questions? （質問はありますか？）
 Now, I will be happy to answer your questions. （それでは、皆様からの質問を受け付けます）

```

質問に答える


```
＜初心者向け＞

– I agree to your point that…（・・・という点ではあなたに賛成します）

– As you mentioned…（あなたがおっしゃったとおり・・・です）

＜中上級者向け＞

– As I mentioned earlier…（先ほど申し上げたように・・・）

– As we saw earlier…（先ほどお見せしたように・・・）

– That’s another way to see it. （たしかにそういう見方もできますね）


```

9. 終了の合図をする

```
＜初心者向け＞

– That’s it from me. Thank you very much（私からは以上です。ありがとうございました）



```
ドキュメントライブラリのカスタム列を更新するPowerShell

###ドキュメントライブラリでまとめてフォルダやファイルをアップロードした後にカスタム列のデータを更新するPowerShell
テストデータの作成などで

```
#ロード
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")

#ユーザーID
$User = "user@xxxxx.onmicrosoft.com"

#更新対象ドキュメントライブラリがあるサイトのURL
$SiteURL = "https://xxxxx.sharepoint.com/sites/xxx/"

#更新対象ライブラリの名称
$DocLibName = "test"

#パスワードを入力
$Password = Read-Host -Prompt "Please enter your password" -AsSecureString

#対象のサイトの読み込み
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds

#対象のライブラリの読み込み
$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List.RootFolder)
$Context.ExecuteQuery()

$camlQuery = new-object Microsoft.SharePoint.Client.CamlQuery
#再帰的に取得（フォルダ内部のデータも対象）
$camlQuery.ViewXml = "<View Scope='RecursiveAll'><Query><Where></Where></Query></View>"
		
$listItems = $list.GetItems($camlQuery)
$context.Load($listItems)
$context.ExecuteQuery()

#無条件に読み込み、存在するデータ分一律の値でUpdate
foreach($listItem in $listItems){
    $listItem["customColumn"] = "test"  #件名
    $listItem["startDate"] = Get-Date -Format “yyyy/MM/dd” #開始予定日　
    $listItem["endDate"] = “2018/12/31” #終了予定日

    $listItem.Update(); 
    $Context.ExecuteQuery();  
}

```
ドキュメントライブラリのリストテンプレートをコピーしてドキュメントライブラリを生成するPowerShell

###リストテンプレートをコピーしてドキュメントライブラリを生成するPowerShell
コンテンツを含む場合は、コンテンツ（ファイル、列の情報）もコピーされますが、件数が多いと処理時間が遅いのである程度を分割して平行で実施した方が良いです。



```
#モジュールのロード
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")  

$siteURL = "https://xxx.sharepoint.com/sites/xxxxx"
$ListTemplateInternalName = "○○○○○○.stp" #コピー元のテンプレート名
$userName = "user@xxxxx.onmicrosoft.com"
$ListName = "test" #コピー後のドキュメントライブラリ名

#認証
$password = Read-Host "Please enter the password for $($userName)" -AsSecureString 
$SPOCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $password)

$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$context.credentials = $SPOCredentials 

$web = $context.Web
$site = $context.Site
$ListTemplates = $site.GetCustomListTemplates($web)
$context.Load($web)
$context.ExecuteQuery()
$context.Load($ListTemplates)
$context.ExecuteQuery()  

$ListTemplate = $ListTemplates | where-Object { $_.InternalName -eq $ListTemplateInternalName }

#必要なドキュメントライブラリ分だけ繰り返す
for($i = 1; $i -le 100; $i++){
      $ListCreation = New-Object Microsoft.SharePoint.Client.ListCreationInformation
      $ListCreation.Title = $ListName + $i
      $ListCreation.ListTemplate = $ListTemplate

      $newList = $web.Lists.Add($ListCreation)

      $context.Load($newList)
      $context.ExecuteQuery()
}

$context.Dispose()

```

###参考
[Create a Document Library from a Template using SharePoint Online PowerShell](https://stackoverflow.com/questions/51257382/create-a-document-library-from-a-template-using-sharepoint-online-powershell)
[Create new document library in SharePoint Online with PowerShell](https://www.sharepointfire.com/2016/01/create-new-document-library-sharepoint-online-powershell/)
[Create a new list from custom template with CSOM in SharePoint Online](https://sharepoint.stackexchange.com/questions/149044/create-a-new-list-from-custom-template-with-csom-in-sharepoint-online)
【Flaskチュートリアル】テーブル作成時の制約をまとめた。

#なんのために共有するか？
sqlite3でテーブルを作成するときのポイントをまとめました。
（知っておくと他のSQLでも応用できるはず。）

flaskのチュートリアルとして作成する
flaskrのデータベースとそのテーブル構成は下記のようになっている。
その中から学習しよう。
下記に制約の解説があるので、
まずはこんな感じになっているとさーっと読み飛ばせばOK。

`CREATE TABLE テーブル名`でテーブルを作成。
flaskではuserテーブルとpostテーブルを取り扱う。

```sql:schema.sql
-- Initialize the database.
-- Drop any existing data and create empty tables.

DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;

CREATE TABLE user (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  username TEXT UNIQUE NOT NULL,
  password TEXT NOT NULL
);

CREATE TABLE post (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  author_id INTEGER NOT NULL,
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  title TEXT NOT NULL,
  body TEXT NOT NULL,
  FOREIGN KEY (author_id) REFERENCES user (id)
);
```

#PRIMARY KEY制約
カラムにPRIMARY KEY制約を設定した場合、
そのカラムは主キーになる。
だいたいテーブル内のidはPRIMARY KEY制約を持ってる。
flaskチュートリアルでも重要なところだけpick upするとこんな感じ。

```sql:schema.sql
CREATE TABLE user (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
(省略)
);

CREATE TABLE post (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
(省略)
);
```

#UNIQUE制約
カラムに格納する値として
既に格納されているデータの値とかぶった値では登録できないようにする場合、
カラムにUNIQUE制約を設定する。
例えばusernameがかぶるのはダメよと。

```sql:schema.sql
  username TEXT UNIQUE NOT NULL,
```

#NOT NULL制約
NOT NULL制約を設定すると、
NULLを格納することができなくなる。
逆にいうと、なんかしらの値があれば格納することができるってこと。
例えば、パスワードはなしはさすがにまずいよねって意味ならこう。

```sql:schema.sql
(省略)
  password TEXT NOT NULL
(省略)
```


#DEFAULT制約

値をテーブルに追加するときに、
timestampはDEFAULTで記述すると便利。

```sql:schema.sql
(省略)
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
(省略)
```

#外部キー(FOREIGN KEY)
他の行と比べると、ちょっと癖のある書き方。
だけどすぐ理解できるから安心を。

idはuserテーブルのPRIMARY KEYになっている。
でそれをpostテーブルの中ではauthor_idという名前で使いたい
ということだ。

こうすると、
そもそもuserテーブルに存在しないidをもつデータは、
postテーブルには格納できねーよ？
って仕組み。


```sql:schema.sql
  FOREIGN KEY (author_id) REFERENCES user (id)
```

#応用編
##CHECK制約
CHECK制約を設定すると、
任意の条件式を指定できます。
例えば0以上の値を設定してほしいときはこう。

```sql:schema.sql
(省略)
  test_result integer check(test_result >= 0 and test_result <= 100));
(省略)
```

#最後に
**「知りたかったことが知れた！」**とか**「新しいことが知れた！」**
と思ったら左の**いいねボタンをポチッと**お願いします！

デザインエンジニアのMasaでした！
ではではドロン！！
<img src="https://storage.googleapis.com/edd-homepage/IntroductionEdD/img/masa.png" width=30%>
Homebrewでダウングレードをする方法

# ダウングレード
Homebrewのダウングレードがまぁまぁ面倒だったのと、
上がっている記事が古くなりつつありそうだったのでメモ。
こちらの記事を参考にさせてもらいました。

https://qiita.com/honeniq/items/778cc08d2db78e6774d8


# brew upgradeして新しいバージョンにしたけど戻したい時
上記記事に書いてあるので(私が使ったことがないので)割愛させていただきます。
`brew switch`コマンドで簡単にバージョン切り替えができるようです。

# 旧バージョンが提供されている場合
上記記事では `versions` リポジトリを追加していましたが、deprecatedされていました。
それぞれのフォーミュラが `gcc@7` のような形でバージョンを指定できるようにしていないと、バージョンを通常の方法で指定してインストールすることはできないと思います。


# 上記二つに該当しない時
HomebrewがFomulaを管理しているrubyスクリプトを集めたディレクトリが存在します。rubyスクリプトはgit管理されており、該当するソフトウェアのlogから該当するバージョンをインストールするように指示したバージョンにrubyスクリプトを戻すことでhomebrewが指定のバージョンをインストールしてくれるようになります。

まずは先ほど述べたディレクトリまで移動します。

```
macOS Mojave 10.14
Homebrew 1.7.7
```

上記の環境においては、`/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula` にありました。今回、zshおよびtmuxのダウングレードを行いたかったので、

```
$ git log zsh.rb
commit d1b4a80301fd3eba0ceb1917baba454eeea9f13e
Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
Date:   Tue Oct 16 19:58:10 2018 +0000

    zsh: update 5.6.2_1 bottle.

...(中略)...

commit 6d3232544b5f6f0d2b65c6ed89622beb11c4643b
Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
Date:   Sun Aug 19 15:13:51 2018 +0000

    zsh: update 5.5.1 bottle.
```

```
$ git checkout 6d3232544b5f6f0d2b65c6ed89622beb11c4643b zsh.rb
```

次に現在使用しているzshをunlinkする必要があります。
unlinkした後はいつも通りinstallすれば該当のバージョンがインストールされます。

```
$ brew unlink zsh
$ brew install zsh
```


# 事の発端
今日、tmuxにて新しいpaneを開いたら、下記のようなエラーが発生。


```
/usr/local/Cellar/zplug/2.4.2/autoload/init.zsh:16: colors: function definition file not found
polling.zsh:17: add-zsh-hook: function definition file not found
__zplug::core::core::get_interfaces:49: regexp-replace: function definition file not found
__zplug::core::core::get_interfaces:49: regexp-replace: function definition file not found
...(中略)...
__zplug::core::core::prepare:67: compinit: function definition file not found
[zplug] ERROR: The loading of zplug was discontinued.
```

最近zshrcをイジイジしていたため、zshrcのデバッグを行なっていたものの、どうにも治らぬ。
もしかして別の問題かと思いエラーログを確認しに行くとissue上がっとるやん。

https://github.com/zplug/zplug/issues/477

曰く、zshとtmuxの最新バージョンが原因らしいとのことでダウングレードを慣行をした次第です。
同じエラー出た人の検索に引っかかるようにどうでも良い蛇足を付け加えました。
Pythonで集合を使ったひらがなチェック

# 背景
~~初めて開発案件に携わったこともあり、自分もQiitaに投稿してみたくなった。~~
担当案件で外部ファイルから読み込んだ文字列が、全てひらがなで構成されているかチェックする必要があり、処理を書いたのでそのメモ。


# 判定の考え方
文字列を構成する文字の集合とひらがな全体の集合の共通集合を取り、その結果で判定する。

- 結果が与えられた文字列の文字集合と同じ：ひらがなのみ
- 結果が与えられた文字列の文字集合と異なる：ひらがな以外が混ざってる 


```Python
def validate_given_word_is_consisted_of_hiragana(word):
    kana_set = {chr(i) for i in range(12353, 12436)}
    word_set = set(word)
    if word_set & kana_set != word_set:
        return '"{}"には平仮名以外の文字が含まれてます'.format(word)
    else:
        return '"{}"は平仮名だけで構成されています'.format(word)
```

なお、全てひらがなではなく、1文字でもひらがなを含む文字列かを判定したい場合、ひらがな全体の集合と文字列を構成する文字の集合の差集合を取り、その結果で判定するとよい。

- 結果がひらがな全体の集合と同じ：ひらがなは含まれていない
- 結果がひらがな全体の集合と異なる：ひらがなが含まれている

```python
def validate_given_word_is_including_hiragana(word):
    kana_set = {chr(i) for i in range(12353, 12436)}
    word_set = set(word)
    if kana_set - word_set == kana_set:
        return '"{}"には平仮名は含まれていません'.format(word)
    else:
        return '"{}"には平仮名が含まれています'.format(word)
```

実際に動作確認してみたソース。

```Python:validate.py
def validate_given_word_is_consisted_of_hiragana(word):
    kana_set = {chr(i) for i in range(12353, 12436)}
    word_set = set(word)
    if word_set & kana_set != word_set:
        return '"{}"には平仮名以外の文字が含まれてます'.format(word)
    else:
        return '"{}"は平仮名だけで構成されています'.format(word)


def validate_given_word_is_including_hiragana(word):
    kana_set = {chr(i) for i in range(12353, 12436)}
    word_set = set(word)
    if kana_set - word_set == kana_set:
        return '"{}"には平仮名は含まれていません'.format(word)
    else:
        return '"{}"には平仮名が含まれています'.format(word)


if __name__ == "__main__":
    print(validate_given_word_is_consisted_of_hiragana('やきにく'))
    print(validate_given_word_is_consisted_of_hiragana('焼き肉'))

    print(validate_given_word_is_including_hiragana('焼き肉'))
    print(validate_given_word_is_including_hiragana('焼肉'))
```
上ソースの出力結果。

```
"やきにく"は平仮名だけで構成されています
"焼き肉"には平仮名以外の文字が含まれてます
"焼き肉"には平仮名が含まれています
"焼肉"には平仮名は含まれていません
```

# 参考
文字列の集合を作るときに参考にさせていただきました。
[[python] いろいろな文字種のリストを作成](https://qiita.com/okkn/items/3aef4458ed2269a59d63)
NiFiノードがダウンした時のエラーハンドリング

NiFiノードがダウンした時のエラーハンドリングについて、２つパターン。
１）外部からNiFiにデータが入る。例えばListen***系
２）NiFi内部のデータをProcessor間で流れる

２つパターンの詳細は下記。
# パターン１：外部からNiFiにデータが入る。
例えばListen***系。
Listen系の処理を [NiFi Network Listening Processors 仕組み](https://qiita.com/zz22394/items/23a66d0c9861b20c005e)にまとめました。
要は、NiFiのListen系処理が間に合わなかったらデータが溢れる。
それを防ぐために、NiFiチューニングか、ハードウェアスケールが必要。

参考資料：
* [ At least once delivery vs exactly once delivery semantics in Apache NIFI ](https://community.hortonworks.com/articles/87948/at-least-once-delivery-vs-exactly-once-delivery-se.html)

* NiFi/MiNiFi間のS2Sプロトコルでデータ伝送するなら、at least onceは問題無い。
* 更に、S2Sポートの後ろにDetectDuplicateを正しく使えば、Exactly onceも可能。
* それ以外のプロトコル、2-phase commitが対応出来るなら（例えばKafka)least onceは保証出来る
**  support 2-phase commit未対応のプロトコル、例えばSyslog protocolなら、NiFiではleast onceの保証は出来ない、あくまでもat most onceレベル。

# パターン２：NiFi内部のデータをProcessor間で流れる
https://stackoverflow.com/questions/50404284/what-if-nifi-fails-to-write-data

NiFiプロセッサー毎にトランザクションがある。
https://github.com/apache/nifi/blob/master/nifi-api/src/main/java/org/apache/nifi/processor/AbstractProcessor.java

```java
public final void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
        final ProcessSession session = sessionFactory.createSession();
        try {
            onTrigger(context, session);
            session.commit();
        } catch (final Throwable t) {
            session.rollback(true);
            throw t;
        }
}
```

*     Session is started
*     Flow file is obtained
*     Operations performed
*     Flow file is transferred or removed
*     Session is committed

で、もしプロセッサーAから、プロセッサーBにデータを渡して、プロセッサーB（例えばPutHDFS or PutFile）が処理中に落ちたら、
Commitはしません。
再起動後、前回のところをもう一度やりますので、データの漏れは無いです。
CloudGarageのIPアドレスをコピーする裏技

先日のアップデートで、ついに、FWで任意ポート指定と送信元IPアドレスが指定できるようになった。
もう全部[CloudGarage](https://cloudgarage.jp/)でいいんじゃないかなって感じだ
ただ、まだコントロールパネルでIPアドレスがコピーできないという弱点がある。

#実は、コントロールパネルでコピーができた
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">（隠し機能を紹介します…）。管理画面のインスタンス一覧でIPアドレスがコピーできなくて困っている方は多いと思います。しかし、実はIPアドレスをクリックしてコピー操作（Ctrl + Cなど）するとクリップボードにコピーされます。中の人たちでも知らない人が多かった機能です。UXは改善します…</p>&mdash; CloudGarage (@CloudGarage_PR) <a href="https://twitter.com/CloudGarage_PR/status/1050196931417321472?ref_src=twsrc%5Etfw">2018年10月11日</a></blockquote>

選択できないだけで、`Ctrl + C`が使える？
そんなバカなと思いつつやってみると...

...できた。
インスタンス名やプライベートIPでも使える。
しかも、見出しで`Ctrl + C`をするとその項目の全インスタント分がコピーされる。改行付きの良い感じで

![alt](https://qiita-image.cloudremix.net/How-to-Copy-IP-Address-in-CloudGarage.jpg)

#結論
もう全部CloudGarageでいい
CppCon 2018からプレゼンの紹介

# はじめに

今年のCppConはワシントン州のBellevueで行われました。
続々とプレゼンがYouTubeにアップされているので、目についたものを紹介していこうと思います。
６月にBellevueの隣のSeattleでのARMA conferenceに参加してきましたが、夏は涼しく新鮮な魚介類も食べられ、非常に居心地がよかったです。


# Herb Sutter: Lifetime check

[CppCon 2018: Herb Sutter “Thoughts on a more powerful and simpler C++ (5 of N)”](https://youtu.be/80BZxujhY38)

数年前にCppConで提案していたダングリングをチェックする機能のデモです。

# Jussi Pakkanen: the Meson Build System

[CppCon 2018: "Compiling Multi-Million Line C++ Code Bases Effortlessly with the Meson Build System"](https://youtu.be/SCZLnopmYBM)

Pythonで書かれたMesonというビルドシステムの紹介です。
非常に簡単に書けるように作られていると言っていたので、今度試してみたい。

# Robert Schumacher: Rules for builds

[CppCon 2018: Robert Schumacher “Don't package your libraries, write packagable libraries!”](https://youtu.be/sBP17HQAQjk)

パッケージマネジャーを作っている側の観点からライブラリのビルド方法について何をするべきでないかを述べています。

# Stoyan Nikolov: Data-oriented Design

[CppCon 2018: Stoyan Nikolov “OOP Is Dead, Long Live Data-oriented Design”](https://youtu.be/yy8jQgmhbAU)

[Coherent Labs](https://coherent-labs.com/)のエンジニアがObject-Oriented Programming(OOP)ではなくData-oriented Design(DoD)でブラウザーエンジンを作ったお話。
snapでdocker

## はじめに

2018/10/21時点ではdocker-ceのubuntu:18.10のdebリポジトリがまだないので、snapでインストールしてみる。
ついでにsystemdやbash-completion周りで気づいたことをまとめる。

## インストール

https://github.com/docker/docker-snap/issues/1#issuecomment-423778054

sudoなしでdockerを使うことがどういうことかは理解しているものとする。

```sh
sudo addgroup --system docker
sudo adduser $USER docker
newgrp docker
sudo snap install docker
```

debリポジトリを追加するとかしなくていいので結構簡単。

## bash-completion

`/snap/docker/current/bin/docker-completion.sh`にあるのでこれを`source`する。

bashrcとかに書いておくなら

```sh
if [ -f /snap/docker/current/bin/docker-completion.sh ]; then
  . /snap/docker/current/bin/docker-completion.sh
fi
```

## systemd

`/etc/systemd/system/snap.docker.dockerd.service`っていうUnitファイルが置いてある。

statusを確認するなら

```sh
systemctl status snap.docker.dockerd.service
```

## daemon.json

`/snap/docker/current/config/daemon.json`にある

## docker.sock

`/var/run/docker.sock`にある。ここは変わらない。

## 気づき

- snapだと`docker-compose`も一緒にインストールされる。
- `/snap/docker/current -> /snap/docker/XXX`というかんじにシンボリックリンクが張ってある。
NiFi Network Listening Processors 仕組み

# Background
ListenSyslog, ListenTCP, and ListenUDPの仕組み

# 概要図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/22587cd8-363f-7e8c-517f-898fa4e5dd3f.png)

一つ Listening 系のprocessorが実行し始めると、独立な thread は起動され、 incoming network connectionsをListenする. 
あるconnectionが入ったら、もう一つthreadが立ち上げられ、Connectionからデータを読み込む。我々はこれを channel readerと呼ぶ (最初の original thread は引き続き additional connectionsを監視).

Channel readerはなる早で connectionからデータを読み込む, そして受け取ったすべてのMessageをblocking queueに保存。
該当Blocking queueはProcessorに共有される。
毎回processor実行時、該当 queueから一つあるいは複数 messagesを取得し、 flow fileに書き込む。

ここで、２つ競合Activityが発生：

* 1)Data ProducerはSocket Bufferにデータを書き込む。同時に、Channel Readerは該当Socket Bufferのデータを読み込む。　もし、外部Data ProducerからSocket Bufferへの書き込む速度がNiFiの読み込み速度を越えたら、incoming data が紛失の可能性がある

* 2)channel readerはデータを message queueに保存し、processorが同時に messages queueからMessageを取得. もしmessages保存の速度がProcessorの読み込み速度より速い場合、Message Queueはだんだん最大キャパシティに達する、これで channel reader がブロック状態になり、 queueの中のSpaceを待つ.  channel reader が blocking状態ですと、 connectionから読まないで、 socket bufferはだんだんいっぱいになり、データが紛失の可能性がある
listをstack/queueとして利用する

#はじめに
先日[こちら](https://qiita.com/hiroyuki_mrp/items/39365baba5eb619bc7e7)を投稿しましたが、改めてstackとqueue(キューと読みます)について記載します。 

#stackとqueueについて

データの保存と取り扱いの方法のことを言います。
stackもqueueもデータを一列に並べますが、データの追加と取り出し方法にそれぞれ特徴があります。


#stack

listのメソッドを使えば、簡単にlistをstackとして使えます。
stackでは**最後に追加された要素が最初に取り出されます ("last-in, first-out")。**

stackの一番上に要素を追加する(データを積む)にはappend()を使い,一番上から要素を取り出すにはpop()をに使います。

```python
>> stack = ["chiba","tokyo","saitama","kanagawa"]
>>> stack.append("ibaraki")#追加
>>> stack.pop()#取り出し
'ibaraki'
>>> stack　
['chiba', 'tokyo', 'saitama', 'kanagawa']
>>> stack.pop()#取り出し
'kanagawa'
>>> stack
['chiba', 'tokyo', 'saitama']
```

#queueとして使う

queueの場合、**最初に追加した要素を最初に取り出します ("first-in, first-out")。**
append()やpop(）は**listの末尾に対して行うのは速いですが、先頭に対して行う場合には、他の要素をひとつずつずらす必要がある為、遅くなってしまいます。**
そこでqueueの実装には`collectionsのdeque`を使用します。※dequeのappend、popはスレッドセーフ(並行処理されることを考慮してる)らしいです

```python
>>> from collections import deque
>>> queue = deque(['chiba', 'tokyo', 'saitama'])

>>> queue.append("kanagawa")#追加
>>> queue 
deque(['chiba', 'tokyo', 'saitama', 'kanagawa'])
>>> queue.popleft()#取り出し
'chiba'
>>> queue
deque(['tokyo', 'saitama', 'kanagawa'])
>>> queue.popleft() #取り出し
'tokyo'
>>> queue
deque(['saitama', 'kanagawa'])
```

#おわり