OmniAICreator/Qiita-1.07M huggingface dataset:
DB2 10.1でユーザ定義関数なしで正規表現を使用する

# 背景
- DB2で`REGEXP_LIKE`などの正規表現を用いる関数が利用できるのは11.1以降
- 政治的な都合などによりユーザ定義関数は使いたくないor使ってはいけない
- それでも正規表現が使いたい

# 試した環境
- DB2 10.1 on AIX 7.1

# 使うもの
- XMLQUERY (XQuery式をSQL内で実行する)
    - `XMLQUERY('XQuery式' PASSING 値 AS "変数名")`でSQLから値を渡せる
    - 戻り値がXMLなのでそのままではSQL内では使えない
- XMLCAST (XMLデータをキャストする)
    - `XMLCAST(対象 AS 型)`でSQLでも使えるようキャストできる
- XQuery式
    - XMLデータを照会および変更するための言語
    - `fn:replace` `fn:matches` などで正規表現が使える

# 使用例
```:replace
db2 => VALUES (XMLCAST(XMLQUERY('fn:replace($c, "[0-9]+", " Fuga ")' PASSING 'Hoge123Hoge4Ho' AS "c") AS VARCHAR(32)))

1
--------------------------------
Hoge Fuga Hoge Fuga Ho

  1 レコードが選択されました。
```
```:matches
db2 => VALUES (XMLCAST(XMLQUERY('fn:matches($c, "[0-9A-Z]")' PASSING 'hogehoge' AS "c") AS VARCHAR(16)))

1
----------------
false

  1 レコードが選択されました。
```
```:replace_for_select
db2 => SELECT ID, NAME, XMLCAST(XMLQUERY('fn:replace($c, "([A-Z])[a-z]+\s?", "$1.")' PASSING NAME AS "c") AS VARCHAR(16)) AS NAME2 FROM TEST_USER

ID   NAME             NAME2
---- ---------------- ----------------
   1 Taro Tanaka      T.T.
   2 Hanako Yamada    H.Y.

  2 レコードが選択されました。
```

