OmniAICreator/Qiita-1.07M huggingface dataset:
cuiでchrome のブックマークを出力するには

### node で chrome のブックマークを読むコマンドを作ってみました

OS:Ubuntu 16.04.5 LTS
他のOSではどこにブックマークが保存されているのかわかりません・・・
コメントで教えて頂けると助かります。

例えばこんなふうにコマンドラインから利用できます

```
./bookmark.js  | grep qiita
2018/06/14 03:26 | https://qiita.com/QUANON/items/3e271b512db299099893 | Docker コンテナ上で wkhtmltopdf を動かす - Qiita
2018/05/17 09:16 | https://qiita.com/edo_m18/items/0aee765a4e612e7a16af | [連載] WebVR入門 vol.3 - Qiita
2018/04/24 03:05 | https://qiita.com/uto-usui/items/4eb21aec704b888936d0 | 《WordPress》2017年末にWP REST API で取得してVue.jsで描画するまでのまとめ。 - Qiita
2018/03/17 10:45 | https://qiita.com/nao-guitarist/items/eeaede5ddc6757b0c83a | GsuiteのGoogle DriveをDrive File Streamに置き換えてみた - Qiita
2018/03/16 10:19 | https://qiita.com/keiono/items/76c0aaabb4e6e0c10dc5 | プログラマーが効果的な可視化を作成する （中編） - Qiita
```

なぜか google 先生は独自の時刻フォーマットを使っていて悩みました・・・

参考
https://stackoverflow.com/questions/19074423/how-to-parse-the-date-added-field-in-chrome-bookmarks-file/19076132#19076132

```
#!/usr/bin/env node

// ブックマークの保存場所
const bookmark = process.env["HOME"] + '/.config/google-chrome/Default/Bookmarks';
var fs = require('fs');

const jsText = fs.readFileSync( bookmark );
let objBM = JSON.parse( jsText );

const digit2 = function(d){
  if(d>=10){
    return d;
  }
  return '0' + d;
}

// Google先生の不思議な時間フォーマット
const dateStr = function(micro){
  let sec = parseInt(micro / 1000000, 10);
  sec += 9*3600; // GMT(UTC)とJSTへの時差

  let days = parseInt(sec / 86400, 10);
  sec %= 86400;
  let hour = parseInt( sec / 3600);
  let min  = parseInt( (sec - hour * 3600) / 60);

  let nd = new Date(1601, 0, 1);
  nd.setDate(nd.getDate() + days);
  nd.setHours(nd.getHours() + hour);
  nd.setMinutes(nd.getMinutes() + min);

  return nd.getFullYear() +'/' 
	+ digit2(nd.getMonth()+1)+'/'
	+ digit2(nd.getDate()) 
	+ ' ' + digit2(nd.getHours())
	+ ':' + digit2(nd.getMinutes());
};

const recursePrint = function( obj ){
  if( obj.type === 'folder'){
    obj.children.forEach( recursePrint );
  } else {
    console.log( dateStr( obj.date_added) + ' | ' + obj.url + ' | ' + obj.name );
  }
}

recursePrint( objBM.roots.bookmark_bar );

```

他の要素を出力したい場合は以下のようにして要素名を調べて
console.logで出力している行を変更すればOK

```
jq '.roots[]' ~/.config/google-chrome/Default/Bookmarks
```

### 追記
chrome のブックマークの仕様はここにあるようです
https://developer.chrome.com/extensions/bookmarks

### 余談
"the epoch" は 1970年1月1日だけだと思ったら色々あるんですね
・・・というか自分が UNIX/linux の epoch しか知らないだけでした・・・

1601/1/1 は Windowsのepoch 

https://en.wikipedia.org/wiki/Epoch_(reference_date)
今日はチャットボットもどきを作成中

こんばんは！

今日は、チャットボットもどきを作成しました。

それではソースコードです。

```PHP

<!doctype html>
<head>
<title>
チャットボットフォーム
</title>
<style>
body{
backgroud:bulue;
}
hr{
width: 1200px;
}
footer{
bottom: 0;
height: 5em;
position: absolute;

}

</style>
</head>
<body>
<?php
$data = htmlspecialchars($_POST['insertmessage'],ENT_QUOTES,'UTF-8');




'<div class="mycomment">';
//date_defaul_timezone_set("UTC");
echo $data.'<br>';
'</div>';
'<div class="autmaticinterface" >';
$arr = array('おはようございます','こんにちは','','こんばんは','おやすみなさい');
	foreach($arr as $key => $val ){
		$time = sleep(25);
			
echo $val;

		}

'</div>';
?>

<div>
<footer>
<hr>
  <div class="form">
	<form method="POST">
	<textarea type="text" name="insertmessage" placeholder="用件を入力してください。"></textarea>
	<input type="submit" value="送信">
	</form>
 </div>
</footer>
</body>
````
こういう書き方をしてみました。

htmlのbodyの中にPHPを入れるようなやり方はあったようななかったようなって

気がしますけども、とりあえずやってみました。

まだ、PHP Data Objectを使っていません。

自分の頭の中でこんな風になったらいいなっていうのを

叶えてみることを目的としてみました。

なので、連想配列とforeach文を使っています。

またsleep関数にかんしては初めて使いました。

「こんばんは」や「おはようございます」

と返したら何秒後かに出る様にしたい

と思って入れてみました。

そして何度か試してみたら

思ったものと少し違うなと思ったりして

現在試行錯誤中です。

PHPマニュアルを見たりしながら

知らない知識を補完したりしています。

CSSも本来の使い方とは違う書き方をしています。

最後にキャプチャを載せます。

![OCT19-1.JPG](https://qiita-image-store.s3.amazonaws.com/0/200171/9f2f36a5-2724-58eb-c2e5-b97f030df2b5.jpeg)

画像は作り初めにスクショを撮ったものです。
nuxt + TypeScriptでプラグインの定義を追加する


nuxt2.1.0, node10.11.0
2018.10.19現在

---

独自のプラグインを書いた場合、vueのTypeScript定義の拡張が必要になる。

単純なプロパティの追加は公式docに記載があるが、独自クラスのインスタンス等を設定したい場合はどうするのがベスト・プラクティスなのか。
https://vuejs.org/v2/guide/typescript.html#Augmenting-Types-for-Use-with-Plugins


とりあえず作ってみた形のもの

```typescript:~/plugin/some-plugin.ts
// plugin classの定義
export class SomePlugin {
  private someStatus: string = '';

  constructor(status: string) {
    this.someStatus = status
  }

  getStatus(): string {
    return this.someStatus
  }
}

// plugin
export default ({ app }, inject) => {
  // ... get status logic
  const st = 'hoge';

  inject('somePlugin', new SomePlugin(st));
};
```

pluginファイルでクラス定義して、、、


```typescript:some.d.ts
declare module '*.vue' {
  import { SomePlugin } from '~/plugins/some-plugin.ts';

  module 'vue/types/vue' {
    interface Vue {
      $somePlugin: SomePlugin;
    }
  }
}
```

d.tsファイルでvue定義を拡張し、、、


```typescript:some.vue
@Component
export default class SomeVue extends Vue {
  getSomeStatus(): string {
    return this.$somePlugin.getStatus()
  }
}
```

実際のvue componentで使う。

これで動きはしたけどもっといいやり方ありそう。
vimの文字色を変える(themeを使う)

vimの文字色を変えたかったのでメモ
https://github.com/chriskempson/vim-tomorrow-theme
の
Tomorrow-Night-Brightの設定が好きなのです。個人的に。


1. .vimrcに指定する

```
colorscheme Tomorrow-Night-Bright
```

2.https://github.com/chriskempson/vim-tomorrow-theme
を/.vimにクローンする

```
pwd
/homes/${USER}/.vim
git clone https://github.com/chriskempson/vim-tomorrow-theme

```

3.https://github.com/chriskempson/vim-tomorrow-theme/colors
の置き場所を/homes/${USER}/.vim/colorsにする。


```
source .vimrc
```
で色が適用されました。
nuxt + TypeScriptで、process.client, process.serverを定義する


nuxt2.1.0, node10.11.0
2018.10.19現在

---

nuxtではnodeの環境変数`process`を拡張する形で、`process.server`, `process.client`が設定されている。

TypeScriptで使う場合は定義も拡張しないとプロパティが存在しないよエラーになるので、適当に拡張する

```typescript:some.d.ts

