OmniAICreator/Qiita-1.07M huggingface dataset:
Haskell入門ハンズオン! #3: 当日用資料 4/5

Haskell入門ハンズオン! #3: 当日用資料 4/5
====================================

はじめに
------

Haskell入門ハンズオン! #3

* 当日用資料 1/5
* 当日用資料 2/5
* 当日用資料 3/5
* (あとで上記3つをリンクにする)

とみてきた。パーサコンビネータとしての道具はそろった。これで四則演算の式を解析できる。

演算子のパース
-----------

はじめに演算子をパースする。演算子をあらわす型シノニムを定義する。

```hs:calc.hs
type Op = Integer -> Integer -> Integer
```

ここでの「演算子」は、「ふたつの整数を引数として、整数をかえす関数」だ。それぞれの演算子用のパーサを定義する。

```hs:calc.hs
ad, sb, ml, dv :: Parse Op
ad = char '+' `build` const (+)
sb = char '-' `build` const (-)
ml = char '*' `build` const (*)
dv = char '/' `build` const div
```

それぞれの記号をパースして、それぞれの演算を結果とするパーサだ。四則演算の演算子は、これら4つの演算子の「どれか」なので

```hs:calc.hs
op :: Parse Op
op = ad `alt` sb `alt` ml `alt` dv
```

対話環境で試してみる。

```hs
*Main> :reload
*Main> fromJust (parse op "+") 9 4
13
*Main> fromJust (parse op "*") 9 4
36
```

関数parseによって得られる関はJust値なので、関数fromJustでなかみの「演算子」を取り出している。取り出された「演算子」(これは関数なので)を数値9, 4に適用した。

式と項
-----

「式」は、ふたつの「項」を演算子でつないだものだ。「項」は、「数」または、「式」を丸括弧でかこったものだ。このように、たがいにたがいの定義に使われているとき「相互再帰の関係にある」という。たとえば「式」の例として、つぎのようなものがある。

    13+5, (12*3)+17, (30-5)/(20*4), ((41/2)+3)*5

「項」の例は、つぎのようになる。

    19, (25+4), ((11*3)/(25-3)), (((315*8)+31)*7)

### 式のパース

式のパーサを定義する。

```hs:calc.hs
expr :: Parse Integer
expr = (term >@> op >@> term) `build` \((x, o), y) -> x `o` y
```

パーサtermは、あとで定義する。\((x, o), y) -> x `o` yは関数リテラルだ。引数をパターン((x, o), y)にマッチさせる。ここで、変数xとyにはパーサtermの結果としての「項」の値がはいる。変数oにはパーサopの結果として、演算がはいる。全体の結果としての「x `o` y」は演算の結果になる。

### 項のパース

項のパーサを定義する。

```hs:calc.hs
term :: Parse Integer
term = number `alt` (char '(' @> expr >@ char ')')
```

「項」の定義は、つぎのようになる。

    「数」または、「式」を丸括弧でかこったもの

パーサtermの定義は、「項」の定義を「そのまま」書けばいい。

できあがり
--------

対話環境で試してみる。

```hs
*Main> :reload
*Main> parse expr "3*(5-2)"
9
```

より使いやすいように関数calcを定義する。

```hs:calc.hs
calc :: String -> Maybe Integer
calc = parse expr
```

対話環境で試す。

```hs
*Main> :reload
*Main> calc "3*(5-2)"
9
*Main> calc "(43+24)/(21-16)"
13
```

ほかの例でも試してみよう。ただし、

* 空白をいれてはならない
* 丸括弧は省略できない(余計な丸括弧もいれられない)

というところに注意する。

