OmniAICreator/Qiita-1.07M huggingface dataset:
RancherにDocker for MacのKubernetesをインポートする

Rancherをとりあえずdocker runで気軽に動かして、Docker for Macで構築したKubernetesを、Rancherから操作したいなーってときの手順をメモしておく。

# 環境

- macOS High Sierra
- Docker for Mac 18.06.1-ce
- Rancher 2.1.1

# Rancherを起動

[Manual Quick Start \| Rancher Labs](https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/#2-install-rancher) このあたりに書いてあるdocker runコマンドをローカルで実行した。

```sh
$ docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher
```

うまく起動してたら、 

```sh
$ docker ps

CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                                      NAMES
XXXXXXXXXXXX        rancher/rancher:latest   "entrypoint.sh"     2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   xxxxxx_xxxxxxx
```

こんな感じで確認できる。

# Rancherにアクセス

ローカルで起動しているので、 http://localhost でアクセスできるのだが、あとで、RancherにDocker for Mac上のk8s clusterを登録するあたりで、localhostでは不都合があるため、自身のIPアドレスでアクセスする。

今回は、 `192.168.1.2` としておく。

ブラウザで、 https://192.168.1.2 にアクセスすると、以下のように証明書があきまへんって画面になりますが、気にせずアクセスする。

<img width="1920" alt="プライバシー_エラー-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/777d96b1-42f2-5441-bbb5-93a6f8f45c7a.png">

初期パスワードを設定する画面が表示されるので、設定する。好きなパスワードをどうぞ。

<img width="1920" alt="Rancher.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/8502b302-187e-008d-5ddd-2d7c1c7670e8.png">

Rancher Server URLを登録する画面が表示される。

ここで、ちゃんと、ローカルのIPアドレスを指定しておかないと、以降の処理で失敗するぞ。

<img width="1920" alt="スクリーンショット_2018-11-22_18_34_52.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/7c60de6c-ed12-3bdc-d768-416213583156.png">

# クラスターを追加

Rancher上で、Docker for MacのKubernetes Clusterを追加する。

クラスターの追加画面を開いて、Importを選択して任意の名前をつける。 ここでは、 `dockerformac` としておいた。

<img width="1920" alt="スクリーンショット_2018-11-22_18_35_49.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/ed14e19a-2d5a-cfde-664e-7106f70d5d58.png">

作成を押すと、以下のような画面になる。

<img width="1920" alt="スクリーンショット_2018-11-22_18_36_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/0063746a-5065-2c09-9f9f-2259b0e2622d.png">

一番下のコピーボタンを押下して、コマンドをクリップボードにコピーする。

真ん中のやつだと、証明書エラーになるので、curlとpipeを使って、いい感じに証明書のエラーを無視して kubctrl applyが実行できるようなコマンドである一番下のを使う。

すると、良い感じに以下のような画面になる。

<img width="1920" alt="Rancher.png" src="https://qiita-image-store.s3.amazonaws.com/0/24050/85510f46-bcf0-e5c1-bcb2-dada229e08ff.png">

これで、Rancher上でクラスターとして認識されたので、カタログとか実行できる状態になったっぽい。

# まとめ

今回は、ひとまず、Docker for Macで実行できる k8s clusterを、Rancherにクラスターとしてインポートするあたりまでをメモった。

また、カタログとか実行していくあたりで何かあるかもだが、いろいろ試してみようと思う。

以上です。
H2Oを実戦投入するためのいろいろ

下記で大体戦える
`service h2o reload`で反映かな。

## TOC

* Basic認証
* IP制限
* 特定コンテンツの403対応 .gitなど

## Basic認証

@h2o.cfg

```cfg
        mruby.handler: |
          require "htpasswd.rb"
          Htpasswd.new("/path/to/.htpasswd", "Realm")  
```

## IP制限

たとえば

```txt
192.168.1.10
127.0.0.1
```

のみを許可したい場合

@ip.rbとかつくって内容は

```ruby
ALLOW_IPS = %w{
    192.168.1.10
127.0.0.1
}
class Acl
  def call(env)
    if ALLOW_IPS.include? env['REMOTE_ADDR']
      [399, {}, []]
    else
      [403, {'Content-Type' => 'text/plain;charset=utf-8'}, ['Forbidden']]
    end
  rescue => e
    $stderr.puts e
  end
end
Acl.new
```

@h2o.cfgには

```cfg
     paths:
       "/":
         mruby.handler-file: /path/to/ip.rb
         file.dir: /var/www/html
```

とかする

## 特定コンテンツの403対応 .git、.htaccessなど

```cfg
    paths:
       "/":
         mruby.handler: |
           acl {
              deny { path =~ /\.git+/ }
              deny { path =~ /\.ht+/ }
           }
         file.dir: /var/www/html
```
EC2 Capacity Reservation 「Open」と「None」の違い

2018/10/25(JST)からEC2オンデマンドインスタンスのキャパシティー予約が出来るようになりました。

### ■キャパシティー予約とは？

[参考リンク]
https://aws.amazon.com/jp/about-aws/whats-new/2018/10/Amazon-EC2-now-offers-On-Demand-Capacity-Reservations/

利用期間のコミットメント無しでRIのようにインスタンスの在庫を確保出来るというサービスですね。
クラスメソッド 大栗さんのブログ記事がわかりやすくて良いと思います。

[参考リンク]
https://dev.classmethod.jp/cloud/aws/ec2-capacity-reservations/

実際にEC2自体は各AZ毎に在庫を持っていますが、東京リージョンでは結構在庫切れに遭遇する事がありました。
特にM4→M5過渡期とか、ap-northeast-1d追加時の別AZとかで顕著だった記憶があります。

個人的にはこの機能、利用料金を見てみると予約期間中も通常のオンデマンド料金がかかり続ける為(2018/11/22時点)、何らかの理由でホットスタンバイには出来ない用途(予約期間中のある時点で生成されるカスタムAMIから立ち上げなければならない等)以外には今の所使う理由はなさそうだなと感じています。

と・・・前置きはこのくらいにして、ここからが本題です。

### ■本題

この機能の追加によって、通常のEC2立ち上げのWEB UIにこんな項目が追加されています。

[日本語]
![2018-11-22_09h53_21.png](https://qiita-image-store.s3.amazonaws.com/0/99499/496d0fd1-5695-b3d4-9da6-f809f462687e.png)

[英語]
![2018-11-22_10h05_02.png](https://qiita-image-store.s3.amazonaws.com/0/99499/ba167d3e-a6a9-f539-f694-1730de56280c.png)

どうやらデフォルトが「Open」のようですが、「なし」もしくは「None」との違いが気になります。
という事でちょっとCapacity-reservationsのユーザガイドを調べてみました。

[参考リンク]
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/capacity-reservations-using.html

~~~

Instance eligibility—Choose one of the following options:

open—(Default) The Capacity Reservation matches any instance that has matching attributes
 (instance type, platform, and Availability Zone). If you launch an instance with matching 
attributes, it is placed into the reserved capacity automatically.

targeted—The Capacity Reservation only accepts instances that have matching attributes 
(instance type, platform, and Availability Zone), and explicitly target the reservation.

~~~

![2018-11-22_18h43_40.png](https://qiita-image-store.s3.amazonaws.com/0/99499/333148f7-70e0-89e3-c88c-56602fe82095.png)


どうやらEC2側の設定値として「Open」を指定していると、Instance eligibilityを Openとするキャパシティー予約を作成した時にその予約を消費してしまうようです。

前述したキャパシティー予約のユースケースを考えると、Instance eligibility設定は自ずと targetedで設定する事になりそうですが、意図せず予約を消費してしまう可能性を考えると私はEC2側の設定値は、
## 「None」を選択した方が無難そう
かなと判断しました。

ちなみに過去に作成したインスタンスは確認する限り全て「None」になっていました。
Birthday Gifts Same Day Delivery

![floralbay banner.jpg](https://qiita-image-store.s3.amazonaws.com/0/293211/2c7adba1-e932-07a1-9fec-6200c96d9032.jpeg)

Floralbay is the best indian florist same day delivery services online store showcases a huge selection of flowers. We have segregated into different kinds of online flowers delivery service in India suiting different occasions. You can order flowers from floralbay.com to gift your loved ones on the occasions like birthday, anniversary, wedding, housewarming, baby shower, online diwali gifts for family and many more. We also provide services like anniversary gifts same day delivery, Special Valentine’s Day flowers, Birthday Gifts Same Day Delivery, you can select from many gorgeous bouquets made from alluring red roses. https://www.floralbay.com/occasion/birthday.html
UNITYで横方向の動きを設定する

## 動き変数を作る

```
// 変数の設定
public float forwardForce = 2000f;　//前進動きの数
public float sideForce = 500f;　//横に動きの数
```

↑のコードは動き数の設定です。


##動きの設定
```
    void FixedUpdate () {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime); // add a force of 2000 z-axis per second
        //右側に動き
        if(Input.GetKey("d"))
        {
            rb.AddForce(sideForce * Time.deltaTime ,0, 0); 
        }
        //左側に動き
        if (Input.GetKey("a"))
        {
            rb.AddForce(-sideForce * Time.deltaTime, 0, 0);
        }

    }
```
↑のコードは「ｄ」のキーボードを押す時に右側に動きますと「a」のキーボードを押す時に左側に動きます。


```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerMovement : MonoBehaviour {
    
    // This is reference to the rigid body component called "rb"
    public Rigidbody rb;

    // 変数の設定
    public float forwardForce = 2000f; //前進動きの数
    public float sideForce = 500f;　//横に動きの数

    // Use this for initialization
    void Start () {
        //rb.AddForce(0, 0, 200);
    }

    // we marked 'Fixed Update' because we using it to render with physics
    void FixedUpdate()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime); // add a force of 2000 z-axis per second
        //右側に動き
        if (Input.GetKey("d"))
        {
            rb.AddForce(sideForce * Time.deltaTime, 0, 0);
        }
        //左側に動き
        if (Input.GetKey("a"))
        {
            rb.AddForce(-sideForce * Time.deltaTime, 0, 0);
        }

    }

}

```

↑のコードは全部のコードでした。

youtube : https://www.youtube.com/watch?v=Au8oX5pu5u4&t=1s
前のレッスン：https://qiita.com/andy1dx/items/a84f1d8a5d8bea371396
laravelでLineBot開発

laravelでLineBotを作ってみた際のメモ

## 前提条件
- laravel5.7の開発環境がそろっていること
    - laravel/homesteadを使用
- Lineアカウント

## 手順
### プロバイダー&チャネル作成
- [LINE Developers Console](https://developers.line.biz/console/)にログイン
- 『新規プロバイダー作成』ボタンからプロバイダーを作成する
- 『Messaging API』のチャネルを作成する
    - プラン：Developer Trial

###  チャネル基本設定
- 『Channel Secret』をメモする
- 『アクセストークン』を『再発行』しメモする
- 『Webhook送信』を『利用する』に変更する
    - ※ngrokで動作確認するため『Webhook URL』は 後で設定する
- 『自動応答メッセージ』を『利用しない』に変更する
- 『友だち追加時あいさつ』を『利用しない』に変更する



### Botアプリケーションの作成
- なにかEventが発生したら、ハローと応答させるアプリケーションとする

#### line-bot-sdk-phpのインストール
```
composer require linecorp/line-bot-sdk
```

#### env設定
- 上記でメモした『Channel Secret』と『アクセストークン』を.envに設定

``` \.env
LINE_ACCESS_TOKEN=*****メモしたアクセストークン*****
LINE_CHANNEL_SECRET=*****メモしたChannel Secret*****
```

#### コントローラー作成
```/app/Http/Controllers/Api/LineWebhookController.php
<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use LINE\LINEBot;
use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\SignatureValidator;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use Exception;

class LineWebhookController extends Controller
{

    public function webhook (Request $request)
    {
        $lineAccessToken = env('LINE_ACCESS_TOKEN', "");
        $lineChannelSecret = env('LINE_CHANNEL_SECRET', "");

        // 署名のチェック
        $signature = $request->headers->get(HTTPHeader::LINE_SIGNATURE);
        if (!SignatureValidator::validateSignature($request->getContent(), $lineChannelSecret, $signature)) {
            // TODO 不正アクセス
            return;
        }

        $httpClient = new CurlHTTPClient ($lineAccessToken);
        $lineBot = new LINEBot($httpClient, ['channelSecret' => $lineChannelSecret]);

        try {
            // イベント取得
            $events = $lineBot->parseEventRequest($request->getContent(), $signature);

            foreach ($events as $event) {
                // ハローと応答する
                $replyToken = $event->getReplyToken();
                $textMessage = new TextMessageBuilder("ハロー");
                $lineBot->replyMessage($replyToken, $textMessage);
            }
        } catch (Exception $e) {
            // TODO 例外
            return;
        }

        return;
    }
}
```

#### ルーティング設定
``` \app\routes\api.php
Route::group(['namespace' => 'Api'], function() {
    // LineからのWebhookを受信
    Route::post('/line/webhook', 'LineWebhookController@webhook')->name('line.webhook');
});
```

### 動作確認
#### ngrokで外部に公開する

```
ngrok http 80
```

#### Webhook URLの設定
- LINE Developers Consoleのチャネル基本設定の『Webhook URL』を編集し、ngrokで発行されたURL(httpsのほう)を登録する
    - ex) https://hogehoge.ngrok.io/api/line/webhook
    - 接続確認し、成功すること

- QRコードでともだち登録して、Botにメッセージを送る
    - Botは「ハロー」と答えてくれるはずである
qmailをインストールしたサーバーに間違えてyumでpostfixを入れてしまった際の対処

# 事象

昔のサーバー(CentOS6)に、セキュリティ対応目的でyum updateをしたところ、`postfix`までインストールされてしまいました。
どうやら`cronie`のアップデートに引きずられてインストールされたようです。

`postfix`がインストールされるだけだったら問題ないのですが、
`alternative`で、`mta`が`postfix`になってしまったので、`sendmail`コマンドを使用しているプログラムが軒並み`qmail`を使用できなくなってしまいました。

※`qmail`はソースインストールしており、`alternative`には出てこない。

そのためなんとか元の状態に戻します。

# 対応内容


### postfixの強制アンインストール
`yum`でアンインストールしようとすると、依存性の関係で他の必要なパッケージまでアンインストールされてしまうため、
`rpm`コマンドで強制的にアンインストールします。

```shell
rpm -e --nodeps postfix
```

### qmailをsendmailに紐付ける
`sendmail`コマンドを使うと裏では`qmail`を使用するように、手動でリンクを貼り直します。

```shell
ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
ln -s /var/qmail/bin/sendmail /usr/lib/sendmail
```

### qmailの再起動

`qmail`を再起動します。

```
svc -t /service/qmail/log/
svc -t /service/qmail/
svc -t /service/smtpd/log/
svc -t /service/smtpd/
```

# 本来どうすべきだったか
`postfix`は`cronie`のアップデートに引きずられてインストールされたようですので、

```shell
yum update
```

ではなく、

```shell
yum update --exclude cronie*
```

とすればpostfixはインストールされないようです。(cronieはアップデートされないままですが…)


以上。
v-tap ディレクティブ

`@mousedown`だけでも良さそうなんですけど、
せっかくなので、タッチデバイスでは`touchstart`使用するように、
`v-tap`というカスタム・ディレクティブ（グローバル）を作成しました。
※ちなみに、`@touchstart`は標準で用意されています。

```js
Vue.directive('tap', {
    inserted: function(el, binding) {
        const tap = (typeof window.ontouchstart === 'undefined')
            ? 'mousedown'
            : 'touchstart'
        let tapFunction = function(event) {
            if (binding.value(event, el)) {
                el.removeEventListener(tap, tapFunction);
            }
        };
        el.addEventListener(tap, tapFunction);
    }
})
```

<p data-height="300" data-theme-id="34631" data-slug-hash="xQpavp" data-default-tab="js,result" data-user="pokkur" data-pen-title="v-tap directive " class="codepen">See the Pen <a href="https://codepen.io/pokkur/pen/xQpavp/">v-tap directive </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>
ReactNativeでスプラッシュスクリーンをいい感じに出す

# RNスプラッシュスクリーンの作り方

React、iOS、Android開発未経験の覚書です。
間違えている可能性もあります。
その時は編集リクエストかコメントで教えてください。

モジュール公式を日本語で噛み砕いたような感じです。
詳しくはモジュールのgithubへ
https://github.com/crazycodeboy/react-native-splash-screen

## 拡張モジュールを導入
```
npm i react-native-splash-screen --save
react-native link react-native-splash-screen
```
## 各OSのネイティブコードをちょっと修正する
### Android
```java:MainActivity.java

import com.facebook.react.ReactActivity;

import android.os.Bundle; // 追記
import org.devio.rn.splashscreen.SplashScreen; // 追記

public class MainActivity extends ReactActivity {
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);  // 追記
        super.onCreate(savedInstanceState);
    }
    // ...other code
}
```

### iOS
```objective_c:AppDelegate.m
#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNSplashScreen.h"  // 追記

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...other code

    [RNSplashScreen show];  // 追記
    return YES;
}

@end
```

## 起動後のscreenとなる所でスプラッシュスクリーンを非表示にする
```javascript:App.js

export default class App extends Component<Props> {

// コンポーネントをマウントできたらスプラッシュを消す
  componentDidMount() {
    SplashScreen.hide();
  }

// other

```

## StatusBarとメイン背景の色を同色にする

```javascript:App.js

// other
  render() {
    return (
      <View style={styles.container}>
        <StatusBar barStyle="light-content" backgroundColor="#212121" /> //　追記
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#212121' //　ステータスバーと色を合わせる
  },
  // other
  ```

## 各OS毎にスプラッシュスクリーンを設定する
### Android

app/src/main/res/layout/launch_screen.xmlを配置する

```xml:launch_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/launch_screen">
</LinearLayout>
```
app/src/main/res/配下にdrawableフォルダを配置する

* drawable-xhdpi
* drawable-xxhdpi

中にlaunch_screen.pngでスプラッシュ画像を置いておく

### iOS
XcodeでlaunchScreen.xibを編集する
tmuxのエラー

tmuxをZRouterでビルドしてターゲットに焼いたところ以下のエラーがでた。

```
# ./tmux
tmux: need UTF-8 locale (LC_CTYPE) but have US-ASCII
```

/usr/share/locale/en_US.UTF-8が無いためかと思い、コピーしたところRT3050なターゲットでは動いた。

ところが、Atherosなターゲットでは依然エラーがでる。

コードを見たところmainの最初に以下の処理がある。

```c
        if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
            setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
                if (setlocale(LC_CTYPE, "") == NULL)
                        errx(1, "invalid LC_ALL, LC_CTYPE or LANG");
                s = nl_langinfo(CODESET);
                if (strcasecmp(s, "UTF-8") != 0 && strcasecmp(s, "UTF8") != 0)
                        errx(1, "need UTF-8 locale (LC_CTYPE) but have %s", s);
        }
```

Atherosなターゲットでlocaleコマンドで見るとあるんだけどな。

```
# locale -a
C
POSIX
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_US.UTF-8
```

ZRouterで同じ設定でビルドしてRalinkでは動いてAtherosでは動かないって、やっぱlocaleのBIGENDIANなんかのバグな気がする。。。

2018/11の13-CURRENTで、とりあえずMT7620で使う事にしました。
pythonでマルチスレッド処理したい(序章)

マルチスレッド処理についてメモ

## プロセスとスレッド
- どちらもOSのマルチタスク機能によって実現している
- *プロセス* = アプリケーションの実行単位
    - メモリを共有しない。同じメモリ上のデータにアクセスすることは基本的にない。
- *スレッド* = タスクにCPUを割り当てる単位。1プロセス内の話。
    - メモリを共有する。同じメモリ上のデータに簡単にアクセス出来る。
    - プロセスが起動されるとメインスレッドが１つ生成される。 

## 基本はシングルスレッド
- １つのCPUで同時に複数のタスク処理はできない

## マルチスレッドとは何か
- CPUの実行時間を細かく分割し、スレッドをこまめに切り替えて割り当てている。
- その割り当てを行なっているのがOSのスケジューラ。つまりスレッドのスケジューリングは、プロセスではなくカーネルのスケジューラが行っている。
- 実行時間はシングルスレッドと変わらないor悪くなる
- (マルチCPUでそれぞれに処理させる方法もある。この場合実行時間は短くなる。)

## スケジューラが行なっていること
- 256段階でスレッドに優先順位をつけている
- 優先度が異なるスレッドが実行状態のときは、優先度が高いスレッドが待ち状態にならないと低いスレッドは実行できない。
- 待ち状態 = ロック状態
- 同じ優先度のときは、それぞれ一定の実行時間(*スレッドクァンタム*)が割り当てられる。デフォルトは100ms。

## マルチスレッドのメリット
- プロセスに比べて消費するリソースが少ない。
- 新しくプロセスを作成する場合と比べて、新しいスレッドを作成する方が起動のオーバーヘッドが少ない。

#### ①レスポンスタイムの向上 ...UIに直結する

- 重い処理をマルチスレッド化することで、他の処理に即時反応出来る
  (ex.ネットワーク通信、重い計算、ディスクへのアクセス)

- これをやらないと、重い処理実行中クライアントアプリがフリーズする(ex.ブラウザ)
- 重い処理の実行状況を監視するのにも使える(ex.プログレスバー)

#### ②スループットの向上 (単位時間あたりの処理能力)
- 遅いデバイス(ディスク、ネットワークなど)の処理結果を待っている時間を有効活用できる
- スループットの向上に繋がる状況はかなり限定的

## 活用される場面
- UIがフリーズするとき
- 複数のクライアントからのリクエストに応答しないといけない時

## マルチスレッドのデメリット
- 処理を全て完了させるまでの時間(*スループット*)は短縮されない。悪化することが多い。
- バグを産みやすい
  - デッドロック ...それぞれのスレッドが互いの完了を待ってしまう状態
  - データの整合性が崩れる ...複数スレッドが１つのデータに同時アクセスをして処理を加えてしまう


## 参考
[第6回　マルチタスクの実行順はどうやって決めるのか](https://tech.nikkeibp.co.jp/it/article/COLUMN/20080326/297106/)
[連載.NETマルチスレッド・プログラミング入門](http://www.atmarkit.co.jp/ait/series/2783/)
Mojaveにしたらsshfsしんだ

モハベって読むんですね。
当然Gitも死んでましたわ。
そっちはすぐ直せたんですけど、英語読むの嫌で記事漁って時間かけてしまったので備忘録しておきます。

```
$ sshfs user@{ip}:/home/hoge hoge -o sshfs_sync -o sync_readdir
mount_osxfuse: the file system is not available (2)
```


[osxfuse not compatible with MacOS Mojave](https://github.com/osxfuse/osxfuse/issues/542)


[Release of FUSE for macOS 3.8.2](https://osxfuse.github.io/2018/07/01/OSXFUSE-3.8.2.html)


```
# before
$ sshfs --version
SSHFS version 2.10
OSXFUSE 3.7.1
FUSE library version: 2.9.7
fuse: no mount point

# after
$ sshfs --version
SSHFS version 2.10
OSXFUSE 3.8.2
FUSE library version: 2.9.7
fuse: no mount point
```

以上です。


お昼休みの間に更新したら、更新は終わるけど、軽作業で足出てしまったので、安易にやっちゃいけなかった。
Rails初心者が躓くRuby文法

#はじめに
初投稿です。
最近Railsを勉強しているのですが、「何この書き方？」というコードに遭遇することが多いです。

ということで復習も兼ねてRails（Ruby）初心者が躓く文法をまとめます。

内容は殆どRails Tutorial４章のまとめです。やっぱり間違いない教材ですね。（８章で挫折した）

#メソッドの括弧は省略できる
Rails Tutorial4章で以下のように書かれています。
>実は、Ruby では丸カッコは使用してもしなくても構いません。次の2つの行は等価です。

>```
stylesheet_link_tag('application', media: 'all',
                                   'data-turbolinks-track': 'reload')
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'
```

Rubyにおいては丸括弧の有無で違いはないようです。
もっと簡単な例ですと、以下の2行も等価になります。

```
puts("Hello Wolrd!")
puts "Hello World!"
```

さらに言うと、クラス定義で使うattr_accessorにも当てはまります。

```
#普通の書き方はアクセサ引数の括弧は省略
class Test1
  attr_accessor :one, :two
    
  def initialize(one, two)
    @one = one
    @two = two
  end
end

#だけど、括弧をつけても意味は同じ
class Test２
  attr_accessor(:one, :two)
    
  def initialize(one, two)
    @one = one
    @two = two
  end
end
```

つまり、いつも使っているattr_accessorは引数の括弧を省略しているということになります。

実際にインスタンス化して試してみると括弧の有無で同じことがわかります。

```
test１ = Test１.new("first", "second")
test2 = Test2.new("first", "second")

puts "#{test1.one} #{test1.second}"
puts "#{test2.one} #{test2.second}"

=>first second
=>first second
```

ちなみに"#{xxx.yyy}"は式展開というもので、ダブルコーテーション内で式を展開できて便利です。

#ハッシュの定義は２パターンある
複数のハッシュを同時に定義する場合は以下のようにします。

```
test = {:one => "first_value", :two => "second_value"}
puts test[:one]

=>first_value
```

そして以下のようにも書けます。

```
test = {one: "first_value", two: "second_value"}
puts test[:one]

=>first_value
```

Rails Tutorialでもこのことが言及されています。
>どちらの記法もよく使われているので、両方の見分けがつくことが重要です。
ただ最初は少し見分けづらいのも事実です。
例えば:nameはシンボルとして独立していますが、引数を伴わないname:では意味が成り立ちません。
次のコードの:name =>とname:は、ハッシュとしてのデータ構造は全く同じです。

>```
{ :name => "Michael Hartl" }
```

>上のコードと、

>```
{ name: "Michael Hartl" }
```

>というコードは等価になります。

ここもハマりがちなポイントだと思います。Railsでは後者の書き方をよく見る気がします。

#最後の引数がハッシュの場合は波括弧を省略できる
これに関してはコードを見たほうが早いと思います。
Rails Tutorialから引用です。
>実は、ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略できます。次の2つの行は等価です。

>```
stylesheet_link_tag 'application', { media: 'all',
                                     'data-turbolinks-track': 'reload' }
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'
```

stykesheet_link_tagは外部スタイルシートを指定するリンクタグを生成するメソッドです。
第一引数にスタイルシートへのパス、第二引数にHTMLオプションを指定します。

この第二引数はこのメソッドの最後の引数であることから、ハッシュを定義する際に使う「｛｝」が省略することができます。

また、以上のコードは途中で改行がなされています。
~~Rubyでは改行と空白を区別していません。よって改行もただのスペースとみなされます。~~
→そんなに簡単な話ではないみたいです。ご指摘ありがとうございます。

更に言うとこのコードはメソッドの括弧も省略されています。
私を始め、初心者にはとっつきづらいコードですが、ここまでの内容を踏まえると理解できるかと思います。

#じゃあ結局、全部省略すればいいの？
というわけでもないようです。
コードの意味としては等価ですが、可読性との兼ね合いや慣習等があるみたいですね。

これに関しては以下の記事が参考になるかと思います。あとは経験ですかね。

Rubyコーディングアンチパターン
https://qiita.com/seiya1121/items/6fcd8a1ab332a4f14439

#おわりに
今回はじめて記事を書いてみましたが、色々と調べなおすことがあり勉強になりました。
またハマりがちな文法を見つけたら追記していこうと思います。

また、筆者も完全に初心者なので間違っている箇所が多々あるかとおもいます。
間違いに気づいた際にはそっと指摘して頂けると非常に助かりますので、なにとぞよろしくお願いします。
【Access】Accessのクエリで半角・全角・ひらがな・カタカナを区別して抽出する方法

#記事概要
AccessのクエリでWHERE文を用いる際、意図しないレコードを抽出してしまうことがあります。
それは、半角・全角・ひらがな・カタカナ・大文字・小文字といった文字形式のみ違う場合です。原因はバイナリモードではなく、テキストモードで抽出をかけてしまうからだそうです。

例えば、次のようなテーブルがあったとします。
テーブル名:tbl_Fruit

| ID       | Fruit       |
|:---------|:------------|
| 1        | みかん      |
| 2        | ﾐｶﾝ         |
| 3        | ミカン      |
| 4        | 蜜柑        |
| 5        | MIKAN       |
| 6        | mikan       |

この時、Accessで次のクエリ文を流します。

```sql:example.sql
SELECT ID, Fruit FROM tbl_Fruit
WHERE Fruit = 'みかん'
```

すると、次のレコードが抽出されます。

| ID       | Fruit       |
|:---------|:------------|
| 1        | みかん      |
| 2        | ﾐｶﾝ         |
| 3        | ミカン      |

上表の通り、**想定した結果「みかん」と違うレコードが抽出されてしまいます！**
#2 解決方法　strComp関数
解決方法として、strComp関数を用いることで解決できます。
実装では次のようなクエリ文を作成しました。

```sql:example.sql
SELECT ID, Fruit FROM tbl_Fruit
WHERE strComp(Fruit,'みかん',0) = 0
```

###strComp関数の補足
strComp関数の引数は次の通りです。

| 引数項番 | 引数内容     | 引数説明              |
|:--------|:------------|:----------------------|
| 1       | string1     |string2と比較する文字列。|
| 2       | string2     |stirng1と比較する文字列。|
| 3       | compare     |比較形式。省略可能。     |

比較形式について、値が"0"の時はバイナリモードで比較を行い、値が"1"の時はテキストモードで比較を行います。
今回はバイナリモードで比較を行うため、値を"0"にしています。

strCompの戻り値は次の通りになります。

| 戻り値 | 条件                       |
|:-------|:--------------------------|
| -1     | string1 < string2         |
| 0      | string1 = string2         |
| 1      | string1 > string2         |
| NULL   | string1 またはstring2がNull|

今回はstring1とstring2がバイナリモードで等しくなる場合のみ抽出したいため、戻り値を"0"と条件づけています。

▼strComp関数の詳細(MSDN)
[https://msdn.microsoft.com/ja-jp/library/cc410330.aspx](https://msdn.microsoft.com/ja-jp/library/cc410330.aspx)

以上。
RealmJS requires a node package manager (n or nvm).

タイトルどおり「RealmJS requires a node package manager (n or nvm).」ってエラーが出てRealm使ったReactNativeプロジェクトをビルドできねえぞボケって話。
普通にreact-native run-iosしたら大出血してXcodeでビルドしたらこう出た。

結論から言うと

```
node_modules/realm/src/RealmJS.xcodeproj/project.pbxproj
```
の863行目を書き換えろと。810行目だったら面白かったのに

```
shellScript = "node ../scripts/download-realm.js ios --sync";
```
に書き換えたら治りました。

[https://github.com/realm/realm-js/issues/2099](https://github.com/realm/realm-js/issues/2099)
そのうち直してくれるらしい。
Windows10にtensorflowを入れるための備忘録

# 要約

　TensorFlowの公式が公開している環境構築方法が全然うまく行かなかったので、解決した流れの備忘録

### Windows10だと、python3.6でTensorflowが実行できない（ただし、理由は知らない）
　公式さんは確かにこう言っています。

```
★　Requires Python 3.4, 3.5, or 3.6
```
 確かに、pipでTensorflowはインストールできるのですが、以下の行を実行することができません。

```python
import tensorflow as tf
```

ずらずらと、大量の出力分が出てきたのと同時に、以下のようなメッセージが末尾の方にありました。

```
Failed to load the native TensorFlow runtime.
```

原因と解法を調べ回っていると、以下の記事にたどり着きます。

- [Windows10でTensorflowとKerasをインストールしようとしてハマった話](https://tkstock.site/2018/06/27/post-436/)
- [Failed to load the native tensorflow runtime #17807](https://github.com/tensorflow/tensorflow/issues/17807)

　ここを読めば、大抵のことは察することができますが、今回は細かい点を抑えようと思います。
　ところで、上の記事の通り、Windows10とPython3.6の相性が悪いらしく、しかも、pipからインストールしたTensorFlowもまた動かないようですので、ここはおとなしくAnacondaを使うことにします。

# 処理手順 

### 0. 入れてしまったpythonはアンインストール

　TensorFlowの導入と同時にpython3系も入れてしまったのなら、消すことを推奨します。
　Anacondaで環境を構築する際にpython3.5を入れることになります。

### 1. Anacondaをインストール
　Anacondaをインストールしましょう。
　インストールウィザードを開いて、流されるままにインストールします。

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/317216/827c4b68-46bb-bfc3-2ee9-addb39ed1554.jpeg)


### 2. Tensorflowの環境を構築する
　ENV_NAMEは、Anaconda上で構築する際の環境の名前なので、自由につけて構いません。
　CPU版のTensorFlowを使いたいのであれば、以下の行の「tensorflow-gpu」を「tesorflow」に差し替えましょう。
　他にも入れたいものがあるなら、後からインストールもできますので、今回はTensorFlowの導入に集中します。

```
conda create -y -n ENV_NAME python=3.5 tensorflow-gpu anaconda
```

　作った環境を有効化しましょう。

```
activate ENV_NAME
```

### 3. 動作確認
　TensorFlowがちゃんと動いてくれるか確認するために、pythonのREPL環境を開きます。
　今の行をプロンプトに入力してください。

```
python -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))"
```

エラーとかワーニングっぽいのが出なければ成功

# まとめ
　インストールできない原因は、Windows10側にあるのかなぁと、なんとなく考えていますが、TensorFlowが動きさえすればいいので、めでたしめでたしです。
　しかし、この記事自体が2018年現在のものであることに十分留意してください。

　それから、Anacondaでいちいち構築した環境をactivateしないといけないのは面倒くさいので、この点の解決は今後の課題になります。（覚えてればの話ですが）
Rdkitを使って、SDFファイルを分解

<h1>目標・目的</h1>
SDFファイルから記述子を求め、csvファイルとして扱えるようにする。

<h3>記述子ってなに？</h3>
記述子とは、分子構造から数値化できるものを表したものである。(csvファイルの形にするようなもの）
>引用元(https://www.yodosha.co.jp/jikkenigaku/keyword/4091.html)
>> 化合物の化学的特徴を，部分構造の特性や物理化学的性質など数値化してあらわした特徴ベクトルを意味する
>引用元2(https://future-chem.com/rdkit-descriptors/)
>>記述子（デスクリプター）とは分子の性質を決める指標のこと

<h3>記述子が必要な理由</h3>
SDFファイルとは、複数の分子を１つのファイルに納めたファイルのことである。（創薬などでは、データの受け渡しがSDFファイルを使っているらしい）
SDFファイルの中身は、取得するDB([pubchem](https://pubchem.ncbi.nlm.nih.gov/)や[PDB](https://pdbj.org/))によっては、カラム名（変数名）がかなり変わってくるが、ほとんどは、「分子量」や「SMILES」や「モル質量」などの基本情報しか載ってないため、記述子は計算などをして、導かないといけない。
　しかし、この記述子は数値となっていることから、機械学習やDeepLearningに使うことができる。現在では、スクリーニング（特徴抽出）やたんぱく質とリガンドとの相互作用分析など、さまざまなところで、最先端の技術が使われている。
例）https://www.jstage.jst.go.jp/article/tjsai/29/1/29_D-TS13_12/_pdf/-char/ja
（２０１４年）
https://www.jstage.jst.go.jp/article/jccj/2/4/2_4_119/_pdf

<h3>実装</h3>
https://datachemeng.com/pythonassignment/
ここのサイトからダウンロードしたSDFファイルを使って、csvファイルを作成していきたいと思います。（ちなみに、上のサイトのコードも見本にさせていただきました。ありがとうございます）

```rdkit.py
from rdkit.Chem import Draw, PandasTools
from rdkit import Chem
import pandas as pd
from rdkit.Chem import Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors
```
これらのライブラリをインポートします。

```rdkit.py
mols = Chem.SDMolSupplier('logSdataset1290_2d.sdf')
mols　#=> rdkit.Chem.rdmolfiles.SDMolSupplier....
```

まずは、SDMolSupplierで、SDFファイルから取得。
しかし、変数molsの中身が見えないため、見たい人は、PandasToolsを使うことで、DataFrameで見ることができる。

```rdkit.py
df = PandasTools.LoadSDF('logSdataset1290_2d.sdf')
df
```


データ整理している

```rdkit.py
y_name = 'logS'
mols = [mol for mol in mols if mol is not None ] #=> SDMolSupplierは入力構造に不備があるとNoneになるため、
len(mols) #=>1290
```

```rdkit.py
descriptor_names = [descriptor_name[0] for descriptor_name in Descriptors._descList]
len(descriptor_names) #=> 200
```
Descriptors._descListは、記述子とその計算メソッドがある。200個もの記述子があるが、それは一部分らしい。

```rdkit.py
descriptors = pd.DataFrame([descriptor_calculation.CalcDescriptors(mol) for mol in mols])#for文で一つ一つ分子を計算している
```

そして、DataFrameに計算された数値を入れていく。

```rdkit.py
descriptors.columns = descriptor_names
smile = [Chem.MolToSmiles(mol) for mol in mols] #=> smileを取得する
descriptors.index = smile
y = pd.DataFrame([float(mol.GetProp(y_name)) for mol in mols]) #分子のlogSを取得
y.index = smile
y.columns = [y_name]
dataset = pd.concat([descriptors, y], axis=1)

dataset.to_csv('dataset.csv') #=> dataset.csvが出力された 
```

yにlogsを取得しているが、logsは化合物の水に対する溶解度の指標であり、　高いと水に対する溶解度は高いことが言える。創薬などでは重要な指標となっている。
<img width="1004" alt="スクリーンショット 2018-11-22 17.09.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/270887/96ef17db-ca88-4ee1-704c-0969353c71b5.png">

上の写真が、csvファイルにした時の数値である。


これで、構造分子を数値化になったので、ここから、PCA（主成分分析）や深層学習に当てはめていき、類似度の評価や相互作用分析に使えるようにしていきたい。

※これを書いた人は、バイオ・ケモインフォマティクスをほとんどわかっていないため、間違いがあれば指摘していただきたいです。
【baserCMS：初心者向け】ページごとの分岐方法

#ページごとの分岐方法

スラッグがworkのページのみに表示したいコンテンツがある場合

~~~php
<?php if (strtolower($this->BcBaser->getContentsName()) === 'work'): ?>
〜コンテンツ〜
<?php endif; ?>
~~~

スラッグがworkのページのみに表示したくないコンテンツがある場合（work以外のページに表示）

~~~php
<?php if (strtolower($this->BcBaser->getContentsName(true)) !== 'work'): ?>
〜コンテンツ〜
<?php endif; ?>
~~~

複数ページ分岐
スラッグがpolicyとfaqのページ以外のページで表示したいコンテンツがある場合

~~~php
<?php
$slug = strtolower($this->BcBaser->getContentsName(true));
if ($slug !== 'policy' && $slug !== 'faq'): ?>
〜コンテンツ〜
<?php endif; ?>
~~~
pecoの簡単で便利な使い方

# peco とは
ぐぐりましょう

# 目的
`find . | peco` を使って検索したファイル/ディレクトリに cd, ls, rm, cat, vim する。
それぞれエイリアスで簡単に使えるようにする。

# こうなる
![peco.gif](https://qiita-image-store.s3.amazonaws.com/0/69140/378bcb35-8f9e-0f0f-ab20-c041d2e3e9ab.gif)

lsp, vimp, catp なども同様に検索し、それぞれのアクションを行います。

# ~/.zshrc
bashでも同じかと。

```shell
function pecofind() { # find コマンドの出力結果をpeco する
  if [ $# -eq 0 ]; then
    find . | peco
  else
    find $1 | peco
  fi
}
function pecofindd() { # find コマンドの出力結果をpeco する。 ファイルが選ばれたら1つ手前のディレクトリを返す
  if [ $# -eq 0 ]; then
    finded=`find . | peco`
  else
    finded=`find $1 | peco`
  fi
  if [ -f $finded ]; then
    echo $finded | perl -pe 's/\/[^\/]*$/\n/g'
  else
    echo $finded
  fi
}
function cdp() {
  dir=$(pecofindd $1)
  echo "\e[32;1mcd\e[m \e[32;1;4m$dir\e[m"
  cd $dir
}
function lsp() {
  file=$(pecofind $1)
  echo "\e[32;1mls\e[m \e[32;1;4m$file\e[m"
  ls $file
}
function rmp() {
  file=$(pecofind $1)
  echo "\e[32;1mrm\e[m \e[32;1;4m$file\e[m"
  rm $file
}
function treep() {
  file=$(pecofind $1)
  echo "\e[32;1mtree\e[m \e[32;1;4m$file\e[m"
  tree $file
}
function catp() {
  file=$(pecofind $1)
  echo "\e[32;1mcat\e[m \e[32;1;4m$file\e[m"
  cat $file
}
function vimp() {
  file=$(pecofind $1)
  echo "\e[32;1mvim\e[m \e[32;1;4m$file\e[m"
  vim $file
}
```

# 注意
find する中身が多いと時間がかかります。(良い手はないか？ )

# おわり
シンプルかつ便利なpecoの使い方でした

# 他のpeco の便利系
peco + ghq が便利すぎて、使ってない人を見かけたらすぐに勧めています。
https://qiita.com/strsk/items/9151cef7e68f0746820d
scpで複数ファイルをダウンロードするときの小さな落とし穴

# TL;DR
scpで、リモートのファイル名をワイルドカード展開やブレース展開するときはエスケープしよう

# 本題
```:リモートサーバーのディレクトリ構成
/home/
└── user/
    ├── file1
    ├── file2
    └── fileA
```

このようなリモートサーバーから、ローカルのカレントディレクトリにファイルをダウンロードしたい。

## file1のみダウンロード
```
scp user@remote:/home/user/file1 .
```

うん、問題ないですね。

## file1, file2, fileAをダウンロード
```
scp user@remote:/home/user/file* .
```

ワイルドカード展開も使えます。
**※追記：後述の通り、環境によります。**

## file1, fileAをダウンロード
```
scp user@remote:/home/user/file{1,A} .
```

ワイルドカードが使えればブレース展開も使えるはずですね。
実際このコマンドも上手く動きます。

パスワードを2回求められることを除いては！

### なぜ？
先ほどのコマンドは、以下と同じです。

```
scp user@remote:/home/user/file1 user@remote:/home/user/fileA .
```

これがもし、1つ目の引数と2つ目とで違うリモートサーバーだとしたら、パスワードを2回入力するのも納得でしょう。
各リモートアドレスが同じかどうかまで、scpは面倒見てくれません。

### 解決策
ローカルのシェルがブレース展開するからいけないのです。
リモート側に展開させましょう。

```
scp user@remote:/home/user/file\{1,A} .
```

ブレースをエスケープしただけですが、これでローカルのシェルではなくリモートサーバ側で展開してくれるので、パスワード1回で済みます。

ちなみにワイルドカード展開も、たまたまローカルマシンに`user@remote:/home/user/file*`にマッチするファイルがなかっただけです。

~~マッチしなければ基本的にそのまま引数に渡してくれるはずですが、~~これもエスケープしておいたほうが安全でしょう。

## 追記：シェルのglobの挙動
ワイルドカード`*`にマッチするファイルがない場合の挙動は、厳密には環境によります。
bash のデフォルト設定なら、上記のようにマッチしなければ`*`を含んだ文字列をそのままコマンドに渡しますが、`shopt`で`nullglob`や`failglob`が設定されている場合は、引数がなくなったりエラーを吐いたりします。
さらに、zshだとエラーになるのがデフォルトです。

このあたりの挙動は以下の記事に詳しく書かれています。

https://qiita.com/anqooqie/items/a2b607fe984ec982fa21
three js　で立体を合成して　立体を作る

空の要素に物体を追加する。
これは何がいいかというと、例えばboxを作るとき、回転させる時の座標が中心にあるけど配置の時にはずれておくと回転の中心をずらす事ができる。

```ruby:qiita.rb
//枠を作る
var _geo = new THREE.Geometry();
var _mat = new THREE.Matrix4();
```

```ruby:qiita.rb
//物体を作る
var _geo1 = new THREE.CylinderGeometry(0,50,50*Math.sqrt(2),3,4);
```

```ruby:qiita.rb
//傾けたり、場所を横にしたりはmatrixでここで設定
_geo1.applyMatrix( new THREE.Matrix4().makeTranslation( 0,-50*Math.sqrt(2)/2,50 ) );
```

```ruby:qiita.rb
//枠に作ったエリアを入れる
_geo.merge(_geo1, _mat);
```

```ruby:qiita.rb
//ここからは普通、マテリアルを設定してメッシュを作る
var _obj = new THREE.Mesh(_geo,new THREE.MeshLambertMaterial({color: 0xa67bfa,
                 wireframe: false}));
```

```ruby:qiita.rb
//配置
scene.add(_obj);
```
SSHキー作ってbitbucketに登録など

#SSHキー作ったり登録したりしてBitBucketにプッシュとかできるようにします。
初投稿になります。何卒よろしくお願い致します。
##環境
- macOS 10.13.6 High Sierra

##まずはSSHキー作るよ
ホーム直下の.sshフォルダに移動します。
隠しファイルになっているので、Finderから見たいときは shift + cmd + . で表示できます。
そしたら鍵作る。

```Bash:ターミナル
$　cd ~/.ssh
$　ssh-keygen -t rsa -b 2048 -C takumiwada129@gmail.com
```


コマンドについて軽く解説
cd ~/.ssh
・ cd   // 移動
・ ~/  // ホームディレクトリ直下
・ .ssh  // .sshフォルダ

ssh-keygen -t rsa -b 2048 -C メールアドレス
・ -t rsa  // rsa暗号（公開鍵暗号方式の暗号）　
・ -b 2048  // 文字数（少なすぎたり4096ではエラーが起こる可能性があるため）
・ -C takumiwada129@gmail.com  // コメント、登録するメールアドレス

すると鍵の名前とパスフレーズを求められるのでそれぞれ適当なに入力します。
ssh-keygenを実行した際、今回のように特にオプションとしてファイルの場所を指定しなければ、
~/.sshフォルダ内にSSHキーは作られます。


鍵の名前を求められたとき、そのままEnterを押すとデフォルトの名前（id_rsa）になります。

今回鍵の名前はデフォルトのを使用します。
randomartが表示されて鍵が作られます。



##作られたフォルダを確認
```Bash:ターミナル
$ ls -l
```
たくさん入ってます。フォルダの中の
・ id_rsaが認証鍵、
・ id_rsa.pubが公開鍵です。（サーバー側に登録する方）
・ authorized_keysは公開鍵を保存、登録しておくためのファイルです。
・ configは設定書。
・ known_hostsは接続したことある各ホストの公開鍵を保存してるファイル。


##鍵のパーミッションを変更する
```Bash:ターミナル
$ chmod 600 id_rsa
```
そのままフォルダの中でパーミッションを変更します。


##configに登録します。
```Bash:ターミナル
$ cd ~/.ssh
$ vi config
```

```Bash:.ssh/config
Host bitbucket.org
    User git
    Port 22
    HostName bitbucket.org
    identityFile ~/.ssh/id_rsa
    TCPKeepAlive yes
    IdentitiesOnly yes
```

##BitBucketに登録します。
```Bash:ターミナル
$ pbcopy < id_rsa.pub
```
まずはpublic keyをクリップボードにコピー。


BitBucketにログインし、「ユーザアイコン」、「bitbucket setting」の中にある「SSH鍵」をクリック。
「鍵を追加」を押し、Labelは適当な名前、Keyに先ほどのpublic keyのコピーをペーストします。

##秘密鍵を認証エージェントであるssh-agentに追加します
```
ssh-add ~/.ssh/id_rsa
```

##接続できるか確認
```Bash:ターミナル
$ ssh -T git@bitbucket.org
# or
$ ssh -vT git@bitbucket.org #　こっちはビルドもできるよ
```



これでSSH keyの登録が完了しました。
続きは後ほど書きます。（リポジトリ作ってプッシュとか出来るようにするとか）

お疲れ様でした。





- - -
###この記事について
こちらの記事は変更があり次第など随時更新していきます。
間違っていたり指摘する点などございましたら、是非コメント等お願い致します。

- - -
###参考
[Mac] ログイン時に~/.ssh直下の秘密鍵をSSH-Asgentに登録する方法
https://qiita.com/nia_tn1012/items/d2bd71dad33032b2ab28
https://qiita.com/0084ken/items/e763c85054a5a1e2cc6c
https://qiita.com/ksugawara61/items/a4f34e5e120bea1732d5


- - -
###更新履歴
[2018-11-22] 
- 「鍵の名前を求められたとき、そのままEnterを押すとデフォルトの名前（id_rsa）になります。」を追加

[2020-08-13] 
- .ssh/configに記述してあるidentityFileのパスを修正
- cd ~/.sshについても解説を記載
- 「ssh-keygenを実行した際、今回のように特にオプションとしてファイルの場所を指定しなければ、
~/.sshフォルダ内にSSHキーは作られます。」を追加
OpenLDAPのindex設定

#前提
CentOS7.5の同梱版のOpenLDAPを使用

#indexとは
LDAPで検索を行う際に、対象エントリを高速に検索することができます。

＜具体的に言うと＞
キャッシュを使用してインデックス情報を作成しておくことで、それを用いて対応するエントリを直ちに探すことができます。


#indexの種類
indexはslapd.conf内のindexディレクティブで指定します。
対象属性名と種類を指定します。
###等価インデックス
属性検索の際に値が完全一致するエントリを検索するのに用いられる。
例えば検索時に「uid=hogehoge」など完全一致する検索を多くするのであればこの指定方法が有効です。
####指定方法

~~~
index uid eq
~~~

###存在インデックス
ある属性を持つすべてのエントリを検索するのに用いられます。
例えば検索時に「displayName=*」などの指定方法で検索をかけることが多い場合はこの指定方法が有効です。
####指定方法

~~~
index displayName pres
~~~

###部分文字列インデックス
属性の値の一部に、指定した値が含まれるかを検索するのに用いられます。
例えば検索時に「cn=*hoge*」のような指定方法で検索をかけることが多い場合はこの指定方法が有効です。
####指定方法

~~~
index cn sub
~~~

これらを組み合わせてこのような指定もできます。

~~~
index uid eq,pres,sub
~~~

#どの属性をインデックス指定すればよい？
基本的には以下2パターンで判断します。
###logファイルを確認
通常は/var/log/slapd.log　などにログを出力するよう指定しているかと思います。
ログファイルの中で以下のような記述がある場合は、対象の属性のインデックスが足りていないと判断できます。

<= bdb_equality_candidates: (uid) not indexed

この場合はuidをインデックス設定すると、検索速度が速くなります。
3日分ほどのログを確認し、同様のログが出ていないか確認します。

###よく使うLDAPフィルタ条件
これは運用によりけりなのですが、検索時に多用する属性がある場合その属性もインデックス指定してあげたほうがより速度が向上します。

例えば、以下のようなフィルタで日次処理を行っていたりする場合は
対象の属性はインデックス指定したほうがよいです。

(&(uid=*)(xxxFlag=1))



#設定方法
###slapd.confの編集

先の例のように、indexディレクティブで追加したい属性と種類を記述します。

~~~slapd.conf
～
index uid eq,pres,sub
index uidNumber pres
～
~~~

###slapindexコマンドの実施
まずldapのサービスを止めます。

~~~
systemctl stop slapd
~~~

slapindexコマンドを実行します。

~~~
slapindex
~~~

すると、以下のようなエラーが出るかと思います。

~~~
WARNING!
Runnig as root!
There's a fair chance slapd will fail to start.
Check file permissions!
~~~

このコマンドを実行した際に、root権限でインデックスが作られます。
基本的にOpenLDAPで使用するDBの所有権はldapで動かす必要があるので
/var/lib/ldap　配下の所有権をldapに変更する必要があります。

~~~
chown -R ldap. /var/lib/ldap/*
~~~

サービスを起動します。

~~~
systemctl start slapd
~~~


念のため、数日間ログをチェックしてインデックスエラーが出ていないかチェックしておくと尚いいです。
luigiでmssqlserverに接続

luigi使ってみたのでメモ

```python

import luigi
import luigi.contrib.mssqldb as ms

class YourTask1(luigi.Task):

    def run(self):
        # output() メソッドで保存先の Target を取得する
        out = self.output()
        # ファイルを開く
        out.touch()


    def output(self):
        return ms.MSSqlTarget("yourserver.database.windows.net","dbname","username@yourserver","password","tablename","updateid")

if __name__ == "__main__":
    luigi.run(main_task_cls=YourTask1)
```

走らせるとき

```shell
python3 luigitest.py --local-scheduler
```
tablesorter.jsに表を動的に切り替えた場合でもソート機能を適応させる

テーブルにソート機能を簡単につけれるtablesorter.jsですが、動的に表を変更した場合正しく動きません。
そもそも、これの仕様が `テーブルのDOMが読み込まれる -> tablesoreterをテーブルに適応` の順番なので表が切り替わったところでソート機能は前の表を参照し続けています。

tableが変更された場合、テーブルのDOM全て削除して再度描画 -> tablesorter適応の順番を取っていたのですがとにかく重い。表を操作するボタンを連打されたら画面が固まりました。
どうにかできないかな～と公式リファレンスを見ていたら。。。

```javascript

$("#table").trigger("update");
```

これでいけるらしいです。マジか。表の変更処理後にこれを実行させるだけでOKですね。
公式リファレンスは読みましょう（戒め）
pymssqlをインストール

pymssqlのインストールがめんどくさかったのでメモ


# step1 pymsssqlのインストール

https://docs.microsoft.com/ja-jp/sql/connect/python/pymssql/step-1-configure-development-environment-for-pymssql-python-development?view=sql-server-2017

```shell

> sudo apt-get --assume-yes update  
> sudo apt-get --assume-yes install freetds-dev freetds-bin  
> sudo apt-get --assume-yes install python-dev python-pip  
> sudo pip install pymssql
```

# step2 sqlserverに接続


https://docs.microsoft.com/ja-jp/sql/connect/python/pymssql/step-3-proof-of-concept-connecting-to-sql-using-pymssql?view=sql-server-2017


```
import pymssql  
conn = pymssql.connect(server='yourserver.database.windows.net', user='yourusername@yourserver', password='yourpassword', database='AdventureWorks')
```
ハッシュ〜Udemy~

#ハッシュ：連想配列　　（複数のオブジェクトをまとめて扱う）


***・ハッシュは複数のオブジェクトを一つのカタマリとして扱う***

***・＃{キー　＝＞　値} がセットのなっている　　通常の配列と異なるのは、番号ではなくて、キー（名前）で値を参照する***

***・＃Hashクラスのオブジェクト***


例文で見ると

```
books = {                                               ➡️booksというハッシュを宣言している、＝の後に{とし、
           “Python入門” => 800,               
           “Ruby入門” => 700,                    キー＝＞値
           “C++入門”=>600
}


puts books[“C++入門”]　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　出力するときはputs

＞＞600という風に出力される
```


#eachメソッド

.each do・・・でまとめてハッシュのなかに格納されているデータを表示していきます。そのためには```.each doの後に　｜｜```：ブロックパラメーターを用いる


**例文**

```
books.each do |key,val|     ➡️eachメソッドでブロックパラメーター内のデータを処理

Puts  “#{key},#{val}円”                      ➡️#{}式展開: 値を展開してから表示する

end                      ➡️ブロック　endで閉じる

Keyと値がセットで表示される
```
chatwork API の使い方 (Ruby)

chatwork へのメッセージの書き込みと、読み取りです。

書き込み
APIトークン と room_id は書き換えて下さい。

```rb:send_message.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	send_message.rb
#
#					Nov/22/2018
#
# ---------------------------------------------------------------------
require 'faraday'
require 'json'
#
# ---------------------------------------------------------------------
STDERR.puts	"*** 開始 ***"
#
URL="https://api.chatwork.com/v2/rooms/11111178/messages"
#
#args = {}
message = "今は、午後３時半です。\n"
message += "日が差してきました。\n"
con = Faraday.new 
res = con.post do |req|
	req.url URL
	req.headers['X-ChatWorkToken'] = 'e12321ef233d8a92deb1cc15bc09b79e'
	req.body = {
    :body => message
  }
#	req.body = JSON.pretty_generate(args)
end

puts	res
puts	res.status
puts	res.body

json_str = res.body

dict_data=JSON.parse(json_str)
#
#puts	"Host:\t" + dict_data['headers']['Host']
#puts	"origin:\t" + dict_data['origin']
#puts	"url:\t" + dict_data['url']
#
STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```

読み込み

```ruby:get_message.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	get_message.rb
#
#					Nov/22/2018
#
# ---------------------------------------------------------------------
require 'faraday'
require 'json'
#
# ---------------------------------------------------------------------
STDERR.puts	"*** 開始 ***"
#
URL="https://api.chatwork.com/v2/rooms/11111178/messages?force=1"
#
con = Faraday.new
res = con.get do |req|
	req.url URL
	req.headers['X-ChatWorkToken'] = 'e12321ef233d8a92deb1cc15bc09b79e'
end
#

STDERR.puts	res.status

puts	res.body

json_str = res.body

dict_data=JSON.parse(json_str)
#
#puts	"Host:\t" + dict_data['headers']['Host']
#puts	"origin:\t" + dict_data['origin']
#puts	"url:\t" + dict_data['url']
#
STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```

メッセージの削除

```rb:delete_message.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	delete_message.rb
#
#					Nov/22/2018
#
# ---------------------------------------------------------------------
require 'faraday'
require 'json'
#
# ---------------------------------------------------------------------
STDERR.puts	"*** 開始 ***"
#
MESSAGE_ID = "1117341951608324096"
URL="https://api.chatwork.com/v2/rooms/11111178/messages/" + MESSAGE_ID
#
con = Faraday.new
res = con.delete do |req|
	req.url URL
	req.headers['X-ChatWorkToken'] = 'e12321ef233d8a92deb1cc15bc09b79e'
end
#

STDERR.puts	res.status

puts	res.body

json_str = res.body
#
#
STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```
繰り返し処理　ブロック〜Udemy〜

#繰り返し処理

**・Rubyで特徴的なのはブロックという、”処理のカタマリ”を渡すことができる仕組みがある**

---

#ブロック
```
・[式] do |I|        # Iはブロックパラメーター
　　     処理
   end
```

>ある式があって、一つづつパラメーターを追加しながら処理をしていく
例えば１〜２０までの数を表示するとか、もしくは２０からカウントダウンして、0まで表示する。
２づつ減らして表示するなどの、***繰り返し処理をブロックとして記述するなどの方法がある***


**・２番目によく使うとされるのが、**

```
Until f.eof       ➡️ end of fileの略：ファイルの終端
   Print f.gets   ➡️getsメソッド　ファイルから一行ぶんデータを読み込む
end
```
>ファイルの読み込み処理
データサイエンス・統計処理などでよく使用する
比較演算子〜Udemy〜



#比較演算子

```
==        等しい

===      等しいcase文で使われる

!=         等しくない

>         より大きい

>=       等しいか、より大きい

<        より小さい

<=       等しいか、より小さい

<=>    左＞右（-1)  等しい（０）大きい（1)

=~     パターンマッチ（正規表現）一致

!~      パターンマッチ（正規表現）一致しない
localhostにHTMLバリデーションを行うパッケージを作ってみました

# 作ったもの
**validate-localhost**

- [npm](https://www.npmjs.com/package/validate-localhost)
- [github](https://github.com/nkzttt/validate-localhost#readme)

## 使い方

```bash
validate-localhost --port=8000 --path=/any/path
```

```bash:エラー表示例
ERR! error at line 9: Element “div” not allowed as child of element “span” in this context. (Suppressing further errors from this subtree.) 
ERR! error at line 11: Element “style” not allowed as child of element “body” in this context. (Suppressing further errors from this subtree.) 
```

他オプションだったり、デフォルト値等はnpm / githubに書いています。

# なんで作った？

職場ではFreeMarkerというjavaのテンプレートエンジンを使っていて、ローカルで動かしているんですが、こいつにHTMLバリデーションをかけたいって思ったのがキッカケです。  
軽く調べて同じものはさなそうだったのと、初パッケージ公開もしてみたくて作りました。  

# どうやってる？

W3Cの[Nu Html Checker](https://validator.w3.org/nu/)を使っています。  
こちらは[API](https://validator.w3.org/docs/api.html)が公開されているのと、それを使ってうまいことやってくれてそうな[パッケージ](https://github.com/zrrrzzt/html-validator)を見つけたので利用させていただきました。  

やっていることは単純で  

1. 指定されたポート（default: 3000）とパス（default: /）にアクセスしてHTMLを取得
2. APIでHTMLを投げて結果を取得
3. エラーの有無でログを出し分け

をやっているだけです。（何も怪しいことはしてません）  

# よかったら使ってね

**少しでも楽にローカルのHTMLにバリデーションをかけたいんじゃー！**  
という方は使ってやってくれると嬉しいです。  
不具合や要望があればissueでもプルリクでもお気軽にお願いします。
python で GPXファイルのデータ変換(time補間)

#目的
GPXファイル(trk:トラックポイント)の時間データを変換する
　- timeに無効値が入り、Google Earth Proがフリーズする場合があるので補間した
　- 無効値例：2000-00-00T00:00:00Z (gpxgyでパースすると Noneになる)

環境：
 * Windows10 Home 64bit
 * Anaconda3-5.2.0-Windows-x86_64 / Python 3.6 version
 * gpxpy 1.3.4

## 【準備】gpxpyインストール
**1. Anaconda Navigator上で [Environments]→[base(root)] →[Open Terminal]**

**2. インストール**
　　`pip install gpxpy`
　　　→"distributed 1.21.8 requires msgpack, which is not installed."と警告がでるのでmsgpackも
　　`pip install msgpack`

## 【プログラム例】

変換前ファイル(sample_timeloss.gpx)にtime補正をして、変換後ファイル(sample_timefix.gpx)に出力する

```python
import gpxpy
import gpxpy.gpx
from datetime import datetime, timedelta

gpx_file_r = open('sample_timeloss.gpx', 'r')
gpx_file_w = open('sample_timefix.gpx', 'w')

# Parsing an gpx file():
gpx = gpxpy.parse(gpx_file_r)

time_set = datetime(2018,1,1,0,0)   # (1)initial date
gps_delta = timedelta(seconds=1)    # (2)gps period: 1s

for track in gpx.tracks:
    for segment in track.segments:
        for point in segment.points:
            if point.time == None:               # (3) invalid time
                time_set = time_set + gps_delta
                point.time = time_set
            else:                                # (4) valid time
                  time_set = point.time  
#            print('Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.time))

gpx_file_w.write(gpx.to_xml())
gpx_file_r.close()
gpx_file_w.close()
```

(1) GPXファイルの先頭でtimeが無効値がだった場合の初期値
(2) ここではtrkpt間隔は1s
(3) timeが無効値(None)の場合は、time_setをtrkpt間隔分更新した値を設定
(4) 有効値はtime_setに保持する。無効値の変換用


## 【変換例】
左(変換前)→右(変換後)のようにtime無効値を補間できた
![result.PNG](https://qiita-image-store.s3.amazonaws.com/0/298713/c49a6e61-b2e6-a282-8743-cdc075875cea.png)
★　Google Earth Proもフリーズしなくなった


## 【参考文献】
【1】https://qiita.com/key/items/20f903a5ac66b6f09782
【2】Pythonではじめるデータラングリング ―データの入手、準備、分析、プレゼンテーション (Jacqueline Kazil) 
【3】https://pypi.org/project/gpxpy/
【4】https://docs.python.jp/2/library/datetime.html
配列〜Udemy〜

#配列

###配列って。。。

>・複数の要素を持つ変数。

>・Arrayクラスのオブジェクト。

>・配列の要素もオブジェクト。

>・配列名[要素番号]


###配列の生成のしかた

>・[“beef”,”pork”,”chicken”]

>・%w(beef pork chicken)       ➡️%W・・・配列名に、当てはめていくやり方例えば、
　flowers = %w(lib rose tulip)とすると、、[“lily”,”rose”,”tulip”]となる




>・データの追加・・・・・配列名＜＜加えたい値



番号で代入もできる

```
flowers[3] = “tsubaki”           ３を椿とする
>>”tsubaki”
puts flowers
Lily
Rose
Tulip
tsubaki
```

----
**配列を確かめる動き**

オブジェクト.empty?・・・配列は空ですか？
返り値・・・nil
                   false
                   true

---
DockerHubから取得したイメージを更新する。

開発お試し用のローカルマシン（mac）では[DockerHub](https://hub.docker.com)の公式イメージの[mongo](https://hub.docker.com/_/mongo/)を使っていたんですが、最新バージョンが4.0.3から4.0.4になってました。

## おりゃ！

```sh
sh-3.2$ docker-compose build
mongo uses an image, skipping
mongo-express uses an image, skipping
```

あれ？

## おりゃ！おりゃ！

```sh
sh-3.2$ docker-compose build --no-cache
mongo uses an image, skipping
mongo-express uses an image, skipping
```

あらま？

## これでした！

```sh
sh-3.2$ docker-compose pull
Pulling mongo         ... done
Pulling mongo-express ... done
```

ダウンロードし直しました、一応イメージのバージョンも確認します。

```sh
sh-3.2$ docker inspect mongo | grep MONGO_VERSION
                "MONGO_VERSION=4.0.4"
                "MONGO_VERSION=4.0.4"
```

あとは```docker-compose up -d```で無事更新できました。
Ruby の http クライアントの使い方 (Post)

faraday というライブラリーを使います。

## プログラム

```rb:http_post.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	http_post.rb
#
#					Nov/22/2018
#
# ---------------------------------------------------------------------
require 'faraday'
require 'json'
#
# ---------------------------------------------------------------------
STDERR.puts	"*** 開始 ***"
#
URL="https://httpbin.org/post"
#
args = {}
args['user'] = 'jiro'
args['password'] = '123456'
#res = Faraday.post URL
con = Faraday.new 
res = con.post do |req|
	req.url URL
	req.headers['Content-Type'] = 'application/json'
	req.body = JSON.pretty_generate(args)
end

# puts	res
puts	res.status
# puts	res.body

json_str = res.body

dict_data=JSON.parse(json_str)
#
puts	"Host:\t" + dict_data['headers']['Host']
puts	"origin:\t" + dict_data['origin']
puts	"url:\t" + dict_data['url']
#
STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```

## 実行結果

```text
$ ./http_post.rb 
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
*** 開始 ***
200
Host:	httpbin.org
origin:	219.126.135.100
url:	https://httpbin.org/post
*** 終了 ***
```

## 確認したバージョン

```text
$ ruby --version
ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [x86_64-linux]

$ pacman -Q ruby-faraday
ruby-faraday 1.8.0-1
```