// processは'NodeJS.Process'で定義されてる
declare namespace NodeJS {
  interface Process {
    server: boolean;
    browser: boolean;
  }
}
```
LaMetric TIMEにAPIを使ってテキストを表示してみた

会社でLaMetric TIMEを購入したので、APIを使用してテキストを表示してみました！

#LaMetric TIMEとは？
LaMetric TIMEは、時計の表示だけでなく、スマホから様々なアプリを登録して、天気、ニュース、セキュリティアラート、デジタルメトリクスデータ、売上高の推移、スマートフォンへの通知などをドットで表示できるいい感じのLED時計です！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247209/7594db5d-9cf7-626c-9c69-9eadfed2da1c.png)
Amazonで買えます↓

[http://amzn.asia/d/7kSUmNp](http://amzn.asia/d/7kSUmNp)

今回は、LaMetric TIMEにコマンドプロンプトからAPIを使用して、プログラミングの初歩である「HELLO!!」を表示しました！

#IPアドレスの確認
APIを使用するには、LaMetric TIMEが使用しているIPアドレスを取得する必要があります。
IPアドレスは、iPhoneのアプリから取得しました。

設定画面＞Wi-Fiの設定を確認すると、IPアドレスが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247209/eeb5291a-7c1e-c12e-7c8a-2e2f99b2ef9d.png)


#Basic認証キーの確認
ドキュメントを読んでみるとBasic認証でAPIを実行できると書いてあります。

ユーザー名はdev、パスワードはApi Keyです。
Api Keyは[DEVELOPERサイト](https://developer.lametric.com/login)にログインしてアカウント情報からDEVICESタブをクリック
これで自分のLaMetricに付与されたApi Keyが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247209/e1ccd252-104c-1b0e-6d12-1887ee05ec36.png)

#ヘッダーの作成
curlコマンドを使用して、APIリクエストをします。
LaMetricはAuthorization ヘッダー を利用するBasic認証なので、ユーザー名とパスワードを : で足した文字列を Base64 でエンコード下ヘッダーが必要ですのでこれを作成します。

Base64エンコードは、以下のサイトで実施しました。
http://www.convertstring.com/ja/EncodeDecode/Base64Encode

dev:[Api Key]
をエンコードしたい内容に入力し、エンコードされたテキストをコピーします。

#curlコマンドの作成
ここまでで下準備は完了しました。
あとは、curlコマンドでAPIリクエストするだけです。


コマンドは以下のようになります。

```
curl -X POST -d "{\"model\":{\"frames\":[{\"text\":\"Hello!\"}]}}" -H "Authorization: Basic [生成したBase64]" -H "application/json" http://192.168.xx.xx:8080/api/v2/device/notifications
```

実行すると、LaMetric TIMEに「HELLO!」が表示されます！

実際の動画はこちら↓
[![LaMetricにAPIでHELLO！を表示してみた](http://img.youtube.com/vi/EZ7LVw-htXI/0.jpg)](http://www.youtube.com/watch?v=EZ7LVw-htXI)

#まとめ
今回は、LaMetric TIME をAPIで動作させてみました！
温度センサーと組み合わせると、いい感じの温度計になりそうですね。
近いうちに、[Gravio](https://www.gravio.com/jp/gpromo/1810-start-edgeware)を使用してIoTデータを表示してみようと思います！
CocosCreatorでタッチを透過させる (swallowTouchesをfalseにする) 方法

## CocosCreatorの(タッチ)イベント登録について
- 記事執筆時点の最新 (v2.0.2) の話

- 公式には `node.on` での設定が推奨されている模様
 - http://docs.cocos2d-x.org/creator/manual/en/scripting/events.html?h=event

- しかし `node.on` によるタッチイベント登録は、内部実装で `swallowTouches:true` となっており「イベントを発火した上で背部のNodeへさらにタッチを通す」ことができない
 - https://github.com/cocos-creator/engine/blob/master/cocos2d/core/CCNode.js#L1387

- cocosの forum にログインして聞こうとしたものの、ログイン時にエラーになり聞くことができない
 - https://discuss.cocos2d-x.org/
 - (ユーザー登録がhttpなのも気になる)
- engineのIssueもあんまり見てないっぽい
 - https://github.com/cocos-creator/engine/issues

## 非公開Apiを用いて設定する

どうにもならないので、昔公開されていた非公開のApiを使用して設定しました
TypeScriptで書いてるので必要に応じてJSに戻すなどしてください

```typescript
const listener1 = cc.EventListener.create({
    event: cc.EventListener.TOUCH_ONE_BY_ONE,
    swallowTouches: false,
    onTouchBegan: (touch: cc.Touch, event) => {
        // Node内をtapしているかでtrue/false切り替えても良い
        return true;
    },
    onTouchEnded: (touch, event) => {
        // 発火した上で透過させたい処理
    }
});
cc.eventManager.addListener(listener1, this.touchNode);
```

非公開なので、 `EventListener`　や `eventManager`部分が赤くなったり下記警告が出力されます。

```
Simulator: JS: [WARN]: The 'cc.eventManager' will be removed in v2.0, please use 'cc.EventTarget or cc.systemEvent' instead.
```

公式も明確に `cc.eventManager` を使わないでくれと言っています
- http://docs.cocos2d-x.org/creator/api/en/classes/Node.html#on
 - `It's the recommended way to register touch/mouse event for Node,
please do not use cc.eventManager directly for Node.`

いつ使えなくなるかはわかりませんが現状の対応ということで
[Swift] iOS開発初心者の疑問をまとめた

# 「?」や「!」マークについて
プロジェクトのコードをみていて度々この謎のマークが出てくることに疑問を抱いていました。

まずSwiftには「オプショナル型「と「非オプショナル型」というものがあるらしく、違いは下記の通りです。
**・オプショナル型はnilの代入を許容することができる**
**・非オプショナル型はnilの代入を許容することができない**

オプショナル型の変数には最後に「?」か「!」をつけます。

```swift
// 例えばStringにnilを代入しようとするとエラーが出ます
$ var a: String = nil
# => error: nil cannot initialize specified type 'String'

// 「?」をつければエラーは出ません
$ var a: String? = nil

// Optionalとついています
$ var a: String? = "hoge"
$ print(a)
# => Optional("hoge")

// 宣言時はnilの状態
$ var a: String?
$ print(a)
# => nil
```

# classについて

こちらはxcodeで新規アプリを作成した際のViewControllerの中身です。

```swift
// UIViewController」を継承している
class ViewController: UIViewController {
    // viewDidLoadの上書き
    override func viewDidLoad() {
        // スーパクラスのviewDidLoadを呼び出す
        super.viewDidLoad()
    }
}
```

ここではまず「ViewController」というclassを作成しており、「UIViewController」を継承しています。
そして「viewDidLoad」という関数をoverride(上書き)している。

`super.viewDidLoad()` はスーパークラスのviewDidLoadを呼び出している。

この辺りは他の言語と似たようなものですね。

# AppDelegateってなんだ？

Xcoodeプロジェクトを開いて目にするのがAppDelegate.swiftというファイル。
アプリ全体のライフタイムイベントを管理する。

中には6つの関数があり、それぞれ呼び出されるタイミングが異なります。

```swift
application
// アプリを起動してストーリーボードが読み込まれた際に動く。

applicationWillResignActive
//アプリがアクティブ状態から非アクティブ状態に移行しようとしているときに動く

applicationDidEnterBackground
//アプリの終了時に動く

applicationWillEnterForeground
//アプリの起動時に動く

applicationDidBecomeActive

applicationWillTerminate
//フリックでのアプリ終了時に動く```
ダンプしたDBをRDSに移そうとしたらEncoding Error

古いエックス２サーバーからダンプして来たWordPressのDBをRDSに移行しようとしたらエラーが出てかなり手間取った
#Encodingエラーでインポートができない
>An error occurred when reading the file, as it could not be read in the encoding you selected (Autodetect - Unicode (UTF-8)).

>Only 119 queries were executed.


使用したMac
HighSierra 10.13.2

Sequel Pro 1.1.2

行なった手順は以下の通り
##RDSにSequel Proから接続して新しくDBを作成
ここでエンコーディングと照合順序は
**・UTF-8 Unicode(utf8)**
**・utf8_general_ci**
に設定した

##DBのエクスポート
phpMyAdmin5.0 で以下のオプションを付与してSQL形式でエクスポート
**・DROP TABLE / VIEW / PROCEDURE / FUNCTIONを追加**
**・圧縮:なし**

１度ローカルに保存して中の確認をした
いくつか参考にさせていただいたページでは、ここでSQLの中を編集しているものもあったが今回は前述したエラーに対して効果がなかった

##Sequel ProからDBのインポート
ここで冒頭のエラーが発生
エクスポートの形式かエンコーディングがおかしいのかと思い何度も試すがダメ
挙句RDSの調子も悪くなり次の日にRDSインスタンスの再起動をした