# 参考
- [IBM Knowledge Center - XQuery 関数を使用した DB2 データの検索](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_10.1.0/com.ibm.db2.luw.xml.doc/doc/xqrgetdata.html)
- [IBM Knowledge Center - XMLQUERY スカラー関数](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0022193.html)
- [IBM Knowledge Center - XMLCAST 指定](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0023486.html)
- [IBM Knowledge Center - matches 関数](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_10.1.0/com.ibm.db2.luw.xml.doc/doc/xqrfnmat.html)
- [IBM Knowledge Center - fn:replace 関数](https://www.ibm.com/support/knowledgecenter/ja/SSEPEK_10.0.0/xml/src/tpc/db2z_fnreplace.html)
- [DB2DBA: DB2 11.1新機能 - 正規表現 - Qiita](https://qiita.com/SVC34/items/8da8fb62db5fd118024a)
vmtoolsd について調べたこと



![image.png](https://qiita-image-store.s3.amazonaws.com/0/104578/4fdb348e-8362-c2f5-525b-c9ae5534337a.png)


```text:
[root@xxxxxx Init]# w
 16:36:44 up 48 days, 21:45,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     :0       :0               26 4月18 ?xdm?  12:21m 23.75s gdm-session-worker [pam/gdm-password]
root     pts/0    172.24.64.218    16:16    4.00s  0.10s  0.00s w
root     pts/1    :0               06 6月18  7days  0.04s  0.04s bash
[root@xxxxxxx Init]# who
root     :0           2018-04-26 18:52 (:0)
root     pts/0        2018-06-14 16:16 (172.24.64.218)
root     pts/1        2018-06-06 17:34 (:0)
```



#関連リンク

https://docs.vmware.com/jp/VMware-Tools/10.1.0/vmware-tools-user-guide.pdf
http://pubs.vmware.com/ws71_ace27/wwhelp/wwhimpl/js/html/wwhelp.htm?context=ws_user&file=tools.7.39.html

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/session-management
http://www.linux-pam.org/Linux-PAM-html/sag-pam_limits.html
https://teratail.com/questions/69369
[☆](http://www.astec-x.com/FAQ/xdmcp-maximum-sessions.html)
iView の Table コンポネントで画像を render する方法

[iView](https://iview.github.io/overview) の `Table` を使って、画像を表示しようとして、やり方がドキュメントになかったので、メモしたい

## ソース

```html
<template>
    <div>
         <Table :columns="columns" :data="tokens"></Table>
    </div>
</template>

<script>
export default {
    data () {
        return {
            columns: [
                {
                    title: 'Name',
                    key: 'name',
                    render: (h, params) => {
                        return h('div', [
                            h('img', { attrs: { src: require(`../../images/${params.row.icon}`) } }),
                        ])
                    }
                },
            ]
        };
    },
};
</script>
```

## ハマったポイント
1. `img` の `src` を指定したいが、 `props` ではできず、`attrs` を使うとできました
2. `img` のパスですが、該当ファイルからの相対パスだけでは画面上に表示できず、`require(...)`を入れるとできました。
WIP: GitHub 頻出英語フレーズ 100

※ WIP なのでまだ 100 個ないです。随時書き足していきます

OSS に Pull Request を投げるときや、逆に自分がメンテナーをしている repo のレビューやコメントのやりとりに使える文例集です。リーディングではなくライティングに活用することを意図しています。主に [rails/rails](https://github.com/rails/rails) のコメント欄などを引用していますが、その他の様々な repo や Stack Overflow などからも拝借しています。

---

**Travis がコケてますが、私の変更とは関係ありません**
Failures in TravisCI aren't related to my changes.

**動きがないので close します。必要であれば reopen してください**
Closing due to inactivity. Reopen as needed.

**まれにコケるテスト**
Occasionally failing tests

**関連する Issue と紐付けるとき**
Related to #30101

**自明な主語を省略するパターンその1**
Looks like many existing Rails users are going to experience this problem.

**自明な主語を省略するパターンその2**
Will do, I'll link the pull request here when I create it.

**コーディング規約とかで禁止するときは Disallow が便利**
Disallow specific global variables

**重複した Issue や PR を閉じるとき**
Closing in favor of #26743.

**A を使っている場合は B は不要です**
If you are using heroku.yml as your build manifest, a Procfile is not required. 

**不要なメソッドを削除するとき**
Remove unused `initialize_attributes` method

**development モードだと正常に動く理由は**
The reason why it works in development is

**次のコードを考えてみましょう。**
Consider the following code:

**不必要な複雑さをもたらす gem**
a gem which can lead to unnecessary complexities.

**諸事情で Approve できないときの文例**
hmm, I can't 👍 on this because my application uses it.

**もうリリースできる？とか聞かれて、まだ無理なとき**
Not yet. 

**この件が原因と思われる問題に遭遇しました**
I've run into an issue that I think is caused by this.

**両方とも必要です**
Both are needed.

**もし hoge メソッドを使用している場合だったらどうなりますか？**
What if we use the `hoge` method?

**同じようなやり方で**
in the same vein that it does with Turbolinks

**脆弱性対応で依存関係を更新するとき**
Update Yard dependency (CVE-2017-17042)

**メソッドの呼び出しを関数の先頭に移動させる必要があります**
You need to move the `event.waitUntil` call at the beginning of the function, otherwise your service worker could be killed in the meantime (which is what's happening).

**機能を箇条書きしたいとき**
With request specs, you can:
- specify a single request
- specify multiple requests across multiple controllers

**この点に関して、ドキュメントが少し不明瞭ですね**
The documentation is a bit unclear on this.

**OSS のバグを踏んで、その修正を Pull Request してる人がいて既に Merge もされているんだけど、その修正を含むバージョンがまだリリースされていないのでコメント欄で「リリースまだ？」って突きたいけど、メンテナの人を怒らせないよう最大限やわらかい表現で言いたいとき**
Are you planning to release this in the next version?

**下記の手順で解決しました**
I was able to resolve by the following steps:
1. foo
1. bar

**軽微なバグの修正**
Minor bug fixes
Windows 8.1 + Excel 2016 > .xlsx保存時に「のコピー」を自動的に付加される > 元の.csvファイルが読み取り専用の場合

```txt:動作環境
Windows 8.1 Pro (64bit)
Excel 2016
```

### 症状

.csvファイルを元に.xlsxファイルを作成したら、「***のコピー.xlsx」というファイル名になっていた。

### 再現手順

1. .csvファイルを「読み取り専用」にしておく
    - 誤操作による上書き防止のため
2. Excelで.csvファイルを開く
3. ファイル > 名前を付けて保存
    - >> この時点で「のコピー」が付いている
4. 拡張子を「.xlsx」にして保存
    - ファイル名まで見ていない場合、「のコピー」付きのファイルが生成される

### 備考

「ファイル　> 名前を付けて保存」時の「のコピー」文字列付加機能。
ない方が良い。

僕以外のユーザー全員がひっかからないのであれば、問題はないけれど。
GoogleMapの埋め込み表示はどうするべき？

#GoogleMapをサイトに埋め込み表示しているけれどこのままでいいの？
GoogleMapの表示について、
maps→maps platformへの仕様変更もあることですし、
疑問に思って調べたところ、わからなかった部分が少し解決したのでメモ

##Google Maps Platform API
2018年6月～7月導入のgoogle maps platform APIは、
18種あるgoogle maps APIを統合して3種のgoogle maps platformとなります
[Google Maps Platform](https://cloud.google.com/maps-platform/?hl=ja)

統合され料金プランが従量制になるだけで、今までのコードのまま使用が可能ですが、
API keyを正しく設定していないと7/16以降表示されなくなる場合があるようです。

と、聞いて、じゃぁ実際自分の管理しているところではどうなのだろう。
API keyはずいぶん前に取得してあるけれど、実際の取得にkeyの設定はしていないが・・・
と調べているうちにわかったのは

##3種の異なる埋め込み表示方法がある
ということでした。

1. google mapsの地図から取得した埋め込み
2. google maps EMBED API
3. その他google maps API

###1. google mapsの地図から取得した埋め込み
表示した地図から
共有→iframeのコードを使って取得したコードを使ってマップを表示する場合、
API keyは不要となります。

google maps platform API checker
というAPIをkeyの設定をして使用しているかのチェッカー（chromeの拡張機能）では、
other Details→ Maps Embed APIを使用していると判断されてしまいます。
でもEmbed APIとは別なんですって。

確かにアクセスURLが微妙に違う・・・

embedの場合
`https://www.google.com/maps/embed/v1/{mode}?key=YOUR_API_KEY&parameters`
マップから共有の場合
`https://www.google.com/maps/embed?pb=parameters`


###2. google maps EMBED API
iframeのコードを使って表示する簡単な埋め込みです
javascriptで記述することがないので、簡単な分できることも少ないです。
詳細は、
[Google Maps Embed API|Google Developers](https://developers.google.com/maps/documentation/embed/guide?hl=ja)
で確認していただくとして、

platform APIになると従量課金制の有料で、200ドル分まではフリーで使えるということですが、
このほかに、
・iOS、Android、Embed でマップを使用（マップ表示のみ）
・マップ URL
は無料で使えます。
つまりEMBED APIはAPI keyを設定する必要があるが、無料で使えるということです。

###3. その他google maps API
ルートを表示したい！
スポットをたくさん設定したい！
ストリートビューのここを表示したい！
など、地図上で表現したいことは様々です。
javascriptを利用して細かい設定をした地図の表示をしたり、
アプリで利用する場合はこれらAPIを使う必要がでてくるでしょう。
しかし、単純な所在地の表示の場合は出番がなさそうです。

wordpressでプラグインを利用してmapを表示している場合、
embed以外の方法で表示しているかもしれません。
つまり、課金の対象となってくる可能性があります。
API keyの設定と支払い方法の設定を確認しておいた方が良いでしょう。

##結論）embedが良さそうだけど...しばらくは共有埋め込み
何の変哲もないサイト内で地図を表示する場合は、
・API keyを取得
・keyに制限を設ける（盗用をさけるため）
・google maps embed APIを使用し、マップを表示する
が良いのかなと思います。
一日のビュー回数などをコントロールすることで、
スポットでビュー回数が上がった場合なども、
表示できない期間が続くようなことを避けることもできます。
よっぽどアクセス数がない限り、無料で使えそうです。

ただ、
盗用を避けるための設定が面倒といえば面倒です。
　[API キーを安全に使用するためのベスト プラクティス](https://support.google.com/cloud/answer/6310037?hl=ja)
API keyをベタ打ちするembed方式はこのままで良いのかしら？とも思います。
セキュリティの観点からすると、もう少し検討をしたほうが良さそうです。

また、マップから、共有→コードを取得する
というところは、
個人利用の観点からまだまだなくならないようにも思います。

しばらくは共有埋め込みでいってみようと思います。
nokogiriがinstallできないときー

nokogiriがinstallできねぇ

```
An error occurred while installing nokogiri (1.8.2), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.8.2' --source 'http://rubygems.org/'` succeeds before bundling.

In Gemfile:
  capybara was resolved to 3.2.1, which depends on
    xpath was resolved to 3.1.0, which depends on
      nokogiri
[jenkins@ip-172-31-36-13 cucumber]$ bundle exec cucumber
Could not find gem 'nokogiri (~> 1.8.2)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```


必要なpackageを追加する

```
$ sudo yum install libxml2-devel libxslt-devel
 ```

bundle installする

```
$ bundle install
Fetching nokogiri 1.8.2
Installing nokogiri 1.8.2 with native extensions
Your bundle is complete!
 ```
Rails チュートリアル メモ 第6章

# メモ

## 6.1.1

* モデル名は単数形、コントローラーとテーブル名は複数形

## 6.1.3

* `rails console --sandbox` でサンドボックスモードに突入可能
* モデルクラスの `create` メソッド = `new` + `save`
    * `destroy` メソッドで DB から削除できるが、メモリには残っている

## 6.1.4

* `find` : DB 上の ID で検索
* `find_by` : ハッシュを与えてそれで検索
    * `find_by_name` のようなメソッドも生えている（こっちが新しい？）


## 6.1.5

* `reload` : DB から読み込み直す
* `update_attributes` :
    * 複数の属性を更新
    * DB への保存まで行う
    * バリデーションも行う
    * 単数版の `update_attribute` もあるが、こっちはバリデーションを行わない
        * 詳細: https://qiita.com/tyamagu2/items/8abd93bb7ab0424cf084
        * ありすぎでは

## 6.2.2

* バリデーションルールはモデルクラスに書く
* バリデーションで失敗すると、そのオブジェクトの `.errors` 属性が埋まる
    * `user.errors.full_messages` などとして情報が取得できる

## 6.2.5

* モデルに `uniqueness : true` を指定すると、`valid?` メソッド実行時に DB が SELECT される
    * 既に存在してないかを確認するため
    * 逆に言うと、`valid?` を実行するまでは `errors` を取得しても何も出てこない

## 6.2.5

* 出てきた4つのバリデーションのうち、`presence` と `uniqueness` は DB レベルでも保証したほうがよさそう
    * `length` は DB 側の型によって決まる
    * `format` は DB 側で検証できなさそう？

## 6.2.5

* マイグレーションの名前は、コミットログのように「何をやったか」がわかるように書くこと
    * 例: `rails generate migration add_index_to_users_email`

```bash
# そうするといい感じになる

ls -1 db/migrate/
20180611072246_create_users.rb
20180614054521_add_index_to_users_email.rb
```

* あとでわかったが、末尾を `to_テーブル名` として、引数で `カラム名:型` を渡すと、いきなりいい感じのマイグレーションを作ってくれる
    * 例: `rails generate migration add_password_digest_to_users password_digest:string`

## 6.2.5

* `before_save` で保存時に何か処理した結果をテストする場合、`reload` が便利

## 6.3.1

* モデルクラスに `has_secure_password` なるメソッドを書くだけで、以下のようなことが起きる
    * DB の `password_digest` カラムに、ハッシュ化されたパスワードを保存できるようになる
    * 以下の属性が生える
        * `password` : ユーザーが入力したパスワード
        * `password_confirmation` : 確認用に2回入力してもらった方のパスワード
        * いずれも、存在性とパスワード一致のバリデーション付き
    * 以下のメソッドが生える
        * `authenticate`
* 条件
    * `password_digest` というカラムが DB に存在すること
    * bcrypt gem のインストール

## 6.3.3

* 前述の通り `password` にはデフォルトで存在性のバリデーションがかかっているが、これは新規追加のときにしか働かないので、そのままだと全てスペースのパスワードに変更できてしまう
    * これを防ぎたかったら、自分で presence バリデーションを書くしかない
    * これを防ぐ必要あるのかな？全て「a」のパスワードを特に防がないのと同じ理由で、放っておいてもいい気もするけど
* なんにせよ、`password` のバリデーションを開いて修正するときは注意が必要そう

## 6.3.4

* DB からユーザーを検索 → 名前だけ変更 → 保存しようとすると、エラーになる
* これは、`password` 属性が埋まっていないから
    * DB には `password_digest` カラムしか存在せず、そこから元のパスワードは復元できない
    * `update_attribute` を使って、バリデーションを回避しつつ修正するしかない
【Visual Studio】Snippet Designerを使ってスニペットを簡単に作る

# はじめに
スニペットが簡単に作れるVisual Studio拡張機能「Snippet Designer」を使ってみました。

# 環境
Windows 10
Visual Studio 2015 Community

# インストール
拡張機能と更新プログラムから Snippet Designer をダウンロードします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/a984b3c4-a58a-0df2-270d-3c340f67d743.png)

ダウンロードしたらVisual Studio再起動して有効にします.

# スニペットを作成する
SnippetDesignerをインストールすると、右クリックメニューの中に"Export as Snippets"という項目が追加されます。

任意のコードを選択して右クリックして"Export as Snippets"を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/b1ed9ba0-d33f-c1f6-be64-19cb4e981fc0.png)


以下のような画面が表示されます。<br>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/31f0b314-6ceb-6e40-7102-ecb5196f8e35.png)

ここで表示されているものがスニペットの中身になります。

```
    [SerializeField, Header("プレハブ")] private GameObject _prefab;
    public GameObject Prefab { get { return _prefab; } }
```


# スニペットのショートカット
スニペットを使うためにはショートカットを登録する必要があります。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/44288/6cb39ca9-deba-383d-f676-c8f8c9a9d301.png)
ウィンドウ上部にある、Shortcutの部分を編集することで、ショートカットを編集することができます。

今回は sfield としました。

<br>

スニペットを保存すると、スニペットが有効になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/be7d753e-6a55-91ae-e489-88bd1143042a.png)


# スニペットを使う
C# コードエディタに戻り、sfieldと入力してTabを押すと、先程作成したスニペットが自動で入力されます。

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/44288/dd7d99af-8450-35c4-396a-f8c391f2e1a6.gif)

スニペットが動くことが確認できました。

# 作成したスニペットの確認
作成したスニペットはメニューの「ツール(T)」 → 「コードスニペットマネージャー」から確認することができます。

.snippetファイルを開くことでスニペットを編集することもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/432e149f-80af-871e-cf1b-a545b7bdad7e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/1176097d-af50-549e-353d-02eae35eb2f6.png)


# スニペットでReplacementを使う
$$で囲うとReplacementとして扱うことができます。

例えば、prefabを以下のように$$で囲ってみます。

```
    [SerializeField] private GameObject _$prefab$;
    public GameObject $Prefab$ { get { return _$prefab$; } }
```

このスニペットを呼び出すと以下のようにタブキーで$$で囲った部分へジャンプ移動することができます。

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/44288/6d152317-affe-056d-9deb-0388e1028cd3.gif)
vue-cli 3.0 で作成したプロジェクトの環境変数(.env)の設定

`vue-cli 3.0` がRCになりました。
2.x系から大きく変わったため、ドキュメントを読みながら
`production`環境と`development`環境でのパラメータを分けたい際に利用する
環境変数の設定方法を記載します。

# 設定ファイルについて
設定ファイルはプロジェクトのルートディレクトリに以下のファイルを置きます。
`src`配下ではないので注意してください。

```sh
# production環境用ファイル
.env
# development環境用ファイル
.env.development
# test環境用ファイル
.env.test
```

# 変数の定義方法
`VUE_APP_○○=xxx` の形式で記載します。
`VUE_APP_`を先頭に付与しないと、その変数は読み込まれません。
私はここでハマりました。もう一度言います。
**`VUE_APP_`をプリフィックスとしてつけないと変数は読み込まれません。**

```sh
# これは読み込まれる
VUE_APP_API_URL_BASE=https://xxx.yyy.example.com/api/

# これは読み込まれない
API_VERSION=v1
```

# アプリケーションから変数へのアクセス
`process.env.○○` でアクセスします。

```js
console.log(process.env.VUE_APP_API_URL_BASE);
// https://xxx.yyy.example.com/api/ が出力される

console.log(process.env.API_VERSION);
// undefinedが出力される
```

# 参考資料
https://cli.vuejs.org/guide/mode-and-env.html#example-staging-mode

# 最後に
そろそろ`vue-cli3.0`向けの記事が増えてきてもいいと思うんです。
まだ仕事では使いづらい段階かもしれませんが、個人の勉強として使う分には
ぜひ`vue-cli3.0`でプロジェクトを作りましょう！
[VCCW2.x] Graphvizをインストールしてコールグラフを表示する

[XHProfをインストール](https://qiita.com/heikyo/items/f7280d727ab85482bfcc)、[XHGUIをインストール]()したので、
今回はコールグラフを表示するようにします。
「Graphviz」が必要になるので、インストールします。

## 環境
| CentOS | 6.7 |
|:-:|:-:|
| PHP | 5.4.45  |
| VCCW | 2.21 |

## Graphvizのインストール＆設定
### インストール

```
$ vagrant ssh
$ sudo yum -y install graphviz graphviz-gd
```

### xhgui/xhprof_lib/config.phpの編集
以下の記述がコメントアウトされているので外します。

```php:[DocumentRoot]/xhgui/xhprof_lib/config.php
//These are good for linux and its derivatives.
$_xhprof['dot_binary']  = '/usr/bin/dot';
$_xhprof['dot_tempdir'] = '/tmp';
$_xhprof['dot_errfile'] = '/tmp/xh_dot.err';
```

## 確認
http://test.xhprof/xhgui/xhprof_html/index.php
から詳細ページへ行きます。
すると以下のような「View Callgraph」というリンクあると思います、

![スクリーンショット 2018-06-11 18.55.57.png](https://qiita-image-store.s3.amazonaws.com/0/10263/79cb48fa-087d-5ed1-a845-34dae22a01a7.png)

をれをクリックすると以下のようなページが確認できると思います。

![スクリーンショット 2018-06-11 18.54.38.png](https://qiita-image-store.s3.amazonaws.com/0/10263/678ae62e-847d-142e-d95c-8d0b06bbfd79.png)

## 参考
[xhprofを使ってみた(XHGUIとCallgraphインストール編）](https://qiita.com/ttsan/items/e26e2dc1394714d13a58)
rails5, bootstrap4でスマホ、PCでヘッダー画像を出し分ける

headerの画像を2枚用意して、出し分ける。

スマホとPCそれぞれに違うクラスを割り当てる。

スマホ[class: "d-block d-md-none mx-auto"]
PC[class: "d-none d-md-block img-fluid"

```haml:index.html.haml
//スマホ
= image_tag("/images/header.png", width: '375', alt: "なろう廃人のすすめ", class: "d-block d-md-none mx-auto")
//PC
= image_tag("/images/header-pc.png", alt: "なろう廃人のすすめ", class: "d-none d-md-block img-fluid pb-2")

```


参考サイト
[Bootstrap4 PCとスマホで画像を切り替える方法](http://clue-design.com/bootstrap4/bootstrap4-pc-sp-img-change)
TwitterKit で Callback URL not approved っておこられた話


最近、Twitter のログイン、ツイート機能などを利用できる SDK、TwitterKit を触る機会があったのですが、
つい最近まで問題なく動作していたコードが突然エラーになっていたので、その解決方法をメモしておきます


#開発環境
Swift: 4.0.3
Xcode: 9.2
iOS: 11.2

# TwitterKit
公式のSDKで、自身が開発したアプリ内で Twitter のログイン、ツイート機能などを実装するために使用

詳しい TwitterKit を用いたログイン、ツイート機能などの実装方法は後述の参考サイトをご参照ください


※TwitterKit は2018年10月31日をもってサポート終了予定のようです
[Twitter Kit SDK のサポート終了のお知らせ](https://blog.twitter.com/developer/ja_jp/topics/community/2018/TKSDK_tr.html)


#今回怒られたエラー内容

TwitterKit のが提供している以下のコードから生成できるログインボタンをタップした際、

```swift
let loginButton = TWTRLogInButton(logInCompletion: { session, error in
            // 何らかの処理
        })
loginButton.center = self.view.center
self.view.addSubview(loginButton)
```

以下のようなログが出力され、ログイン画面に遷移できませんでした

```
Callback URL not approved for this client application.
Approved callback URLs can be adjusted in your application settings
```

コールバック URL が承認されていないよって怒られました

ついこの間まで問題なく使用できていたのに、、、


#解決方法
2018年06月12日に認証周りの仕様変更が行われたようで、
連携アプリの[設定画面](https://apps.twitter.com/)で、call back URL を設定しなくてはならなくなったようです

連携アプリの設定画面を開き、Settings タブから Callbacks URLs を設定します
この時、設定するフォーマットは `twitterkit-{連携アプリの Consumer Key}://` とします
![スクリーンショット 2018-06-14 0.08.40.png](https://qiita-image-store.s3.amazonaws.com/0/53717/9e164d0f-5e25-0dd8-6d71-0ab7d0b18879.png)

ちなみに、連携アプリの Consumer Key は、Keys and Access Tokens タブから確認できます


#参考させていただいたサイト
[[iOS 11] Social.framework廃止に伴い、アプリにTwitter機能を実装する方法](https://dev.classmethod.jp/smartphone/ios11-feature-twitter-on-app/)
Android StudioのAVD初期設定

#はじめに
授業で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#AVDの初期設定
###AVDの起動
![8.png](https://qiita-image-store.s3.amazonaws.com/0/249280/c6406923-ce94-d028-64f7-6c54e2678e84.png)
右矢印のアイコンをクリックすると、起動できる
※起動に時間が掛かる場合があるため、暫く待つ

![9.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b69431e7-f833-aab9-3a02-eca98b9719eb.png)
↑起動したらこの画面になる

###言語設定
最初に起動したときは、OSが英語仕様になっているので言語設定で日本語にする
![10.png](https://qiita-image-store.s3.amazonaws.com/0/249280/388d2304-9023-0261-dbe2-c94b12e9e653.png)
赤枠をクリックする

![11.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b3211389-2174-6ffb-c83f-f479ec901286.png)
クリック後に出てくる画面を一番下までスクロールすると、[Settings]というアイコンがあるので、クリック

![12.png](https://qiita-image-store.s3.amazonaws.com/0/249280/5dcf7653-bd5c-78c2-5f7f-c2d18550c453.png)
一番下までスクロールして、[System]をクリック

![13.png](https://qiita-image-store.s3.amazonaws.com/0/249280/80030731-7402-126e-ca08-8412d11f41de.png)
[Languages & input]をクリック

![14.png](https://qiita-image-store.s3.amazonaws.com/0/249280/6ad039f1-28b8-480d-217e-2cb612a934ab.png)
[Languages]をクリック

![15.png](https://qiita-image-store.s3.amazonaws.com/0/249280/7a408587-dd69-43d8-cae9-e057191f0b6f.png)
[Add a language]をクリック

![16.png](https://qiita-image-store.s3.amazonaws.com/0/249280/de541933-cad5-619d-8e6d-e336cfc51cd0.png)
一番下までスクロールすると[日本語]があるので、クリック

![17.png](https://qiita-image-store.s3.amazonaws.com/0/249280/3b85edd3-f112-fba4-efc2-276800a8ffaf.png)
日本語が追加されるので、赤枠を上にドラッグする

![18.png](https://qiita-image-store.s3.amazonaws.com/0/249280/efdf6f05-298d-67fb-c57c-89e47021d9a0.png)
これで言語表記が日本語に変わる

###日本語入力ができるように設定を変更する
![19.png](https://qiita-image-store.s3.amazonaws.com/0/249280/ca150aeb-5598-8967-fb75-72b30a3f2cf7.png)
先ほどの画面から左上の矢印で戻るとこの画面になるので、その下の[仮想キーボード]をクリック

![20.png](https://qiita-image-store.s3.amazonaws.com/0/249280/21190664-2500-f3ac-4ae5-8d0b200b7a05.png)
[キーボードを管理]をクリック

![21.png](https://qiita-image-store.s3.amazonaws.com/0/249280/73146ac1-c51e-26c3-24a7-42163df839ed.png)
キーボードを管理画面で[Japanese IME]のスイッチをONにする

![22.png](https://qiita-image-store.s3.amazonaws.com/0/249280/8630b5ef-60f5-f221-01d4-345c89e42ea3.png)
[OK]をクリックすると、日本語入力ができるようになる

###時刻の修正
AVDの時刻表示を見ると現在時刻からずれているため、現在の時刻と合わせる。
※これは、Windows OSとAVDとの相性の関係で、タイムゾーンを自動取得にしていると起こる問題

![23.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b7af96d9-7a71-7e64-b4bf-c7a10a1eb343.png)
[日付と時刻]をクリック

![24.png](https://qiita-image-store.s3.amazonaws.com/0/249280/920fbb50-c930-0a3c-df3f-72120939ca85.png)
[タイムゾーンの自動設定]をOFFにし、[タイムゾーンの選択]をクリック

![25.png](https://qiita-image-store.s3.amazonaws.com/0/249280/445acd55-03de-5cd9-f4e3-3061f1731d45.png)
下にスクロールしていくと、[日本標準時]があるのでこれをクリック

![26.png](https://qiita-image-store.s3.amazonaws.com/0/249280/4a8538fc-b505-ae4c-bf27-375959853517.png)
これで時刻の設定が完了する
Android Studioについてのまとめ

#はじめに
授業で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#Android Studioの画面構成、プロジェクトのファイル構成
###画面構成とProjectツールウィンドウのビュー
![2.png](https://qiita-image-store.s3.amazonaws.com/0/249280/8b62de85-37e8-00ec-c855-ce427fe387f9.png)
新規プロジェクトを作成すると、上の画像のように左右に分かれている。
左側の赤い枠の所がツールウィンドウ、右側のオレンジの枠の所がエディタウィンドウという。
ツールウィンドウには、デフォルトではProjectツールウィンドウが表示されている。プロジェクトツールウィンドウのファイルをダブルクリックするとエディタウィンドウ上でそのファイルが編集できるようになっている。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/249280/bdb39c16-0858-0c53-b694-eb4a666e1271.png)
Projectツールウィンドウの上にあるタイトルバーをクリックすると、ドロップダウンリストになっているのでこのリストを選択することでProjectツールウィンドウのビューを変更できる。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/249280/26b048b6-c30c-1c3e-492c-bcd3f1a95709.png)
Projectに変更すると、このようなファイル構成になる。

###Androidビューのファイル構成
![5.png](https://qiita-image-store.s3.amazonaws.com/0/249280/69e3b67d-6e4c-7c70-0428-a9bd67578533.png)
表示されているファイル構成は、大きく分けて
manifests
java
res
の3つのファイルがある。

####manifests
![6.png](https://qiita-image-store.s3.amazonaws.com/0/249280/93431d9e-858e-def5-c3fc-1ddf8ad9e71f.png)
このフォルダ中には、[AndroidManifest.xml]というファイルが格納されている。
AndroidManifest.xmlというファイルには、このアプリを実行するために必要な設定が記述されている。

####java
![7.png](https://qiita-image-store.s3.amazonaws.com/0/249280/ad024e1a-6fba-429d-a184-4598dcd95085.png)
このフォルダ中には、名前の通り[.java]ファイルが格納されている。
Androidアプリ開発では、アプリの画面構成を[.xml]ファイルに、処理を[.java]ファイルに記述する。
このうちの処理を担当する[.java]ファイルを格納しているのが、このフォルダである。
パッケージ右側に[(androidTest)]や[(test)]と記述されているのは、Androidアプリをテストするための[.java]ファイルの格納先。

####res
![8.png](https://qiita-image-store.s3.amazonaws.com/0/249280/0ef3a6b9-6a38-7917-b052-af257c95dc9c.png)
Androidでは、画面構成を[.xml]ファイルに記述する。そういった[.xml]ファイルやアプリで使われる画像ファイルなどを格納するのが、このresフォルダである。
※resはresourceの略

####resフォルダ内のサブフォルダ構成
drawable
　画像を格納
layout
　画面構成に関わる[.xml]ファイルを格納
mipmap
　アプリのアイコンを格納
values
　アプリで表示する固定文字列(strings.xml)、画面のスタイル(style.xml)、色構成(colors.xml)を表す[.xml]ファイルなどを格納
Android StudioのAVD作成

#はじめに
授業で学んだ事のメモとして残します。
※添付している画像は全てスクリーンショットとペイントで編集しました。

#AVD作成の手順
###AVD Managerを起動する
![1.png](https://qiita-image-store.s3.amazonaws.com/0/249280/5e8cec45-69c3-b289-e4e9-287a09f3869d.png)

ここから起動できる

![2.png](https://qiita-image-store.s3.amazonaws.com/0/249280/bf19a014-a18e-9716-f3a9-dd88952a3639.png)

Tools→AVD Managerでも起動できる

![3.png](https://qiita-image-store.s3.amazonaws.com/0/249280/7e700f04-ee8d-8399-b9d3-d769f668870b.png)

###端末種類を選択する
![4.png](https://qiita-image-store.s3.amazonaws.com/0/249280/b1e26fe4-b611-4c01-dd23-441ca9723305.png)
自分が作りたい端末の種類を選択

###システムイメージを選択する
![5.png](https://qiita-image-store.s3.amazonaws.com/0/249280/1e93aee5-1f8e-ab2a-2ba0-1301880f1bc0.png)
Recommended(おすすめ)タブが表示されるが、最初は選択できるものがないので[x86 Images]タブを選択し、表示されるリストの中から[Oreo]を選ぶ。
※システムイメージとは、AVDの動作に必要なものをまとめたファイルの事で、AndroidのバージョンやAVDを起動する環境に応じてファイルが違う。また、[Download]のリンクを選択すると、そのシステムイメージがダウンロードできる。

###詳細設定を確認
![6.png](https://qiita-image-store.s3.amazonaws.com/0/249280/de0b4b0b-9f83-5ef0-74ea-f20e9bb63dfe.png)
[Enable Device Frame]のチェックを外す
※[Show Advanced Settings]を選択すると、詳細設定が可能になる

![7.png](https://qiita-image-store.s3.amazonaws.com/0/249280/ff16d3b6-f57c-58fb-1b42-8f10b37e246c.png)
これで作成完了
Angular 2　メモ

#引数の宣言

**1.　2つ型の場合**
------------------
key: string | Array<string>

**2.　あったらこの型に使用**
------------------
interpolateParams?: Object

String
(key: string | Array<string>, interpolateParams?: Object): Observable<string | any>;

**3.　2番目以降個数不定　⇒...args: any[]**
------------------
call(str: String,...args: any[])
console.log(args);

一つ：
call('HELLO','Aさん')
//=> ["Aさん"]

3つ：　
call('HELLO','Aさん','Bさん','Cさん')
//=>  ["Aさん","Bさん","Cさん"]


#String判定

let strNull:   any = null;
    let strEmpty:   any = '';
    let strHasWord:   any = 'HELLO';
    
    if (strNull){
      console.log('strNull' + strNull);
      //NO Log
    }
    if (strEmpty){
      console.log('strEmpty' + strEmpty);
      //NO Log
    }
    if (strHasWord){
      console.log('strHasWord' + strHasWord);
      //=> 'HELLO'
    }
#String置換


```
fun substituteWord( args?: any[]): any {
    //get resource
    let result: String = "{{param1}} - {{param2}} of {{param3}}";
    //replace params
    if (args) {
      for (let i = 0; i <= args.length; i++) {
        let pattern = '\\{{param' + (i + 1) + '\\}}';
        let regPattern = new RegExp(pattern);
        result = result.replace(regPattern, args[i]);
       }
    }
    //console.log(result);
    return result;
}
let result: String =  this.substituteWord(['1','50','1000'])；
//console.log(result);
//=> '1-50 of 1000'
```
GPSの研究　その7

#概要
GPSを理解したかった。
RINEXから、衛星までの擬似距離を取ってみた。

#サンプルコード

```
from ObsParser import *
from NavParser import *
from Utils import Utils
from Geometrias.Punto3D import Punto3D
from Proyecciones.Cargeo2Geo import Cargeo2Geo

def main():
	navParser = NavigationParser('brdc0590-1.11n')
	obsParser = ObservationParser('89090590-2.11o')
	for obs in obsParser.getObservations():
		tobs = obs['EPOCA']
		epocObj = {
			'EPOCA': tobs,
			'OBSERVACIONES': {}
		}
		for sat in obs['OBSERVACIONES'].keys():
			if 'G' in sat:
				observation = obs['OBSERVACIONES'][sat]
				efem = navParser.getParams(tobs, sat)
				if not efem or not 'P2' in observation:
					continue
				epocObj['OBSERVACIONES'].update({
					sat: {
						'OBSERVACION': obs['OBSERVACIONES'][sat]
					}
				})
	print (epocObj)
	pass

if __name__=="__main__":
	main()
	print ("ok")

```


#結果

```
'G02': {
	'C1': {
		'VALUE': 22402645.008, 
		'LLI': None, 
		'SSI': 6.0
	}
}, 
'G04': {
	'C1': {
		'VALUE': 20565303.43, 
		'LLI': None, 
		'SSI': 7.0
	}
}, 
'G07': {
	'C1': {
		'VALUE': 22181773.156, 
		'LLI': None, 
		'SSI': 5.0
	}
},
'G08': {
	'C1': {
		'VALUE': 24495107.648, 
		'LLI': None, 
		'SSI': 4.0
	}
}, 
'G10': {
	'C1': {
		'VALUE': 21478321.484, 
		'LLI': None, 
		'SSI': 6.0
	}
}, 
'G13': {
	'C1': {
		'VALUE': 20168944.047, 
		'LLI': None, 
		'SSI': 7.0
	}
}, 
 'G20': {
	'C1': {
		'VALUE': 23186783.133, 
		'LLI': None, 
		'SSI': 5.0
	}
}, 
'G23': {
	'C1': {
		'VALUE': 21860039.258, 
		'LLI': None, 
		'SSI': 7.0
	}
}
```

以上。
CSSセレクタで指定した複数イベントターゲット要素の共通/限定処理

_div.item_がいくつかあるが、いずれかclickした対象だけを**青く**して他を**赤く**したい。

<p data-height="265" data-theme-id="0" data-slug-hash="eKEOMe" data-default-tab="js,result" data-user="pokkur" data-embed-version="2" data-pen-title="querySelectorAll and forEach" class="codepen">See the Pen <a href="https://codepen.io/pokkur/pen/eKEOMe/">querySelectorAll and forEach</a> by pokkur (<a href="https://codepen.io/pokkur">@pokkur</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


```js:js
const item = document.querySelectorAll('.item')

Array.prototype.forEach.call(item, (e) => {
    e.addEventListener('click', (e) => {
        Array.apply(null, item).forEach((e) => e.style.background = `hsl(358, 100%, 62%)`) // clickされてないitemは赤く
        e.currentTarget.style.background = `hsl(196, 100%, 53%)` // clickされたitemは青く
    }, false)
})
```

どなたか、これもっと使い勝手良いヘルパーとかつくってださい……。
[Java] logback slf4j サンプル

# やりたいこと
単にコンソールでslf4jを簡単に試したいだけ
~~なのに、調べる情報はどれもつらつらと長ったらしいものばかりです。~~

では始めます。

##(1) logbackを入手
   http://logback.qos.ch/download.html
   logback-1.2.3.tar.gzを取得。

   - slf4j-api-1.7.25.jar
   - logback-classic-1.2.3.jar
   - logback-core-1.2.3.jar

   を探し出して、./lib/を作って、そこに格納

##(2) Test.javaを作成

```Test.java
   import org.slf4j.LoggerFactory;
   import org.slf4j.Logger;
   public class Test {
     public static void main(String[] args){
       Logger logger = LoggerFactory.getLogger("Test");
       logger.info("info: {}", "情報");
       logger.warn("warn: {}", "警告");
       logger.error("error: {}", "エラー");
     }
   }
```

この時点でのカレントディレクトリの構成

```
$ tree
.
|-- Test.java
`-- lib
    |-- logback-classic-1.2.3.jar
    |-- logback-core-1.2.3.jar
    `-- slf4j-api-1.7.25.jar
```


##(3) ビルド

```shell
$ javac -cp .:./lib/logback-core-1.2.3.jar:./lib/logback-classic-1.2.3.jar:./lib/slf4j-api-1.7.25.jar Test.java
```

##(4) 実行

```
$ java -cp .:./lib/logback-core-1.2.3.jar:./lib/logback-classic-1.2.3.jar:./lib/slf4j-api-1.7.25.jar Test
14:46:17.371 [main] INFO Test - info: 情報
14:46:17.375 [main] WARN Test - warn: 警告
14:46:17.376 [main] ERROR Test - error: エラー
```


# ファイルに出力
logback.xmlを用意します。

```
$ tree
.
|-- Test.java
|-- lib
|   |-- logback-classic-1.2.3.jar
|   |-- logback-core-1.2.3.jar
|   `-- slf4j-api-1.7.25.jar
`-- logback.xml ★これ
```

logback.xmlの中身。とりあえずこれで出ます。

```
<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>test.log</file>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>
```

手順(3)(4)を実施
カスタムURLスキームの処理でハマった話

## はじめに
カスタムURLスキームに応じて、Android アプリに何かをさせたい時ってありますよね。そういう時はアクティビティに `intent-filter` を持たせて

```xml:AndroidManifest.xml
<intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="smpl" />
</intent-filter>
```

アクティビティで `intent.dataString` を取得して、スキームに応じた処理をすると思います。

## 何が問題か
カスタムURLスキームに応じて何かをする場合、いくつかのケースが考えられます。

状態|やること
---|---
起動していない|起動してスキームに応じた画面を表示
バックグラウンドにいる|復帰してスキームに応じた画面を表示

この二つの違いは `onCreate` 以降で `intent` を取得するか、`onNewIntent` で `intent` を取得するかだと思います。

ぼくがハマったのは次の条件を満たしたケースです。

- カスタムURLスキームで起動
- バックキーでバックグラウンドに遷移
- タスクから選択して復帰

問題は、タスクから選択して復帰した時に `intent.dataString` を取得すると、カスタムURLスキームで起動した時と同じ `intent.dataString` が取得できてしまうという点です。

## どう対応したか
~~だいぶハマったのですが、結論を述べると `intent.sourceBounds` の有無で「タスクから選択して復帰」したかどうかを判定しました。~~

```kotlin:端末によって動作が異なる
val dataString = intent?.let {
    when (Intent.ACTION_VIEW == it.action && it.sourceBounds == null) {
        true -> it.dataString
        else -> null
    }
}
```

~~`sourceBounds` は画面座標を返します。タスクから選択した時はタップした座標が `sourceBounds` の戻り値として取得でき、何らかの `intent` を取得して起動する時は null が取得できます。~~

### 追記
上の方法では端末によって `intent.sourceBounds` が取得できないケースがあり、意図した動作をしないことがわかりました。ただしくは `intent.flags` を取得して `FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY` かどうかを判定します。

```kotlin:意図通りに動作する
val dataString = intent?.let {
    when (Intent.ACTION_VIEW == it.action && (Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY.and(intent.flags)) == 0) {
        true -> it.dataString
        else -> null
    }
}
```


## 参考
- [Intent#getSourceBounds()  |  Android Developers](https://developer.android.com/reference/android/content/Intent.html#getSourceBounds())
- [Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY  |  Android Developers](https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
mailコマンドでメールを読みたかったけどハマった

メールサーバーにログインしてmailコマンドでメールを確認しようとして
解決するのに手間取ったのでメモを残しておきます。


## No mail for foo
mailコマンドでメールを読むには下記のようにメールコマンドを実行します。
ところが「メールがない」と。

```
$ mail
No mail for foo
```
 
これはメールの格納場所を~/Maildirに変更しているためです。
以下のように格納場所を指定すると読めるようになります。

```
$ mail -f ~/Maildir
```
コチラのページを参照させていただきました。
http://yu-write.blogspot.com/2013/11/centos-maildirmailbox-mail.html


## 次ページに移動したい

mailコマンドでメールを確認することはできるようになりました。
しかしメールが大量にあり読みたいメールは選択できません。
？とタイプしてヘルプを確認してみてもページを移動するコマンドはなさそうです。

どうするのか？
manページに答えがありました。前方に移動するには```z```、後方は```z-```だそうです。

```
    z[+|-]            ヘッダ表示を前方または後方に1画面スクロー
                       ルします。表示するヘッダ数は screen 変数で
                       設定します。
```

コチラのページを参照させていただきました。
https://hacknote.jp/archives/470/
Amazon S3 からディレクトリ単位でダウンロードする方法

ストレージしてあるログをディレクトリ単位でまとめてダウンロードしたかったが、
S3 の GUI にあるダウンロード選択肢が非活性化してたので、AWS CLI を使って取得したときのメモ。
AWS CLI の説明は省略します。

## AWS CLI のインストール
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html
※ インストール後にアクセスキーなどの設定が必要です。

## AWS CLI で Amazon S3 からディレクトリ単位でダウンロードするコマンド
プロファイルを複数設定しているときは `--profile production` のように対象プロファイルを指定します。

1. `sync` コマンド  
    `aws s3 sync s3://myBucket/targetDir /localDir`  
2. `cp` コマンド  
    `aws s3 cp s3://myBucket/targetDir /localDir --recursive`  

-- 追記
`sync` って名前いかにも副作用ありそうな顔してるから後でちゃんと調べる
CakePHP2 SQLをログで確認したい

発行されたSQLをログに吐き出したい。
debugkitは便利だけど、ピンポイントで確認したい時もある。
いつもやり方を忘れてしまうのでメモ。

## ログ出力

```PHP
$this->log($msg, 'debug');
```

コントローラーでもモデルでも好きなところに書く。
logメソッドの第二引数に書き込みたいログファイル名を指定すればよい。
ちなみにログファイルのパスは`/app/tmp/logs/debug.log`。

## SQLのダンプ

```PHP
$model->getDataSource()->getLog();
```

デバッグレベルが２以上でないと出力されないので注意。

## まとめ

```PHP
$this->log(
    $model->getDataSource()->getLog(),
    'sql'
);
```

ちなみに画面に表示したい場合は、

```PHP
debug($model->getDataSource()->getLog());
```
GPSの研究　その6

#概要
GPSを理解したかった。
RINEXから、読み出した衛星の軌道をEARTHで、眺めてみた。

#写真

![sat.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/2ab6d3b1-fae2-3ede-68ea-3aac6aa35330.jpeg)

#サンプルコード

```
from lxml import etree
from pykml.factory import KML_ElementMaker as KML
import pyproj

ecef = pyproj.Proj(proj = 'geocent', ellps = 'WGS84', datum = 'WGS84')
lla = pyproj.Proj(proj = 'latlong', ellps = 'WGS84', datum = 'WGS84')
sats = [
	"G02 6262234.031370984 -14613110.981922923 21254935.229655903",
	"G04 19040661.998708855 -8311756.524602333 16532658.634675292",
	"G07 26078664.69836943 5588070.077162541 -239561.27794465935",
	"G08 24470813.305349953 -95731.17177840695 -10965308.78942738",
	"G10 10946425.106999923 -13217422.981333993 19960118.04486387",
	"G13 17400028.443231095 1461399.2922087098 19887536.270703305",
	"G17 21078475.93615281 -13351300.07070003 -8639709.183587706",
	"G20 14385911.569008492 20514420.345839 8765413.838559393",
	"G23 9336918.80677975 12048291.269695656 21723935.800126303" 
]

doc = KML.kml(
	KML.Folder(
	)
)
for sat in sats:
	l = sat.split(' ')
	x = float(l[1])
	y = float(l[2])
	z = float(l[3])
	lon, lat, alt = pyproj.transform(ecef, lla, x, y, z, radians = False)
	pm = KML.Placemark(
		KML.name(l[0]),
		KML.Point(
			KML.altitudeMode("absolute"),
			KML.coordinates("{},{},{}".format(lon, lat, alt)),
		),
		KML.Style(
			KML.IconStyle(
				KML.Icon(
					KML.href('http://maps.google.com/mapfiles/kml/paddle/A.png')
				),
				KML.scale(40)
			)
		)
	)
	doc.Folder.append(pm)

print (etree.tostring(doc, pretty_print = True).decode())

```

以上。
Rack::Attack.throttle の設定でハマった

[Rack::Attack](https://github.com/kickstarter/rack-attack)はRackで動いてるウェブアプリを攻撃から守るgem。`throttle` の設定書いてる時にハマったのでメモ。

### 何が起きたか

環境変数に設定書いとくかーと思ったら数値で書くべき設定 `limit` と `period` の型が文字列になってたので例外になってた。起動時は例外にならないので、実際のリクエストがそこで処理されるまで気づかない。具体的な箇所は[lib/rack/attack/throttle.rb#L37 の `count > current_count`](https://github.com/kickstarter/rack-attack/blob/1942ab39cae1b450b33664aed0216cf5a3d7fee0/lib/rack/attack/throttle.rb#L37)で `ArgumentError (comparison of Integer with String failed)` になる。

### 対策

`.to_i` とかする。

```ruby
Rack::Attack.throttle("requests by ip", limit: ENV['LIMIT'].to_i, period: ENV['PERIOD'].to_i) do |request|
  request.ip
end
```

```plaintext:.env
LIMIT=6
PERIOD=60
```
pipenvとかBundler以前に知っておいて欲しいこと

- `gem` と `bundle` ってどっちを使えばいいんですか？
- `pipenv`！？ Pythonには何種類のパッケージングツールがあるんですか！！
- `Gemfile.lock` ってコミットしないんですよね！？偉い人がそう言ってました！！


落ち着いてください。個別ツールの話をする前に、まずこれを覚えておいてください。

> **ライブラリ** か **アプリケーション** かで、依存ライブラリの管理の仕方・バージョンの指定方法が違う

これを理解すれば、自然とツールの使い方も解るはずです。

# 「プロジェクト」には２種類ある。依存ライブラリにも２種類ある

RubyやPython（や他の言語）のプロジェクトは、大きく２種類に分けられます。

- **ライブラリ**
  - 他のライブラリやアプリケーションに組み込まれて使うもの
- **アプリケーション**
  - 直接使うことができるもの。他のプロジェクトに組み込まれることは基本的に無い

また、プロジェクトが依存しているライブラリも２種類に分けられます。

- **直接依存**
  - プロジェクトで利用しているライブラリのこと
- **間接依存**
  - 直接依存のライブラリが利用している別のライブラリのこと

※なお「直接依存」「間接依存」は一般的な用語ではありません（通じなくはないと思いますが）。「間接依存」より「推移的依存」の方が一般的かもしれません。

# **ライブラリ**のバージョン指定戦略

ライブラリでは、できるだけ緩くバージョンを指定します。

「このライブラリは pandas 0.22.0 をインストールした環境でしか動作しません。0.21.0 でも 0.22.1 でもダメです」なんて厳しい制約があるライブラリは使ってもらえないですからね。

なので、*ライブラリでは「直接依存」についてのみバージョンを指定し、間接依存については指定しません。* 直接依存についても、バージョンは特定の１バージョンではなく、範囲で指定します（pandas >= 0.22.0, < 1のように）。バージョンの下限はテストして動作が確認された最低バージョンを指定します。

なお、最大バージョンは微妙な問題があります。というのは、互換性がないバージョンアップをするライブラリもあるからです（有名な例だと Angular 1.x → 2.x とか）。"numpy ">= 1.14.3", "==1.*" のように、メジャーバージョンレベルで指定するのが穏当でしょう。

# **アプリケーション**のバージョン指定戦略

アプリケーションでは、どの環境でも同じバージョンが使われるようにしたいはずです。さもないと・・・

「開発環境では動くのに、本番環境では動かない」
「俺のマシンでは動くのに、あいつのマシンでは動かない」
ということになります。

そのため、**直接依存も間接依存も全て指定します**。また、バージョンも厳密に(`== x.y.z` の形で)指定します。

とはいえ、**全部のバージョンを書き下して管理するのは大変**なので、RubyやPythonでは２ファイルに分けて管理しています。

- 直接依存を指定するファイル（手動で管理する）
    - Gemfile
    - Pipfile
- 直接依存・間接依存の詳細なバージョンを指定するファイル（自動更新できる
    - Gemfile.lock
    - Pipfile.lock

# 「プロジェクトには２種類ある」と言ったな、あれは嘘だ

なお、困ったことにライブラリともアプリケーションとも言い切れないプロジェクトがあります。

例えば、curl の代替コマンドの[HTTPie](https://github.com/jakubroztocil/httpie) は、使い方の観点では明らかにアプリケーションです。しかし、Pythonのライブラリ配布の仕組みを使用して配布している（PyPIで公開され、`pip install httpie` でインストールできる[^1]）ので、依存ライブラリは、`setup.py` に指定しています。

[^1]: HTTPieはbrewやaptでもインストールすることができ、その場合は厳密にバージョン指定された依存ライブラリがインストールされます（「アプリケーション」的な戦略）。なので、ここで「困った」例に httpie を挙げるのは濡れ衣です。

困ったもんです。

おそらく、HTTPieの場合は、そもそも配布方法が間違いなのです。`pip install httpie` でインストールするとシステムのPythonを変更することになるので[^2]、他のアプリケーションに影響を与える恐れがあります。

a. システムのPythonとは別にPythonインタープリタをビルドし、そこにインストールする
b. 依存ライブラリも全て含んだ、単一のバイナリとして配布する（Go等では可能。Pythonでもツールを使えばできるかも）

本来、このような方法をとるべきなのでしょう。

[^2]: `pyenv` などで複数のPythonがインストールされている場合は、システムのPythonとは限りませんが。

## 参考

- [Pipenvの進んだ使い方 / Pipfile vs setup.py
](http://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#pipfile-vs-setuppy)
chromeディベロッパー・ツールにVue.js devtoolのタブが表示されない時の対処法

Vue.jsのデバッグツール
[Vue.js devtool](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)

CDNからVue.js本体をminファイルで読み込むと、
「Vue」タブがディベロッパー・ツールから消えてしまったので対処法をメモ。

下記の一文をスクリプトの先頭に追加。

```JavaScript:index.js
Vue.config.devtools = true;
```
Twitterログイン認証ができなくなって困っている方

見事に自分のサイトもなっていたので・・・

## Callback URLsに追加する

結論から言うと

1. [apps.twitter.com](https://apps.twitter.com/)にアクセス
2. 対象のアプリケーションを選び、**settings**タブを開く
3. **Callback URLs**に、本番で使用している`callback_url`を指定する

<img width="525" alt="スクリーンショット 2018-06-14 13.37.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/100188/43e3208d-3c02-dc80-e364-e8b7ba4d9fd2.png">

## 背景

2018年6月12日から、settingsに登録されているURLとパラメータで送られてくる`callback_url`の照合を行っているようで、マッチしない場合にエラーが返るようになりました。

[Callback URL](https://developer.twitter.com/en/docs/basics/callback_url.html)

私もローカル開発用の`callback_url`しか登録しておらず、見事にエラーになっていました・・・

アナウンスは１ヶ月ほど前からされていたそうです。確認せずすみません！
Laravel で MariaDB の CRUD (その 6 Delete)

## こちらのページの続きです。

>[Laravel で MariaDB の CRUD (その 5)](https://qiita.com/ekzemplaro/items/c25e0615fa2edaad594c)
データ削除機能を作ります。

<ol>
<li>ルーティングを確認</li>
>articles.destroy があることを確認

```bash
php artisan route:list
```

<li>一覧ページに削除のリンクをつけます。</li>

```php:resources/views/articles/index.blade.php
{{-- layoutsフォルダのapplication.blade.phpを継承 --}}
@extends('layouts.application')

{{-- @yield('title')にテンプレートごとにtitleタグの値を代入 --}}
@section('title', '記事一覧')

{{-- application.blade.phpの@yield('content')に以下のレイアウトを代入 --}}
@section('content')
<div>
    <a href="/articles/create">新規作成</a>
</div>
<table>
 @foreach ($articles as $article)
	<tr>
    <td>{{$article->title}}</td>
    <td>{{$article->body}}</td>
	<td><a href="/articles/{{$article->id}}">詳細を表示</a></td>
	<td><a href="/articles/{{$article->id}}/edit">編集する</a></td>
<td>
	<form action="/articles/{{$article->id}}" method="post">
      {{ csrf_field() }}
      <input type="hidden" name="_method" value="delete">
      <input type="submit" name="" value="削除する">
    </form>
    {{-- <a href="/articles/{{$article->id}}">削除する</a> --}}
</td>
	</tr>
  @endforeach
</table>
@endsection
```
<li>詳細ページに削除のリンクをつけます。</li>

```php:resources/views/articles/show.blade.php
{{-- layoutsフォルダのapplication.blade.phpを継承 --}}
@extends('layouts.application')

{{-- @yield('title')にテンプレートごとの値を代入 --}}
@section('title', '記事詳細')

{{-- application.blade.phpの@yield('content')に以下のレイアウトを代入 --}}
@section('content')
  <h1>{{$article->title}}</h1>
  <p>{{$article->body}}</p>
  <br><br>
  <a href="/articles/{{$article->id}}/edit">編集する</a>
<form action="/articles/{{$article->id}}" method="post">
      {{ csrf_field() }}
      <input type="hidden" name="_method" value="delete">
      <input type="submit" name="" value="削除する">
    </form>
  <a href="/articles">一覧に戻る</a>
@endsection
```

<li>destroyアクションを編集</li>

```php:app/Http/Controllers/ArticlesController.php
// 略
    public function destroy($id)
    {
  // idを元にレコードを検索
  $article = Article::find($id);
  // 削除
  $article->delete();
  // 一覧にリダイレクト
  return redirect('/articles');
    }
// 略
```

<li>サーバーを起動してブラウザーで確認</li>

```bash
php artisan serve
```

>http://localhost:8000/articles
![laravel_jun1412.png](https://qiita-image-store.s3.amazonaws.com/0/179446/8ea77c4d-ea78-6243-a433-6e5e15fb084f.png)
詳細画面
![laravel_jun1413.png](https://qiita-image-store.s3.amazonaws.com/0/179446/448e3ae9-e627-e145-b7a1-a2fe79601ea4.png)


</ol>
Quicksight東京リージョンのソースIPアドレス範囲(CIDR)

※2018/06/14 時点の情報です。

Asia Pacific (Tokyo)　→　**13.113.244.32/27**

![2018-06-14_13h36_05.png](https://qiita-image-store.s3.amazonaws.com/0/99499/d356279e-a29c-b30b-aa4b-58919550ba6e.png)

RedshiftのSGに登録してあげたら、ちゃんとクエリできるようになりました。

https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/regions.html
こちらの日本語版ドキュメントが追いついていなくて東京リージョンが追加されておらず、
https://docs.aws.amazon.com/quicksight/latest/user/regions.html
こちらのEnglish版ドキュメントにはバッチリ書いてありました。
gyp WARN EACCES attempting to reinstall using temporary dev dir "/path/xxx/yyy/zzz"

# 内容
```
% sudo npm i -g XXXXXXXX
```

でなにかインストールしようとした時に

```
gyp WARN EACCES attempting to reinstall using temporary dev dir "/path/xxx/yyy/zzz"
```

というエラーが出てインストールできなかった時の対処法

# 1. コマンドオプション追加

```
% sudo npm i -g XXXXXXXX --unsafe-perm
```

# 2. npmの設定に追加
```
% npm set unsafe-perm=true
```

`$HOME/.npmrc` に設定が追加される

```
% cat ~/.npmrc
unsafe-perm=true
```

以降はオプション `--unsafe-perm` をつけなくてもインストールできる
mainの無いFortranのコードをCのコードから呼び出して動かす

# 今回の環境

Cの処理系: clang
Fortranの処理系: Flang
OS: Linux

# Fortranのコード

以下の様なFortranのコードを試した。

```fortran:arraytest.f90 
function array_1d(b,c) bind(c, name = 'array_1d')
      implicit none
      integer,intent(in),value::b,c
      integer::array_1d,k
      integer a(0:3)
      complex(kind(0d0))::ca(0:100)

      a(0) = b
      a(1) = c
      a(2) = b+c
      a(0) = a(0)*a(2)
      a(1) = a(1)*a(2)
      ca=cmplx(0d0,0d0,kind=8);
      do k=1,3
        ca(k)=k+ca(k)
      enddo
      array_1d= a(1) + a(2) + real(ca(2))
end function
```

## ポイント

```txt
bind(c, name = 'array_1d')
```
でCで参照する際の関数名を明示しておくのが吉。

```txt
integer,intent(in),value::b,c
```

Fortranは参照渡しが基本なので、Cから呼べるように
値渡しを指定する。

# Cのコード

先ほどのFortran内のarray_1d関数を呼び出すだけの以下のコードを用意。

```c
#include <stdio.h>

extern int array_1d();

int main(int argc,char**argv) {
   printf("array_1d = %d\n",array_1d());
}
```

# ビルド方法

```bash
flang -c arraytest.f90 
```

-cを指定することで、.oまでの作成になるので、main関数がなくても
flangに怒られなくなる。


```bash
clang -c atest.c 
clang -o atest atest.o arraytest.o
```

## そこそこ数値計算するようなケース

次に、以下のコードで試した。

```fortran:cmplxchk.f90 
module m_zeta
contains
function zeta3(sr,si) bind(c, name = 'zeta3')
    implicit none
    complex(kind(0d0)),external ::mymain 
    double precision,value::sr,si
    double precision::zeta3,rr,ri
    complex(kind(0d0))::s,tt

    s = cmplx(sr, si)
    tt= mymain(s)
    
    rr = real(tt)
    ri = aimag(tt)
    zeta3 = rr + ri
contains

function mymain(s)
  implicit none
  complex(kind(0d0)),intent(in)::s
  complex(kind(0d0))::mymain

  mymain = sin(s)
end function mymain

end function zeta3
end module m_zeta
```

```c:btest.c
#include <stdio.h>

extern double zeta3(float x,float y);

int main(int argc,char**argv) {
        printf("ans = %lf3.8\n",zeta3(0.5,-14.0));
}
```
```bash
flang -c cmplxchk.f90 
clang -c btest.c
clang -o btest btest.o cmplxchk.f90
```

と同様にすると、以下の様にリンクに失敗する。

```txt
cmplxchk.o: In function `m_zeta_zeta3_mymain':
/root/cmplxchk.f90:23: undefined reference to `__mth_i_cdsin'
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
```

そこで、

```
clang -o btest btest.o cmplxchk.o /root/miniconda3/lib/libflang.a -lm
```

と、flangのランタイムライブラリとlibm.soを指定すると
無事に実行バイナリが生成される。

ここに挙げたFortranoのコードでは不要であったが
別件で自分が試したケースだと

```
clang -o btest btest.o zeta4.o /root/miniconda3/lib/libflang.a /root/miniconda3/lib/libflangrti.a -lm
```

というように、libflang.aの他にlibflangrti.aの指定も必要だった。

# 関連記事

- [Fortran実装のゼータ関数をWASMにして動かしたかった件](https://abrakatabura.hatenablog.com/entry/2018/06/13/204136)
Devise+OmniauthでTwitter認証時に「OAuth::Unauthorized 403 Forbidden」が出て認証できなくなった

2018年6月13日朝から、Railsで作った自作サービスでTwitter認証をするとエラーが発生していました。

<img width="1029" alt="スクリーンショット 2018-06-14 13.00.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/236911/6389e893-098a-43e6-ebc4-7b2891c94285.png">

なんだろうと思いググってみると世界中でも同じ事象が起こっているようで、原因は**TwitterAPIの仕様変更**によるものでした。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Experiencing momentary disruptions? <br>This means you have not enabled whitelisting for your callback URLs. Be sure to follow our guidance on how to make these changes by June 12th or your callback URLs will fail. See our May forum post for guidance. <a href="https://t.co/uWBvhX30E6">https://t.co/uWBvhX30E6</a></p>&mdash; Twitter API (@TwitterAPI) <a href="https://twitter.com/TwitterAPI/status/1004823735772241920?ref_src=twsrc%5Etfw">2018年6月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

TwitterAppsで設定しているコールバックURLと、リクエストで送るコールバックURLのパラメータが**異なる場合に弾く**仕様に変わったとのことです。


# コールバックURLを見直す
僕の自作サービスの場合、Twitter認証後は`users/mypage`に飛ばすようにしていたので、Twitter AppsのコールバックURLには`https://hogehoge/users/mypage`に設定していました。これがよくなかったようです。

![8FBD8047-90A9-42C3-A41A-FD2F15678C30.jpg](https://qiita-image-store.s3.amazonaws.com/0/236911/f271c7e2-c780-6dfa-3273-48c803f255ef.jpeg)


[この記事](https://techracho.bpsinc.jp/hachi8833/2017_05_16/40096)を参考に、コールバックURLを`https://hogehoge/users/auth/twitter/callback`にします。


続いてアプリ側です。Rails＋Devise＋Omniauthで実装しているので、`config/devise.rb`のコールバックURLを見直します。

```ruby:config/devise.rb
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET']
```
ここでコールバックURLを明示していなかったので、

```ruby:config/devise.rb
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'], callback_url: "https://hogehoge/users/auth/twitter/callback"
```

とし、明示的にコールバックURLを一致させたところ解決しました。
（追記：Localと本番環境でURLが異なるはずなので、dotenvなどで環境変数にするとよいです。）

以上です。