OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelのモデルでRailsでいうbefore/afterフィルタしてみた

LaravelでRailsのbefore/afterフィルタみたいなのが作れるか確認してみた。
[LaravelからMySQLのデータをいじってみた](https://qiita.com/b_a_a_d_o/items/bfafd5f94b64bfd8253e)の続きっぽいもの。

## 環境

PHP 7.1.16
Laravel 5.6.26

## 実装

モデルに以下のような感じで書き足す。
Railsでどのフィルタに相当するかをコメントに記載した。

```php:app/Bug.php
:
use Log;
:
    protected static function boot()
    {
        parent::boot();
        
        // たぶん該当なし
        self::retrieved(function(Bug $bug)
        {
            Log::info('retrieved');
        });
        
        // before_create
        self::creating(function(Bug $bug)
        {
            Log::info('creating');
        });
        
        // after_create
        self::created(function(Bug $bug)
        {
            Log::info('created');
        });
        
        // before_update
        self::updating(function(Bug $bug)
        {
            Log::info('updating:' . $bug . ':' . implode(",", $bug->getOriginal()));
        });
        
        // after_update
        self::updated(function(Bug $bug)
        {
            Log::info('updated:' . $bug . ':' . implode(",", $bug->getOriginal()));
        });

        // before_save
        self::saving(function(Bug $bug)
        {
            Log::info('saving');
        });
        
        // after_save
        self::saved(function(Bug $bug)
        {
            Log::info('saved');
        });
        
        // before_destroy
        self::deleting(function(Bug $bug)
        {
            Log::info('deleting');
        });
        
        // after_destroy
        self::deleted(function(Bug $bug)
        {
            Log::info('deleted');
        });
    }
:
```

## コンソールから実行してみる

```bash
php artisan tinker
```

### update

```php
$b = Bug::all()->first()
$b->hours = 1.2
$b->save()
```

↓

```
local.INFO: retrieved  
local.INFO: saving  
local.INFO: updating:{..."hours":1.5,...}:...1.20,...
local.INFO: updated:{..."hours":1.5,...}:...1.20,...
local.INFO: saved  
```

### delete

```php
$b = Bug::all()->last()
$b->delete()
```

↓

```
local.INFO: retrieved  
local.INFO: deleting  
local.INFO: deleted  
```

### insert

```php
$b = new Bug
$b->date_reported = '2018-05-06'
$b->save()
```

↓

```
local.INFO: saving  
local.INFO: creating  
local.INFO: created  
local.INFO: saved  
```

## その他

- モデルを介さない操作では機能しない。
  - 例えば`DB::table('bugs')->where('bug_id', 1)->update(['hours' => 1.5])`のような
- `ing`系は`false`を返すと処理は完了しない（insert/update/deleteされない）
- `updating/updated`のところで利用しているが、Railsで言う`_change[0/1]`のようなものは`$bug->getOriginal()`と`$bug`を利用すればなんとかできる。
【Ruby】self.インスタンス変数がよく分からない

rubyでselfの使い方がよく分からない。
ということで、調べていくうちに、そもそもクラスってなんだっけ？
インスタンスってなんだっけ？インスタンス変数って？
インスタンスメソッド？あれ？ってなってしまった。
的な状態が今。




- クラス　：設計図
- インスタンス　：設計図を元に生成された実際のモノ
- インスタンス変数　：---下例①

```ruby.rb
class Ruby_lesson
  attr_accessor :weakday
                 #↑これがインスタンス変数
  attr_accessor :teacher
                 #↑これがインスタンス変数
  attr_accessor :price
                 #↑これがインスタンス変数
```

つまりインスタンスが持つ情報を変数化したもの、というイメージ

- インスタンスメソッド :クラスの中で定義しインスタンスに対して呼び出すもの---下例②

```ruby.rb
class Ruby_lesson
  attr_accessor :weakday
  attr_accessor :teacher
  attr_accessor :price

  def info
    puts "情報を参照します"
    #↑infoメソッドは"情報を参照します"を出力する、ということを定義した
  end
end

lesson1 = Ruby_lesson.new
#Ruby_lessonクラスのインスタンスを生成しlesson1に代入した
lesson1.info
#Ruby_lessonクラスの中のインスタンスlesson1に対しinfoメソッドを呼び出した


#実行結果=>
"情報を参照します"
```





>さあ本題だ！! self.インスタンス変数とは何か

・・・かれこれ１時間格闘したけど分からなかった。
self.を抜かしてコードを書いても結果が変わらないじゃないか！
教えて、わかる人ーーー！！
VS Codeのターミナル部分の文字色を変更する

Visual Studio Code（Mac版）で、ふとTerminal部分の文字の色を緑色にしたくなったので変更しました。

メニュー部分から`Code`→`基本設定`→`設定`

下記の設定を追加

```json
    "workbench.colorCustomizations": {
        "terminal.foreground": "#00FF00",
    }
```

<img width="907" alt="settings_json_—_hello_app.png" src="https://qiita-image-store.s3.amazonaws.com/0/176619/9553ac02-7cc4-5339-c693-02695e152af5.png">
Terminal部分がマトリックスっぽくなりました。
<img width="747" alt="settings_json_—_hello_app.png" src="https://qiita-image-store.s3.amazonaws.com/0/176619/c07564c9-0e59-f435-8c14-260c706f645c.png">
そのうち元に戻すかもしれません汗。
apollo-cli で GraphQL Schema から TypeScript/Flow/Scala/Swift のコードを生成する

対象は apollo-cli がサポートしてるもので自分の好みとかではない。今回自分が必要だったのは TypeScript。

こういう schema.graphql 持ってるとする。

```graphql:schema.graphql
type Query {
  user: User!
}

type User {
  id: ID!
  name: String!
}
```

で、これを使うコードを生成したいとして、ファイル構成に色々と前提がある。こんな感じ

```
schema.graphql
queries/
  getUser.graphql
```

getUser は schema 定義からそれを叩くクエリ

```graphql:queries/getUser.graphql
query getUser {
  user {
    id
    name
  }
}
```

`query getUser ` の部分は単純な graphql query としては省略可能なのだが、型生成で名前をつける都合上必須になっている。

今回の目標は、この schema.graphql を元に getUser.graphql の結果に型を付ける。

## apollo-cli でコード生成

ググると apollo-codegen と apollo-cli と apollo が出てきてややこしいが、Issue 見る限りは今後 apollo に集約されるとのことだったので apollo を使う。

```
npm i -g apollo
```

(npm i -g apollo-cli だとapolloとは別に apollo-cli コマンドが入る。ややこしい)

apollo codegen:generate がコードを生成するコマンドだが、 `*.graphql` を直接食えず、それをコンパイルした json が必要

```
$ apollo schema:download --endpoint schema.graphql
```

これで schema.json が生成される。

コマンド名が schema:download なのが気持ち悪いが、 apollo は PaaS 売ってる会社がスポンサーなので、どうもサーバーからスキーマ定義を落とすのが前提にあってこういう定義になってるっぽい。graphqool とかが念頭にありそう。

生成した schema.json を使ってコードを生成する。

```
$ apollo codegen:generate --target=typescript --schema=schema.json --queries="queries/*.graphql"
```

実行すると `queries/__generated__/getUser.ts` が生成される。

ここで target を scala や swift にするとそれらのコードが生成された。たしかにここまでgraphql の定義だけしか使ってないので、言語に縛られていない。

## React + TypeScript で生成された型を使う

react-apollo/Query を使うとする。



まず、この getUser.graphql を webpack 経由で読み込めるようにする必要がある。 `yarn add graphql-tag` して、 webpack.config.js の module.rules に .graphql のローダーを追加する。

```js:webpack.config.js
  // module.rules
  rules: [
    // ...
    {
      test: /\.(graphql|gql)$/,
      exclude: /node_modules/,
      loader: "graphql-tag/loader"
    }
  ]
```

これで次のような gql タグ付き文字列でクエリを読み込むのと同等の表現になる。

```js
import gql from 'graphql-tag'
export default gql`...`
```

生成された型を使って、Reactのコードに型をつける。

```typescript:pages/index.ts
import { Query } from "react-apollo";
import getUser from "../queries/getUser.graphql";
import { getUser as GetUserType } from "../queries/__generated__/getUser";

const GetUserQuery: React.ComponentType<{
  query: any;
  children: (p: { loading: boolean; data: GetUserType }) => React.ReactNode;
}> = Query as any;

export default () => {
  return (
    <GetUserQuery query={getUser}>
      {props => {
        if (props.loading) {
          return "Loading...";
        }
        return `Hello, ${props.data.user.name} - ${props.data.user.id}`;
      }}
    </GetUserQuery>
  );
};
```

ちなみに、Query をキャストしてるのは children を介して data に型を付けたいのもあるが、Query がそもそも定義間違ってるのか React.Component の型を満たしていなくて普通に使うだけで型エラーが起きていた…ので握りつぶした。

もうちょい一般化できそうだが、とりあえずこんな感じだと思う。

server 込みで動いてるリポジトリはこちら https://github.com/mizchi-sandbox/graphql-next-ts
ツールとか使わずER図を書きたい。mermaid.jsつかってみた。


ER図を書きたい。
が、環境が制限されているため便利ツールはダウンロードできず。

jsライブラリでmermaidとやらを発見。
CDNでmermaidを利用。

marmaid.js結構よい。

これに限らずかもしれないが、テキストで図を描けるのが助かる。
マウスを利用していちいち細かに設定するのは面倒すぎるため。

https://mermaidjs.github.io/flowchart.html

こまかくCSSを指定できると見栄えも改善できそう。
ただ、簡易なER図を作る目的だと、デフォルトの記法でほぼ完結できた。

```html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="mermaid.min.css">
</head>
<body>
  <div class="mermaid">
  graph LR
      A --- B
      B-->C[fa:fa-ban forbidden]
      B-->D(fa:fa-spinner);
  </div>
  <script src="mermaid.min.js"></script>
  <script>mermaid.initialize({startOnLoad:true});</script>
</body>
</html>
```

一旦CDNでよんでサンプルを参考に作成。あとsubgraphを追記したぐらい。
コードはファイル落としてきたばん。
もっと楽に書きてーmarkdownで全部成立しないかな〜
Devise+bootstrap4のusers#editのコピペ用テンプレ


##editビュー

```haml:app/views/devise/registrations/edit.html.haml
= render partial: "/matomes/flash-message"
.container-fluid
  .card.card-default.devise-bs.m-5.bg-light{style: "border-radius: 10px !important;"}
    .card-title.mx-4.mt-4
      %h4= t('.title', resource: resource_class.model_name.human , default: "Edit #{resource_name.to_s.humanize}")
    .card-body
      = form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
        .form-group
          = f.label :名前
          = f.text_field :name, autofocus: true, class: 'form-control'
        .form-group
          = f.label :email
          = f.email_field :email, autofocus: true, class: 'form-control'
        .form-group
          = f.label :current_password
          %i
            (#{t('.we_need_your_current_password_to_confirm_your_changes', default: 'we need your current password to confirm your changes')})
          = f.password_field :current_password, class: 'form-control'
        .form-group
          = f.label :password
          %i
            (#{t('.leave_blank_if_you_don_t_want_to_change_it', default: "leave blank if you don't want to change it")})
          = f.password_field :password, autocomplete: "off", class: 'form-control'
        .form-group
          = f.label :password_confirmation
          = f.password_field :password_confirmation, class: 'form-control'
        = f.submit t('.update', default: 'Update'), class: 'btn btn-primary'
```

##partial(flashメッセージ)

```haml:app/views/matomes/_flash-message.html.haml
-# フラッシュメッセージ
- flash.each do |key, value|
  %div{:class => "alert alert-#{key} mb-1"}
    .container
      = value
```


##SCSS

```scss:app/assets/stylesheets/matomes.scss
//flash message
.alert-notice {
  color: #3c763d;
  background-color: #dff0d8;
}
.alert-alert {
  background-color: #f2dede;
  color: #a94442;
}
```
Devise+bootstrap4のusers#showのコピペ用テンプレ

参考リンク
[Devise で作成した User モデル用のコントローラーの index, show アクションを追加](https://easyramble.com/create-users-index-show-on-devise.html)

###ルーティング設定
devise_forの後に以下を追加。

```ruby:routes.rb
resources :users, :only => [:index, :show]
```

###コントローラ作成

```terminal:terminal
$ bundle exec rails g controller Users index show
```

```ruby:users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end
end
```

###ビューファイルを作成

app/views/users/show.html.haml

```haml:show.html.haml
- provide(:title, @user.name)
%h1
  My page (#{@user.name})
```
DOM,オブジェクト指向

#DOMとjsの関係
jsはDOMをもとに操作しているので、DOMができる前に操作しようとするとエラーになる。
#オブジェクトの操作方法
1.オブジェクトのメソッドを実行したいとき
**オブジェクト名.メソッド名(引数値);　**

2.オブジェクトのプロパティを変更したいとき
**オブジェクト名.プロパティ名 = 値;**

#documentオブジェクトの操作方法
HTML5より前
`getElemntByid(id値)
getElementsByTagName(タグ名)
getElementsByClassName(クラス名)`

HTML5から
`querySelector(セレクター)`
*セレクターは`#title`とか`.name`

#まとめ
- オブジェクトの持つ変数はプロパティ、関数はメソッド。
- 現実世界の考えをプログラムの世界に取り入れた仕組みの言語をオブジェクト指向言語といってる。
- jsはDOMが作られてから実行されればいいからDOMContentLoadedを使おう。

>[ウェブカツ！！](https://webukatu.com/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
結婚式のためにリアルタイムスライドショーを作ってみる〜簡易版編〜

[前回](https://qiita.com/tommy-hayashida/items/fe86cab9b1aec1fcb993)までのあらすじ。

:bride_with_veil: < 結婚式の余興のためにリアルタイムスライドショー作るよ！

ところが先日「スライドショーほんとに作ってる？」と夫にせっつかれたので(怒)、とりあえずそれっぽい簡易版を作ってみました。
今回はプログラムを書かずにやってみます。

# プログラミングせずに作ってみる

## 環境

使用するOSはLubuntu 16.04です。

## ローカルフォルダへ写真を送信
ローカルフォルダへ写真を送るのに、[Dropboxのファイルリクエスト](https://www.dropbox.com/ja/help/files-folders/create-file-request)を使います。

[Dropbox公式](https://www.dropbox.com/ja/install-linux)からダウンロードしてきてインストールしました。
インストールが完了するとDropboxフォルダが作成され、中身がオンラインのフォルダと同期します。

写真を送ってもらいたい相手へはファイルリクエストの案内メールを送ります。
ブラウザから写真を投稿できるので、新しくアプリをインストールする必要がないとこが良いです。
メールアドレスの入力が必須ですが、知り合いしかいない結婚式なのでまあ大丈夫でしょう。

## スライドショー

「Ristretto」というXfceデスクトップ向けの画像ビューアーを使って、スライドショーを表示します。
Lubuntuソフトウェアからインストールできます。
Ristrettoの良い所は、スライドショーを流している途中でもフォルダに新しく追加された画像を表示してくれるところです。
他の画像ビューアーとかだと、スライドショーを開始した時点でフォルダにあった写真しか表示してくれなくて……。

こんな感じで簡単なスライドショーができます。

![2018-07-06-222611_1280x800_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/205531/f18b8bd6-8b33-7383-8d40-d7b684a13293.png)

# とりあえず完成

ひとまず

- Webを通して写真を投稿してそれをスライドショーとしてリアルタイムに表示する

という機能を実装できました。

が、夫に見せたら微妙な反応でした……。

課題は

- 写真を1枚ずつしか表示できないので、写真が増えたら全て見せるのにめちゃくちゃ時間がかかる。
- 表示順を動的に制御できないので、投稿した写真をすぐスライドショーに映し出せない。そのためリアルタイム感が薄い。

といったところでしょうか。
2つめのGitHubアカウントでリポジトリをcloneする

なんかいつも苦労するから今回できた方法をメモ。

# 前提
- 普段自分で使っているGitHubアカウントは設定済みで、チェックアウトとか普通にできる。
- そこに仕事用のMFAつきGitHubアカウントでリポジトリをチェックアウトしたい

# やったこと
- 仕事用アカウントでapi Tokenを作成する
- `git clone https://<GitHubユーザー名>@github.com/hoge/fuga.git`
- パスワードを求められるので、先程作成した仕事用アカウントのapi Tokenを入力する

この方法でチェックアウトできました。

仕事やめるときはキーチェーンアクセスからgithub.comの仕事用のアカウントを削除すれば、認証が残らないので安全ですね。まぁGitHub側のアカウントも消えるから平気だろうけど。
Gitで誤ったcommitをしたときの解決方法

##前提
リモートリポジトリを以下のコマンドで作成
```git --bare init —share```　

-shared オプション付きで作った場合、
none-fast-forward な push が断固拒否される設定になり、revertやresetを実行しても取り消すことができない。


#取り消しできない例
・ローカルでcommitを取り消し、そのあとのpushが実行できない。
例）
１，ローカルのブランチで直前のコミットを取り消し
```git reset --hard HEAD^```
２，１をリモートリポジトリにpush
```git push -f ```
error: denying non-fast-forward refs/heads/master (you should pull first)


#解決方法

##デフォルトのブランチ（master）へのcommitの取り消し
１，リモートサーバにログインし、リモートリポジトリのパスまで移動
２，現在のブランチの確認
```git branch```
３，git logで取り消すcommitを確認
```git log```
４，取り消し
　例）直前のcommitの場合
```git reset HEAD~ —soft```
５，再度、git logでcommitが取り消されたことを確認

##デフォルト以外のブランチへのcommitを取り消し
１，対象となるブランチからバックアップブランチ作成
```git checkout -b bk_{対象となるブランチ名}```
２．ローカルブランチでコミットの取り消し
３．リモートのブランチを削除
```git push origin :{対象となるブランチ名}```
４，削除したブランチ名で2をpush
```git push -u origin {対象となるブランチ名}```
この方法だと、defaultのブランチに設定されているブランチは削除できない。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
2018/07/09 ご指摘いただきcomit→commitに変更
Bashのワンライナーでファイルから一行ずつ読み取ってフォルダを作成する

ものすごく簡単ですけど、良く忘れるので備忘録として投稿。
testに作成したいフォルダ名を一行ずつ用意しておき、以下のコマンドを実行すればおｋ

`awk '{print $1}' < test | xargs mkdir`


```bash
$ ls
test

$ cat test
aaa
bbb
ccc

$ awk '{print $1}' < test | xargs mkdir

$ ls
aaa/  bbb/  ccc/  test
```

awkコマンドを使うのは、一行ずつ処理をさせたいから。

結果としては同じだけど、ファイルから一行ずつ読み取って、mkdirの引数に渡してコマンドを実行したい場合はxargs に `-L 1 -t`オプションを付ければよい。

```bash
λ awk '{print $1}' < test | xargs -L 1 -t mkdir
mkdir aaa
mkdir bbb
mkdir ccc
```
mkdir以外のコマンドを実行したい時のアイデアとして。

cat  test でもいいんだけどね！！！
[python][unittest] datetimeのユニットテスト


# 背景

ユニットテストを書くときに、
**時刻周り(`datetime`)のモックアウト** が意外とやりにくい。

これは何故かというと `datetime` の提供する関数がちょいちょい
**C拡張モジュール**として書かれているため。

C拡張モジュールで書かれていると標準ライブラリの
[unittest.mock](https://docs.python.jp/3/library/unittest.mock.html) で置き換えることができない。

# 解決方法

**freezegun** を使う。

```
$ pip install freezegun
```

名前のように、 `datetime` で取得した時間を凍結することが出来る。

## freezegunの使い方

### (1) デコレータで修飾された関数の中でのみ時刻が置き換わる。

```py
import freezegun
from datetime import datetime


@freezegun.freeze_time('2018-07-06 21:56:56')
def main():
    print(datetime.now()) # 2018-07-06 21:56:56
```


### (2) with構文で置き換える。

```py
import freezegun
from datetime import datetime

dt = datetime(2018, 7, 6, 21, 56, 56)

def main():
    with freezegun.freeze_time(dt):
        print(datetime.now()) # 2018-07-06 21:56:56
```

### (3) デコレータとしてもコンテキストマネージャとしても使わない場合

```py
import freezegun
from datetime import datetime


def main():
    freezer = freezegun.freeze_time('2018-07-06 21:56:56')
    freezer.start() # ←こちらがキモ
    try:
        print(datetime.now())
    finally:
        freezer.stop() # ←こちらがキモ
```        


# freezegunのレポジトリ

https://github.com/spulec/freezegun


# 参考
[Python: freezegun で時刻のテストを楽に書く - CUBE SUGAR CONTAINER](https://blog.amedama.jp/entry/2016/12/06/220000)
関数

```js
var num = 100;
if(num == 100){
 num = num*1.08;
 alert('変数numは'+num+'です');

}elseif(num == 200){
 num = num*1.08;
 alert('変数numは'+num+'です');

}elseif(num == 300){
 num = num*1.08;
 alert('変数numは'+num+'です');

}
```
これが、関数を使うとこうなる↓

```js
var num = 100;
if(num == 100){
 alert(total(num));

}elseif(num == 200){
 alert(total(num));

}elseif(num == 300){
 alert(total(num));

}

function total(hikisuu){
 var result = hikisuu * 1.08;
 return '変数numは'+result+'です';
}
```
同じような処理をまとめることができる。

基本的な形は↓

```js
function 関数名(引数１,引数2,引数3){
 //処理
 return 値;
}
```
引数は、渡したい値を受け取る変数。作った変数名はこの関数内だけで使える。なければ空でも良い。複数の場合はカマで区切る。関数名が同じでも、引数の個数が違うと別物と判断されるので注意。

>[ウェブカツ！！](https://webukatu.com/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
Git の pre commit などの hook を完全無効化する

# TL;DR

`git config --add --global core.hooksPath /dev/null`

------------

Git の hook スクリプトたちは基本的には勝手には動かない。
`$GIT_DIR/hooks` もしくは `core.hooksPath` にスクリプトがあるときだけ動作するが、`$GIT_DIR/hooks` にファイルを git clone しただけで置く方法はない(はず)。
https://git-scm.com/docs/githooks

しかし、husky は npm install 時に `$GIT_DIR/hooks` 以下にファイルを勝手に展開することで、設定なしに hook を強制してくる。
これは、例えばプロジェクトで lint する hook を husky で設定されているが、自分はエディタで保存時にやるようにしているような場合には git 操作の邪魔にしかならない。
どうやら `core.hooksPath` が設定されていればそれが優先されるため、ファイルが存在しない場所を指定することで hook を完全無効化することができる。
FlaskとAjaxでコード200が出るのにエラーが発生する際の対処

Vue.jsとPython 3のFlaskで連携をとっていた時の問題。
# 問題
### jQueryのajaxで返り値がとれない

```js:main.js
$.ajax({
    url: "http://127.0.0.1:5000/upload",
    type: "POST",
    data: JSON.stringify(data),
    timeout: 10000,
})
.done(function(res) {
    // 成功時の動作
}) 
.fail(function(XMLHttpRequest, textStatus, errorThrown) {
    // 失敗時の動作
})
```

```python:server.py
@app.route('/test', methods=['POST'])
def test():
    data = request.data
    # 処理
    return "これが届かなーい"
```

POSTしたデータを処理し、何らかの値を返す際にエラーが出た。サーバー側は200を出しているのでサーバーには問題なく届いている。

# 解決策

Ajax側の設定(Content-Typeなど)かと思ったがそうではないらしい。散々調べて行き着いたのが`Access-Control-Allow-Origin`の問題。何回も見ましたけどね。

### 引っかかったポイント

```python:server.py
from flask_cors import CORS

app = Flask(__name__, template_folder='templates')
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
```

これを挟めばいいですよーという情報がたくさんあるが、これではなかった。これのせいで時間を取られた。

### Python 2 系の方法

Python 2 系の方法があるとのことで試してみる。上のコードを修正。

```python:server.py

api = Flask(__name__)

@api.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
    return response
```

成功。一体なんだったんだ。。。

# 原因

`Access-Control-Allow-Origin`の設定場所については様々な情報があるが、適切な場所に配置してあげないとダメっぽい（当たり前のことだが）。

参考：https://www.hands-lab.com/tech/entry/3716.html
　　　https://stackoverflow.com/questions/22181384/javascript-no-access-control-allow-origin-header-is-present-on-the-requested
Docker プライベートリポジトリ(http)を使う


- プライベートリポジトリがhttpな場合にpull/pushできるようにする
  - CentOS7

# 設定

- `/etc/docker/daemon.json`に下記を設定 (無ければれば新規作成)

    ```daemon.json
    {
      "insecure-registries" : ["myregistrydomain.com:5000"]
    }
    ```
- docker再起動
  - `systemctl restart docker`


# 参考

- <https://docs.docker.com/registry/insecure/>
Growiの構築手順 - Ubuntu Server 18.04

# 目的・ゴール
Ubuntu Server 18.04上にGrowiを構築することを目的としています。今後、Ansible Playbookの作成やDockerfile作成を行うための手順整理として構築手順を自分なりにまとめています。

# Growiとは？
> Markdownで書けるオープンソースのWikiシステム

とのことです。詳細は[Growi.org](https://growi.org/)を参照ください。

# Growiの構築手順
Growiの構築手順は以下のパッケージをインストールし、GrowiのパッケージをGitHubから取得してビルドします。
- nodejsとnpmのインストール
- yarnのインストール
- mongodbのインストール

**注意** 各パッケージにバージョン指定がさているものがあります。
- nodejsのバージョンは8.x系が指定
- npmのバージョンは5.x系が指定
- MongoDBのバージョンは3.x系が指定


オプションとして、RedisやElasticSearchを入れて連携することも出来るようですが、今回は割愛。

## nodejsとnpmのインストール
Growiはnodejsで書かれたアプリケーションのようです。なのでnodejsとnpmをインストールします。インストール方法は[ここ](https://nodesource.com/blog/installing-node-js-8-tutorial-linux-via-package-manager/)を参考にしました。以下の通りインストールします。

```shell
$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt update && sudo apt install nodejs
$ nodejs --version
v8.11.3
$ npm --version
5.6.0
```
nodejsが8.x系であること、npmが5.x系であることを確認してください。

## yarnのインストール
yarnはnpmと同様にjavascriptのパッケージマネージャです。[ここ](https://yarnpkg.com/lang/en/docs/install/#debian-stable)を参考にしました。以下の通りインストールします。

```shell
$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
$ sudo apt update && sudo apt install yarn
$ yarn --version
1.7.0
```

## mongodbのインストール
GrowiのバックエンドはMongoDBのようです。Ubuntuの場合、MongoDBは特にレポジトリの追加なしでインストールできるようです。以下の手順でインストールします。

```shell
$ sudo apt install mongodb
$ mongo --version
MongoDB shell version v3.6.3
git version: 9586e557d54ef70f9ca4b43c26892cd55257e1a5
OpenSSL version: OpenSSL 1.1.0g  2 Nov 2017
allocator: tcmalloc
modules: none
build environment:
    distarch: x86_64
    target_arch: x86_64
```

MongoDbは3.x系であることを確認してください。

## Growiの起動
ここまで来れば、後はGrowiをGitHubから取得して起動するだけです。以下の手順でGrowiを立ち上げます。

```shell
$ cd /opt
$ sudo git clone https://github.com/weseek/growi.git
$ cd ./growi
$ sudo yarn
$ MONGO_URI=mongodb://MONGO_HOST:MONGO_PORT/growi sudo npm start
```

Growiはデフォルトで3000番ポートを使用しますのでhttp://*HOSTNAME*:3000/にアクセスし、以下のページが表示されるか確認します。
![Growi-image.png](https://qiita-image-store.s3.amazonaws.com/0/264707/4db10be8-324d-2bc3-ac52-e37f2561600d.png)

## おまけ
Growiを80番ポートで起動するには`config/env.prod.js`ファイルを開き、PORTの行を以下のように追加します。

```js:config/env.prod.js
module.exports = {
  NODE_ENV: 'production',
  // FORMAT_NODE_LOG: false,
  PORT: '80' //この行を追加
};
```
Docker noneイメージの削除

# noneイメージを表示する

```
docker images --filter "dangling=true"
```

# noneイメージを削除する1

```
docker rmi $(docker images -f "dangling=true" -q)
```

- `-q`はイメージIDのみ表示

# noneイメージを削除する2

- 1のコマンドだとnoneイメージがない場合、`"docker rmi" requires at least 1 argument.`となる
- シェルスクリプト 等で上記が困る場合とか

```
docker images -f "dangling=true" -q | xargs --no-run-if-empty docker rmi
```

- `--no-run-if-empty`
  - 引数が無い場合には、コマンドを実行しない


# 参考
- <https://docs.docker.com/engine/reference/commandline/images/#filtering>
- <https://docs.docker.com/engine/reference/commandline/images/#options>
- <https://suin.io/540>
- <https://stackoverflow.com/questions/35416962/error-while-cleaning-images-from-docker>
FirebaseInstanceIdServiceがDeprecatedになった件


### FirebaseInstanceIdServiceが非推奨に
2018/06/28に**FirebaseInstanceIdService**が非推奨になりました。
https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdService

firebase-messaging:**17.0.0**までは下記の処理でtokenを取得していました。

```AndroidManifest.xml
<service android:name=".MyFirebaseInstanceIdService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>
```

```MyFirebaseInstanceIdService.kt
class MyFirebaseInstanceIdService : FirebaseInstanceIdService() {
    override fun onTokenRefresh() {
        val token = FirebaseInstanceId.getInstance().token
        // tokenの処理
    }
}
```
firebase-messaging:**17.1.0**からは**新しいtokenが作成された際の処理**と**任意のタイミングでのtokenの取得**の実装方法が変わります。
###新しいtokenが作成された際の処理
**FirebaseMessagingService**に**onNewToken**メソッドが追加されました。
FirebaseMessagingServiceを継承したクラスでonNewTokenメソッドをオーバーライドします。

```AndroidManifest.xml
<service android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

```MyFirebaseMessagingService.kt
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String?) {
        // tokenの処理
    }
}
```

### 任意のタイミングでのtokenの取得
任意のタイミングでtokenを取得する際は`FirebaseInstanceId.getInstance().token`を利用していましたが、これも非推奨になりました。
tokenを取得する方法は2種類あります。

```kotlin
val task = FirebaseInstanceId.getInstance().instanceId
task.addOnSuccessListener { token ->
        // tokenの処理
}
```

```kotlin
thread {
    val senderId = "123456789012"
    val token = FirebaseInstanceId.getInstance().getToken(senderId, "FCM")
}
```

**senderId**はFirebaseのプロジェクト→設定→クラウドメッセージングの送信者IDという項目に書いてある12桁の数字です。
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/239126/030c244a-7eb6-587a-62e1-2669f7379bf5.png)
スキマ時間でインフラ関連の技術が学習できそうな動画リストを探してみた

## はじめに

インフラ技術の学習のために、技術書やドキュメントをじっくり読み込む学習ももちろん必要だと思うのですが、スキマ時間で気軽に学習できたら良いなとも思っていました。

そこで、最近のプログラミング学習動画のように、短め(5 ~ 10分)の動画で学習できそうなリストを探してみました。

※自分が学習したい技術に偏ってるかもしれませんがご容赦ください

## AWS

### AWS Service Update

https://www.youtube.com/playlist?list=PLzWGOASvSx6HWttdnuxjhH26ghWIC7pUk

<a href="https://www.youtube.com/channel/UCnjKWUK2t5QJYfeqqilhJhQ" target="_blank" rel="nofollow noopener">  Amazon Web Services Japan 公式 YouTube チャンネル</a> が更新しています。週次単位でAWSのアップデートを確認できます。

### What's New with AWS

https://www.youtube.com/playlist?list=PLhr1KZpdzukfsuHJK5mv40wVsMMhgOZ-Q

<a href="https://aws.amazon.com/jp/blogs/aws/" target="_blank" rel="nofollow noopener">AWS News Blog</a>で有名なJeff Barrによる動画リストです。同じく週次単位でAWSのアップデートを確認できます。

## GCP

### Google Cloud Platform チュートリアル

https://www.youtube.com/playlist?list=PLmoHjhhs3ySED7BvQ3FV6V2t2UMHju4KC

<a href="https://www.youtube.com/channel/UCxl3AizmA_6YC4lpeycP8kA" target="_blank" rel="nofollow noopener">Google Cloud Japan 公式 YouTube チャンネル</a> が提供しているリストです。GUIコンソール操作によるチュートリアルが試せます。

### Kubernetes Best Practices

https://www.youtube.com/playlist?list=PLIivdWyY5sqL3xfXz5xJvwzFW_tlQB_GB

<a href="https://www.youtube.com/channel/UCJS9pqu9BzkAMNTmzNMNhvg" target="_blank" rel="nofollow noopener">Google Cloud Platform 公式 YouTube チャンネル</a>が提供しているリストです。Kubenetes を使うにあたってのベストプラクティスについて、それぞれ動画で解説してくれます。

## CircleCI

### How to

https://www.youtube.com/playlist?list=PL9GgS3TcDh8x6tcY7HDq2zmEx0fAtwWsM

<a href="https://www.youtube.com/channel/UC9_Pmtv-cUccKkusuapItMQ" target="_blank" rel="nofollow noopener">CircleCI 公式YouTubeチャンネル</a>が提供しているリストです。CircleCIの使い方をチュートリアル形式で確認できます。

## OneLogin

### 管理者向けトレーニング

https://www.youtube.com/watch?v=pSGPeZRjXnw&list=PLRPIpgyNOS6meLkHe1jDZ0v6pvz_DnZLq

<a href="https://www.youtube.com/channel/UC4mup2Tsf3GvICslTER2DtQ" target="_blank" rel="nofollow noopener">OneLogin 公式YouTubeチャンネル</a>が提供しているリストです。G Suite や Active Directory を使った SSO の設定方法を動画で学習できます。

## New Relic

### New Relic Tutorials

https://www.youtube.com/playlist?list=PLmhYj7Jl81JHCWLfTfT5Fv1JDLjrQ5nH_

<a href="https://www.youtube.com/channel/UCEzfm-p8t6ZkMUr-zuL4hJw" target="_blank" rel="nofollow noopener">New Relic 公式YouTubeチャンネル</a> が提供しているリストです。チュートリアル形式でNew Relicの使い方を確認できます。

## Firebase

### Firecasts

https://www.youtube.com/user/Firebase/playlists?view=50&sort=dd&shelf_id=9

<a href="https://www.youtube.com/channel/UCP4bf6IHJJQehibu6ai__cg" target="_blank" rel="nofollow noopener">Firebase 公式YouTubeチャンネル</a>が提供しているリストです。Android/Web/IOS それぞれのチュートリアル動画を確認できます。

## 終わりに

調べてみると、意外にYouTubeに公式チャンネルが多く存在していることがわかりました。これから調べたリストを消化していきたいと思います。

もし他にも良さそうな動画リストありましたら教えてください。
django rest framework : method override

- 以下記事を試行済みの想定.
    - https://qiita.com/Satoshi_Numasawa/items/53c6de8816de53e92851


# Description
- viewset の指定 method(create, updateなど) を上書きする


# 上書き
以下, 対応する method を上書きする

```python:api/views.py
from rest_framework import viewsets
from rest_framework.response import Response

from api.models import User

from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all().select_related()
    serializer_class = UserSerializer

    def list(self, request):
        # GET    :  /api/users/

    def create(self, request):
        # POST   :  /api/users/

    def retrieve(self, request, pk=None):
        # GET    :  /api/users/:id/

    def update(self, request, pk=None):
        # PUT    :  /api/users/:id/

    def partial_update(self, request, pk=None):
        # PATCH  :  /api/users/:id/

    def destroy(self, request, pk=None):
        # DELETE :  /api/users/:id/
```


# list 実装例
```python:api/views.py 
from rest_framework import viewsets
from rest_framework.response import Response
from api.models import User

from .serializers import UserSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    list:
    Return a list of all the existing users.
    """

    queryset = User.objects.all().select_related()
    serializer_class = UserSerializer

    def list(self, request):
        """
        list:
        Return a list of all the existing users.
        """

        # 全 user 情報を取得し, serialize 
        data = UserSerializer(User.objects.all(), many=True).data
 
        # http response として返す
        return Response(status=200, data=data)
```

# 参考
- http://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions
- http://www.django-rest-framework.org/api-guide/responses/
VMwarePlayerでAmazon Linux 2を起動

# 前提条件

* VMware Player インストール済み
* vmnetcfg.exe でDHCPサービス起動済み
* genisoimage を実行するLinuxサーバが使用可能

※VMware Player でvmnetcfg.exeを使用する方法は検索お願いします。

# 参考URL
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/amazon-linux-2-virtual-machine.html


# 1. イメージのダウンロード

https://cdn.amazonlinux.com/os-images/2017.12.0.20180330/vmware/
から、"amzn2-vmware_esx-2017.12.0.20180330-x86_64.xfs.gpt.ova"をダウンロードする。

# 2. インポート
ダウンロードした上記のファイルをダブルクリックする。

![01_import.png](https://qiita-image-store.s3.amazonaws.com/0/63464/58d7bd9b-902c-6963-82fe-0e77405a3495.png)

失敗するが、"再試行"をクリック
![02_retry.png](https://qiita-image-store.s3.amazonaws.com/0/63464/7c45ac3e-e59a-1906-3ea2-bf9c39faa134.png)

GRUBメニューから<font color="red">ブートする前にシャットダウン</font>する。
![03_grub.png](https://qiita-image-store.s3.amazonaws.com/0/63464/40460303-5fdd-0a22-f85f-d33e7a270f3c.png)

# 3. seed.iso の作成

```file:meta-data
local-hostname: zephyranthes
```

```file:user-data
#cloud-config
# vim:syntax=yaml
users:
# A user by the name ec2-user is created in the image by default.
  - default
# Following entry create user1 and assigns password specified in plain text.
# Please not use of plain text password is not recommended from security best
# practises standpoint
  - name: ryouma
    groups: sudo
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    plain_text_passwd: password
    lock_passwd: false
chpasswd:
  list: |
    ec2-user:password
    root:password

write_files:
  - content: |
    # Disable network configuration after first boot
    network:
      config: disabled
    path: /etc/cloud/cloud.cfg.d/80_disable_network_after_firstboot.cfg
```
※root,ec2-userのパスワード、追加ユーザを設定しました。

以下のコマンドでseed.isoを作成し、VMwarePlayerからアクセスできるところに配置する。
<pre>
genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
</pre>

# 4. 仮想マシンの設定変更

メニューを開く
![04_config_1.png](https://qiita-image-store.s3.amazonaws.com/0/63464/e1763814-bc4c-36e9-0b4d-adf182becd58.png)

CD/DVDドライブを追加
![05_config_2.png](https://qiita-image-store.s3.amazonaws.com/0/63464/a8f2b872-0e97-ee3d-bfe0-15679b94c325.png)
"ISOイメージを使用する"を選択
![06_config_3.png](https://qiita-image-store.s3.amazonaws.com/0/63464/9ff5249a-4c0f-d48b-61c4-2d2197565efb.png)
作成したseed.isoを指定
![07_config_4.png](https://qiita-image-store.s3.amazonaws.com/0/63464/3ed8571c-4f38-c18d-0c6d-844c564e6505.png)
環境に応じて、ネットワークアダプタの設定を変更（NATにした）
![08_config_5.png](https://qiita-image-store.s3.amazonaws.com/0/63464/4fa4e7fc-77d3-2480-9199-e280fb1a981d.png)

# 5. 仮想マシンを起動
無事に起動しました。
sshや固定IPなどの設定はよしなに。

![09_login.png](https://qiita-image-store.s3.amazonaws.com/0/63464/06f819ce-dbe0-40e6-d6a6-bc2fc23af82a.png)
![10_ssh.png](https://qiita-image-store.s3.amazonaws.com/0/63464/51058e69-3022-2224-e4f6-402582752fcf.png)
vps 上の Arch Linux に Jupyter notebook をインストール

次のページを参考にしました。
[Jupyterを導入しよう -リモート編-](https://qiita.com/Miggy/items/5466a2c1e968602f3ebe)
[リモートサーバでjupyter notebookを起動させローカル環境で使う](https://qiita.com/Miggy/items/5466a2c1e968602f3ebe)

1) Jupyter のインストール
次のページにあります。
[Jupyter Installation](https://wiki.archlinux.org/index.php/Jupyter#Installation)

```bash
sudo pacman -S jupyter-notebook
sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension
sudo pacman -S ipython
```

2) sha鍵 の生成

```text
$ ipython
Python 3.6.6 (default, Jun 27 2018, 13:11:40) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from IPython.lib import passwd

In [2]: passwd()
Enter password: 
Verify password: 
Out[2]: 'sha1:5ade54f818*************************'
```

3) 環境設定

```bash
jupyter notebook --generate-config
```

.jupyter/jupyter_notebook_config.py
というファイルが出来ます。

4) .jupyter/jupyter_notebook_config.py の編集

```python:.jupyter/jupyter_notebook_config.py
# Configuration file for jupyter-notebook.
from jupyter_core.paths import jupyter_config_dir, jupyter_data_dir
import os.path
import sys
sys.path.append(os.path.join(jupyter_data_dir(), 'extensions'))

c = get_config()
# 略
#
# 該当する箇所のコメントアウトを外して編集

c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.password = u'sha1:XXXXXXXXX' #先ほど生成されたsha鍵を記述
c.NotebookApp.extra_template_paths = [os.path.join(jupyter_data_dir(), 'templates') ]
c.NotebookApp.server_extensions = ['nbextensions']
#
```

5) Jupyter Notebook の起動

```bash
jupyter notebook
```

6) クライアントでアクセス

![jupyter_jul06.png](https://qiita-image-store.s3.amazonaws.com/0/179446/e841d70e-0dea-36ce-f750-c2351bd41bf0.png)


```text
$ jupyter --version
jupyter core     : 4.6.3
jupyter-notebook : 6.0.3
qtconsole        : not installed
ipython          : 7.13.0
ipykernel        : 5.1.4
jupyter client   : 6.0.0
jupyter lab      : not installed
nbconvert        : 5.6.1
ipywidgets       : 7.5.1
nbformat         : 4.4.0
traitlets        : 4.3.3
```
Chef::Util::FileEditによる処理は、String操作でも簡単に実装可能で、かつ応用もしやすい

Chef::Util::FileEditは、以下の様にStringを用いた処理に代替可能で、sedやawkも使いやすい。


#Chef::Util::FileEditの例

```ruby:

file '/tmp/text' do
  content lazy {
    f = Chef::Util::FileEdit.new(path)

    f.insert_line_if_no_match(/^ABC\s/, "ABC \n")
    f.search_file_replace_line(/^ABC\s/, "ABC DEF\n")
    f.search_file_delete_line(/^GHI/)

    f.send(:editor).lines.join
  }
end
```
個人的によく使うのはこの辺り。

#Stringによる同等の処理の例
それぞれ以下の様に代替可能

```ruby:

file '/tmp/text' do
  content lazy {
    s = %x(cat #{path})                   # Chef::Util::FileEdit.new相当

    s += "ABC \n" unless s =~ /^ABC\s/    # insert_line_if_no_match 相当
    s = s.gsub(/^ABC\s.*\n/, "ABC DEF\n") # search_file_replace_line 相当
    s = s.gsub(/^GHI.*\n/, '')            # search_file_delete_line 相当

    s                                     # send(:editor).lines.join 相当
  }
end
```

可読性は落ちるかもしれないが、何をするのかが明確にわかる様になったとも言える。


# 途中の処理にsedやawkも使える

```ruby:


file '/tmp/text' do
  content lazy {
    s = %x(cat #{path})

    s += "ABC \n" unless s =~ /^ABC\s/
    s = s.gsub(/^ABC\s.*\n/, "ABC DEF\n")

    s = %x( { cat <<'_EOC_'               # sedを使ったsearch_file_delete_line 相当
#{s.chomp}
_EOC_
            } | sed '/^GHI/d'
        )

    s
  }
end
```

sedやawkが得意な人は好きな方で
echo "#{s}" | sed ... などとしないのは、各種記号が含まれる場合への対応。

参考
- [Class: Chef::Util::FileEdit](https://www.rubydoc.info/github/opscode/chef/Chef/Util/FileEdit#search_file_delete_line-instance_method)
- [Chefによるテキストファイル編集をfileリソースにおけるsed, awkで行う例](https://qiita.com/hiroyuki_onodera/items/0fd08cfd9a8c8c2e432d)
Vagrant上でgit pushできない！！

#結論：できました。
Vagrantの再起動でどうにかなりました

#困ったこと
git add .もgit commitもうまく行ったのに突如、pushできなくなった…

#エラー文
```
ssh: Could not resolve hostname github.com: Temporary failure in name resolution
fatal: The remote end hung up unexpectedly
```
原因はMacをスリープにしてたり、再起動を行ってたりでローカルとvagrantとの接続がおかしくなってたみたい

#Vagrantのコマンドとかの参考
https://qiita.com/htk_jp/items/929875eaa5afc71c25ed

めっちゃ助かりました
http://www.kurisankaku.xyz/entry/2016/04/22/103000
nltkでBLEUしたメモ

文章同士の似ている度合を計算するBLEUのnltk版をお試ししたメモ

※BLEUの詳しいことは[こちら](http://www2.nict.go.jp/astrec-att/member/mutiyama/corpmt/4.pdf)を見てください～

#環境
python 3.6.4
nltk 3.2

#参考様
[A Gentle Introduction to Calculating the BLEU Score for Text in Python](https://machinelearningmastery.com/calculate-bleu-score-for-text-python/)


#コードと結果

```python:bleuTest.py
from nltk import word_tokenize
from nltk import bleu_score

hy = "I have a pen"
hy = word_tokenize(hy)
re = "I have a apple"
re = word_tokenize(re)
res = [ re ]

BLEUscore = bleu_score.sentence_bleu(res, hy)
print("score : " + str( BLEUscore ))
```

Warningが出るけどいけるっぽいです～


```python:結果
/home/user/.pyenv/versions/anaconda3-5.0.1/envs/ml/lib/python3.6/site-packages/nltk/translate/bleu_score.py:490: UserWarning: 
Corpus/Sentence contains 0 counts of 4-gram overlaps.
BLEU scores might be undesirable; use SmoothingFunction().
  warnings.warn(_msg)
score : 0.7071067811865476

```
Pythonで世界地図-13（等高線　初心者向け）

Contour plotサンプルプログラム
https://matplotlib.org/gallery/images_contours_and_fields/irregulardatagrid.html#sphx-glr-gallery-images-contours-and-fields-irregulardatagrid-py

```python:
#!/usr/bin/python3
# coding: UTF-8

import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

lon1 = 137.0 #地図中心
lat1 = 37.0
lon2 = 10.0 #地図の大きさ（片側）
lat2 = 10.0

map = Basemap(llcrnrlon=lon1-lon2,llcrnrlat=lat1-lat2,urcrnrlon=lon1+lon2,urcrnrlat=lat1+lat2,resolution='i',projection='cyl')

#等高線
lon = np.linspace(lon1-lon2,lon1+lon2,11) #lon = 127〜147, 2度毎
lat = np.linspace(lat1-lat2,lat1+lat2,11) #lat = 27〜47, 2度毎

x, y = np.meshgrid(lon,lat)
#x, y = map(x, y)                    #projection='cyl' の場合は不要。
z = np.array([                                    #4 - 黄色、 0 - 紺色
    [0,  1,  0,  0,  0,  2,  0,  0,  0,  4,  0],  #lat=27
    [4,  0,  3,  0,  0,  0,  1,  0,  0,  2,  0],  #lat=29
    [0,  2,  0,  0,  0,  2,  0,  0,  0,  1,  0],  #lat=31
    [0,  0,  0,  3,  0,  0,  1,  0,  0,  2,  0],  #lat=33
    [0,  4,  0,  3,  0,  0,  1,  0,  0,  4,  0],  #lat=35
    [0,  2,  0,  0,  2,  0,  0,  2,  0,  1,  0],  #lat=37
    [0,  0,  4,  0,  1,  0,  0,  3,  0,  0,  0],  #lat=39
    [1,  0,  0,  3,  0,  0,  0,  4,  0,  2,  0],  #lat=41
    [0,  1,  0,  2,  0,  0,  3,  0,  0,  4,  0],  #lat=43
    [0,  1,  0,  2,  0,  0,  3,  0,  0,  4,  0],  #lat=45
    [2,  0,  0,  0,  0,  1,  0,  0,  0,  4,  0]]) #lat=47
#lon=127,129,131,133,135,137,139,141,143,145,147

map.drawcoastlines() #海岸線
map.contourf(x, y, z) #等高線 (塗りつぶし)
#map.contour(x, y, z) #等高線 (塗りつぶしなし)
#map.contourf(x, y, z, colors=['r','b']) #赤と青が交互で表示のみ
map.colorbar()


map.drawmeridians(np.arange(127, 149, 2),labels=[True,False,False,True]) #経線
map.drawparallels(np.arange(27, 49, 2),labels=[True,False,False,True]) #緯線

plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/59e428c0-9d39-9915-6fa9-0c76dda307ae.png)
Xamarin.iOS Maps Static APIを利用した地図画像生成

自作のランチアプリを作っている時に、だいたいこの辺みたいな感じで、GoogleMapのピン付き画像が欲しかったので使用してみた。

どんな感じかと言うと、


ピンを立てたい位置に照準を合わせて、


<img width="375" alt="IMG_0166.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/84002/3d5e0884-ecc5-e0ed-0cb8-dee38b5e7e49.png">



確定ボタン的な何かをタップすると、

![スクリーンショット 2018-07-06 19.12.32.png](https://qiita-image-store.s3.amazonaws.com/0/84002/1ec9af78-ed26-9040-39c6-38a19892ed2d.png)

照準を合わせたところにピンがたった画像が生成されるといった感じ。


##実装

1.表示されているGoogleMapの中心座標を渡す

```c#

CGPoint point = Mapview.Center;
Mapview.Projection.CoordinateForPoint(point);
```

2.Maps Static APIに、GoogleMapの中心座標の`Latitude`と`Longitude`を渡し叩く

```c#

string url = Uri.EscapeUriString("https://maps.google.com/maps/api/staticmap?markers=color:red|" + $"{lat},{lng}" + "&zoom=16&size=" + 207 + "x" + $"{Math.Floor(this.screenShotViewWitdh)}" + "&sensor=true");
NSUrl googlmapsStaticMapApi = new NSUrl(url);
```

3.NSData.FromUrlを使い、画像データを取得する

```c#

return UIImage.LoadFromData(NSData.FromUrl(googlmapsStaticMapApi));
```

4.前の画面に画像データを渡す

```c#
public override void ViewWillDisappear(bool animated)
		{
			base.ViewWillDisappear(animated);

			if(IsMovingFromParentViewController){
				var parentVc = NavigationController.ChildViewControllers;
				//HACK: コントローラー名でなおかつそのコントローラーが生きている状態という条件にした方が良さそう
				var childvc = ParentViewController.ChildViewControllers[1] as UpLoadDataViewController;
				childvc.setMapImage(MakeStaticGoogleMap());
				childvc.setLatLng(lat, lng);
            }    
		}

```

5.渡ってきた画像データをImageViewに入れる

```c#

public async override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            if (map != null)
            {
                StreetAddressImageView.Image = map;
            }
            if (shop != null)
            {
               //未実装
            }
        }
```




画像生成部分の全体

```c#

public UIImage MakeStaticGoogleMap(){
            CGPoint point = Mapview.Center;
            CLLocationCoordinate2D coordinate2D = Mapview.Projection.CoordinateForPoint(point);
            lat = coordinate2D.Latitude;
            lng = coordinate2D.Longitude;
			string url = Uri.EscapeUriString("https://maps.google.com/maps/api/staticmap?markers=color:red|" + $"{lat},{lng}" + "&zoom=16&size=" + 207 + "x" + $"{Math.Floor(this.screenShotViewWitdh)}" + "&sensor=true"); //$"{Math.Floor(this.screenShotViewHeight)}"
			NSUrl googlmapsStaticMapApi = new NSUrl(url);
            return UIImage.LoadFromData(NSData.FromUrl(googlmapsStaticMapApi));
        }

```

StackOverFlowのどっかにあった質問をみてやったのですが忘れてしまったので思い出したら貼っておきます。。
[Mac High Sierra]HomebrewでインストールしたMySQLの自動起動設定


ターミナルからbrew listで、MySQLがHomebrew経由でインストールされていることを確認。

```
$ brew list
apr		boost		git		jemalloc	libpq		mysql		php@7.0
apr-util	brotli		glib		jpeg		libsodium	nghttp2		php@7.1
argon2		c-ares		gmp		libev		libtool		openssl		unixodbc
aspell		freetds		httpd		libevent	libzip		pcre		webp
autoconf	freetype	icu4c		libffi		mcrypt		php
bash-completion	gettext		jansson		libpng		mhash		php@5.6
```

brew servicesコマンドでMySQLの起動を設定。

```
$ brew services start mysql
==> Successfully started `mysql` (label: homebrew.mxcl.mysql)
```
ひと昔前のARToolKitを使ってみた

iOS向けのスマホアプリを開発する際に、ARToolKitなるものを使用してみました。

これはAppleがARKitをリリースする随分前からオープンソースとして広く利用されてきていました。

C言語ライブラリであり、中身をそんなにいじらなくても好きな位置に好きなオブジェクトをARで表示させることができます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/269231/070931e6-8cca-16b0-9a31-19084f65ec33.png" width=50%>

ご覧のように誰でも簡単にARスマホアプリを開発することができるので、みなさんも一度は是非使ってみてください。
Cognos レポートのプロパティでの概要集計と詳細集計の違い

#概要集計と詳細集計の違い
Cognosで何かこんな設定があるのは知ってるけど、あんまりちゃんと理解しようとしてなかったのを、ちょっと真面目に理解しようとしてみたシリーズです。

レポートの概要集計と詳細集計の違いってわかりますでしょうか。

![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/40acd137-7126-6fcc-fbe2-9d80606253f4.jpeg)

詳細集計の方は簡単です。

例えばレポート実行してみると、この表示になりますが、ここでの製品ラインごとの「数量」は、ある製品ラインのそれぞれの製品が、XXの日付にXX担当者によってXXの方法でXXの地域で販売された、その個々の販売履歴を足し合わせた、製品ラインごとの合計値が表示されています。
![009.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/8d4d80eb-66dd-d185-efb2-87db73a9d819.jpeg)

例えば、詳細集計を「合計」ではなく「最大値」にすると、こんな感じに数値は下がります。
これは、個々の販売履歴の合計ではなく、個々の販売履歴で最大だった一件を表示しているからです。
![010.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/00dfa837-24ba-d22e-d918-67c3b4b2f662.jpeg)

さて、では「概要集計」って何でしょう。
マニュアルに書いてある、以下の部分がその説明なのだろうかと思いますが、ピンと来ません。

**リレーショナル・データの集計**
https://www.ibm.com/support/knowledgecenter/ja/SSEP7J_11.0.0/com.ibm.swg.ba.cognos.ug_cr_rptstd.doc/c_cr_rptstd_wrkdat_add_summary_rel.html#cr_rptstd_wrkdat_add_summary_rel
<抜粋>
集計は、すべてのデータ・ソースに対してサポートされており、リストのヘッダーやフッター、およびクロス集計の合計行や合計列で、どのようにデータ・アイテムを合計するかを指定します。

クロス集計でやった場合は実は簡単です。

概要設計に「個数」を指定してみて、クロス集計の交点をクリックすると表示されるツールバーの「集計」アイコンから、「デフォルトの集計」を選択してみます。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/7278b136-eac2-2a6d-5834-0828f478f93e.jpeg)

すると、このような集計行・集計列が表示され、見ての通り、行の合計個数、列の合計個数が表示されています。
つまり、「集計」アイコンで集計行・集計列を作った時の、デフォルトの集計規則が指定されるわけですね。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/e13c986f-84ba-9c3f-ca0c-82cf21fb989b.jpeg)

リストの場合が困ったものです。
「リストのヘッダーやフッター」と言っているものが良く分からないので、
とりあえずクロス集計同様、概要集計を「個数」にして、「集計」アイコンから「デフォルトの集計」を選択してみます。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/1eb51952-e045-b414-195b-312746afc6d9.jpeg)

おやおや、「個数」ではなく「合計」で集計されちゃったよ、となります。
リストの場合、クロス集計とは動きが違うんだよ、というのがこの概要集計の設定項目を理解する上で知っておく必要のあるポイントです。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/0444d0a0-8378-dff5-f073-5b79bb3d0438.jpeg)

じゃあ、何なんだろうと思って、今度は「製品ライン」のセルの方を選択して表示される「グループ化」のアイコンを選択してみます。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/ebaeb85f-9980-ac68-b1ac-54807e243f10.jpeg)

おおっと、できました。
つまりリストの場合は、「集計」機能ではなく、「グループ化」の様な機能で集計行が生成された時に、「概要集計」の設定が効いてくるようですね。
![008.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/29d23db9-44a6-be75-01c8-c631b17aac89.jpeg)

何でクロス集計とリストで動きが違うのだろう、とは思いますが、そういうものの様なので、そういうものだと理解しておいて頂ければと思います。

以上です。
たまに人に聞かれる事がありますので投稿しておきました。
Android端末のADBによるWiFi設定について(SH-M05編 Android 7.1.2)

## あらまし
Android(SH-M04)をキッティングするにあたりadbで自動化(バッチ化)することを思いついた。
apkのインストールなどは、問題なく行えたものの、
ADBでのWiFi設定が苦労したが、力技で解決できたので、共有したい。

## ADBによるWiFi設定について
そもそも、標準では、CLIで設定する方法はないので、いろいろ探したところ、
StackOverFlowにて解決策を見つけた。
https://stackoverflow.com/questions/8708886/connecting-to-wi-fi-using-adb-shell
のjpihlさんが回答されている、
https://github.com/steinwurf/adb-join-wifi
を端末にインストールすることで解決できた。

実際は、インストール・設定完了後アンインストールをバッチで行った。

何事もないかに見えたが、テストで現場にてこの方法ではうまくいかないことが発覚した。

「SSIDがステルスの場合は、接続できない。」

いろいろ調べると、フラグがあるらしいことはわかったが、
adb-join-wifiにはこの機能がなかった。

## ステルス回避策

いくつか端末を持ち込んでいたところ、つながる端末があった。
設定画面から手動で入れたものであった。
このため、

```
adb shell am start -n com.android.settings/.wifi.WifiSettings
```
　と

```
adb shell input tap 
```
などを駆使し、SH-M04でのキッティングは成功した。

なお、スクリーンショットを取るバッチファイルを作り、
TAPする座標を確認した。
座標確認に役立ったのは、以外にもペイントである。

が

## 本題は、SH-M05である。

Androidのバージョンが上がった関係で、メニューの中にSSIDを追加する項目がなかった。
SSIDが表示されているListViewの最終行に表示されていた。
セットアップ環境により、何行目に出てくるかわからない。

いろいろとこねくり回して、
com.android.settings.wifi.WifiDialog
が設定のダイアログだということはわかったが、表示させる術がわからなかった。
もし、ご存知の方がいたら教えてほしい。

ついぞ解決方法を見つけることとなった。

## 意外な~~犯人~~解決方法

わかってしまえば（力技では）単純な話であった。
実際に発行したのは以下のコマンドである。

```
adb shell am start -n com.android.settings/.wifi.WifiSettings
adb shell input keyevent 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 KEYCODE_ENTER
```

おわかりいただけただろうか。
KEYCODE_DPAD_DOWN(↓)を連打後、Enterキーを押すのである。
SSIDが表示されない領域まで持っていくのである。
↓を連打がミソで、SSIDが死ぬほど出ているような環境下であれば、20の値をもっと増やしてやれば良い。
なお、SSID以外はフォーカスは表示されないので注意されたい。



これが、ことの顛末である。

めでたし、めでたし。

---
なお、別件で、マルチバイトで文字列を流し込む必要が出てきたが、下記の記事で解決できた。
https://qiita.com/yuki-nakamura/items/4bd0ea7524521e731335
YARD macro を使った Rails scope のドキュメントの書き方

[YARD](https://yardoc.org/) を使って、rails の scope のドキュメントを書こうとした時に、色々試行錯誤したのでメモ。

## macro を使わない方法

`# @!group Scopes` はお好みで。

一般的な DSL 的な書き方にドキュメントをつける時の書き方。

```ruby
class Post < ApplicationRecord
  # @!group Scopes

  # @!method active
  #   @!scope class
  #   @return [ActiveRecord::Relation]
  scope :active, -> { where(status: 'active') }

  # @!method nonactive
  #   @!scope class
  #   @return [ActiveRecord::Relation]
  scope :nonactive, -> { where.not(status: 'active') }

  # @!method status(status)
  #   @!scope class
  #   @param [String] status
  #   @return [ActiveRecord::Relation]
  scope :status, ->(status) { where(status: status) }

  # @!endgroup
end
```

## macro を使った方法

同じようなドキュメントを書きまくる時に省力化出来るマクロを使った場合。

一番最初にマクロを定義してあげれば、以降同じメソッドを使ったものは自動的にドキュメントを認識して書いてくれるし、必要に応じて `@` タグを追加できる。

```ruby
class Post < ApplicationRecord
  # @!group Scopes

  # @!macro [attach] scope
  #   @!method $1
  #   @!scope class
  #   @return [ActiveRecord::Relation]
  scope :active, -> { where(status: 'active') }

  scope :nonactive, -> { where.not(status: 'active') }

  # @overload status(status)
  #   @param [Symbol] status
  scope :status, ->(status) { where(status: status) }

  # @!endgroup
end
```

## HTML

HTML の出力結果はどちらも同じで、下記のような形になる。

`# @!group Scopes` 宣言を入れておくと、 *Class Method Summary* ではなく、 *Scopes* にサマリーがまとまって表示される。

<img width="1009" alt="HTML" src="https://qiita-image-store.s3.amazonaws.com/0/2908/541ee5f3-8600-e8fd-f18b-cfb9ec3f2427.png">

## 試行錯誤した点

* `@!macro` の宣言をリポジトリ全体のどこか１箇所だけでできないか試したけどダメだった。**わかる人いたら教えてください！**
* guard 使って実行すると微妙に挙動が変わるところがあってハマる
* `@!macro` を使う場合 `@!methodo` ではメソッドの宣言を上書きできなくて、`@overload` 使うと出来ることに気がつくのに時間がかかった

## 参考

[File: Tags Overview — Documentation for yard \(0\.9\.12\)](https://www.rubydoc.info/gems/yard/file/docs/Tags.md#macro)
get_postsを用いてカテゴリーとカスタムフィールドの複合条件で投稿を取得する

WordPressで作ったサイトの変更案件で下記の条件に該当する投稿一覧を取得するコトになった。

- 複数のカテゴリーに該当しない
- 特定のカスタムフィールドに値が設定されたコトがない　または　特定のカスタムフィールドの値が1ではない

ということで、get_postsの検索条件をゴニョゴニョと変更

```PHP
$args = array(
	'post_type' => 'post',     // 投稿タイプ
	'posts_per_page' => 3,     // 取得件数
	'cat' => array(-1, -2,),   //除外するカテゴリーID。categoryではなくcat。AND条件。
	'meta_query' => array(
		// hogehogeという特定のカスタムフィールドの値が1ではない
		array(
			'key' => 'hogehoge',
			'value' => 1,
			'compare' => '!=',
		),
		// hogehogeという特定のカスタムフィールドの値が一度も設定されたコトが無い
		array(
			'key' => 'hogehoge',
			'compare' => 'NOT EXISTS',
		),
		// OR条件で検索する
		'relation' => 'OR',
	),
	'order' => 'DESC',         // 並び順
	'orderby' => 'date',       // 並び順のキー
);
$posts = get_posts($args);
```

カテゴリーIDは管理画面のクエリ文字列(tag_id)で確認できます。

##参考にさせてもらいました
 - [get_postsで、複数のカスタムフィールドをキーにして検索・取得する方法](https://www.sandalot.com/get_posts%E3%81%A7%E3%80%81%E8%A4%87%E6%95%B0%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%82%92%E3%82%AD%E3%83%BC%E3%81%AB%E3%81%97%E3%81%A6%E6%A4%9C/)(外部サイト)
 - [WordPressで指定したカスタムフィールドが存在しない場合の投稿一覧を取得する方法](https://qiita.com/17ringe/items/ff145fc05f09f1229021)(Qiita)