##結果
[Fixing Sequel Pro SQL Encoding Error For Imported SQL Files](https://ilikekillnerds.com/2014/08/fixing-sequel-pro-sql-encoding-error-for-imported-sql-files/)
こちらを参考にして解決
Linux環境からエクスポートしたMysqlのDBをMac上のSequelProを使ってインポートするとエンコーディングがおかしくなるとのこと
なのでダンプファイルをインポートする際に自動検出ではなく
**Western(Mac OS Roman) / 欧米(Mac OS Roman)**
を選んで無事にインポート
Rails4から5にアップデートする時にキャッシュストアの設定でハマった

# 環境
Rails 5.1

# 何が起こったか
rails4系から5系にアップデートしたところ、POST時にエラーで落ちるようになった

```
Can't verify CSRF token authenticity.
request_forgery_protection.rb:195 handle_unverified_request : ActionController::InvalidAuthenticityToken
```

# 原因
要するに[これ](https://github.com/petergoldstein/dalli/issues/613)関連。

セッションストアの設定が正しくできていなかったために、memcachedサーバからセッション情報が正しく取得できず、結果としてCSRF tokenの認証に失敗していたという流れだったようだ。

# 対応
[これ](https://github.com/petergoldstein/dalli/issues/613#issuecomment-213491251)の通りに対応した。

## cache_storeの設定を追加

``` ruby:config/environments/production.rb
config.cache_store = :dalli_store, ['memcache_server_1', 'memcache_server_2']
```

## config/initializers/session_store.rbを修正

``` ruby:config/initializers/session_store.rb
Rails.application.config.session_store(
  ActionDispatch::Session::CacheStore,
  :key => 'session_key',
  :expire_after => 1.days
)  
```

# ちなみに
[アップデートガイド](https://railsguides.jp/5_1_release_notes.html)には明確な記述が見当たらないのだが、どうやらRails5.0まではデフォルトで作成されていた```config/initializers/session_store.rb```は[5.1で削除されているようだ](https://stackoverflow.com/questions/44507072/why-was-session-store-rb-removed-in-rails-5-1)。ただ、ファイルに書かれた設定は今も有効なので、今回の対応では、オプションの設定などは引き続き```config/initializers/session_store.rb```に書くようにした。
[VBA] CSV 文字列を二次元配列に変換する


## はじめに

CSV 文字列を（ワークシートに書き込むためなどで）二次元配列に変換したいことはよくあります。

私は別の仕組みで CSV 文字列を作り、Excel とやり取りしています。

データ自体にカンマが含まれることは多々あるので、区切り文字は任意のものに簡単に置き換えできることが望ましいです。

また、`WorksheetFunction.Transpose()` を使ってワークシートに書き込むことも多いため行列入れ替えた形で二次元配列に初期化したいことが、しばしばあります。

このような要件から、自分の使いやすいように変換関数を作成しました。

## スニペット

```vb
' -----
' CSV を分解して二次元配列にして返す。
' 引数  :csvText                二次元配列に変換したい CSV 文字列
'       :recSep                 レコード区切りの文字。既定値は vbCrLf。
'       :fldSep                 フィールドの区切り文字。既定値は ","。
'       :swapRowColumn          行と列を入れ替えるかの真偽値。既定値は False。
' 返値  :二次元配列
' https://qiita.com/Tachy_Pochy/items/89cc44237f872a2d9f09
' -----
Public Function CSV2Array(csvText As String, _
                          Optional recSep As String = vbCrLf, _
                          Optional fldSep As String = ",", _
                          Optional swapRowColumn As Boolean = False) As Variant
    Dim ret As Variant
    Dim lines As Variant
    lines = Split(csvText, recSep)
    
    If UBound(lines) <= 0 Then GoTo EmptyExit
    
    Dim flds As Variant
    flds = Split(lines(LBound(lines)), fldSep)
    If swapRowColumn Then
        ReDim ret(LBound(flds) To UBound(flds), LBound(lines) To UBound(lines)) As String
    Else
        ReDim ret(LBound(lines) To UBound(lines), LBound(flds) To UBound(flds)) As String
    End If
    
    On Error GoTo ErrorExit
    
    Dim r As Integer, c As Integer
    Dim fields As Variant
    For r = LBound(lines) To UBound(lines)
        If Trim(lines(r)) <> "" Then
            fields = Split(lines(r), fldSep)
            For c = LBound(flds) To UBound(flds) ' １行目のフィールド数を使用し、各行でまちまちにならないようにする。
                If swapRowColumn Then
                    ret(c, r) = fields(c)
                Else
                    ret(r, c) = fields(c)
                End If
            Next
        End If
    Next
    
    CSV2Array = ret
    Exit Function
ErrorExit:
    Debug.Print r, c, lines(r)
    MsgBoxEx Err.Description
    Exit Function
EmptyExit:
    ret = Array()
    CSV2Array = ret
End Function
```
mrbgem CIにドメインを付けてもらった

今まで https://103.128.221.202.static.iijgio.jp/jenkins/ で運用していたmrbgem CIなんですが、この度 `ci.mruby.org` というドメインを付けてもらいました:
https://github.com/mruby/mruby.github.io/issues/61
（対応してくれた @yukihiro_matz に感謝！）

https://ci.mruby.org/jenkins/ にアクセスするとmgem-listの各mrubyリリースとブランチごとのビルド結果などを見ることができるので、興味あればどうぞ。

## 経緯
まずは前置きとしてサービスについてざっくり説明します。
1年ほど前にIIJ GIOを使う機会があって、mgem-listに登録してあるmrbgemをJenkinsでビルドしたいなーと思って始めたプロジェクトをそれから運用していました。
そして、[フクオカRuby大賞](http://www.digitalfukuoka.jp/topics/116?locale=ja)を受賞することができてそのままIIJさんのご厚意で継続して運用しています。
基本的にJenkinsで、特殊なのはmgem-listにあるmrbgemごとにJobを作るといったところくらいです。
IIJ GIOのサーバー提供のIIJさんに感謝！

そして、[最近mruby-metaprog関連で](https://udzura.hatenablog.jp/entry/2018/10/17/201528)、2.0で起きうる非互換問題がにわかにmruby界隈で認知されはじめて、[Fukuoka.rb](https://fukuokarb.connpass.com/)のslackチャンネルで「mgemのCIあるよ」と発言したところ、ドメインをもらってはと薦められて今回に至るとった感じです。
@udzura さんに感謝！

## 技術的なこと
一応、Qiitaなので技術的なところを書くと、Let's Encryptでドメインに証明書を付け直しました。
そして、nginxで以下のような設定を書いて動いています:
https://github.com/mrbgems/jenkins/commit/4bce1e0c393e3c552a736ba07ee91dc4fdfdd99d
（Jenkinsのjsやcssなどの静的ファイルをnginxでいい感じにキャッシュしたいんですが、どうやったらいいんでしょうかね...）

無料でTLSの証明書が付くのは簡単で良い世の中ですね。
ただ、そう何回もやるようなことでもないので、手順をかなり忘れていて焦りました。

## 宣伝とか
テストが失敗しているmgemに修正を送ってあげると喜ばれると思うので、気になったmgemがあれば送って見るといいかもしれません。
また、自分のmgemがどのバージョンで動くのかチェックしてみるとよいかもしれません。

勝手にGitHubに取ってある一人組織[mrbgems](https://github.com/mrbgems)もあるので気軽に[Issueを立て](https://github.com/mrbgems/issues/issues/new)て貰えれば何かしらお手伝いします。

最後に、今回お手伝いなどしてくださった方々に感謝を。
備忘録：SDKMANのインストール

#導入理由
Javaは言語仕様が気に入っている言語ですが、Pythonのpipみたいなパッケージマネージャがなくて不便なのが難点でした。
趣味で気軽に試すのにも結構手間がかかる。
しかし、最近SDKMANなるツールで開発環境を手軽に構築できるようになったという。
インストールまでやってみる。
ほぼ以下のブログを参考にインストールしてみる。
参考：
[blog.beaglesoft.net 　SDKMANでJavaの環境開発環境をセットアップしてみる](http://blog.beaglesoft.net/entry/2017/08/14/110000)
#SDK MAN のインストール
```
$ curl -s "https://get.sdkman.io" | bash
```
ターミナルで以下のコマンドを起動。
ただし、参照元の開発環境はMacのようだが、こちらはUbuntuなのでsource先が少し違うことに留意。

```
$ source "/home/{user}/.sdkman/bin/sdkman-init.sh"
$ sdk help
```
helpの案内が出たらこれでよい。
これからどうするかはまた調べて書く。
AWSでsudoパスワードを設定した

新しくインスタンスを立ててsshでsudoしたところパスワードを聞かれないので、とりあえず新しくパスワードを設定した。
そのあとパスワードの設定はやらなくていい、と怒られたので結局消してしまった

流れは
ユーザーのパスワードを設定
sudoers.d/cloud-initを編集

#パスワードを設定
```shell-session
$ sudo passwd ubuntu
```
パスワードを２回聞かれるので入力
ちなみに乱数を作るのにpythonで生成

[ランダム文字列生成(Python)](https://qiita.com/FGtatsuro/items/92bca91ed665449ab047)
こちらを参考にさせていただきました。ありがとうございます。

```shell-session
$ sudo visudo -f /etc/sudoers.d/cloud-init
#以下のように編集

ec2-user ALL=(ALL) ALL
```

完了したら保存して閉じる

##パスワードの消去

さっきと逆順にやることに
ちなみに

```shell-session
$ sudo visudo
```
でsudoersの編集ができるけど、今回はそもそもsudoers.d/cloud-initを編集したのでこっちを戻す

```shell-session
$ sudo visudo -f /etc/sudoers.d/cloud-init
```
から最初に入力した列を消す

```shell-session
$ sudo su
# passwd -d ubuntu
```

結局２度手間になってしまったので、はじめにしっかりと確認してから作業をすればよかった
ブラウザからAWS Lambda Functionを呼び出して何かさせたい

ブラウザからJSを使ってAPI Gateway経由させてリクエストを処理させる方法に関しては記事を見つけたんですが

そんなめんどくさいことをしたくない（）という超ものぐさ思考
やってみて思ったのは、Lambdaを起動して何かをさせるだけならURL一発で動くものが作れるという、いい時代になったなあ、っていう小学生並みの感想が浮かぶやつだった（何）

あとはまあ、IoT Buttonとかあの辺と同じぐらいの気軽さを、ブラウザからアクセスするやり方でやってみたかったんですよ。

# 注意

セキュリティとか知らんがな状態なので、URL非公開にするとか、自衛は必要かと思う。
まあ個人でやるとかそのレベルを想定していて、実際にできちゃったから記事にしてみた次第です。

そもそも重要な場面ではちゃんとセキュリティとか考慮してね！

# 何ができたの

* URLのみでAPI Gatewayへリクエストを送信（してちゃんと受理される）できた
* GETリクエストを投げると、Lambdaの実行結果が返ってくるようにできた
* GETリクエストにパラメータを持たせて、その内容をLambdaに渡して処理ができた

たぶんこの辺ができれば、簡単な処理をさせたいんだけどわざわざサーバ用意するのもなってあたりは半分ぐらいは実現できるんじゃないかなーーー

# どうやったの

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-on-demand-https-example-configure-event-source_1.html

これに従って作っていくと、LambdaとAPI Gatewayがセットで作れるので、あとはブラウザからURL叩いた時にリクエストを受理できるように調整すると、いい具合にできる。
筆者はPythonを使っているので、Pythonのブループリントを利用したけど、内容としては検索で引っかかるどのブループリントを使っても同じ内容っぽい。

とはいうものの、これだけだと役に立たなさすぎる記事が出来上がるので、つまづきポイントを解説しようと思う

# Lambdaにどのようにリクエストが渡るのか

API Gatewayに対して、GETリクエストを送信した場合、Lambdaの起動時に以下のようなデータが、eventに入った状態で起動します

```json:event
{
…略
  "queryStringParameters": {
    "param1": "hogerahogera",
    "param2": "asdftyuio"
  }
…略
}
```

paramXXがGETリクエストに含まれるクエリになります。
なので、Lambda関数のハンドラは lambda_function.lambda_handler として

```python:lambda_function.py
def lambda_handler(event, context):
    payload = event["queryStringParameters"]
    param1 = payload["param1"]
    param2 = payload["param2"]
```

のような感じにしてやると、パラメータがそのまま取得できます。便利。

# API Gateway側で処理されるレスポンスの形式を作る

当然なんですけど、Lambda関数で return True とかやってもAPI Gatewayは認識してくれないので、ブラウザ側にはステータスコード400が返ったりするわけです
API Gatewayに返すレスポンスとしては

* statusCode
* body
* headers

の3つが必要のようです。
まあ見てわかると思うんですけど、Lambdaの実行結果をbodyに入れて、成功か失敗かは、StatusCode200か400か、みたいなごく必要最低限の実装でよい場合は、

```python:lambda_function.py
def create_response(err,result):
    if err:
        status = "400"
    else:
        status = "200"

    return {
        'statusCode': status,
        'body': result,
        'headers': {
            'Content-Type': 'application/json',
        },
    }
```

みたいな感じでやればよいと。雑だけどこれで動く。

# URL直でAPI Gatewayに処理を受理させる方法

（正直ガバガバすぎて怒られそうだけど）できます
API Gatewayのページに飛ぶと、Lambdaのブループリントで作ったAPIが既に表示されていると思います。
このAPIのページに入って、メソッドの実行についてANYになっている部分に移動します。

クライアント→メソッドリクエスト→統合リクエスト→Lambda関数
クライアント←メソッドレスポンス←統合レスポンス←Lambda関数
と表示される画面。
メソッドリクエストの設定をします。

* 認証：なし
* リクエストの検証：必要に応じて設定する
* APIキーの必要性：False

にします。

URLクエリ文字列パラメータの設定で、
クエリ文字列の追加から、GETリクエストに含まれるクエリの設定をします。
必須のチェックを入れると、上記のリクエストの検証を有効にしていると、必須チェックを実施してくれます。

これで、（セキュリティ的には問題ありだが）ブラウザからURLに対してリクエストして、受理されるようになりました。

## それにしてもセキュリティがガバガバすぎるのでは？

筆者はLambda関数の内部で、正当なリクエストかどうかのチェックを設けました
（そのぐらいならすぐできるわ、って思って…超雑なだけなんだけどさ）

# APIのデプロイ

各APIのページの　アクション→APIのデプロイ　でデプロイ先のステージを指定してデプロイすればOK

左ペインにあるステージ　→　デプロイ先のステージを選択すると、URLが表示されているので、このURLに対して、
https://～～～～/ステージ/リソースのところに表示されているAPIの階層
でアクセスできるようになります。

# 筆者が作ったもの
AWS EC2の起動ボタン

サーバに上げて動かすほどじゃないけどこの機能がほしい、みたいな場面だったのでAPI Gateway → Lambda は最適じゃねえかな！って思った。

起動ボタンのHTML自体はローカルにおいておくという方法が使えるし。
Intel SGX を使用した双方向マイクロペイメントチャネル ( Teechan )

#何の話？
ビットコインは単位時間あたりに処理できるトランザクション数に限りがあります。
所謂スケーラビリティ問題です。これを解決するために、トランザクションの処理をブロックチェーンの外で行うマイクロペイメントチャネルというアプローチがあります。
その中で、trusted execution environment (TEE) を使用した Teechan という双方向マイクロペイメントチャネルが提案されています。

元の論文は:point_down:
[Teechan: Payment Channels Using Trusted Execution Environments](https://www.cs.cornell.edu/people/egs/papers/teechan.pdf)

参考サイト
https://techmedia-think.hatenablog.com/entry/2016/12/24/152906

参考サイトでプロトコルの詳細が説明されているので、ここでは大雑把に書きます。

#Intel SGX
Teechan では Intel SGX を使用して TEE を構築しています。主に SGX の以下の2つの機能を使用しています。

- enclave : 重要なデータを格納するメモリ内の領域です。この enclave が TEE になります。enclave 内のデータは特権モードでもアクセスすることが不可能で、特定のプログラムからアクセスしか許可されません。
- remote attestation : リモートの enclave 同士で認証を行う機能です。所望のコードが通信相手の enclave 内で動いていることを確認できます。

remote attestation の詳細は[ ここ ](https://software.intel.com/sites/default/files/managed/57/0e/ww10-2016-sgx-provisioning-and-attestation-final.pdf)で確認できます。
ざっくり説明すると、認証される enclave A は認証する enclave B へ署名を送信します。 (実際には quoting enclave が介入する)
enclave B はその署名をサードパーティの Intel attestation service (IAS) に送信して、IAS がその署名は enclave A からのものであると検証し、その結果を enclave B に返します。

#Teechan
Teechan の概要な以下の通り。
<img width="445" alt="teechan1.png" src="https://qiita-image-store.s3.amazonaws.com/0/296896/d869408b-00a5-5199-9d97-fe585511c1b9.png">
[Teechan: Payment Channels Using Trusted Execution Environments](https://www.cs.cornell.edu/people/egs/papers/teechan.pdf) から

enclave の機能により、Bob は Bob TEE に( Teechan のアプリケーション外から )不正にアクセスできないので、Alice から見て Bob TEE は安全なんですね。これを利用して Alice は自身のビットコインの秘密鍵を Bob TEE に送信します。Bob も Bob TEE に自身の秘密鍵を送信します。
即ち、Bob TEE には Alice と Bob の秘密鍵が存在しています。Bob は Bob TEE にアクセスできないので Alice の秘密鍵を奪うことはできません。Alice TEE も同様に Alice と Bob の秘密鍵が存在しており、Alice は Alice TEE 内の Bob の秘密鍵を奪うことはできません。

ここで気を付けることは、Alice は Bob TEE に秘密鍵を送信する前に、remote attestation 機能を用いて Teechan のコードが Bob TEE で動作していることを確認しなければいけません。Bob が不正に Teechan のコードを書き換えて、資金を奪うような細工をしている可能性があるからです。

Teechan のプロトコルは、他の双方向ペイメントチャネルと同様です。
オープニングトランザクションで 2-of-2 multisig へ資金をデポジットし、ペイメントの更新を複数回行い、クロージングトランザクションでチャネルを閉じます。TEE がペイメントの更新を管理しているので、過去のトランザクションを不正にブロードキャストされるという心配がありません。

結果として、Teechan は以下のように動作します。
<img width="421" alt="teechan2.png" src="https://qiita-image-store.s3.amazonaws.com/0/296896/2dbba04f-89c6-515b-4361-ed68df55792a.png">

TEE が trusted third party として機能しているんですね。
Alice が Bob に送金したいときは、Alice TEE へペイメントのリクエストを送るだけです。
Alice TEE は両者の秘密鍵を持っているので、いつでもトランザクションに署名を行うことができます。

#感想
前提として、Intel と SGX のセキュリティを信頼する必要がありますね。
あと SGX を持っている人も限られているので、気軽に導入するのは難しそう。
統計学入門8.2をPythonで解く試み

#概要
統計学入門の問8.2の2番(p173)の問題をPythonにて解きます。

8.2<ランダム・ウォーク>　確率変数X1,X2,…,Xnは独立で,確率分布
P(Xi=1)=p, P(Xi=-1)=q (i=1,2,...,n)
に従っている.ただしp=1-q.

p=0.4の時,X1+X2+...+X10,X1+X2+...+X20の近似的確率分布をグラフにせよ。

#環境

Jupyter notebookを用います。

#ソースコード
```ruby:code
import numpy as np
import matplotlib.pyplot as plt
from sympy import *

def ranwal(k):
    ans=factorial(10)/(factorial(k)*factorial(10-k))*(0.4**k)*(0.6**(10-k))
    return ans #関数を設定

def data():
    result=[]
    for k in range(11):
        result.append(ranwal(k))
    return result #0~10の間で回す
plt.plot(data())
```

```ruby:code2
import numpy as np
import matplotlib.pyplot as plt
from sympy import *

def ranwal(k):
    ans=factorial(20)/(factorial(k)*factorial(20-k))*(0.4**k)*(0.6**(20-k))
    return ans #関数を設定

def data():
    result=[]
    for k in range(21):
        result.append(ranwal(k))
    return result #0~20の間で回す
plt.plot(data())
```

#結果
以下のようなグラフを得ました。
![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/297130/cfa86965-5196-96d7-610b-76915a904605.png)

![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/297130/cbcee0b6-20e7-7829-cfaf-6f3a1df5d5f1.png)

間違い等あればご一報ください。

#参考文献
統計学入門(東京大学出版会)
ハッカソンに参加したこともないのに、ハッカソン企画をはじめてやってみた

エンジニア向けのイベント企画を任されたのでその時に考えたことを書きます。
イベント自体は明日開催なので、開催後どうだったかも後ほど書きたいと思います。

#イベントそのものの趣旨を考える。
主催者にとってハッカソンは手段であって目的ではありません。
ハッカソンをやる目的は自社APIの認知を上げたり、技術コミュニティをオフラインでつくったりなどいろいろありますが、ハンズオンでもいいわけです。

別のやり方もあるので、ハッカソンは置いといて、そもそもイベントを通して何を得たいのかを考えました。

議論を重ねた結果、ハッカソンが一番いいとなりました。

#ハッカソンについて調べる。
ハッカソンをすることが決まったものの、ハッカソンに参加したことがないので段取りはわかりません。
概念やハッカソンの結果、イベント情報などはググればたくさん出てきますが...

参考になったのはGoogleが出しているハッカソンの運営ガイドです。
https://sites.google.com/site/devreljp/Home/hackathon-in-a-box/hackathon-guide

#ハッカソンに参加する。
読んでも実感がわかないのでとりあえず有名どころのハッカソンに参加してみました。
私はLINE Bootawardsの鎌倉市の賞を取ろうぜ！っていう感じのものに参加しました。

そこで、参加理由に「来月ハッカソンを主催するのでノウハウを盗みに来ました。」といったら、主催者の方が快く資料を送ってくださいました。これがむちゃくちゃ使えた。
こういうことは言ってみるものです。

#イベントをデザインする。
最初に考えたハッカソンイベントの趣旨、目的を果たすためにどうすればよいかをひたすら考えます。ここでは事務的なことよりも、どうやったらAPIをイベント後も使いたくなるかといったことを考えます。

チーム分けはしておいたほうがいい、Githubのレポジトリは先に作っとけ、など運営の事務作業的なことは先ほど書いたGoogleの運営ガイドにすべて書いています。

#事務作業をする。
イベントのデザインをしていく中で必要なものが見えてくるので、リストを作ったり、実際に調達しに行ったりします。イベントの設計が変わったら必要なものも変わるのでデザインと事務作業は行ったり来たりすると思います。

#当日資料を作る。
考えたデザイン通りに物事が進むようにプレゼン資料や配布資料をつくります。これも同じくイベントの設計が変わったら必要なものも変わります。

###あとは当日楽しむ！
Nodeでファイル書き込み

ファイル書き込み（新規作成/追記）

[fs.appendFile](https://nodejs.org/api/fs.html#fs_fs_appendfile_path_data_options_callback)

```js
const fs = require('fs');
const textFile = 'test.txt';

// return Promise
exports.write = (text) => {

  return (async () => {

    await new Promise((resolve, reject) => {
      fs.appendFile(textFile, textFile, (error) => {
        error ? reject(error) : resolve();
      });
    }).catch((error) => {
      console.log(error);
    });

  })();
}
```

とやるのかと思ってたけど同期処理があった。

[fs.appendFileSync](https://nodejs.org/api/fs.html#fs_fs_appendfilesync_path_data_options)

```js
const fs = require('fs');
const textFile = 'test.txt';

// return Promise
exports.write = (text) => {
  try {
    fs.appendFileSync(textFile, text);
  } catch (error) {
    console.log(error);
  }
}
```
C#のBatteryChargeStatesで悩んだ話

#電源状態取得してた
C#のSystemInformation.PowerStates.BatteryChargeStates使ってバッテリーの残量取得してたらある一定範囲の残量で取得できて~~なかった~~**ように見えた**
#分析
どうやら33%から66%の時に取得できてない？
#結果
BatteryChargeStates.LowとBatteryChargeStates.Highの間にはそもそもプロパティがなかった
→switchで分岐してたのでdefaultに追加することで対応
Docker / Kubernetes おすすめ学習参考資料まとめ 🐳

## :whale: おすすめの動画
 
「Docker入門 (全11回) - プログラミングならドットインストール」
https://dotinstall.com/lessons/basic_docker

「【たった1時間半でできる】YouTube動画でDocker基礎 + Laravel開発環境ハンズオン #YYPHP｜湊川あい@わかばちゃんと学ぶ本 発売中｜note」
https://note.mu/llminatoll/n/nfd4ea73d58a1

## :books: 書籍
Docker/Kubernetes 実践コンテナ開発入門
https://amzn.to/2TxuM4l
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18351/0577a79d-20f7-97fa-96b2-4092486b2bdb.png)

Docker実践ガイド
https://amzn.to/2TExF3s
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18351/acb45e2b-6e21-1dfd-6bc7-83643a9353ed.png)

Dockerによるアプリケーション開発環境構築ガイド
https://amzn.to/2Qh0ZOo
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18351/049dd659-ea2f-693e-5a15-46151ec88692.png)


## :whale: おすすめのスライド

「（Azure Antenna）AKSでコンテナアプリ DockerからKubernetesまで実践入門 - Speaker Deck」 
https://speakerdeck.com/shin5ok/azure-antenna-aksdekontenaapuri-dockerkarakubernetesmadeshi-jian-ru-men

「Docker Tokyo」
https://www.slideshare.net/cyberblackvoom/docker-tokyo

「開発環境で使う Docker / docker-for-development - Speaker Deck」
https://speakerdeck.com/shin1x1/docker-for-development

「Masahito Zembutsu presentations | SlideShare」
https://www.slideshare.net/zembutsu


## :whale: ブラウザで実行できるplaygroundまとめ - Qiita
https://qiita.com/AkihiroSuda/items/71eb91752375829d30eb
統計学入門7.8をPythonで解く

#概要
以下の統計学入門の問題をPythonで解く。
![Document 37_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/258414/b184b528-dc00-d448-9388-dbe289885204.jpeg)

#環境
Jupyter notebook

#実装
```python
# %%
# 東京大学出版会「統計学入門」練習問題7.8のPythonによる計算。
# f_xの定義において、コメントアウトする行を変更することで、i～iiiのそれぞれに対応可能。

# ====setup
import sympy as sym
from sympy.plotting import plot
import matplotlib.pyplot as plt

sym.init_printing()
plt.rcParams["font.size"] = 13


n = sym.Symbol("n", real=True)
x = sym.Symbol("x", real=True)
oo = sym.oo
e = sym.exp(1)
lamda = sym.Symbol("lamda", real=True)


# ===ここf_xの定義

f_x=1 # i)
# f_x = lamda*e**(-lamda*x) # ii)
# f_x=sym.Function("f")(x) # iii)

# ===Parameters only for Plotting

lam = 6
n_v = 5
up=1

# ===integrate to know the probability which x gets 0-to-x in

p_a = sym.integrate(f_x, (x, 0, x))

# ===gets cumulative distribution function 

f_ac_max = ((p_a)**n).simplify()
f_ac_min = (1-(1-p_a)**n).simplify()

# ===gets distribution function by differential

f_max = sym.diff(f_ac_max, x).simplify()
f_min = sym.diff(f_ac_min, x).simplify()

# ===Plot

if f_x!=sym.Function("f")(x):
    print("now plotting")
    plot(f_ac_max.subs(n, n_v).subs(lamda, lam), (x, 0, up), title="Maximum accumulation",xlabel="F(x)="+str(f_ac_max))

    plot( f_ac_min.subs(
        n, n_v).subs(lamda, lam), (x, 0, up), title="Minimum accumulation",xlabel="F(x)="+str(f_ac_min))

    plot(f_max.subs(n, n_v).subs(lamda, lam), (x, 0, up), title="Maximum distribution",xlabel="f(x)="+str(f_max))

    plot( f_min.subs(n, n_v).subs(lamda, lam), (x, 0, up), title="Minimum distribution",xlabel="f(x)="+str(f_min))
    plt.show()
else:
	print(f_ac_max,f_ac_min,f_max.doit(),f_min.doit())
```

#結果

解答のグラフはn=5のもの。(ii)についてはλ=6と置いて図示した。
直接の答えは各グラフの右下に付記している。

(i)の解答
![image.png](https://qiita-image-store.s3.amazonaws.com/0/258414/d3bd9858-9297-d94e-385e-3305ac65042b.png)

(ii)の解答
![image.png](https://qiita-image-store.s3.amazonaws.com/0/258414/f3d99d0e-5e7c-748c-ab02-688dc10d4112.png)

(iii)の解答
```Integral(f(x), (x, 0, x))**n -(-Integral(f(x), (x, 0, x)) + 1)**n + 1 n*f(x)*Integral(f(x), (x, 0, x))**(n - 1) n*(-Integral(f(x), (x, 0, x)) + 1)**(n - 1)*f(x)
```

(iii)のグラフィカル表示
![image.png](https://qiita-image-store.s3.amazonaws.com/0/258414/4b8c0eb8-f1f5-22ce-aadf-94adbbe7fbff.png)
MUTANTによるサウンド管理

音ネタやプラグインを販売しているSonicwireから、無償で公開されている、サウンドブラウザー「MUTANT」
https://sonicwire.com/mutant

![スクリーンショット 2018-10-19 16.27.39.png](https://qiita-image-store.s3.amazonaws.com/0/6047/ddd498f7-079b-6120-a917-d5fa22f08f59.png)

昔からSE管理に使っていたが、プレビュー用途でしか使えないと思い込んでいたが、そんなことなかったのでメモ。

数十GBのライブラリにしても、軽快に動作し、階層構造も扱え、キーボードショートカットによるプレビューが可能、、

で、最近気づいたが、これ "プレビューアプリ" ではなく "ファイルブラウザ" だった。

つまり、ファイルブラウザ感覚でFinderとかにドラッグアンドドロップできる！
つまり、そのままWwiseのヒエラルキーにドラッグ&ドロップできる！

謎サーチ&コピーバッチを組んで運用してた私ってほんとバカ。。

> SE以外に、楽曲の管理とかもこいつにやらせてよかった...
> 内部DBに直接クエリを投げれば、ENUM自動生成もできそう...

### 自分用メモ

- AudioObject からの Event作成 ショートカット : command + shift + E
Dockerでfs.watchは動作しないので、代わりにgazeを使用しましょう。

# したいこと
Nodeでファイルを監視しておき、変更があったらある処理を行う

fs.watchをラッパーしている[chokidar](https://github.com/paulmillr/chokidar)を使用して監視する

```javascript
  chokidar.watch('./src', {ignored: /(^|[\/\\])\../}).on('all', (event, path) => {
    handleChange();
  });
```


# Dockerで動作させると・・・

```bash
% docker-compose up watch                                         (git)-[master]
Starting watch_1 ... done
Attaching to watch_1
watch_1 exited with code 0
%
```

Exitしてしまう。


# 解決策

Gulpでも使用されている[gaze](https://github.com/shama/gaze)というモジュールを使うと解決します。
参考： https://stackoverflow.com/questions/42473561/nodejs-fs-watch-is-not-reacting-to-changes-inside-a-docker-container

```javascript
gaze(['./src/**'], (err, watcher) => {
  if (err) throw err;
  watcher.on('all', (event, file) => {
    console.log(event, file);
    handleChange();
  });
});
```

```bash
% docker-compose up watch                                         (git)-[master]
Starting watch_1 ... done
Attaching to watch_1
watch_1   | changed /app/src/components/schemas/UserInfo.yml
```
Slickでcoalesceする方法

scalaのPlayFrameworkでSlickを使用してDB操作を行う際のcoalesceのやり方メモ。

####play-slickのバージョン

```build.sbt
libraryDependencies += "com.typesafe.play" %% "play-slick" % "3.0.3"
```
####記法

```
A.ifNull(B)
```
例えば

```
SELECT COALESCE(A,B) FROM TABLE_NAME
```

は

```
val query = TableQuery[TABLE_NAME].map(x => x.A.ifNull(x.B))
```

となる
【メモ】JavaScriptのメンバ変数までprototypeを付けてしまった場合のNGとOKケース

JavaScriptでクラスをnewして作ったインスタンスＡと、もう１つnewで作ったインスタンスＢがある時、ＡとＢの各メンバ変数を変更した後で両方を出力してみたらＡとＢが同じになっていて驚いた！

よくよくソースを見てみたらメンバ変数にまでprototypeを付けてしまっていたからこうなっただけだったorz
……というだけの話。


## 実際のコードと、デモ

デモはjsfiddleで確認できます。

### NGケース

デモ：https://jsfiddle.net/pinoxox/6bryu4ka/

```javascript
    var MyClass = function() {};
    MyClass.prototype.vars = {
        memba : ''
    };
    MyClass.prototype.init = function(opt) {
        $.extend(this.vars, opt); // jQuery利用想定
    };
    MyClass.prototype.print = function() {
        $('body').append( '<p>'+ this.vars.memba +'</p>' );
    };
    var cA = new MyClass();
    cA.init({ memba : 'hoge' });
    cA.print(); // -> hoge
    var cB = new MyClass();
    cB.init({ memba : 'fuga' });
    cB.print(); // -> fuga
    cA.print(); // -> hoge ではなく fuga
```

### OKケース

デモ：https://jsfiddle.net/pinoxox/7xw9L1k6/

```javascript

    var MyClass = function() {
        this.vars = {
            memba : ''
        };
    };
    MyClass.prototype.init = function(opt) {
        $.extend(this.vars, opt); // jQuery利用想定
    };
    MyClass.prototype.print = function() {
        $('body').append( '<p>'+ this.vars.memba +'</p>' );
    };
    var cA = new MyClass();
    cA.init({ memba : 'hoge' });
    cA.print(); // -> hoge
    var cB = new MyClass();
    cB.init({ memba : 'fuga' });
    cB.print(); // -> fuga
    cA.print(); // -> hoge は保たれる
```
郵便番号一覧のCSVからH2DBを使って地域番号の一覧を取る

CSVファイルを簡単にselectしたかった。

## H2 Databaseの準備
`H2 Database Engine`を[公式サイト](http://www.h2database.com/html/main.html)からダウンロード。

```terminal
$ wget http://www.h2database.com/h2-2018-03-18.zip
$ unzip h2-2018-03-18.zip
$ sh ./h2/bin/h2.sh
```

流れでsh実行しちゃってるが、ブラウザが立ち上がり、コンソールが表示されれば準備OK
![image-20181019114707238.png](https://qiita-image-store.s3.amazonaws.com/0/298766/8bb4324d-dd0a-4a45-c2fc-bf162a52e625.png)

## CSVをselectする
今回のCSVは郵便番号の一覧を使う。

```terminal
$ wget https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
$ unzip ken_all.zip
$ ls KEN_ALL.CSV
KEN_ALL.CSV
```
sqlはブラウザのコンソールから投げられる。

CSVファイルをテーブルとして扱うには `CSVREAD`関数を使えばOK。

```sql
select *
from
  csvread('./KEN_ALL.CSV', null, 'shift-jis', ',')
limit 5
;
```
これでselectできる。
![image-20181019123718944.png](https://qiita-image-store.s3.amazonaws.com/0/298766/3dd9012f-f59d-ffe9-bf2e-4f74cee06c08.png)
ヘッダーがおかしい。

`CSVREAD`の第2引数をnullにするとCSVの1行目をヘッダーとして扱う模様。

```sql
select *
from
  csvread('./KEN_ALL.CSV', ',,,,,,,,,,,,,,,', 'shift-jis', ',')
limit 5
;
```
カンマを入れると簡単に出せた。
![image-20181019142126283.png](https://qiita-image-store.s3.amazonaws.com/0/298766/de2b6a24-00b4-b2f0-c960-3d20fcecf841.png)

## 地域番号の一覧
郵便番号の3桁の内、頭2桁が地域番号になるので切り取ってグループ化する。

C10については `一町域が二以上の郵便番号で表される場合の表示　（注3）　（「1」は該当、「0」は該当せず）`とのことで、地域が曖昧な郵便番号を省く。

```sql
select substr(c2,0,2) cd, c7
from
  csvread('./KEN_ALL.CSV', ',,,,,,,,,,,,,,', 'shift-jis', ',')
where 1=1
  and c10=0
group by substr(c2,0,2), c7
order by cd
;
```
![image-20181019145642296.png](https://qiita-image-store.s3.amazonaws.com/0/298766/005de47f-091d-9e4a-ebb7-93b870e2c153.png)


### まとめ
単純なselectなら直ぐ返ってくるので便利。

テーブル結合しようとすると全然返ってこないので、パフォーマンス出したい場合はテーブルを作っちゃったほうがいい。

```sql
create table kenall as select * from csvread('./KEN_ALL.CSV', ',,,,,,,,,,,,,,', 'shift-jis', ',')
```

ちなみに、CSVファイル指定のカレントディレクトリは `h2`の親になってるのでご参考まで。

```terminal
./KEN_ALL.CSV
./h2/bin/h2.sh
```

ちゃんちゃん。
Qiita週間コメント数ランキング【自動更新】


直近でコメントがついて盛り上がってる？記事を自動で集計して投稿できるようにしてみました。
コメントされるってことは良い記事か、良い議論がされてるに違いない！

※不具合などもし気が付かれましたらお知らせいただけると嬉しいです。

#### 集計方法
- 集計方法: 8時間ごとにQiita API v2を利用して集計 (**2025-06-23 19時**更新)
- 集計期間: **2025-06-16** から **2025-06-23** に投稿された記事
- コメント数: **5**以上コメントされた記事


## 1位 [shared_ptrで管理されたクラス内でthis(自身のshared_ptr)を扱いたいときの落とし穴](https://qiita.com/comefrombottom/items/fc6c01163db7acc66983)

**8**コメント　**0**いいね / [comefrombottom](https://qiita.com/comefrombottom) さん 2025-06-20 06時投稿
```C++ ``` ```shared_ptr ``` ```enable_shared_from_this ``` 


## 2位 [5250, CLコマンドの代わりにSQL(IBM iサービス）でシステム構成情報を取得する](https://qiita.com/gomAnomalocaris/items/530326b1e36c8cf6f281)

**6**コメント　**1**いいね / [gomAnomalocaris](https://qiita.com/gomAnomalocaris) さん 2025-06-17 08時投稿
```IBMi ``` ```ibmiservices ``` ```IBMiサービス ``` 


## 3位 [JavaScript の世界から「オブジェクト」という単語を排除したい！](https://qiita.com/bkh4149/items/92fb0906a210b2c2e743)

**6**コメント　**0**いいね / [bkh4149](https://qiita.com/bkh4149) さん 2025-06-21 08時投稿
```JavaScript ``` ```オブジェクト ``` 


## 4位 [[入門] C/C++の未定義動作を10倍安全に回避するテクニック集](https://qiita.com/ShigemoriMasato/items/c3fb14fa995799595795)

**5**コメント　**91**いいね / [ShigemoriMasato](https://qiita.com/ShigemoriMasato) さん 2025-06-20 07時投稿
```C ``` ```C++ ``` ```入門 ``` ```未定義動作 ```
GAE/GoからalgoliaのAPIを叩いても結果が返ってこない件の対処

GAE/Goからalgoliaを利用する時、httpClientを置き換えないと失敗する様子。appengine用にtransportを設定し直す必要があるみたいです。


```golang
import (
	"context"
	"github.com/algolia/algoliasearch-client-go/algoliasearch"
	"google.golang.org/appengine/urlfetch"
	"net/http"
)

ctx := appengine.NewContext(r)
client := algoliasearch.NewClient(APP_ID, ADMIN_KEY)

// 下のコードを書く必要がある
transport := &http.Client{
	Transport: &urlfetch.Transport{
		AllowInvalidServerCertificate: true,
		Context: ctx,
	},
}
client.SetHTTPClient(transport)
```

ローカルでは動いてて、本番環境だと動かない時はこれが原因っぽいです。恐らくalgolia以外で外部APIを叩くライブラリでも同じ設定が必要になりそう
JREにSSL証明書をインポートする（Windows編）

Javaプログラムから https などのSSLサイトへアクセスするプログラムを実行した時、自己証明書などpublicな証明書でない場合は SSLHandshakeException が発生すると思います。
その場合は実行する JRE に該当のSSL証明書をインポートすれば解決します。

# SSL証明書をエクスポートする
:::note info
証明書ファイルが既に手元にある場合、この手順はスキップしてください
:::
- ブラウザの鍵マークをクリック
- SSL証明書をエクスポートする（細かい手順はブラウザによって異なるので省略）
- 拡張子 cer のファイルとしてエクスポートされる

# 証明書の格納先
JRE の証明書情報は次のファイルに格納されている。
`{JAVA_HOME}\jre\lib\security\cacerts`
（例）C:\Program Files\Java\jdk1.8.0_171\jre\lib\security\cacerts

# コマンドプロンプトを起動する
Program Files 配下のファイルを変更するため、管理者権限が必要
アイコンを右クリックして「管理者として実行」からコマンドプロンプトを実行する
（管理者権限が不要なパスに JDK がインストールされていれば通常起動でもいけるはずだが、未確認）

# インポートコマンドを実行する
次のコマンドをコマンドプロンプトから実行すると、証明書がインポートされる
### コマンドの書式
keytool は JDK に含まれているので {JAVA_HOME}\bin にPATHが通っているか keytool.exe のフルパスを指定する必要がある
```Console:コマンドプロンプト
keytool -import -trustcacerts -file [cerファイルのパス] -keystore [cacertsのパス] -alias ca
```
### コマンド例
```Console:コマンドプロンプト
keytool -import -trustcacerts -file "C:\dev\cert\hoge.cer" -keystore "C:\Program Files\Java\jdk1.8.0_171\jre\lib\security\cacerts" -alias ca
```
### 実行
キーストアのパスワードを求められるので、デフォルトの「**changeit**」を入力する
最後に信頼するか聞かれるので「y」を入力する

```Console:コマンドプロンプト
キーストアのパスワードを入力してください:
所有者: CN=fujimic.com
発行者: CN=fujimic.com
シリアル番号: 9xxxxxxxxxxxxxx4
有効期間の開始日: Wed Dec 20 17:35:48 JST 2017 終了日: Tue Dec 15 17:35:48 JST 2037
証明書のフィンガプリント:
         MD5:  9D:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:B9
         SHA1: E1:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:DE
         SHA256: 3A:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:56
署名アルゴリズム名: SHA256withRSA
サブジェクト公開鍵アルゴリズム: 2048ビットRSA鍵
バージョン: 3

拡張:

#1: ObjectId: 2.x.xx.19 Criticality=false
BasicConstraints:[
  CA:true
  PathLen:2xxxxxxxx7
]

#2: ObjectId: 2.x.xx.15 Criticality=false
KeyUsage [
  Key_CertSign
]

この証明書を信頼しますか。 [いいえ]:  y
証明書がキーストアに追加されました
```

これで自己証明書でもアクセスできるようになったはずです！
HTMLの基本的なタグ

プログラミングを勉強する人がまず最初に学ぶのが[HTML][link1]です。
今回はその[HTML][link1]で使用する基本的なタグについてご紹介します。
[link1]:https://techacademy.jp/magazine/4843

##タグとは
タグとは[HTML][link1]の中で構造や形を指定するためのマークアップです。
基本的には開始タグと終了タグの間に文章を記入します。

*例：<開始タグ>HTMLの本的なタグ</終了タグ>*


##頻出タグ
- **html**
HTMLを書く際に必ず必要になるタグです。
基本的に全てのタグの上に来る要素となり、中にはheadとbodyのタグが入ります。
- **head**
ページそのものの情報を指定するタグです。中にはtitle、meta、linkといったタグが入ります。
- **title** 
ブラウザの名前を入れるタグです。
- **meta** 
文字コードなどを指定するタグです。終了タグがつかないため注意が必要です。
- **link**
スタイルシートといった文書を外部から参照する際に使うタグです。こちらもmetaタグと同様終了タグがつきません。
- **body**
htmlの大部分をしめるタグです。この中に様々な細かいタグで文章を構築していきます。
- **header**
サイトの導入となる情報を入力します。検索エンジンに表示されるタイトルや概要を記入します。
- **footer**
ページ下部にコピーライトや連絡先を記載する際に使われます。


##まとめ
以上、今回は[HTML][link1]を書く際に大枠となるタグをご紹介しました。
あくまで型ですので大事なのはさらに細かいコンテンツ作成に使われるタグですが、
大枠となるタグを無視してはサイトが完成しません。
まずここに記載されているタグと役割を覚えてから、次のステップに進みましょう。
high sierra で rbenv  を使おうとしたら迷路に迷い込んだ

だいたいのことはわかるとなんてことはないんだけれども、わかるまではたいへんですね。

```
$ rbenv install 2.5.1
ruby-build: use openssl from homebrew
Downloading ruby-2.5.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2
Installing ruby-2.5.1...
ruby-build: use readline from homebrew

BUILD FAILED (OS X 10.13.6 using ruby-build 20180822)

Inspect or clean up the working tree at /var/folders/qn/21yqw2396zl26pmq6tq0sw9c0000gn/T/ruby-build.20181019123602.65838
Results logged to /var/folders/qn/21yqw2396zl26pmq6tq0sw9c0000gn/T/ruby-build.20181019123602.65838.log

Last 10 log lines:
/usr/local/include/Block.h:263:2: error: unknown type name 'lzma_bool'
        lzma_bool reserved_bool2;
        ^
/usr/local/include/Block.h:264:2: error: unknown type name 'lzma_bool'
        lzma_bool reserved_bool3;
        ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [file.o] Error 1
make: *** Waiting for unfinished jobs....
```

気軽に rbenv install したら怒られました(´・ω・｀)
エラーログ書いておいたから読めよ。って言われたので見ます。

```
/usr/local/include/Block.h:16:3: error: Never include this file directly. Use <lzma.h> instead.
#       error Never include this file directly. Use <lzma.h> instead.
        ^
```

こんなん書いてありました。 Block.h 使うんじゃねえよ、 lzma.h 使えよ常考。って言われたので、 lzma.h とやらを探しましょうかね。

```
$ ls /usr/local/include/lzma.h
/usr/local/include/lzma.h
```

あるやんけ。

ここから深い迷宮に迷い込んだんですが、迷った道筋をいくつか

* lzma.h 入れ直したらいけるじゃろ -> brew install xz -> 関係なかった
* gcc のライブラリのパス通ってないんじゃね -> export LD_LIBRARY_PATH=/usr/local/include -> お門違い

結局世界のお友達によれば

https://github.com/rbenv/ruby-build/issues/1169

> brew がどう管理してんのかしらんけれども Block.h 使うなよ。手で記述削除しろや

まじすか。

> /usr/local/include 使ってっからダメみたいよ。 /usr/local/include_old って名前にしてみ

まじすか。
***
まじだった。

なるほど。 察するに high sierra より前のバージョンだと、 /usr/local/include 使ってたけれども、今は /usr/include を使っていると。で、同名のファイルがあったら、古い /usr/local/include を先に見ちゃうんだ。ってことみたいですね。

別のアプローチで情報探していればすぐにわかったっぽいですな。だから誰も詰まらないわけで、記事にもならんと。自分は書くけれども。


#### 2019-04-18 追記
この /usr/local/include を mv してしまうことで brew 経由で postgresql がうまくインストールできない問題が発生しました。参考された方々ほんとに申し訳ないです(´・ω・｀)

https://qiita.com/ninjaninja/items/f9dcdca92d1ef9847b5d
こちらの記事にそのトラブルの経緯を書いております。

簡単にいうと、 mv したあとに、 空の /usr/local/include ディレクトリを作ってください。それで問題はおきなくなります。
メソッド集

## pluck

```

where
User.select(:id).where("age >= ?", 20).map(&:id)

pluck
User.where("age >= ?", 20).pluck(:id)

出力
User.where("age >= ?", 20).pluck(:id, :name)
#=> [[1, '太郎'], [2, '花子'], [3, '二郎']]

```
Nodeでさくらのメールを使う

ここではさくらのSMTPを使って送信を行います。

[nodemailer](https://github.com/nodemailer/nodemailer)
[nodemailer document](https://nodemailer.com/smtp/)
を使用します。

# ポイント

tlsを使用するには`secure: true`ですが465ポート強制になってしまう。
さくらは587を要求しているので`secure: false`で`requireTLS: true`を設定する必要がある。

# コード

```js:mail.js
const mail = require('nodemailer');

const transporter = mail.createTransport({
  host: 'XXXXXXXX.sakura.ne.jp',
  port: 587,
  secure: false,
  requireTLS: true,
  auth: {
      user: 'user',
      pass: 'pass'
  }
});

let mailOptions = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Message',
  text: ''
};

// return Promise
exports.send = (body) => {

  mailOptions.text = body;

  // メール送信
  return (async () => {
    const result = await transporter.sendMail(mailOptions).then(info => {
      return {
        flag: true,
        data: info
      };
    }).catch(error => {
      return {
        flag: false,
        data: error
      };
    });

    if (!result.flag) {
      console.log(result.data.stack);// メール送信失敗時のスタックトレース
    }

  })();
}
```
(自分用)Wineのフォントの文字化けを解消する

#Winetrickをインストール
ここを参考にしました。ありがとうございます。
[Symfowareについての考察blog
](https://symfoware.blog.fc2.com/blog-entry-2228.html)
以下のコマンドでインストール。

```
sudo apt-get install -y winetricks
```
以下のコマンドで立ち上げる。

```
wintricks
```
Select the default wineprefixを選択。
Install a fontを選択。
Amazon Inspetcorで評価のステータスが「エラーが発生して完了」となった場合に確認すべき点

<img width="580" alt="スクリーンショット 2018-10-19 14.55.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/149679/bbedc998-e2d0-1abf-7b88-c1ddfde300aa.png">

1. 評価の一覧の「Exclusion」列値のリンクをクリック
<img width="1149" alt="スクリーンショット 2018-10-19 14.59.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/149679/241c2b0e-69bf-20d4-8715-f3e27f987025.png">

2. Description欄とRecommendation欄をチェック
モーダルウィンドウが小さくて正直確認しづらいです。。
そんなときは以下のダウンロードボタンから内容をダウンロードしてから確認しましょう！
<img width="738" alt="スクリーンショット 2018-10-19 15.01.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/149679/171926d4-3144-1648-48b5-8e81fc1eced6.png">

### 参考リンク
- [AWSドキュメント Amazon Inspector の除外](https://docs.aws.amazon.com/ja_jp/inspector/latest/userguide/inspector_exclusions.html)
C++ Builder XE4 > geometry > 比率固定でTPanel, TChartのサイズをScaleBy()で調整する

```txt:動作環境
C++ Builder XE4
```

### 仕様

- TPanel, TChartの配置を比率で固定
- フォームのサイズに基づいて、その比率になるように拡大縮小をする

用途: SVGAから4K UHDまでに対応するUIにて。

### 実装 v0.1

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

static int s_defaultWidth_form; // ScaleBy()処理に使うため、デフォルトサイズを保持するための変数
static int s_defaultHeight_form; // ScaleBy()処理に使うため、デフォルトサイズを保持するための変数

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B_fitClick(TObject *Sender)
{
	static float curFactor = 1.0;

	float factor_width = (float)this->Width / s_defaultWidth_form;
	float factor_height = (float)this->Height / s_defaultHeight_form;

	// ScaleBy()でサイズ変更するため、一旦元のサイズに戻す
	this->ScaleBy(100/curFactor, 100);
	this->Width = s_defaultWidth_form;
	this->Height = s_defaultHeight_form;

	// 小さい比率に合わせてScaleBy()する
	if (factor_width > factor_height) {
		curFactor = factor_height;
	} else {
		curFactor = factor_width;
	}
	this->ScaleBy(100 * curFactor, 100);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	s_defaultWidth_form = this->Width;
    s_defaultHeight_form = this->Height;
}
//---------------------------------------------------------------------------

```

### 結果

実行直後 (ウィンドウサイズ変更なし)

![2018-10-19_14h53_15.png](https://qiita-image-store.s3.amazonaws.com/0/32870/2570b919-a6df-cc5c-f30b-1c91a91853fc.png)

サイズ変更後
![2018-10-19_14h54_05.png](https://qiita-image-store.s3.amazonaws.com/0/32870/dfc27dda-1ebe-7a9b-ccee-d795baffec7c.png)

Fitボタン押下後

![2018-10-19_14h54_49.png](https://qiita-image-store.s3.amazonaws.com/0/32870/efae7a6e-d6e9-38ad-76c0-bd723cd509b0.png)

### 備考

Fitボタンを何回も押下すると、微妙にサイズが変わる。
この機能をきちんと使う場合には要調査。


### 関連

- [C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」変更状態でフォームのHeight, Widthを設定する実装](https://qiita.com/7of9/items/a257b00f334d75b9406b)