[当日用資料 5/5へ](https://qiita.com/YoshikuniJujo/items/2d2b28598f6dbb45b44a)
初めての Docker 30分チュートリアル：Dockerfile で Image を build まで

## 本記事の想定オーディエンスとゴール
初めて Docker を使う人．最小限の学習コストで Dockerfile による Image 作成までをハンズオンしたい人．
1. インストール
2. Hello World
3. commit コマンドで新 Image 作成
4. Dockerfile を使用し build コマンドで新 Image 作成

#### 環境
VirtualBox 5.1.28
CentOS-7-x86_64-Minimal-1611
Docker version 1.12.6

#### Docker とは
- コンテナ型の仮想化環境を提供するオープンソースソフトウェア．Docker 社提供．
- 完全仮想化を行うハイパーバイザ型製品（VMwareなど）と比べて，ディスク使用量は少なく，仮想環境 (インスタンス) 作成や起動が早い．

#### 基本用語
**Docker Image** ~ アプリケーションとその実行環境，ファイルシステムや設定をまとめて1つのパッケージにしたもの．公式に配布されているものがあり，自作もできる．
**Docker Container** ~ Docker Image を起動し，その内部でアプリケーションが稼働している状態．
**Dockerfile** ~ 特定の Image を作成するスクリプト．
**Docker Registry** ~ Image を共有するためのサーバソフトウェア（**Repository** は Registry 内のカテゴリ）
**Docker Hub** ~ Docker 社公式 Registry.

# 1. Docker インストール
（コマンドはすべて root ユーザにて実施することとします）

```
# yum install docker
# systemctl start docker
# systemctl enable docker
```
#### 基本コマンド(1)
**# docker images** ~ ローカル Repositry に保存されている Image の一覧
**# docker run \<Image 名\>** ~ 指定 Image を起動
**# docker ps** ~ 起動中 Container 一覧
**# docker ps -a** ~ 停止中も含めた全 Container 一覧
# 2. Hello World
```
# docker run hello-world
```
run は Image を起動するコマンド．
"hello-world" Image を探し，ローカル Repository になければ，Docker Hub（公式 Registry）から pull し，Container を起動する．
Container は "Hello from Docker!" 他のメッセージを出力し終了．

```
# docker images   # ローカル Repository に hello-world Image が追加されたことを確認．
# docker ps -a    # 停止済みの hello-world の Container があることを確認
# docker ps       # 停止済みの hello-world の Container が表示されないことを確認
```
#### 基本コマンド(2)
**# docker pull \<Image 名\>** ~ Registry から Image をダウンロード
**# docker commit \<Container 名/ID\>** ~ 操作した Container を新 Image として作成
# 3. CentOS Image を pull -> yum update -> 新 Image として作成
```
# docker pull centos:centos7   # Docker Hub からダウンロード
# docker run -it --name centos7-01 centos:centos7 bash
```
-it オプションで bash 実行，プロンプト表示．--name オプションは Container 名を指定．

```:bash
# yum -y update
# exit
```
```
# docker ps -a    # 停止済みの centos7-01 の Container があることを確認
# docker commit centos7-01 tanishi/yum-update   # tanishi/yum-update の Repository に新 Image を作成
# docker images   # ローカル Repository に tanishi/yum-update が追加されたことを確認．
```
### 基本コマンド(3)
**# docker build -t \<新 Image 名\> { Dockerfile のあるディレクトリ }** ~ Dockerfile で新 Image を作成
# 4. Dockerfile で ruby インストール済みの新 Image を作成
任意のディレクトリ（今回は /var/tmp/ ）に Dockerfile という名のファイルを作成．

```
# cd /var/tmp/
# vi Dockerfile
```
以下を記述．

```:Dockerfile
FROM tanishi/yum-update # 元の Image
RUN yum -y install ruby
```
```
# docker build -t tanishi/ruby /var/tmp/
```
確認．

```
# docker images   # ローカル Repository に tanishi/ruby が追加されたことを確認
# docker run -it --name ruby-01 tanishi/ruby:latest bash
```
```:bash
# irb
irb > p "Hello Ruby!"
"Hello Ruby!"
=> "Hello Ruby!"
irb > exit
# exit
```
#### 基本コマンド(4)
**# docker rmi \<Image 名/ID\>** ~ 指定 Image 削除
**# docker rm \<Container 名/ID\>** ~ 指定 Container 削除
**# docker rm \`docker ps -a -q\`** ~ 停止中も含めた全 Container 一括削除
####後片付け
全コンテナ削除．

```
# docker rm `docker ps -a -q`
```
【React Native】Googleログインで使用してるGoogleアプリ切り替え時にする管理画面の操作とソース変更箇所 for iOS

## やりたいこと
iOSのGoogleログイ認証を使用しています。
Googleの管理画面で別のアプリ(スマホアプリではなく、Google管理画面上のアプリ)に
向き先を変更したいです。

## 前提
すでにGoogleログインの実装が完了している前提のため、
Googleログインを導入する方法は記載していません。

## 管理画面
https://console.cloud.google.com
　→CLIENT_IDなどを取得
https://developers.google.com/mobile/add?platform=ios
　→「GoogleService-Info.plist」取得

## 変更箇所
### 管理画面
パッケージ名：バンドルID

## xcode
infoのschemeにGoogleService-Info.plistにある、REVERSED_CLIENT_IDを利用

![url-config.png](https://qiita-image-store.s3.amazonaws.com/0/170662/872a14ba-bce1-e74f-f2ee-b5cd3ce69ddc.png)

### GoogleService-Info.plist変更
パス：ios/GoogleService-Info.plist

### GoogleSignin.configure
jsソースで、Googleログインを使用する画面で下記の関数を呼ぶ必要がある。
GoogleSignin.configure

https://console.cloud.google.com
で確認できる値を入れる。
WEB_CLINENT_ID：webのクライアント ID
IOS_CLINENT_ID：iOSのクライアント ID

＞例

```
GoogleSignin.configure({
  iosClientId: <WEB_CLINENT_ID：web>, // only for iOS
  webClientId: <IOS_CLINENT_ID：iOS>, // client ID of type WEB for your server (needed to verify user ID and offline access)
})
.then(() => {
  // you can now call currentUserAsync()
});

```
DockerでLAMP環境を作るときにハマったこと

# `docker-compose`で動くLAMP環境を作った。
https://github.com/uutarou10/lamp-docker-compose

作りました。中身は

- PHP 7.2.3
- MySQL 8.0
- phpMyAdmin

という構成。

わかってみれば大したことではないのだが結構ハマって時間を溶かしてしまったので何かのお役に立てばということで書いておく。

LAMP使いたいだけなら↑のリポジトリcloneしてきて云々する方が早い。

## `Authentication plugin 'caching_sha2_password' cannot be loaded`と言われる
MySQLを立ち上げて、mysqlコマンドなりphpMyAdminなりで接続しに行くと`Authentication plugin 'caching_sha2_password' cannot be loaded`と言われてしまう。

当然認証情報は合ってるはず。

これは、MySQLの8からデフォルトの認証方式が、caching_sha2_passwordというものに変わったことに起因するようで、デフォルトを従来のmysql_native_passwordにするようにconfigに書いておくことで、従来のアプリケーションからでも利用できる。

MySQL公式のDockerイメージでは、`/etc/mysql/conf.d/`以下にある`.cnf`という拡張子のファイルを読み込んでくれるようになっているので私は以下のようなDockerfileと設定を書いてDockerイメージを作成した。

```change_default_auth.cnf
[mysqld]
default_authentication_plugin= mysql_native_password
```

```dockerfile
FROM mysql:8

ADD ./change_default_auth.cnf /etc/mysql/conf.d/.

CMD ["mysqld"]
```

当然、volumeでコンテナの`/etc/mysql/conf.d`をホストに持ってきてそこに設定ファイルを置くのでも構わないが、コンテナを起動するよりも前においておく必要がある。(コンテナを起動した時にユーザーが作成されるため)

## PDOでMySQL使えない
続いてPDOでMySQLが使えない問題。

PHPのDockerイメージは軽くするために、最低限のものしか入っていないそうで、PDOのMySQLドライバーも標準では入っていない。

そこで、これも公式のPHPのイメージをベースにした以下のようなDockerfileを書いて解決した。

```dockerfile
FROM php:7.2.3-apache

RUN apt update &&\
    docker-php-ext-install pdo_mysql &&\
    echo 'date.timezone = Asia/Tokyo' >> /usr/local/etc/php/conf.d/99_myconf.ini

CMD ["apache2-foreground"]
```

拡張をインストールするためのUtilがDockerイメージに含まれているのでそれを使う(RUNの2行目`docker-php-ext-install`がそれ)

ついでにタイムゾーンも合わせておく。
HangoutsChatにPHPから投稿してみる

HangoutsChatが使えるようになっていたので、Webhookをサクッと試してみました。

## 前提条件
```shell:terminal
% sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.2
BuildVersion:	18C54

% brew --version
Homebrew 1.8.6
Homebrew/homebrew-core (git revision 91f9; last commit 2019-01-08)
Homebrew/homebrew-cask (git revision 366f9; last commit 2019-01-07)

% php -v
PHP 7.3.0 (cli) (built: Jan  3 2019 10:08:00) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.0-dev, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.0, Copyright (c) 1999-2018, by Zend Technologies
```

## Webhookの準備
[チャットルームの名前] → [Webhookを設定]
<img src="https://qiita-image-store.s3.amazonaws.com/0/133646/4b47b08f-6f67-06cc-ef31-af6f4227708d.png" width="40%">
[Webhookを追加]をクリックして、名前とアイコン画像を適当に設定して[保存]をクリック
出来上がったWebhookのURLをとっておく

## ソースの準備
```php:chat.php
<?php
// WebhookのURL
$url = 'https://chat.googleapis.com/v1/spaces/...';
// 送りたいメッセージ
$message = 'めっせーじ';

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => json_encode(['text' => $message], JSON_UNESCAPED_UNICODE),
    CURLOPT_HTTPHEADER => ['Content-Type: application/json']
]);

$response = curl_exec($curl);
var_dump($response);
curl_close($curl);
```

## 実行
コマンドラインから実行します。

```sh:terminal
% php chat.php
```

## 参考文献
https://dev.classmethod.jp/cloud/aws/google-hangouts-chat-integration-with-aws-lambda/
JNAでC++に渡した文字列が文字化けしてしまう場合

# 事例
JavaのString型をJNAでC++に渡す場合にChar*型で受け取りstd:string型に代入して扱うと文字化けしてしまう

## 文字コードの問題
どうやらJavaでは**UTF-16**が使われているみたいで、今回の自分のC++の環境では**Shift-JIS**が必要な環境だったみたいです。

> C++では環境によってそれぞれの型で扱える文字コードが変わってくるみたいです。
> @yumetodoさんありがとうございました。

おそらくその変換がうまくいっておらず、エラーになってしまったのではないかと推測してます。

## 解決策
> ここの方のコードを一部引用させていただいております。
> http://nekko1119.hatenablog.com/entry/2017/01/02/054629

```c++:use.cpp
#include <iostream>
#include <string>
#include <codecvt>
#include <cassert>
#include <locale>

void useString(char* str){
  std:string strUtf;
  strUtf = str;
  /* uft-8からshift-JISに変換 */
  strShiftJis = utf8_to_multi_cppapi(strUtf);
  /*こっから先は好きにしてください*/
}

std::string utf8_to_multi_cppapi(std::string const& src)
{
  auto const wide = utf8_to_wide_cppapi(src);
  return wide_to_multi_capi(wide);
}

std::string wide_to_multi_capi(std::wstring const& src)
{
  std::size_t converted{};
  std::vector<char> dest(src.size() * sizeof(wchar_t) + 1, '\0');
  if (::_wcstombs_s_l(&converted, dest.data(), dest.size(), src.data(), _TRUNCATE, ::_create_locale(LC_ALL, "jpn")) != 0) {
    throw std::system_error{ errno, std::system_category() };
  }
  return std::string(dest.begin(), dest.end());
}

std::wstring utf8_to_wide_cppapi(std::string const& src)
{
  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
  return converter.from_bytes(src);
}
```

## 結論
文字コードのこと勉強できてよかった。


### 参考文献
http://marupeke296.com/CPP_charUnicodeWideChar.html
http://nekko1119.hatenablog.com/entry/2017/01/02/054629
https://cpprefjp.github.io/reference/codecvt/codecvt_utf8_utf16.html
https://theolizer.com/cpp-school1/cpp-school1-18/
タブレット利用アプリのIE対応におけるリスク


**タブレット利用アプリ**の開発において、**IE対応**をした際に生じたトラブルを3つ紹介します。

# IE対応で発生したトラブル

## ①360°画像が回転しない
### 内容
タッチ操作で360°画像が回転しない(PCでマウス使用すると回転する)
### 解決方法
MSプレミアサポートに問い合わせ、IE のタッチ操作に対応するコンテンツを作成


## ②選択候補値上でスクロールできない
### 内容
候補値を選択する際、候補値ではなく候補値横の細いスクロールバーをタッチして操作しなければならない(PCでは問題なし)
### 解決方法
MSプレミアサポートに問い合わせ、レジストリの設定を変更


## ③モーダル部で操作すると変な線が出現する
### 内容
モーダル部でタッチ操作すると変な線が表示される
### 解決方法
モーダルをやめて別画面化
### 理由
* バグ修正を実施するよりも別画面を作成する方が**工数**がかからないこと
* 別画面化しても**ロード時間**が短いこと

# まとめ
タブレット利用アプリ開発のIE対応において**タッチ操作**と**モーダル**にはリスクあり！

### 付録
https://anond.hatelabo.jp/20180308013517
UnitTestで自作構造体を比較したい

みなさんtestしてますか？

わたしはもちろんできてません:expressionless:
しようとは思っているのですが状態です。
そこで、とりあえず始めてみたらtestを書く習慣がつくのではないかと思い始めました。

そこで、詰まったのが**自作構造体の比較**です

XCTestには、`XCTAssertEqual`というメソッドあります。
このメソッドは、`Equatable`に準拠しているものを比べて、同じならテスト成功。違うとテスト失敗にしてくれます。

# 文字列の場合
```MyTests.swift
func testString() {
	let expected = "foo"
	let actual = "foo"
	XCTAssertEqual(expected, actual)
}
```

成功しましたね:relaxed:
String型はEquatableに準拠しているんですね！

# 自作構造体の場合
```user.swift
struct User {
	let name: String
	let age: Int
}
```
自作構造体を作りました！
このUserを比較したい時がきっとあるはず！

```MyTests.swift
func testUser() {
	let expected = User(name: "foo", age: 10)
	let actual = User(name: "foo", age: 10)
	XCTAssertEqual(expected, actual)
}
```
比較したいのならば、Equatableに準拠しなさいと言われます。
なので、Equatableに準拠させます

```user.swift
extension User: Equatable {
	static func ==(lhs: User, rhs: User) -> Bool {
		return lhs.name == rhs.name && lhs.age == rhs.age
	}
}
```
そうすると、`testUser()`メソッドがテストでき、成功になりました！（やったね）

# まとめ
自作構造体でも`Equatable`に準拠させることで比較することができま...したが、自作構造体をプロジェクトで使うときも`Equatable`が使えてしまいます。
そこで、テストの時だけ、自作構造体を`Equatable`に準拠させたいと思います。

# 自作構造体の比較（テストの時だけ）
```user.swift
struct User {
	let name: String
	let age: Int
}
```
まずは、自作構造体を作ります
そして、テスト書きます

```MyTests.swift
func testUser() {
	let expected = User(name: "foo", age: 10)
	let actual = User(name: "foo", age: 10)
	XCTAssertEqual(expected, actual)
}
```

そして、自作構造体を`Equatable`に準拠させるのですが、`user.swift`ではなく`MyTests.swift`に書きます

```MyTests.swift
class MyTests: XCTestCase {
    func testUser() {
		let expected = User(name: "foo", age: 10)
		let actual = User(name: "foo", age: 10)
		XCTAssertEqual(expected, actual)
    }	
}

extension User: Equatable {
	static func ==(lhs: User, rhs: User) -> Bool {
		return lhs.name == rhs.name && lhs.age == rhs.age
	}
}
```
このようになり、`XCTAssertEqual`で自作構造体が使えるようになりました。
ここに`Equatable`の準拠を書くことで、プロジェクト側は自作構造体が`Equatable`に準拠してない状態で使えます
試しにプロジェクト側で`Equatable`を使ってみます。

```ViewController.swift
class ViewController: UIViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
		
		let user = User(name: "foo", age: 10)
		let user2 = User(name: "foo", age: 10)
		
		if user == user2 { //Binary operator '==' cannot be applied to two 'User' operands
			print("ok")
		}
	}
}
```
自作構造体の比較をしているところで、`Binary operator '==' cannot be applied to two 'User' operands`というエラーがでます。
つまり、**テストでは使えるのに、プロジェクトでは使えない**という目的を果たしました:clap:

# 真・まとめ
テストだけで、比較がしたかったり、なにかしたい場合があった時に、テストの方にextensionで拡張をすると、プロジェクトの方には反映されないことがわかりました。
これでみなさんのテストが捗ることを祈っております。
SQLServerのトリガーでOracleのBeforeを疑似的に再現する

##概要
以下記事の補足というか、タイトル部分で痛い目を見たので専用記事。
https://qiita.com/so_nkbys/items/67f5be1049ab09618aca

そのまんま、ORACLEのトリガー属性"Before"をSQLServerで実装した際のメモ。

##環境
以下の環境とする。

テーブル名:table1
カラム内容

|名称|型|その他|
|:-:|:-:|:-:|
|ID|int|PK|
|Name|Varchar(50)|not null|
|tips|Varchar(50)||

##コード

```Create_Tg01_table1.sql
Create trigger tg01_table1 on table1 
instead of insert, update ,delete as
begin
	-- Table1PK変数群
	declare @ID int;

	-- カーソル
	declare oldRecords cursor for select ID from deleted;
	--declare newRecords cursor for select * from inserted;

	-- レコード削除フラグ
	declare @IsDelete bit;
	set @IsDelete = 0;

	-- レコード挿入フラグ
	declare @IsInsert bit;
	set @IsInsert = 0;

	-- トリガー処理必須実行フラグ
	-- 0:更新レコードがない場合は処理を行わない(ORACLEのトリガーと同じ動作)
	-- 1:更新レコードがなくてもトリガーの処理は行う
	declare @IsExecTrigger bit;
	set @IsExecTrigger = 0

	-- 処理区分判定
	if Exists(select * from deleted)
	begin 
		set @IsDelete = 1;
	end

	if Exists(select * from inserted)
	begin
		set @IsInsert = 1;	
	end
	
	-- 変更がない場合は終了
	if @IsDelete = 0 and @IsInsert = 0 and @IsExecTrigger = 0
		return;	

	-- この辺りでトリガーにてやりたいことを記述

	-- 変更がない場合は終了
	if @IsDelete = 0 and @IsInsert = 0
		return;	

	-- 実際行われるはずだった処理の実行(更新は削除→挿入で実行)
	-- 削除
	if @IsDelete = 1
	begin
		open oldRecords;

		while (1 = 1)
		begin
			Fetch next from oldRecords into @ID;

			-- Fetchが最終行の場合はループを抜ける
			if @@FETCH_STATUS <>0
				break;

			-- 削除実行
			delete from table1 where id = @ID;
		end

		-- 資源開放
		CLOSE oldRecords;
		DEALLOCATE oldRecords;
	end

	--挿入
	if @IsInsert = 1
		insert into table1 select * from inserted;

END


```

##動作確認コード

```Test.sql

delete table1;

insert into table1 (id, name, tips) values (100, '蓮巳 敬人', '生徒会副会長');
insert into table1 (id, name, tips) values (200, '来栖 真琴', 'OSIRIS BASE');
insert into table1 (id, name, tips) values (300, '赤ずきん', 'かわいい');
insert into table1 (id, name, tips) values (623, '鴫野睦', 'むつ１むつ２');

update table1 set Name = 'むつみさんは' , tips = 'すごくかわいい'
update table1 set tips = 'むつみさん' where id = 623;

delete table1 where id = 300;

insert into table1 (id, name, tips) values (101, '蓮巳 敬人2', '割とポンコツ');
insert into table1 (id, name, tips) values (201, '来栖 真琴2', 'やっぱりポンコツ');
insert into table1 (id, name, tips) values (301, '赤ずきん2', 'フードどこ行ったかわいい');
insert into table1 (id, name, tips) values (6233, '鴫野睦', 'むつ１むつ２');
select * from table1;

```

##結果
|ID|Name|Tips|
|:-:|:-:|:-:|
|100|むつみさんは|すごくかわいい|
|200|むつみさんは|すごくかわいい|
|101|蓮巳 敬人2|割とポンコツ|
|623|むつみさんは|むつみさん|
|201|来栖 真琴2|やっぱりポンコツ|
|301|赤ずきん2|フードどこ行ったかわいい|
|6233|鴫野睦|むつ１むつ２|

##所感
ORACLEでBeforeつけるだけなのにこんなに実装しなきゃいけないとかしんどい。

##なお(余談)
当初はnewについてもカーソルを開けてUpdate時はチェック…としようとしてたが全件比較しなきゃいけないことに気づき断念。
あと、更新情報の入るカーソル名の変数名を"newTable"にしてたら延々と処理実行時にエラーを吐かれた。
何かと思ったらこれ、予約語の模様。inserted使う場合はカーソル名に注意。
Azure Ubuntu14.04 ローカライズ(日本語化,タイムゾーン)

Azure　VMの『Ubuntu Server 14.04 LTS』イメージで作成後のローカライズ方法

## 日本語化

### Ubuntu Japanese Team の GPG 鍵とパッケージ レポジトリを追加
```shell-session
$ sudo wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
$ sudo wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
$ sudo wget https://www.ubuntulinux.jp/sources.list.d/wily.list -O /etc/apt/sources.list.d/ubuntu-ja.list
```

### アップデート、パッケージをアップグレード
```shell-session
$ sudo apt-get update
$ sudo apt-get upgrade -y
```

### インストール(日本語 Remix DVD に追加されているパッケージと同じもの)
```shell-session
$ sudo apt-get install -y ubuntu-defaults-ja
$ sudo reboot
```

### ログインしているユーザーの言語を日本語に設定
```shell-session
$ sudo update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
$ source /etc/default/locale
```

*確認コマンド

```shell-session
$ echo $LANG
```

## タイムゾーン

### タイムゾーンを 日本時間 (JST、”Tokyo”) に設定
```shell-session
$ sudo vi /etc/timezone
```

>変更前: Etc/UTC
>変更後: Asia/Tokyo

*確認コマンド

```shell-session
$ sudo dpkg-reconfigure --frontend noninteractive tzdata
```


## その他

### LXDE

日本語環境では文字化けするので日本語フォントを入れておきます。

```shell-session
$ sudo apt-get install fonts-noto-cjk fonts-noto-hinted
```

## 参考サイト

[Ubuntuの日本語環境](https://www.ubuntulinux.jp/japanese)

[Azure Virtual Machines 上にデプロイした Ubuntu Server 15.10 を日本語化、RDP 経由でアクセスする](https://kogelog.com/2016/03/05/20160305-01/?doing_wp_cron=1520583377.0546820163726806640625)
Raspberry Pi > C > RPi_i2c_comm_180227: v1.0 > センサーからのデータ読取まで | RPi以外への移植と動作

```txt:動作環境
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
gcc (Raspbian 4.9.2-10) 4.9.2
とあるI2Cセンサー
```

[Raspberry Pi > C > RPi_i2c_comm_180227: v0.4 > GPIOピンのレベル設定と、レベル読取まで](https://qiita.com/7of9/items/b925c943822deb7f9d01)
の続き。

とあるI2Cセンサーの読取まで実装できた。

### GitHubリポジトリ

[v1.0 @ GitHub](https://github.com/yasokada/RPi_i2c_comm_180227/releases/tag/v1.0)

### 処理概要

- GPIO19: SDA
- GPIO26: SCL

上記のピンとVCC, GNDピンを使用し、ソフトウェアI2Cでセンサーからのデータを取得する。

```RPi_i2c_comm_180227.c
...
int main(void)
{
    int slvAdr = 0x44; // Slave address
    char vals[10] = {0};
    int idx;

    //test_clockout_ioin();

    // 1. init
    i2c_Setup();

    // 2. start measurement
    // write header
    i2c_SendStartCondition(/* withInit=*/true);
    i2c_SendSlaveAddress(slvAdr, /*bfRead=*/false);
    if (i2c_IsACK()) {
        printf("ACK\n");
    };
    // send command
    i2c_SendData(0x2C); // 0x2C: arbitrary
    if (i2c_IsACK()) {
        printf("ACK\n");
    };
    i2c_SendData(0x06); // 0x06: arbitrary
    if (i2c_IsACK()) {
        printf("ACK\n");
    };
    i2c_SendStopCondition();

    // 3. wait for measurement
    Wait_millisecond(15); // 15: arbitrary

    // 4. obtain data
    // read header
    i2c_SendStartCondition(/* withInit=*/false);
    i2c_SendSlaveAddress(slvAdr, /*bfRead=*/true);
    if (i2c_IsACK()) {
        printf("ACK\n");
    };
    for(idx=0; idx<6; idx++) {
        vals[idx] = i2c_ReadData(/* isLast=*/(idx==5));
        printf("%d\n", vals[idx]);
    }
    i2c_SendStopCondition();

    // 5. finish
    i2c_Teardown();

    return 0;
}
```

### ソース構成

![](http://yuml.me/diagram/class/[RPi_i2c_comm_180227]->[i2_comm_180302], [i2_comm_180302]->[wait_msec_nsec_180301], [i2_comm_180302]->[i2c_gpio_180309], [i2c_gpio_180309]->[gpio_RPi_180309])

### RPi以外への移植

以下のようにすることで、RPi以外での実装が可能であった。

- i2c_gpio_180309以下を書替え
- wait_msec_nsec_180301以下を書替え
- RPi_i2c_comm_180227のmain()関数内の処理を実装する
- ファイル終端をCR+LFにする (Windowsの場合)

以下はRPi以外でのセンサーからの読込みの結果。
移植直後クロックの設定に失敗していたが、Analog Discovery 2で応答を確認しながらデバッグするとすぐに解決した。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/82bd1392-864d-54f0-9895-6265ddc85277.png)

DIO 11は使用してないピン。Analog Discovery2の警告メッセージがI2Cのラインの描画に重なるための対処。

これで、[RPiで動作確認] > [組込みで実装]の流れができあがった。 

### 備考

linux上で作ったソースをWindows上の組込み開発環境にて使おうとすると「終端コードが特殊です」のようなメッセージが表示される。

linuxではLFの終端で、WindowsではCR+LFの終端の違いに起因する。
リリース計画をたてよう

＊こちらはオプトテクノロジーズの社内勉強会資料になります

---

# 自己紹介

株式会社オプト　シニアエンジニア @sisisin

- [GitHub](https://github.com/sisisin)
- [Twitter](https://twitter.com/_sisisin)
- フロントエンドマン（Angular,AngularJS中心）
- Scalaも少々
- 最近はスクラムマスターやってます

---

# 突然ですが、計画立ててますか？

---

スプリントプランニング、事業計画、etc...
アジャイル開発の文脈でよく用いられる「リリース計画」というものを簡単に紹介しようと思います

---

### どんなもの？

開発チームの実力に照らし合わせて作成した、どの機能がどのぐらいの時期にリリースできそうかという計画

「プロジェクトのゴール」、「優先順位付けされ、可能な範囲で見積もられたユーザーストーリー」、「イテレーションの長さ」、「ベロシティ」があればリリース計画を立てることが可能であるといえる

---

アウトプットイメージ

![IMG_20180309_162513.jpg](https://qiita-image-store.s3.amazonaws.com/0/54872/1a1a0e31-74a0-61d0-e806-4f04d28ec350.jpeg)



---

### なんのためのもの？

- 事業責任者目線：プロダクトの事業計画を敷くため
- 開発チーム目線：事業の目標に対して自分たちがどこまで行ける見込みなのか？また、途中経過で今どこにいるのか？を見える化し、適応するため

---

### 大事なポイント

- リリース計画は常に流動的であり、プロダクトの状況に合わせて継続的にメンテナンスしていかないと意味がなくなってしまう
- 計画はあくまでも「見込み」であり、これを約束するためのものではない
    - 出来なさそうという「見込み」がわかったときにQCDSをどう調整するか？を考えるために利用する
- この計画は「変化への対応」のための道具である、という認識を持つ

---

### どうやって作るか

- リリース計画を作成する
    - プロジェクトのゴールを決める
    - イテレーションの長さを決める
    - ベロシティを算出する
    - ユーザーストーリーを見積もり、優先順位をつける
    - 用意した情報を元に、どの機能がいつごろに出せそうか？を書き出す
- リリース計画を更新する

---

#### リリース計画を作成する

##### プロジェクトのゴールを決める

- 「いつまでに」、「どんな機能を」、「どのぐらいのコストで」などを決定する
- 日付主導か、機能主導かが決まっていると良い
    - 計画に変更があったときに、「この日までにはリリースをしたいのでこの機能は諦めよう」というような判断を下せるようにするため

---

##### イテレーションの長さを決める
##### ベロシティを算出する

ここで、「期間」と「実力」を数値化して、1イテレーションでどれだけのモノを提供できるのかを算出するための準備をします
スクラムを実施しているのであれば、簡単に出せますね。

---

##### ユーザーストーリーを見積もり、優先順位をつける

積み上がっているユーザーストーリーを見積もり、優先順位に並び替えます
日付主導のプロジェクトの場合、ここでどこまでいけそうか？を元に優先順位が変わってくるかと思います

---

##### 用意した情報を元に、どの機能がいつごろに出せそうか？を書き出す

ここまでくれば書き出すだけです。簡単！

---

##### リリース計画を更新する

チームの状況が変わったら都度更新をします
例えばイテレーションの終了時や、新しいユーザーストーリーが発生したときに見直すのが定番です

---

### やってみてどうなったか

- 次何をやるのかがわからない、ということがなくなり、将来への不安が減った
- 締切のある作業に対して、現時点でヤバいかどうかが即座に分かるようになった
- 向こう半年でやりたいことベースに、ユーザーストーリーの優先度を議論できるようになった
    - 例えば、「こっちやってたらこの半年であっちのストーリー終わらせきれないかもしれないから優先度下げよう」というような会話

---

まとめ

アジャイルな開発プロセスでの中長期的計画方法であるリリース計画について紹介しました。
大事なのは、「自分たちのために活用する」という前提と、そのための継続的なメンテナンスかなと思います。
是非活用していきましょう


---

参考資料：アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~
GKEからVPN経由でオンプレにつなげられなかった場合の対処

## 経緯

自社の環境だとGCP+オンプレのハイブリッド(?)な開発環境を使っているのだが、GKEからオンプレの環境に繋がらない問題に直面した

GKE(というかk8s)のネットワークの設定とか調べて何とか解決できたので、同じ問題にあたった人の助けとなるように対処方法を明記しておく

## そもそもの原因

原因はk8sのIPマスカレードのデフォルト設定とVPNのLocal IP rangesが被ってたのが原因でした

オンプレ環境につなぎに行く際にはIPマスカレードしてもらいたいのだが、k8sのデフォルトの設定だと、 `10.0.0.0/8` の範囲のIPはIPマスカレードの対象外になっていて、VPNのLocal IP rangesがその中に含まれている場合に今回の問題が起こるようです

## 対処方法

幸運なことに日本語ドキュメントが用意されてたのでそちらを参考に対処を実施した

[IP マスカレード エージェント  |  Kubernetes Engine  |  Google Cloud Platform](https://cloud.google.com/kubernetes-engine/docs/ip-masquerade-agent?hl=ja)

簡単にいうと、ip-masq-agentをDaemonSetとして起動して、IPマスカレードの設定をConfigMapとして登録してね、ってことみたいです

設定用のyamlファイル作ったので、こちらを `kubectl create` してもらえればIPマスカレードの設定変更されると思います

```yaml:kube-system.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ip-masq-agent
  namespace: kube-system
data:
  config: |
    nonMasqueradeCIDRs:
    #   - 10.0.0.0/8
      - 192.168.0.0/16
      - 172.16.0.0/12
    resyncInterval: 60s
---
# https://raw.githubusercontent.com/kubernetes-incubator/ip-masq-agent/master/ip-masq-agent.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: ip-masq-agent
  namespace: kube-system
spec:
  template:
    metadata:
      labels:
        k8s-app: ip-masq-agent
    spec:
      hostNetwork: true
      containers:
      - name: ip-masq-agent
        image: gcr.io/google-containers/ip-masq-agent-amd64:v2.0.0
        securityContext:
          privileged: true
        volumeMounts:
          - name: config
            mountPath: /etc/config
      volumes:
        - name: config
          configMap:
            # Note this ConfigMap must be created in the same namespace as the daemon pods - this spec uses kube-system
            name: ip-masq-agent
            optional: true
            items:
              # The daemon looks for its config in a YAML file at /etc/config/ip-masq-agent
              - key: config
                path: ip-masq-agent
```

```sh
# 設定確認@node(10.0.0.0/8が除外されているのを確認)
# iptables  -t nat -L IP-MASQ-AGENT
Chain IP-MASQ-AGENT (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             169.254.0.0/16       /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
RETURN     all  --  anywhere             192.168.0.0/16       /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
RETURN     all  --  anywhere             172.16.0.0/12        /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
MASQUERADE  all  --  anywhere             anywhere             /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL
```

## 課題

GCE上のDockerコンテナからオンプレにつなぐ際にはMTUの設定の変更が必要だったのだが、なんか知らんがGKEからの接続の際には特にMTU変更しなくても繋がったので、そのあたり調査したい
大学卒業生のための$HOMEバックアップ

## はじめに

卒業と同時に、大学のアカウントが消えてしまいます。
いままで大学の環境で作業してきたファイルたちをバックアップしたい時期ですよね。

**使用容量が限られている場合**だと、`ssh`後、`$HOME`を圧縮したファイルを生成する容量の余裕もありません。
そこで、**大学環境にファイルを生成しなくてもバックアップ**できるコマンドの紹介です。
（大学にかぎらずSSHしてコマンドが叩ける環境ならどこでも使えます）


## バックアップコマンド

バックアップの仕方は、以下のコマンドをローカルでたたきます。後は待つだけです。
（リモートでたたかないことに注意）

```bash
ssh myuserid@hogehoge.ac.jp tar zcf - . > my_backup.tar.gz
```

コマンドを叩くと、
大学の`$HOME`が圧縮された`my_backup.tar.gz`がローカルのカレントディレクトリに生成されていきます。

### 詳細

そもそも`ssh`コマンドは、例えば、`ssh myuser@hoge.jp ls -l`とすればリモートでの`ls -l`の結果が返ってきます。

* `myuserid@hogehoge.ac.jp`はいつもログインしているものに変更してください
* `tar zcf - .`
 - `.`はリモートログイン後のカレントディレクトリ(おそらく`$HOME`）になります
 - `zcf`は圧縮のオプションです
 - `-`は圧縮結果を標準出力に吐かせる指定です
*  `> my_backup.tar.gz`はリダイレクトで標準出力に出てきている`tar.gz`をローカルにファイルとして保存します



## 進捗の確認

別のターミナルを開いて、以下のコマンドでファイルの容量の増加を確認すれば、いいと思います。

```bash
du my_backup.tar.gz
```

## 参考

* [[Linux]ファイルの圧縮、解凍方法](https://qiita.com/supersaiakujin/items/c6b54e9add21d375161f)
CentOS 6.8 初期設定いろいろ2

備忘録的なものになってしまっているのであしからず

#ネットワーク設定を変える
ブリッジ設定

service NetworkManager stop
を打つと
NetworkManager デーモンを停止中:                           [  OK  ]
とでてきて、NetworkManagerを切れます。
`chkconfig networkManager off`
`/etc/rc.d/init.d/network restart`
の2つのコマンドを入れたらうまくいきました。参考サイトは下のもの
http://dellmaster2007blog.blogspot.jp/2015/12/br0-kvm.html

#xrdpを再インストール
基本的には以下のサイトを参考にすればうまくいく。
http://kogelog.com/2014/09/23/20140923-02/
ちなみに以下のようなiptableの設定も行った。この設定はxrfpのものであると覚えておこう。
`iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 3389 -j ACCEPT`
`service iptables save` 
`service iptables restart`

#wireshaskを入れる
 `sudo yum -y install wireshark-gnome`
これで一発OK
配列を用いた条件分岐で一括処理

# 仕様
配列とループ処理を組み合わせることで、複数の変数に一括で同じ処理を行うマクロ変数。
例えば、変数A, B, C, Dそれぞれの欠測値をすべてUN(Unknown)に置き換えるときに使用する。
同じ処理を行う仕様のため、複数の変数同じ型であることが前提である。

# コード

``` chgVarsValue.sas
/*
 * Argument description
 *   type[num]:       if target variable is character, type = 1. else any values.
 *   tgtVal[num/chr]: Target value. if type=1, this argument needs double quotations.
 *   outVal[num/chr]: Output value. if type=1, this argument needs double quotations.
 *   chgVars[chr]:    Target variables. Enter with a space separater. 
 */
%macro chgVarsValue(type, bf, af, chgVars);
    %if &type. = 1 %then %let _type=$;
    %else _type=;
    array chgvv(*) &_type. &chgVars.;
    do _z = 1 to dim(chgvv);
        if chgvv(_z) = &bf. then chgvv(_z) = &af.;
    end;
    drop _z;	
%mend chgVarsValue;
```

# 処理内容
前述のように、**変数A, B, C, Dそれぞれの欠測値をすべてUN(Unknown)に置き換える**場合は次のように引数を指定する。

```Example01.sas
%chgVarsValue(1, "", "UN", A B C D)
```

引数`type`で型を指定する必要があるのは、arrayステートメントで配列に変数を定義する際に、文字型の場合は変数名の前に"$"が必要であるためです。
つまり、type=1の場合は`array chgvv(*) $ A B C D`となり、それ以外の場合（数値型の場合）は`array chgvv(*) A B C D`となります。
配列に指定された変数はすべてループで順番に同じif文の処理が実行され、引数`bf`で指定された値から引数`af`で指定された値に変換されます。

# 実行結果
マクロchgVarsValueの使用例と実行結果（データセットresult）です。

```Example02.sas
data sample;
    AA = "abc"; BB = "efg"; CC = "hij"; output;
    AA = "";    BB = "efg"; CC = "hij"; output;
    AA = "abc"; BB = "";    CC = "hij"; output;
    AA = "abc"; BB = "efg"; CC = "";    output;
    AA = "abc"; BB = "";    CC = "";    output;
    AA = "";    BB = "efg"; CC = "";    output;
    AA = "";    BB = "";    CC = "hij"; output;
    AA = "";    BB = "";    CC = "";    output;
run;

data result;
    set sample;
    %chgVarsValue(1, "", "UN", AA BB CC);
run;
```
![mChgVarsValue_Result.png](https://qiita-image-store.s3.amazonaws.com/0/199826/f9c76d84-19ab-3e36-ca06-7d4b20e9bc59.png)
CentOS 6.8 64bitの初期設定いろいろ1


# sudo設定
visudoで
Allow root to run any commands anywhere
root   ALL=(ALL)   ALL
を
Allow root to run any commands anywhere
root   ALL=(ALL)   ALL
tkl    ALL=(ALL)   ALL
に変更

#gccの設定
4.4.7を4.8.2に変える
gcc -vこれで確認
http://www.task-notes.com/entry/20151114/1447492231を参考にした。
devtoolset-3を入れた
`yum install scl-utils`
`cd  /etc/yum.repos.d/`
`wget https://copr-fe.cloud.fedoraproject.org/coprs/rhscl/devtoolset-3/repo/epel-6/rhscl-devtoolset-3-epel-6.repo`

`yum install devtoolset-3-gcc devtoolset-3-binutils`
`yum install devtoolset-3-gcc-c++ devtoolset-3-gcc-gfortran

入ったかどうか確認
`ll /opt/rh/devtoolset-3/root/usr/bin/gcc`

`/devtoolset-3/root/usr/bin/gcc`
`ll /opt/rh/devtoolset-3/root/usr/bin/g++`

PATHを通す
`scl enable devtoolset-3 bash`

このままだとシェルを起動する度に上のscl enableのコマンドを入れることになるので自動化が必要。そちらに関するURL

https://qiita.com/Momomotsu/items/964779a916f190d5e8dd


ちなみにglibcを確認する時はいかのコマンド
`yum list installed | grep glibc`


#ネットワーク設定
iptableの設定
`cp -ipv /home/tkl/backup/iptables.backup /root/iptables.backup`
`cp -ipv /home/tkl/backup/iptables.backup3 /root/iptables.backup3`

確認場所はrootに入ってから
`cd /`
`cd root`
`ls`
でオッケー

restoreするときは
`iptables-restore < /root/iptables.backup`
`service iptables save`
`cat /etc/sysconfig/iptables`
SASで単換字式暗号(ROT13)

# はじめに
本投稿の内容は、前回投稿した [Rで単換字式暗号(ROT13)](https://qiita.com/tatsuki7275/items/40a7e047bddde3c256ed "Rで単換字式暗号(ROT13)") のSASバージョンです。
ROT13についての説明は上記の記事で説明しているため、割愛させていただきます。
使用しているのは、無料のSAS University Editionです。

# SASでコーディング
以下は作成したROT13暗号化のSASマクロです。

``` ROT13.sas
%macro ROT13(tgt_var, out_var);
    %let bfLine = ABCDEFGHIJKLMNOPQRSTUVWXYZ;
    %let afLine = %sysfunc(substr(&bfLine., 14, 13))%sysfunc(substr(&bfLine., 1, 13));
    %let bfVals = &afLine.%sysfunc(lowcase(&afLine.));
    %let afVals = &bfLine.%sysfunc(lowcase(&bfLine.));

    &out_var. = translate(&tgt_var., "&bfVals.", "&afVals.");
%mend ROT13;
```


## マクロ内での処理内容
処理自体はアルファベットを13文字ズラした文字に置き換えているだけです。
ただし、Rと異なり、SASにはアルファベット26文字を出力する関数がないため、`%let bfLine = ABCDEFGHIJKLMNOPQRSTUVWXYZ;`としています。変数`bfLine`の各アルファベットをを13文字ズラした変数が`afLine`。
変数`bfLine`, `afLine`に小文字化したアルファベットを追加で結合した変数が`bfVals`, `afVals`です。
各マクロ変数に格納される値はこちら。
***
![mROT13_mvarLog.png](https://qiita-image-store.s3.amazonaws.com/0/199826/21a69f76-06f5-f580-bb08-af6aab6de7df.png)
***

最後にtranslate関数で指定の変数のアルファベットを変換し、指定の変数に出力します。
上記の処理はデータステップでも可能ですが、以下のような、関数的な用い方をするために、各変数を `%let` でマクロ変数として定義しています。

``` Example01.sas
data result;
    set sample;
    %ROT13(AA, BB);
run;
```


# 実行結果
作成したROT13マクロの使用例と実行結果です。
変数`Before`の文字列のうち、アルファベットのみが（大文字小文字を区別して）変換されて変数`After`に出力されます。

``` Example02.sas
data sample;
    length Before $15.;
    Before = "Hello World!"; output;
    Before = "Stack Overflow"; output;
    Before = "1234567890"; output;
    Before = "あいうえお"; output;
run;

data result;
    set sample;
    %ROT13(Before, After);
run;
```

![mROT13_Result.png](https://qiita-image-store.s3.amazonaws.com/0/199826/b4149f4d-3aa2-508c-4da8-12d680302b2d.png)
Project Euler 50「連続する素数の和」

@cof さんに頂いたコメント内の関数（get_prime_boolean）を丸パクリ。
いやはや、よくできてますねこの関数。美しいです。
ちゃんと内容理解したからコピペしちゃっていいですよね。

# Problem 50 「連続する素数の和」
素数41は6つの連続する素数の和として表せる:
41 = 2 + 3 + 5 + 7 + 11 + 13.
100未満の素数を連続する素数の和で表したときにこれが最長になる.
同様に, 連続する素数の和で1000未満の素数を表したときに最長になるのは953で21項を持つ.
100万未満の素数を連続する素数の和で表したときに最長になるのはどの素数か?

```python
def hoge(num):
    primes = [ i for i, b in enumerate(get_prime_boolean(num)) if b ]
    cnt, ans = 1, 0
    for n in range(len(primes)):
        if primes[n] > num / cnt: break
        for m in range(n + cnt, len(primes) + 1):
            N = sum(primes[n:m])
            if N >= num: break
            if m - n > cnt and N in primes:
                cnt, ans = m - n, N
    return ans

def get_prime_boolean(search_max):
    prime_boolean = [False,False] + [True] * (search_max-1)
    prime_boolean[4::2] = [False] * (len(prime_boolean[4::2]))
    p = 3
    p_max = int(search_max ** 0.5) + 1
    while p <= p_max:
        if prime_boolean[p]:
            prime_boolean[p**2::p] = [False] * (len(prime_boolean[p**2::p]))
        p += 2
    return prime_boolean

print(hoge(1000000))
```
Nuxt.jsの動的でネストされたルート補足

# これは何？
- 公式ドキュメントの[動的でネストされたルート](https://ja.nuxtjs.org/guide/routing#%E5%8B%95%E7%9A%84%E3%81%A7%E3%83%8D%E3%82%B9%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%83%AB%E3%83%BC%E3%83%88)が分かりにくかったので、その補足です。

# 実現したいrouting
- `users/` => ユーザー一覧
- `users/:id` => ユーザー詳細
- `users/:id/posts` => ユーザーの投稿一覧
  - これが今回実現したかったこと

# 結論
↓のように配置することで実現出来ました。

```
pages/
--| users/
-----| index.vue
-----| _id.vue
-----| _userId/
--------| posts/
----------| index.vue
```

# 蛇足
- `pages/users/_userId/`の `_userId/`のフォルダ名は先頭に`_`がついてれば何でもいい
- 公式では`_slug/`となっていて英語力が足らず混乱しましたが何でもいいというニュアンスを伝えたい模様？
- `_userId`のフォルダ名がそのまま`validate`などの`params.userId`のようなparam名になる
- ~~`pages/users/index.vue`は`pages/_users.vue`でもいい~~
    - `pages/users/*`がすべて`pages/_users.vue`にルーティングされてしまう模様
    - index.vueを使いましょう
brctl, tapコマンド基本編

brctlコマンドは以下の通り。

addbr \<name> 新しいブリッジ作る
delbr \<name> ブリッジを消す
show 確認できる
addif \<brname> \<ifname> ブリッジに追加
delif \<brname> \<ifname> ブリッジを削除
show \<brname> そのブリッジ情報

他にもスパニングツリーの設定も可能。
tapデバイスはtunctlから作成可能

tunctl –t \<Tap 名>　tapデバイスを作成する
tunctl -d 　         tapデバイスを削除する

brctlのコマンドについて
https://wiki.archlinuxjp.org/index.php/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8
tapコマンドについて
http://hogem.hatenablog.com/entry/20120908/1347110891

以上
VICredentialStoreItemを使用したvCenter Serverへの自動接続

#はじめに
PowerCLIで作成したスクリプトをタスクで実行する場合等、自動的にvCenter Serverに接続したい場合に使用します
Get-Credential使う方法もあるけど、[公式にコマンドレットが用意](https://www.vmware.com/support/developer/PowerCLIforTenants/PowerCLIforTenants51/html/New-VICredentialStoreItem.html)されているのでそっちを利用します

#認証ファイル作成
あらかじめ認証ファイルを作っておきます
パスワードについはGet-Credentialしてから色々するんでもいいかもしれないけど、一回だけなのでコマンドラインで入力しちゃいます
ショルダーハックに注意(ぉ

```powershell
$vc_cred_file = 'C:\hoge.xml'
New-VICredentialStoreItem -Host <ホスト名/IPアドレス> -User <User名> -Password <パスワードべたうち> -File $vc_cred_file
```

#認証ファイル使用
作成した認証ファイルの使用方法
スクリプトに組み込んで使ってます

```connect.ps1
$vc_cred_file = 'C:\hoge.xml' #認証ファイル作成でつくったファイルを指定
$vc_cred = Get-VICredentialStoreItem -File $vc_cred_file
Connect-VIServer -Server $vc_cred.Host -User $vc_cred.Host.User -Password $vc_cred.Password -Protocol https
```
CentOS6.8でgccの更新と自動化

参考サイトはこちら
http://www.task-notes.com/entry/20151114/1447492231
これに載っていたとおりにやったらうまくいきました。
最初のwget http://people.centos.org/tru/devtools-2/devtools-2.repo
がうまくいかない場合は
wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo
を入力。
最後の自動化についてはこちらのサイトを参考にしました。
http://qiita.com/giwa/items/28c754d8fc2936c0f6d2
コマンド
nano ~/.bashrc
で~/.bashrcを開いて
source /opt/rh/devtoolset-2/enable
を入力しました。
このファイルはルートの隠しファイルみたいです。
その他にもあるみたいなので詳しくはこちらのサイトで
http://qiita.com/magicant/items/d3bb7ea1192e63fba850
http://qiita.com/hirokishirai/items/5a529c8395c4b336bf31

ありがとうございました。
gunicornで管理しているアプリをリロードする方法


### 起動
```shell
$ gunicorn app:app -p /tmp/gunicorn.pid 
```

### リロード
```shell
$ kill -HUP `cat /tmp/gunicorn.pid`
```

### 解説
起動処理で masterpid を出力し、それを `kill -HUP` に渡すとwokerプロセスがリロードされる
Xamarin iOSでVRリモコンを試す

ELECOMのスマホVR用コントローラ[JC-VRR01](http://www2.elecom.co.jp/products/JC-VRR01BK.html)をiOSで使うときのための、チートシートを作ってみた。

*リモコンをゲームパッドモードで動作させるには、「Select」ボタンを押しながら電源スイッチを「iOS」側にスライドさせる。詳しくは[取り扱い説明書](http://www.elecom.co.jp/support/manual/peripheral/gamepad/jc-vrr01/jc-vrr01_v1.pdf)を参照。*

![ELECOM JC-VRR01.png](https://qiita-image-store.s3.amazonaws.com/0/69744/d18f43fb-1278-ef5e-ac2b-bf393358b0bf.png)

ボタンごとにアルファベットをふたつ記載しているのは、down / upに対応。ボタンを押し込んだときと離したとき、それぞれでキーコードが送られてくる仕様で、キーリピートのようなものではないので、「押している間」のような処理が書きやすそう。

Xamarin.iOSで利用するためのコードは下記のとおり。

```ViewController.cs
    public partial class ViewController : UIViewController
    {
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // add key-commands
            var action = new Selector("KeyTouched:");
            foreach (var alp in Enumerable.Range('a', 26))
            {
                AddKeyCommand(UIKeyCommand.Create(new NSString(((char)alp).ToString()), 0, action));
            }
        }

        [Export("KeyTouched:")]
        private void KeyTouched(UIKeyCommand command) 
        {
            Console.WriteLine(command.Input);
        }
    }
```
【React Native】Googleログインで使用してるGoogleアプリ切り替え時にする管理画面の操作とソース変更箇所 for Android

## やりたいこと
AndroidのGoogleログイ認証を使用しています。
Googleの管理画面で別のアプリ(スマホアプリではなく、Google管理画面上のアプリ)に
向き先を変更したいです。

## 前提
すでにGoogleログインの実装が完了している前提のため、
Googleログインを導入する方法は記載していません。

## 管理画面
https://console.cloud.google.com
　→CLIENT_IDなどを取得
https://developers.google.com/mobile/add?platform=android
　→「google-services.json」取得

## 変更箇所
### 管理画面
パッケージ名：バンドルID
SHE-1：
＊SHE-1の取得方法

```
keytool -exportcert -keystore {.keystoreのパス} -list -v
```

### google-services.json変更
パス：android/app/google-services.json

### GoogleSignin.configure
jsソースで、Googleログインを使用する画面で下記の関数を呼ぶ必要がある。
GoogleSignin.configure

https://console.cloud.google.com
で確認できる値を入れる。
WEB_CLINENT_ID：webのクライアント ID
IOS_CLINENT_ID：iOSのクライアント ID

＞例

```
    const config = {
      webClientId: {WEB_CLINENT_ID：web},
      offlineAccess: false,
    };
    if (Platform.OS === 'ios') {
      config.iosClientId = {IOS_CLINENT_ID};
    }
    await GoogleSignin.configure({ config });
```
three.jsでanimation system

# 概要

three.jsでanimation systemを、理解したかった。
jsdoで試して見た。

# JSONLoader
http://jsdo.it/ohisama1/efFX
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/e/f/F/efFX.jpg?t=1520569405)

# ObjectLoader
http://jsdo.it/ohisama1/SQsY
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/S/Q/s/SQsY.jpg?t=1520559519)

# FBXLoader
http://jsdo.it/ohisama1/cW9X
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/c/W/9/cW9X.jpg?t=1520558736)

# ColladaLoader
http://jsdo.it/ohisama1/GShQ
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/G/S/h/GShQ.jpg?t=1520558198)

# GLTFLoader
http://jsdo.it/ohisama1/8JbS
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/8/J/b/8JbS.jpg?t=1520559338)

# MMDLoader
http://jsdo.it/ohisama1/kO8n
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/k/O/8/kO8n.jpg?t=1520558867)

# BVHLoader
http://jsdo.it/ohisama1/CZsX
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/C/Z/s/CZsX.jpg?t=1520560322)

以上。
RailsでArel、早見表

# RailsでArel、早見表

### 等号、不等号

```sql
  scope :without_directs, -> { where( arel_table[:sample_kind_id].not_eq(SampleKind.direct) )}

# (>は gt) 
  scope :sample_check_passed, -> do
    pr = GrandsonTbl.arel_table          # joinでつないだ別テーブルのカラム見るとき
    where(pr[:good_quantity].gt(0))
  end

# (=は eq) 
  scope :no_movement_in_sample, -> do
    st = StTbl.arel_table
    where(st[:id].eq(nil))
  end

# (>= は  gteq) 
  scope :sons_created_n_month_before, -> (n)do
    sn = SonTbl.arel_table
    where(sn[:created_at].gteq((Time.now - n.months).to_s(:db)))
  end

# (< は lt) 
  scope :after_reflection, -> do
    sn = SonTbl.arel_table
    where(sn[:reflected_at].lt(Time.now.to_s(:db)))
  end

```


### 結合した子テーブルのデータを見る
1. 重複する名前の列は tableにエイリアスをつけておく 
2. selectメソッドで指定。  
3. 補足(結合、抽出条件つき)
 
例) 以下のSQLをArelで

```sql
SELECT A.code, A.id, B.sku_id, B.quantity,B.created_at, B.reflected_at
FROM A_tbls A
INNER JOIN son_tbls B on B.po_id = A.id
INNER JOIN grandson_tbls C on C.po_detail_id = B.id
LEFT JOIN st_tbls st on st.st_tbl_type = 'SonTbl'
  AND st_tbl_id = B.id
  AND st_tbl_kind_id = 5
WHERE B.created_at >= '2017-10-01'
  AND B.reflected_at < now()
  AND B.status = 'recorded'
  AND A.arrival_kind_id <> 5
  AND C.good_quantity > 0
  AND st.id is null;

```

1. 重複する名前の列は tableにエイリアスをつけておく( AS )

```ruby
  sp = Supplier.arel_table.alias('sp')
```

2. selectメソッドで指定。

```ruby
   self.・・・・.select("A_tbls.id as a_id, A_tbls.*, son_tbls.*")
```

3. 外部結合、抽出条件つき

```ruby
  scope :with_st_tbl_sample, -> do
    st = StTbl.arel_table
    pd = SonTbl.arel_table
    arel_table.join(st, Arel::Nodes::OuterJoin).on(
      Arel::Nodes::And.new([
        st[:st_tbl_type].eq('SonTbl'),
        st[:st_tbl_id].eq(pd[:id]),
        st[:st_tbl_kind_id].eq(5)
      ])
    )
  end
```

 生成されるSQLを確かめる(.to_sql)

```ruby
[1] pry(main)> ATbl.with_st_tbl_sample.to_sql
=> "SELECT FROM `A_tbls` LEFT OUTER JOIN `st_tbls` ON `st_tbls`.`st_tbl_type` = 'SonTbl' AND `st_tbls`.`st_tbl_id` = `son_tbls`.`id` AND `st_tbls`.`st_tbl_kind_id = 5"
```

OK

 scopeがつなげれるか確認しておく(.class)

```ruby
[5] pry(main)> PoTbl.with_st_tbl_sample.class
=> Arel::SelectManager
```

  これはそのままではメソッドチェーンでつながらないので

```ruby
  .joins( self.with_st_tbl_sample.join_sources )
```
これでつながる。



### 多段ネスト(子テーブル、孫テーブル)

```ruby
  scope :join_sons_and_grandsons, -> { joins(:son_tbls => [:grandson_tbls]) }
```
knockoutJSのifバインディングの罠

# はじめに
とあるhtml5 + knockoutJSでつくられているシステム開発中、knockoutJSのifバインディングではまった。
※検証に用いたKnockout.jsのバージョンは 3.4.2 です。 

# きほんのきほう
[公式ドキュメント](http://kojs.sukobuto.com/docs/if-binding)のifバインディングを見て、一番単純な記法だとこんな感じ。

```index.html
いつも見えてるやつだぜ！
<div data-bind="if: property.aTrueValue">
 ifバインディングの評価値がtrueだったらでるぜ！
</div>
```
```test.js
ko.applyBindings({
    property: { 
        aTrueValue:ko.observable(true)
    }
});
```
ふるまい

|aTrueValueがtrue|aTrueValueがfalse|aTrueValueが存在しない|
|---|---|---|
|text表示|text非表示|text非表示|

aTrueValueが無かったり、falseだったりするとちゃんとfalseとして評価される。ふんふん。



# やべーうごき①～observableの中身で評価すると～
observableのオブジェクトでifバインディングの評価をするときほん編の通り想定通りの動きをしてくれるが、observable引数無の実体の値でifバインディングを使うと少し変な動きになる。

```index.html
いつも見えてるやつだぜ！
<div data-bind="if: property.aTrueValue()">
 ifバインディングの評価値がtrueだったらでるぜ！
</div>
```
```test.js
ko.applyBindings({
    property: { 
        aTrueValue:ko.observable(true)
    }
});
```
ふるまい

|aTrueValueがtrue|aTrueValueがfalse|aTrueValueが存在しない|
|---|---|---|
|text表示|text非表示|<font color="Red">text表示</font>|
~~存在しないのにifバインディングの評価がtrueに。。。~~
<font color="Orange">(2018/3/11 追記）ifバインディングはプロパティの有無まではbooleanで判定してくれるが、存在しない関数はエラーとなり、結果DOMが生成されてしまう！！</font>

# やべーうごき②～複数項目の論理式～
複数のobservableオブジェクトでifバインディングの評価をするとへんてこになる。

```index.html
いつも見えてるやつだぜ！
<div data-bind="if: (property.aTrueValue && property.anotherTrueValue)">
 ifバインディングの評価値がtrueだったらでるぜ！
</div>
```
```test.js
ko.applyBindings({
    property: { 
        aTrueValue:ko.observable(true), 
        anotherTrueValue:ko.observable(true)
    }
});
```
ふるまい

|---|aTrueValueがtrue|aTrueValueがfalse|aTrueValueが存在しない|
|---|---|---|---|
|anotherTrueValueがtrue|text表示|<font color="Red">text表示</font>|text非表示|
|anotherTrueValueがfalse|text非表示|text非表示|text非表示|
|anotherTrueValueが存在しない|text非表示|text非表示|text非表示|
~~条件式の頭がfalseなのにifバインディングの評価がtrue。~~
<font color="Orange">(2018/3/11 追記）[javascriptの論理式について盛大に勘違いしてました。](https://qiita.com/Imamotty/items/bc659569239379dded55)functionはtrue評価されてしまうので、後方のプロパティでifバインディングが効く模様。でもプロパティが存在しない場合はfalseになる。なかなか複雑。。。</font>

# やべーうごき③～複数項目の論理式with中身評価～
複数のobservableオブジェクトの中身で評価してみる。

```index.html
いつも見えてるやつだぜ！
<div data-bind="if: (property.aTrueValue() && property.anotherTrueValue())">
 ifバインディングの評価値がtrueだったらでるぜ！
</div>
```
```test.js
ko.applyBindings({
    property: { 
        aTrueValue:ko.observable(true), 
        anotherTrueValue:ko.observable(true)
    }
});
```
ふるまい

|---|aTrueValueがtrue|aTrueValueがfalse|aTrueValueが存在しない
|---|---|---|---|
|anotherTrueValueがtrue|text表示|text非表示|<font color="Red">text表示</font>|
|anotherTrueValueがfalse|text非表示|text非表示|<font color="Red">text表示</font>|
|anotherTrueValueが存在しない|<font color="Red">text表示</font>|text非表示|<font color="Red">text表示</font>

~~条件式の頭が存在しないと、trueなんだね！すっごーい！~~
<font color="Orange">(2018/3/11 追記）①と同様、存在しない関数はエラーとなるのと、ショートサーキット評価で上記仕様になっているみたい。</font>

# 結論
ifバインディングを使う場合は
<font color="Red">条件式のプロパティを定義したうえでobservableの中身で評価する</font>
を守らないと想定通り動かなさそう。

# 参考
https://stackoverflow.com/questions/15307504/knockout-js-if-binding-on-multiple-booleans
http://kojs.sukobuto.com/docs/if-binding
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators
Raspberry Pi > Geany > bookmark機能 > Ctrl-m: ブックマーク付加/解除 | Ctrl-, : ブックマークへ移動

```txt:動作環境
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
Python 2.7.9
Geany 1.24.1
```

Geanyのブックマーク機能については以下を見つけた。

https://askubuntu.com/questions/487030/is-there-bookmark-in-geany

- <kbd>Ctrl</kbd>-<kbd>m</kbd>: ブックマーク付加/解除
- <kbd>Ctrl</kbd>-<kbd>,</kbd>: ブックマークへジャンプ
    - カンマ
    
付加したブックマークはGeanyを終了すると解除される。

<kbd>m</kbd>と<kbd>,</kbd>がキーボード上で隣り合わせなのは、意図した設計なのだろうか。

> Using the bookmarking feature together with the commands to switch from one editor tab to another (Ctrl-PgUp/PgDn and Ctrl-Tab) provides a particularly fast way to navigate around multiple files.

タブ（ソースファイル）の切替と組合せると使い勝手が良いとのこと。
bundle installで「Downloading xxx revealed dependencies not in the API or the lockfile」というエラーが出た時の対処法

# bundle installで特定のgemがインストールできない

Railsの勉強中、書籍に付属のサンプルプログラムを動かすため、ソースをダウンロードして`bundle install`を実行したら以下のようなエラーが出た。

```
bundle install
Fetching gem metadata from https://rubygems.org/..........
Using rake 10.4.2
Using i18n 0.7.0
Using json 1.8.2

...

Fetching rdoc 4.2.0
Downloading rdoc-4.2.0 revealed dependencies not in the API or the lockfile (json (~> 1.4)).
Either installing with `--full-index` or running `bundle update rdoc` should fix the problem.

In Gemfile:
  sdoc was resolved to 0.4.1, which depends on
    rdoc
```
どうやら`rdoc-4.2.0`というgemのダウンロードでコケている模様。
この状態で`bin/rails s`を実行すると、対象のgemが見つからない旨のエラーが出る。

```
Could not find rdoc-4.2.0 in any of the sources
Run `bundle install` to install missing gems.
```

かなしい。

# 対処法

エラーメッセージによると`--full-index`か`bundle update rdoc`を実行しろとのこと。

```
Either installing with `--full-index` or running `bundle update rdoc` should fix the problem.
```

`--full-index`は`bundle install`のオプションのようだが、説明を見てもよくわからなかった…
> Use the rubygems modern index instead of the API endpoint.
> [Bundler: bundle install](http://bundler.io/v1.7/man/bundle-install.1.html)


`Gemfile.lock`を見てみると対象gemのバージョンが別環境と異なっていたので、問題となっているgemをアップデートすることにした。

```
bundle update rdoc
```

`bundle update rdoc`を実行すると`Gemfile.lock`で指定されている`rdoc`のバージョンが更新された。

```
Using rdoc 4.3.0 (was 4.2.0)
```

以降のgemも無事にインストールされ、`bin/rails s`でプログラムの起動が確認できた。


## 補足
`Gemfile.lock`で指定されているgemのバージョンが、[RubyGems.org](https://rubygems.org/)のリストに存在しない場合にも「Could not find xxx in any of the sources」エラーが発生する模様。

[bundle install すると Could not find xxx in any of the sources と怒られる場合の対処法 - Qiita](https://qiita.com/jnchito/items/44ab1df134369ed76911)

こちらもgemのupdateで解決するみたい。