OmniAICreator/Qiita-1.07M huggingface dataset:
クラス指向の初心

# はじめに
これはポエム。
クラス指向についてのまとめ。
状態不変性を維持する為、「メソッドのみの静的クラス」にしか適応できません。
プロパティは用意してもいいですが、get専用でなければいけません。

# クラス指向
名前の通り、「**クラス(分類)**」を軸にした**構想や表現**のことです。
この構想を**実際に動くコード**に落とし込むのことが**クラス指向プログラミング**です。

クラス指向には2つの構想、表現があります。

- 分類、種類(type,kind)
- 階級、階層(rank,hierarchy)

一般的にはこの2つのバランスを考慮しながら物事を整理し、
構想や表現を構築する事が、クラス指向の目的となります。

### まとめ

- クラス指向は、物事を分類したり、階級をつけて整理する考え方
- 上記によって整理された構想を、PCで動くコードで表現する事をクラス指向プログラミングと言う

非常にシンプルですね。シンプルイズベストです。



# 「分類」
クラス指向の一つ「分類」に慣れましょう。
練習をしてみましょう。

- にんじん
- 豚肉
- 牛乳

これを「液体、個体、気体」で分類してみましょう。

- 固体:にんじん、豚肉
- 液体:牛乳

次に、「動物から採れるもの、植物から採れるもの」で分類してみましょう。

- 動物から採れるもの:豚肉、牛乳
- 植物から採れるもの:にんじん

次に、「おいしい、まずい」で分類してみましょう。
・・・・・・・・・・・・
・・・・・・
はい、くだらないですね。
練習はここまでにしましょう。

### まとめ

- 分類の仕方は**無限**にある
- **無用**な分類もあれば、**有用**な分類もある
- 応用：プログラミング上で包含関係にあるコードは、個別のクラス毎に記述することになる

非常に**当たり前**と言った感じです。
しかし、**有用な分類**を見つけるには、より高い知識と知能と運と根気が必要になります。
**有用な分類**を見つけられば、後はそれにそって物事を分類するだけです。

# 「階級」
無限にある分類の中に、特別にされている分類があります。
「**階級**」という分類です。
物事の順序や部分集合、親子関係を分ける際に有用な分類です。

# さいごに
よりよい「有用な分類」を見つけるには、そのドメイン(案件)に関する幅広く、深い知識が必要です。
そういう意味では、途中で別の分類方法を思いつくかもしれません。
そうなった際にも困らないよう、コードの置換技術や、クラス替えの自動化方法は身に着けておきましょう。

はじめにも書いた通り、これは「メソッドのみの静的クラス」にのみ有用な概念です。
動的クラスでは別途「オブジェクト指向」という別の構想が必要になり、扱う概念の範囲が別になることに注意してください。
リモートデスクトップの接続元コンピュータのIPアドレスを取得

Windowsサーバーに接続している端末のIPアドレスをログオン時点で取得したいが、
下記のリンクにあるように、ログオンスククリプトを使っている時は%CLIENTNAME%などの環境変数が使えないようだ。

[リモートデスクトップの接続元コンピュータのIPアドレスを取得する方法](https://answers.microsoft.com/ja-jp/windows/forum/windows_xp-networking/%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87/0c085de1-7930-4b0e-8813-b1ab429c7b0e)


と言うわけで、

[【初心者向け】各OSのTCPポート番号からプロセス/サービス調査コマンド入門](https://dev.classmethod.jp/cloud/aws/ec2-tcp-port-process-check-command/)
にあるようにnetstat コマンドを使ってIPアドレス情報を取得することができる。

```

netstat -n -p tcp | find ":3389"

```

IPアドレスだけを変数に代入したい場合は、下記のコマンドを打てば取得できる。

```
for /f "tokens=2 delims=:" %i in ('netstat -n -p tcp ^| find ":3389"') do set a=%i
set b=%a:~4%
set c=%b: =%
echo %c% 
```

BATファイルで使用したい場合は、％はエスケープする必要があるので、％％に変換して、下記のようにする

```
for /f "tokens=2 delims=:" %%i in ('netstat -n -p tcp ^| find ":3389"') do set a=%%i
set b=%a:~4%
set c=%b: =%
```


これ、パッと見ただけだと何やっているかわかり難い。

一つずつ分解して説明すると

まず、下記の[netstatコマンド](http://www.atmarkit.co.jp/fnetwork/netcom/netstat/netstat.html)を使って、取得した接続一覧からRDPの3389ポートを持つ行を[findコマンド](https://tech.nikkeibp.co.jp/it/free/NT/WinKeyWord/20040805/1/find.shtml)で抽出する。 

```
netstat -n -p tcp | find ":3389"
```

次に[forコマンド](http://www.atmarkit.co.jp/ait/articles/0106/23/news004_2.html)で、
()の中の出力結果を「：」で区切った結果の２番目を変数aにセットする。「|」はエスケープするため「^」を前に入れる。

```
for /f "tokens=2 delims=:" %i in ('netstat -n -p tcp ^| find ":3389"') do set a=%i
```

変数aから4文字目以降を取得する。
[BATファイルで文字列の切り出し
](https://www.upken.jp/kb/kZwpzAqblKfZDjtMXuWuwioeExKNdE.html)

```
set b=%a:~4%
```

変数bから空白を削除する。``%V:c1=c2%　　文字c1を文字c2に置換する。`` 

```
set c=%b: =%
```
項目リスト：ドキュメント>Office クライアントの開発>Office 共有

#Office クライアントの開発
##Office との統合
###iOS アプリケーションからの Office との統合
###iOS ドキュメント ピッカーのための Office のサポート
###Windows ユニバーサル アプリからの Office との統合
###Win32 同期クライアントからの Office との統合
###Android ストレージ アクセス フレームワークのための Office for Android サポート
###Android アプリケーションからの Office との統合
##Office Online Server
##Office for Mac
##Office 共有
###[Office の 32 ビット バージョンと 64 ビット バージョン間の互換性](https://qiita.com/Q11Q/items/80b235f10b1392876a86)
###IM アプリケーションと Office の統合
###管理容易性アプリケーションと Office 365 クイック実行インストーラー
###Office テレメトリ ログ
####テレメトリ ログによる Office ファイルとカスタム ソリューションのトラブルシューティング
####Office の互換性に関する問題
###Office VBA オブジェクト ライブラリ リファレンス
###Office VBA 言語リファレンス
###Office プライマリ相互運用機能アセンブリのリファレンス
###Open XML SDK 2.5
 ###CSISyncClient を使用した ODC の制御
客先常駐なVimmerのためのGit付属のVim使用方法


# Vimが使いたい

客先常駐のSE／PGにとってはネット環境がない＋フリーソフト導入禁止みたいな環境で
働くことはよくあることかと思います。

サクラエディタや秀丸（筆者は秀丸は使ったことないが）は多くの現場で
導入されている／使っているのを見る一方で、Vimが導入されている／使っている人がいる現場など
見たことがありません（筆者はみたことない）、当然Vimを使うことも入手することもできません。

しかし、幸運にもバージョン管理にGitを使っているならまだ望みはあります。

# GitのVimを使う

Gitのインストール先のディレクトリを開きます。
Git付属のVimは下記のパスにいます。
（version 2.16.2.windows.1の場合）
これをコマンドプロンプトなどから直接起動することでVimを単体で使うことができます。
![cmd_vim.png](https://qiita-image-store.s3.amazonaws.com/0/74246/2d0aa7d8-87ca-4a66-025d-b70121a8829d.png)
`Git\usr\bin\vim.exe`

ですがこの方法では環境によっては（バージョンの影響かも？）
日本語の全角文字の表示が乱れたり、スクロール時に残像がのこったりします。
そこでこれまたGit付属のMinttyを使います。

# GitのMinttyでVimを使う

Git付属のMinttyはVimと同じパスにいます。
ダブルクリックで起動して、MSYSを選択します。

![select_shell.png](https://qiita-image-store.s3.amazonaws.com/0/74246/25377a43-6a16-73e9-d249-ae7a0b5be41d.png)

`Git\usr\bin\mintty.exe`

vimを起動します。

![mintty.png](https://qiita-image-store.s3.amazonaws.com/0/74246/694650db-4f28-40c5-1f2d-5fcaa7aa00d6.png)
![mintty_vim.png](https://qiita-image-store.s3.amazonaws.com/0/74246/0e228654-a77b-1c0d-88cf-e42c57f33b56.png)

フォントなどはお好みで変えてください、ウインドウのタイトル部分の右クリックメニューから
設定画面を出すことができます。

![option.png](https://qiita-image-store.s3.amazonaws.com/0/74246/f1acb9a0-59b6-8357-7d22-5e3b6b8fb645.png)

# 追記：minttyでcmd.exeを使う

なぜかMSYS2の起動がめっちゃ遅い、立ち上がらないこともしばしば。
原因についてはわからないけどとりあえずVimを使うための回避策を見つけたので書いておく。

minttyからコマンドプロンプト（cmd.exe）を使えばとりあえずVimは使える。

`Git\usr\bin\mintty.exe %COMSPEC%`

これでminttyからコマンドプロンプトを使うことができる。
ここからVimを立ち上げればよい。
rails server実行時にJavaScript runtimeエラー

いつものようにrails serverを実行したとき、JavaScriptエラーに遭遇してしまったときの解決法

<h2>JavaScript runtime</h2>

エラーメッセージは以下

```terminal:terminal
$rails server
︙
/home/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/execjs-2.7.0/lib/execjs/runtimes.rb:58:in `autodetect'
: Could not find a JavaScript runtime. 
See https://github.com/rails/execjs for a list of available runtimes. 
(ExecJS::RuntimeUnavailable)
```
ログを見ると丁寧にGithubのページリンクが載っている。
読み解くと、どうやらGemfileにtherubyracerというgemを追加してあげればよさそうだ。

```text:gemfile
︙
gem 'therubyracer'
```

でbundle update後、再度実行

```terminal:terminal
$ bundle update
$ rails server
︙
/home/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-4.2.6/lib/active_support/core_ext/numeric/conversions.rb:131:in 
`block (2 levels) in <class:Numeric>': stack level too deep (SystemStackError)
```

今度は別のエラーとなってしまった


<h2>stack level too deep</h2>
解決方法は[こちら](https://stackoverflow.com/questions/41504106/ruby-2-4-and-rails-4-stack-level-too-deep-systemstackerror)に載っていた。
今回はrailsのversionを4.2.6で実行していたが、4.2.8に変更することで解決しそうだ。

ということでGemfileを編集する。

```text:Gemfile
︙
gem 'rails', '4.2.8' → '4.2.6'に修正
```

再びbundle updateをして実行

これで解決できた。
python -Sでexit()を殺す

```python
PS C:\Users\takey\Desktop\myspace\workspace> python -S
Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)] on win32
>>> exit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'exit' is not defined
>>>
```

[コマンドラインと環境 -S](https://docs.python.jp/3/using/cmdline.html#id3)

> -S(原文)
site モジュールの import と、そのモジュールが行なっていた site ごとの sys.path への操作を無効にします。後に site を明示的に import しても、これらの操作は実行されません (実行したい場合は、 site.main() を呼び出してください)。

```python
>>> import site
>>> exit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'exit' is not defined
>>> site.main()
>>> exit()
PS C:\Users\takey\Desktop\myspace\workspace>
```
[ssh] Macでssh接続(パスワード認証->公開鍵認証)

## 環境
 - 自分のMac
 - sshで接続するMac

## やる事
 1. 同一ネットワーク内からsshで接続出来るようにする
 2. 異なるネットワークからsshで接続出来るようにする
 3. パスワード認証から公開鍵認証にする
 
## 作業
### 1. 同一ネットワークから接続出来るようにする
#### ssh接続される側
   - 設定 > 共有 > リモートログインのチェックをON
   
<img width="671" alt="スクリーンショット 2018-10-16 23.08.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/117388/11ab8e39-a120-5f14-7f56-7c45a3fd1815.png">
   
#### ssh接続する側
   - 'このコンピュータにリモートからログインするには、"ssh [端末名]@[IP]"と入力してください。'の""部分をそのまま打ち込む
   
```
$ ssh [端末名]@[IP]
```
   
### 2. 異なるネットワークから接続出来るようにする
  - 接続先PCがある場所のグローバルIPを調べる
   https://www.cman.jp/network/support/go_access.cgi
    
  - 接続先PCのIPを固定にする
   設定 > ネットワーク > 詳細 > TCP/IP
   - IPv4の設定を'DHCPサーバーを使用(アドレスは手入力)'に変更
   - IPv4アドレスを入力(=適当に空いているIPで良いと思います。ex. 192.168.1.253)
   
  - 接続される端末の設定で、ssh接続のポートを指定してあげる

   
```
$ sudo vi /etc/services

/etc/servicesの以下の行を，
ssh              22/udp     # SSH Remote Login Protocol
ssh              22/tcp     # SSH Remote Login Protocol
↓以下のように好きなポート番号に変更する
ssh              6XXXX/udp     # SSH Remote Login Protocol
ssh              6XXXX/tcp     # SSH Remote Login Protocol
```
    
  - 接続先ネットワークのルーター設定を変更する
   - ssh接続の際にポート指定すると、指定された端末に振ってあげる、といった設定(=静的IPマスカレード)
   
  - ssh接続の設定を反映させるため、接続される側の端末を再起動
      
  - ssh接続する
   
```
$ ssh [端末名]@[グローバルIP] -p [ポート番号]
```

### 3. ssh接続をパスワード認証から公開鍵認証にする
上のままだと何も認証なく接続出来てしまうので、今回はパスワード認証->公開鍵認証の設定をする
  
#### /etc/ssh/sshd_configを設定(パスワード認証)

 - 設定ファイルを編集
  
```
$ sudo vi /etc/ssh/sshd_config
↓
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes # ここのコメントアウトを外す
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no # ここのコメントアウトを外してnoに
```
  -  一旦ssh接続を抜けて、再度接続し、パスワード認証になっていることを確認する
  
#### /etc/ssh/sshd_configを設定(公開鍵認証)

 - 公開鍵を生成する
   - http://ponsuke-tarou.hatenablog.com/entry/2017/10/19/002727
   - http://cameong.hatenablog.com/entry/2017/02/17/011429
 
```
--- 自PCの設定 ---
# 1. オプション指定しない場合、デフォルトで~/.ssh配下にid_rsaとid_rsa.pubが生成される
$ ssh-keygen -t rsa
$ ls ~/.ssh/
id_rsa      id_rsa.pub

# 2. コピペ出来るように、クリップボードに保存しておく
$ cat ~/.ssh/id_rsa.pub | pbcopy
```

 - 生成した公開鍵を、ssh接続先のPCに記載する

```
$ ssh [端末名]@[グローバルIP] -p [ポート番号]

--- ssh接続先PCの設定 ---
# 1. クリップボードの内容をここにペースとして保存
$ sudo vi ~/.ssh/authorized_keys

# 2. 設定ファイルを編集
$ sudo vi /etc/ssh/sshd_config
↓
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no # ここをnoに
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no

# 3. sshdを再起動する
$ sudo launchctl stop com.openssh.sshd
```

 - 一度ssh接続を抜け、再度接続する

```
変更前:
$ ssh [端末名]@[グローバルIP] -p [ポート番号]
Password: xxxxxx
-> パスワードが分かれば、接続出来ていた。

変更後:
$ ssh [端末名]@[グローバルIP] -p [ポート番号]
端末名@グローバルIP: Permission denied (publickey).
-> 秘密鍵がないと接続出来ない。
```

## その他
 - ssh接続される側の設定が変わって、sshのfingerpringが変更になって、接続できない場合がある
  - https://qiita.com/grgrjnjn/items/8ca33b64ea0406e12938

## 最後に
ネットワーク周りの設定は、セキュリティに関わってくるのでよく調べてから行った方が良いです。
やる際は自己責任で頑張りましょう！今回も良い勉強になった。
Active Recordのバリデーションについて調べてみた1

Rails Active Recordのバリデーションあまりよくわかっていないので、調べてみました。
バリデーションのヘルパーについては次回

## バリデーションって？
正しい値だけをデータベースに保存するために、値を制限できる。保存の前に値の検証を行う

## 具体的な使用方法
### バリデーションを実行するタイミングとトリガとなるメソッド
- 新規レコードを作成後、保存のアクションをするタイミングで実行
- 下記のメソッドは、バリデーションが実行されるため、バリデーションに引っかかると保存に失敗する

`create, create!, save, save!, update, update!`
　！付きのメソッドは、破壊的メソッドでレコードが無効な場合は例外を発生させる。
　　非破壊的なメソッドの場合は無効の場合以下の挙動
　 `save/update => false, create => オブジェクトを返す`


### バリデーションのスキップ
saveメソッドに　`validate: false` を与えると、バリデーションのスキップができる
`save(validate: false)`

＝＝＝下記のメソッドもバリデーションをスキップする＝＝＝

- decrement!
- decrement_counter
- increment!
- increment_counter
- toggle!
- touch
- update_all
- update_attribute
- update_column
- update_columns
- update_counters

### バリデーションの確認メソッド
トリガになる処理を行う前に、手動でバリデーションを実行することもできる

- valid?

```ruby:user.rb
class User < ApplicationRecord
  validates :name, presence: true
end
 
User.create(name: "piyopiyo").valid? # => true
User.create(name: nil).valid? # => false
```

- errors.messages
バリデーション実行後、 `errors.messages`　インスタンスメソッドを使用すると、発生したエラーが確認できる
(*このメソッドはエラーのコレクションを返します。*)
newでインスタンス化されたオブジェクトは、エラーが保存されない、createやsaveなどトリガなるメソッド実行時のみ


- errors[ ]
errors[:attribute]で、特定のオブジェクトの属性が有効かどうかを確認
`User.create.errors[:user]`
*attributeの全てのエラーの配列を返す、属性でエラーが出なかった場合は空配列を返す*

- errors.details[ ]
errors.details[:attribute]で、invalidな属性で、どのバリデーションが失敗したのかを確認
**:errorがキーで、 `失敗したバリデーター` のシンボルが値となるハッシュの配列を返す**
[{ error: :hogehoge }]

```ruby:user.rb
class User < ApplicationRecord
  validates :name, presence: true
end

user = User.new
user.valid? # => false
user.errors.details[:name] # => [{errors: :blank}]
```

## これから調べること
- [ ] 条件付きのバリデーション
- [ ] バリデーションヘルパーについてさらう
GraphQLのフィールドの追加

# やりたいこと：型に一個独自のフィールドを追加したい

[ゼロからGraphQLの記事](https://qiita.com/Hiroyuki_OSAKI/items/e1fc16b973fa499c32e2)にも書きましたが、GraphQLサービス実装は`resolver`実装がメイン。

フィールド追加は型定義自体は簡単です。`type`定義にフィールド名を書けばいい。

じゃあその値は`resolver`にどうやって書くの？

フィールド追加の場合はやり方がちょっと特殊。

## 参考にすべきApolloのドキュメント

https://www.apollographql.com/docs/graphql-tools/resolvers

## Resolverへの書き方：型の下にフィールド名を書く

Apolloのドキュメントを見ると、`resolver`定義のところで普通は`Query`しか書かないところが、、
(すいません、型定義は私が足しました。見るべきは`resolver`ですよ)

```typescript
const typedef = `
  type Author {
    posts: [Posts]
  }
`

const resolver = {
  Query: {
    author(obj, args, context, info) {
      return find(authors, { id: args.id });
    },
  },
  Author: {
    posts(author) {
      return filter(posts, { authorId: author.id });
    },
  },
};
```

**なんか`Author`が増えてる**

そして、**なんか`Author`の下に`posts`というフィールドの実装が生えている**、、、

つまり、

**フィールドの追加は、resolverの直下に型名`Author`を書いて、その下にフィールド名を付けて実装を置く**

ということなのでした。

ドキュメントを読めば書いてあるのですが、なんか気づきにくい。なんでだろう。

一応`graphql-yoga`でも動作確認済みです。
Pythonista3でstashを実行しNo module named 'urlparse'が出た場合の解決方法

# 問題
Pythonista3でStaShを実行し`git clone`をしようとしたら下記エラーが発生


~~~
stash: <class 'ModuleNotFoundError'>: No module named 'urlparse'
~~~

# 原因
stashをpython3で実行しているため

# 解決策
設定から`Default Interpreter`を選択しバージョンを**2系**に変更してから'stash'を実行
その後、'git clone'を実行する
※stashを実行したら、`Default Interpreter`はバージョンを**3系**に戻してOK

単純なことなのに、すごく悩みました。
インスタンスを2系で立ち上げれれば良いので他の方法もあるかも知れません。

# 参考にしたissues抜粋
https://github.com/ywangd/stash/issues/321

>Well, you can still run StaSh in python2 (works also in pythonista 3) until git is ported. You could even run a py2 StaSh-instance and a py3 StaSh-instance next to each other at the same time, so you could use 'git' in py2 StaSh and do your py3 work in the py3 StaSh instance.
良いか悪いかは別としてCursorNotFoundを防ぐmongoidのno_timeoutメソッドについて


## 前提
mongoidではクエリの実行時間が長い場合に
 `Moped::Errors::CursorNotFound` というエラーが発生してしまいます:fire:

実行時間が長すぎるということは設計にしろ発行するクエリにしろ何らかの見直しが必要なこともあると思います。
しかし、多少実行時間が掛かっても、処理をタイムアウトしたくない場合があります。

```
例) 何十万件のデータを扱うスクリプトをrakeタスク上で実行する場合
```

そんな時のためにタイムアウトせずに
mongoidのクエリを実行出来る `no_timeout ` というメソッドがあります！

## 使用されることが想定されるケース

- 大量件数に対する繰り返し処理を行う場合

```ruby
# ここのHogeはモデル
Hoge.no_timeout.each do |hoge|
  繰り返しの中で実行したい処理
end
```

通常、 `.no_timeout` を付けない場合、実行に時間が掛かる件数の場合、
eachの途中で `Moped::Errors::CursorNotFound` になります。
laravel5.5でGoogle chromeからs3にあるファイルをダウンロードできない不具合に対応する

こんばんはD3vel0pperです。
今日は表題の通りの記事です。

## 何が起こったか

結論から書くと、 chromeの不具合(仕様？)により、s3にあるファイルをダウンロードする際に、一手間かけないといけなくなりました。

具体的には、ファイルを `putFileAs()` を用いてs3上にアップロードする際、第4引数にメタデータとして `['ContentType' => 'binary/octet-stream']` を指定する必要があります。

## 環境

Google Chrome 69.??
laravel 5.5
flysystem-aws-s3-v3(s3のドライバ) ?? ← 現在確認中です

## 経緯

最近業務でlaravelを触っており、またデータベースやバックエンドにawsのdynamodbやs3を採用したプロジェクトを担当しております。
その中で、laravel上で作成し、s3にアップロードしたcsvファイルをlaravelにて構築したwebアプリケーション上からダウンロードする処理がありました。

その際、以下のようなコードを書いておりました。

```blade.php
<a href="path_to_s3_file" download>hogefilename.csv</a>
```
upload処理を担当するController部分

```controller.php
Storage::disk('s3')
    ->putFileAs(
        $path,
        new File($local_path_to_file),
        $filename,
        'public'
    );
```
この状態で、アップロードを行い、chromeに表示されたリンクをクリックしてダウンロードしようとすると、真っ白なページに飛ぶだけでダウンロードが始まりませんでした。

よくあるミスとして、awsのcledentialなどが間違っているパターンや、ファイルがそもそもアップロードされていないなどをチェックしましたが、どれも問題ありませんでした。

また、s3へのurlが間違っているかと思い、リンクurlとs3の管理画面から該当のファイルのurlを確認しましたが、こちらも問題なし…

と、上司と色々調べていたところ、アップロードされたファイルのメタ情報に違いがあるという指摘が。
確かに見てみると他のダウンロードできる（s3へ管理画面からアップロードしたもの）には `Content-type: binary/octet-stream` が、一方ダウンロードできないものについては `Content-Type: text/csv` が付与されていました。

そこで、管理画面上からこのメタデータの値を `Content-type: binary/octet-stream` へと変更したところ、正常にダウンロードできるようになりました。

## laravelにてどうやってメタ情報をセットするか

ここまでくると、どうやってs3のメタ情報を指定するのか、と言うことを調べることになりました。
そして、結果的に以下のサイトを見つけました。

https://stackoverflow.com/questions/28989605/add-metadata-headers-expires-cachecontrol-to-a-file-uploaded-to-amazon-s3-us

これによると、s3へのアップロード処理として使える `putFileAs()` メソッドは、公式サイトのドキュメントでは `'public'` を指定することで公開状態にできる、と言う説明に止まっていますが、どうやら *メタ情報を連想配列にして渡すことができる* とのこと。

参考までに渡せるキーは以下が代表例です。

`'CacheControl'`
`'Expires'`
`'StorageClass'`
`'ServerSideEncryption'`
`'Metadata'`
`'ACL'`
`'ContentType'`
`'ContentDisposition'`
`'ContentLanguage'`
`'ContentEncoding'`
`'visibility'`

この中に、今回探していた `ContentType` がありますので、これをキーとしてControllerを以下の処理へと書き換えました。

```controller.php
Storage::disk('s3')
    ->putFileAs(
        $path,
        new File($local_path_to_file),
        $filename,
        [
            'visibility' => 'public',
            'ContentType' => 'binary/octet-stream'
        ]
    );
```

## 結果

この処理へと変更したのちにアップロードしたファイルは、きちんとダウンロードされるようになりました。
しかし、公式ドキュメントに書いておいてほしいと言うのは贅沢なんだろうか。。。

ちなみに、私は「よっしゃわかった！headerの書き方と同じだろ！」と思って `['Content-Type' => 'binary/octet-stream']` とか書いて３０分ぐらい潰しましたので、みなさん同じ轍は踏まないでくださいね。。。

以上です。ご指摘等あればどしどし送ってください。
Cabocha環境をWindowsでDockerを使ってお手軽構築

[言語処理100本ノック 2015の第4章: 形態素解析](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch4)を解くためにCabochaを使えるようにしました。係り受け解析に使います。

最初はWindows上に直に構築しようとしたのですが、64bitのWindowsでは挫折しました(可能かもしれませんが、時間をかけたくなかったのでDocker使いました)。Cabochaが32bitのMecabを参照してしまい、エラーとなるからです。
ちなみに他PCのWindows10環境ではWSL上にCabochaをインストールしました。WSLに直接インストールするよりDockerでpullした方が簡単ですね。

参考リンク

- [自然言語処理100本ノックをWindows/Python3で　第五章を解く](https://hytmachineworks.hatenablog.com/entry/2017/12/09/105027)：環境構築時におおいに参考にしました
- [MeCab公式サイト](http://taku910.github.io/mecab/)：名前の由来は作者の好物だからメカブらしい・・・
- [Cabocha公式サイト](https://taku910.github.io/cabocha/)
- [形態素解析 wikipedia](https://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90)：文を分解します。日本語は英語みたいなスペース区切りじゃないので大変。
- [構文解析 wikipedia](https://ja.wikipedia.org/wiki/%E6%A7%8B%E6%96%87%E8%A7%A3%E6%9E%90)：係り受け解析ではないですが・・・。
- [初心者用Docker基本コマンド一覧(新旧スタイル対応)](https://qiita.com/FukuharaYohei/items/ef5cf790b5269e73cdb3)：久々のDockerだったので過去の自分の記事を見ながらDockerを動かしました。
- [記事「滝沢カレンの理解不能な文章を言語解析してみた。」](https://qiita.com/naoyu822/items/9d7a83879c161573f63c)：面白い記事でした:point_up:

#環境
|種類|バージョン|内容|
|:--|:--|:--|
|OS|Windows8 64bit |自宅PCなのでWindows8.1です|
|Docker|Docker Toolbox|インストールは[「Windows 8.1でDocker ToolboxをインストールしてDockerを動かす」](https://qiita.com/FukuharaYohei/items/a913f5ef5a5aa550f46a)参照|

#インストール手順
##1. Docker HubからPull
Docker Hubの[dockeryama/docker.cabocha](https://hub.docker.com/r/dockeryama/docker.cabocha/)を使わせていただきました。いろいろなRepositoryを精査して決めたわけではなく、環境構築を早く終わらせたかったので適当に選んでいます。もっと最適なRepositoryがあるかもしれません。
Docker Quickstart Terminalを起動してRepositoryをpullします。

```docker
docker pull dockeryama/docker.cabocha
```

イメージを確認します。

```docker
docker images
```

##2. Docker containerを作成
Pullしたイメージ"dockeryama/docker.cabocha"から"cabocha"という名前のcontainerを作成し、container一覧を表示。

```docker
docker container create -it --name cabocha dockeryama/docker.cabocha
docker container ls -a
```

##3. 確認
[Windows10未満のDocker Quickstart Terminalでは日本語表示できないらしい](https://qiita.com/bfkbx960/items/b0e8692d5bfe8adb5d5a)のでファイルを使ってcabochaを動かします。
###3.1. ファイルコピー
面倒ですが、ローカルPCのファイルをcontainerにコピーします。ファイル内には以下の文章を書いています。
「私は電車が好きです。」

```docker
docker container cp sample.txt cabocha:tmp
```

###3.2. Cabocha実行による係り受け解析
まずはcontainer起動しbash実行。

```
docker container start cabocha
docker container exec -it cabocha bash
```

tmpフォルダに移動してcabochaを実行します。

```bash
cd tmp
cabocha <sample.txt> sample_out.txt
```

###3.3. Cabocha解析結果確認
exitでcontainerを抜けます。

```bash
exit
```

DockerのファイルをローカルPCのtmpフォルダにコピーします。面倒くさい。

```docker
docker container cp cabocha:tmp/sample_out.txt /tmp
```

ファイルをWindows上で見ると、形態素解析され係り受けができていることを確認できます(例文が少し悪くてわかりにくい:sweat:)。
![10.cabocha_result01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/f7d1fafb-1079-bf75-8af3-5cd92e908733.jpeg)

#cabocha実行オプション
ちなみにcabocha実行時にf1オプションを付加すると詳しく結果が出てくれます。オプションについては[「CaboCha/南瓜: Yet Another Japanese Dependency Structure Analyzer」](https://taku910.github.io/cabocha/)を参照ください。

```bash
cabocha -f1 <sample.txt> sample_out_f1.txt
```

![10.cabocha_result02.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/36a690e1-a77f-374b-9a86-f6ab11c2c293.jpeg)
sympyで「積分(integrate)」をやってみた

(参考)台形則（数値積分）
https://qiita.com/omu58n/items/55699bd127ed74d6b73f

```fullscript.py
from sympy import *
var("x a b s")
f=(1-x**2)**(1/2)
a=0
b=1
s=integrate(f, (x, a, b))
print('s   =',s)
print('s   =',simplify(s))
print('s   =',0.443113462726379*sqrt(float(pi)))
print('pi/4=',float(pi/4))
# s   = 1.0*hyper((-0.5, 1/2), (3/2,), exp_polar(2*I*pi))
# s   = 0.443113462726379*sqrt(pi)
# s   = 0.785398163397448
# pi/4= 0.7853981633974483
```
hyperの日本語版を見つけた。
(参考)チュートリアルを読む＞これは知らん。
https://showa-yojyo.github.io/notebook/python-sympy/tutorial.html
exp_polarの日本語版を見つけた。
(参考)常微分方程式
https://showa-yojyo.github.io/notebook/python-sympy/ode.html
個人的リーダー論（チームまとめるポリシー）

これまでの経験とか失敗とか知識などから得た自分なりのリーダー論。
たまに自分でやれていない時もあるけど、そこは後で落ち込んで何とかリカバリーします。
あと、自分のスタイルに合ったものになってる。してる。
リーダー論は、原則的なものはあるかと思うけど、合う合わないは、人それぞれ。（原則的なものは別途まとめてみよう。そうしよう。）

・縁の下で支えるリーダー。あれこれ指示しない。
・指示ではなく、なるべく自然に自発的に仕事をやってもらう
・各人の能力を活かした仕事にする
・指示内容の背景から説明する
・インプット、アウトプットを明確にする
・仕事をしてもらう上で短期・中期・長期的な期待をインプットする
・会社に貢献しろとは言わない。各個人にスキルや経験が残るようにして、その結果、会社に貢献した結果になるようにする
・（主に新人向け）相手が社会人として、これから生きていく、食べていけるように貢献する
・問題が発生した時には一緒に解決する。
・傾聴する。否定しない。上から目線で言わない。
・感情的に怒らない。
・ネガティブな発言をしそうになった時は、一呼吸置いて、逆の意味（ポジティブ）な言葉に置き換えて発言する。
・業務的な内容の報告・連絡は、なるべく簡潔に短く時間を区切るようにする
・相談された時は、お互い納得できるまで出来るだけ長い時間を割く。
・仕事より体調が大事
・残業ありきの計画を立てない。
【変態】ArduinoとMozziでうねうね動くクラドニ図形【動的】

#まずはこちらを
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">うねうね動くクラドニ図形、変態だな。<a href="https://twitter.com/hashtag/%E5%85%B1%E7%8A%AF%E8%80%85?src=hash&amp;ref_src=twsrc%5Etfw">#共犯者</a> <a href="https://t.co/GKcCejCQY8">pic.twitter.com/GKcCejCQY8</a></p>&mdash; peiくん.make (@p3ishunma2) <a href="https://twitter.com/p3ishunma2/status/1052196594659938304?ref_src=twsrc%5Etfw">October 16, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#以前書いた記事の続きです。
[【自作】ArduinoとMozziでつくるクラドニ図形【簡単】](https://qiita.com/p3ishunma2/items/26d9d90020e75fefd5db)
の続編として、今回はクラドニ図形をセンサで動かしてみたいと思う。
どうなるだろうか。
#前回との変更点
硫化カドミウム (CdS) を使った半固定抵抗のcdsセルを、回路に組み込む。
手で覆ったり、光を当てると抵抗値が変わるので、Mozziと組み合わせればテルミンも作れる。
#回路図
![chladni_回路図.png](https://qiita-image-store.s3.amazonaws.com/0/285932/369f8c0a-ee5f-e9af-4da3-0fc52c67a4ed.png)
#プログラム

```c++:Chladni.ino:
#include <MozziGuts.h> //Mozziのライブラリを利用するために読み込み
#include <Oscil.h> //音出力用のオシレーターテンプレートの読み込み
#include <tables/sin2048_int8.h> //オシレーターでサイン波を利用するために読み込み
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA); //オシレーターのサイン波の形式を設定
#define CONTROL_RATE 64 //コントロールレート

int pitch = 200;

void setup(){
  startMozzi(CONTROL_RATE); //コントロールレートを設定
  aSin.setFreq(pitch); //出力する周波数
  Serial.begin(9600);//Start connection with serial monitor

}

void updateControl(){
  int pitch = mozziAnalogRead(1); //1番ピンから入力
  aSin.setFreq(pitch); //出力する周波数
  Serial.println(pitch);
}
int updateAudio(){
  return aSin.next(); //サイン波を引き続き出力
}
void loop(){
  audioHook(); //音の出力
}
```

出力はただの正弦波で、周波数をアナログ入力に変えてるだけ。
センサの値を確認するために、シリアルモニタに出力
プルアップ/プルダウンの切り替えや、周波数に任意の定数をかけ算して、調整してみても面白い
[Laravel] ページネーションを Bootstrap 4 スタイルにする

# 環境

- Laravel 5.5
- Bootstrap 4.1

# やりたいこと

Laravel 5.5 だと Eloquent ORM の `paginate()` および `$model->links()` によって出力されるページネーションが Bootstrap 3 スタイルなので、 Bootstrap 4 スタイルにしたい。

# 実装

`bootstrap/app.php` の末尾の `return` の手前あたりに以下を追記する。

````bootstrap/app.php
Illuminate\Pagination\AbstractPaginator::defaultView("pagination::bootstrap-4");
````

# おまけ: ページネーションをセンタリングする

Bootstrap 4 スタイルの `$model->links()` から出力される `<ul>` 要素はフレックスコンテナになっているので、 `.text-center` や `.mx-auto` などのクラスを付加した `<div>` 要素で囲んでもセンタリングされない。 `.pagination` クラスに対して `justify-content` を指定する必要がある。

````
<style>
    .pagination { justify-content: center; }
</style>
````

# 参考

- [Laravel 5.5 Pagination for Bootstrap 4](https://laracasts.com/discuss/channels/laravel/laravel-55-pagination-for-bootstrap-4)
各WEBサービスでの2段階認証の対応状況を確認してみた

Yubico セキュリティキー を購入したので、各WEBサービスでの2段階認証の対応状況を確認してみた。

| WEBサービス | 認証アプリ | FIDO U2F | SMS | 備考 |
|:---|:--:|:--:|:--:|:---|
| Google | ● | ● | ● | 他にスマホ認証あり |
| Github | ● | ● | ● | |
| Slack  | ● | × | ● | |
| Facebook | ● | ● | ● | |
| BitBucket | ● | ● | × | |
| Amazon | ● | × | ● | |
| AWS | ● | ● | × | 認証アプリとU2Fは排他設定 |
| Twitter | ● | ● | ● | |
| Qiita | ● | × | × | |
| Yahoo!JAPAN | ● | × | ● | 認証アプリは専用 |
| Nulab | ● | × | ● | |
| Discord | ● | × | ● | |
| Microsoft | ● | × | ● | 認証アプリは専用 |
| dアカウント | ● | × | ● | 認証アプリは専用 |
| Blizzardアカウント | ● | × | ● | 認証アプリは専用 |
VS Code 1.28 の新機能 - ショートカット設定画面の検索機能の改善

https://code.visualstudio.com/updates/v1_28#_record-and-search-keyboard-shortcuts

キーボートショートカットの設定画面で既存の定義を検索する際に、特定のキーバインドについて検索したい場合、今まではいちいち`shift+k`とか`ctrl+k`とかを手で入力する必要があったが、直接のキー入力によって検索条件のキーバインドを指定できる機能が追加された。

`Alt` + `K`を押すか、もしくは入力欄右端にあるキーボードのアイコンを押すと`キーの記録`モードになる。このモードの時に例えば`Ctrl`+`K`を押すと入力欄に`ctrl+k`と表示される。`ESC`を押すとモードが解除される。

![keybind.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/62f0cd65-f20c-9cd6-99fa-981626ff5515.gif)

ただ、Windows版で試してみると、記号がことごとく`oem_comma`とか`oem_period`とかみたいな文字列になってしまって使えない・・・（キーボードの種類による？）。

![keybind_ng.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/e07daa9a-f0c3-4f27-9392-a63f3d11ed7d.gif)
【Swift】enumのraw valueをオーバーフローさせると？

# 結論
コンパイルエラーで怒られます:innocent:

``` swift
enum Number: Int {
    case max = 9223372036854775807
    case next    // Integer literal '9223372036854775808' overflows when stored into 'Int'
}
```

# 解説

## enumのraw valueについて
Swiftのenum(列挙型)はcaseに対応した値を持たせることができます。
この値のことをraw valueといいます。

raw valueを設定するには列挙型の定義で列挙型名の後に続けて`:raw valueの型`のように書き、それぞれのケースに`=`で指定します。

``` swift
enum Number: Int {
    case one = 1
    case two = 2
    case ten = 10
}
```

Int型のraw valueのデフォルト値は0で、`=`で指定しなかった場合は直前のケース+1の値になるという特性があります。

``` swift
enum Number: Int {
    case zero
    case one
    case ten = 10
    case aaa 
}
```
``` swift
print(Number.zero.rawValue)  // 0
print(Number.one.rawValue)   // 1
print(Number.ten.rawValue)   // 10
print(Number.aaa.rawValue)   // 11
```

## オーバーフローについて
オーバーフローとは、限界を超えてしまった状態です(ざっくり)
SwiftのInt型は符号付き整数を表すので、64ビット環境で
-9223372036854775808から9223372036854775807までの数値を表現できます。
この値は`Int.min`および`Int.max`で取得できます。
minを下回る、もしくはmaxを上回る計算などするとエラーとなります。

``` swift
print(Int.min)  // -9223372036854775808
print(Int.max)  // 9223372036854775807

// これはオーバーフローによるエラー
Int.max + 1
```

# ということで

enumの自動採番でIntの限界を超えるとどうなるのか気なってしまった結果、この記事ができあがりました。
結果は冒頭の通り、普通にコンパイルエラーです:innocent:

922京3372兆368億5477万5807を超えるケースを列挙する際には注意しましょう:innocent:
オンプレ MySQL から Aurora への移行（JAWS-UG 名古屋 AWS 勉強会 データベース祭り!! LT 2018.10.17）

## はじめに

 - 自己紹介はありません
 - 話す内容＝個人の見解です
 - 基本的に作業時点で確認した情報です（2017/6 ～ 9）
 - 詳細は Qiita にまとめています
  - https://qiita.com/hmatsu47
  - https://hmatsu47.hatenablog.com/aurora

---

## 今日話す内容
 - 移行前後の環境
 - データ移行
 - 性能問題
 - その他の制約（Failover 処理／バグ／未サポート機能）

---

## 移行前の環境
 - VMware vSphere
 - ストレージアプライアンス（10G-iSCSI）
 - MySQL 5.5 × 2（メインは 1 台）
 - データは 1TiB 未満（DB／ファイル）
 - DR:BD や MySQL 準同期レプリケーション等は使わず
 - Webサーバ数台（Java 8／Tomcat 8）
 - Web ～ DB 間 Connection Pooling あり（Commons DBCP2）

---

## 移行後の環境
 - Web サーバは EC2 へ（東京 AZ-a と AZ-c に分散配置）
 - Aurora は db.r3.2xlarge がメイン（途中で db.r4 へ）
 - ファイルは S3 へ

---

## データ移行 (1/3)
 - DMS は使わず MySQL レプリケーションで複製
  - DMS の制約の問題があった
  - 治安の悪いデータ（0000-00-00 00:00:00）が複製できない
  - キャラクタセット：UTF8MB4 がサポートされない

---

## データ移行 (2/3)
 - Aurora クラスタの FQDN が長すぎる
  - レプリケーションマスターの指定で 60 文字制限に引っかかる
  - 対応策：Aurora クラスタ名を短めに
 - タイムゾーン不一致問題（オンプレ側設定もれ）
  - タイムゾーン「SYSTEM」が指す時刻：JST（オンプレ）／UTC（Aurora）
  - 対応策：オンプレ側で明示的に JST（Asia/Tokyo）を設定

---

## データ移行 (3/3)
 - レプリケーション先で LAST_INSERT_ID が 0 になるバグ（後述）
  - 対応策：バイナリログ形式を MIXED → ROW に

---

## 性能問題 (1/3)
 - Connection Pooling の性能問題が発生
  - ピーク時クエリ数を捌けない
  - Failover で詰まる
 - AZ 内のネットワークレイテンシの影響
  - オンプレ比 1.5 ～ 2 倍のレイテンシ（当時）
  - その後ネットワークの増強で幾分改善
  - さらに NITRO 世代ではオンプレに近いレベルまで軽減されている

---

## 性能問題 (2/3)
 - AZ 間のネットワークレイテンシの影響
  - ms オーダーなので、DB データ書き込み時に必要な数の ACK が返るまでの時間がどうしても長くなる
 - 改善策 1：Java GC 時間の調整
 - 改善策 2：高速な Connection Pooling に入れ替え：DBCP2 → HikariCP

---

## 性能問題 (3/3)
 - シーケンシャルな処理の性能問題
  - 夜間バッチ処理など
  - レイテンシの影響を大きく受ける
  - 改善策：データの読み込み対象の絞り込みを徹底
  - （最近は非同期先読み（AKP）やパラレルクエリなどで改善）

---

## その他の制約／Failover 処理
 - Aurora Failover で Writer 向けの Connection が Reader に接続してしまう
  - 通常は MariaDB Connector/J で Failover 対応する
  - MySQL Connector/J と挙動が違うので断念
  - Connecion Validation 用のストアドを作成して対応
  - Reader に接続したらエラー→ Connection Pooling 側で再接続するように

---

## その他の制約／Fixされないバグ
 - MySQL 5.6.10／MySQL 5.7.12 より後に Fix されたバグのうち AWS が対処せず残したもの
  - 例：レプリケーションフィルタが使用されていると LAST_INSERT_ID が不正にレプリケートされる (バグ #69861)
  - バージョン 1.17 で Fix (2018/3/13)

---

## その他の制約／Auroraでサポートされない機能
 - MySQL 5.6.10／MySQL 5.7.12 より後に実装された機能の大半
  - 例 1：RANDOM_BYTES()／MySQL 5.6.17 でサポート
  - 例 2：MySQL 8.0 で実装された JSON 関数のバックポート／MySQL 5.7.22 でサポート

---

## まとめ
 - Aurora 固有の問題というより AWS 環境（複数 AZ による冗長化）にフィットさせるのに苦労した（レイテンシ問題）
 - Aurora 固有の問題は、MySQL で Fix or 追加実装された機能の取り込みが追い付いていない点への対処がメインだった

---

## ありがとうございました
配列とポインタの加算でハマった話


# やりたかったこと
`string.h`にあるmemcpy()関数を使って配列を希望の数だけコピーできるがこれを用いて大きな配列から適当な部分を切り出して保存したかった。

全てint型と仮定して例にだすと，
BUFF = {1,2,3,4,5,6,7,8} とあるならば，A={1,2,3,4},B={5,6,7,8}のように分けたい。

マルチバイト文字列をシリアル通信で送る時などに使うだろう。

## 正解（のうちの一つ）
配列Aに値を詰めるのは楽勝でBに詰めるのに詰まったのだが，
結論から言うと以下のように書くのが良いだろう。

```c
   memcpy(&a,&buff,sizeof(int)*4);
   memcpy(&b,&buff[4],sizeof(int)*4);
```

&buff[4]でbuffの5番目の値の先頭のアドレスを指す。
コメントを頂いたが送り手と受けてが配列ないしポインタで定義されているなら以下の様に書き換えても構わない。

```c
   memcpy(a,buff,sizeof(int)*4);
   memcpy(b,buff+4,sizeof(int)*4);
```

## ポインタの加算にて失敗した話
C言語の授業でおぼろげにポインタを加算した記憶があった私は以下のコードでも動くだろうと最初に実装したがこれは間違いであった。


```c
   memcpy(&a,&buff,sizeof(int)*4);
   memcpy(&b,&buff+4,sizeof(int)*4);
```

このコードの間違いは，buffについている+4の加算が変数`buff`のサイズ×4つ分アドレスを移動してしまうという点にある。

今回，buffを8列*int = 32バイトと仮定したので（注：intのサイズは環境に依る）これは計128バイト，=0x80分も動いてしまう。

ポインタをint*でインクリメントするならintの大きさの分のみインクリメントされるが，今回のbuffはいわばポインタのポインタint**を指すことをうっかり忘れていたのだった。


# 再現コード

以下のコードを実行して未来の自分にはこの教訓を思い出してほしい。

```c++

#include<stdio.h>
#include<string.h>

int main() {
   int buff[8]={1,2,3,4,5,6,7,8};
   int a[4],b[4];
   int* ptr;
   
   memcpy(&a,&buff,sizeof(int)*4);
   memcpy(&b,&buff[4],sizeof(int)*4);
   printf("%d %d\n",a[0],b[0]);
   
   ptr = &buff[0];
   printf("array: %p %p %p\npointer: %p %p %p\n",&buff,&buff+1,&buff[4],ptr,ptr+1,ptr+4);
   
}
```

- 計算結果は以下の通り。

```
1 5
array: 0x7ffe69c9ff00 0x7ffe69c9ff20 0x7ffe69c9ff10
pointer: 0x7ffe69c9ff00 0x7ffe69c9ff04 0x7ffe69c9ff10
```

## 余談：マルチバイト列から浮動小数点の復元
今回の受けては同じint型だったが，uchar型で4つ値を受けてfloatで定義したアドレスに値を順次詰めることで浮動小数点を復元できる。

```C++
#include <stdio.h>
#include <string.h>

int main()
{
    float f1,f2;
    unsigned char bf[8],in1[4],in2[4];
    
    float v1 = 9.8;
    float v2 = 0.1;
    
    memcpy(&in1,&v1,4);
    memcpy(&in2,&v2,4);
    
    for(int i=0;i<4;i++){
        bf[i]=in1[i];
        bf[i+4]=in2[i];
    }
    printf("%s \n",bf);
    
    memcpy(&f1,&bf,4);
    memcpy(&f2,&bf[4],4);
    
    printf("f1 = %f, f2 =  %f \n",f1,f2);

    return 0;
}
```

ためしてみるよろし。
〈準備編〉Bootstrapの読み込み方法

まずHTMLにCSSを読みこませる。
HTMLのheadに以下をtitleの上に入れる。

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


次にJavascriptを読み込ませる。
HTMLのbodyの一番下に以下を入れる。
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>


これはBootstrap公式ページのBootstrap CDNに用意されている。

さらに、JavaScriptを動かす為に、jQueryの読み込みも必要なので、
同じくBootstrap公式ページのBasic　templateの中にある下記を、先ほどのJavaScriptの上にコピペする。
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">
文章を左側にoverflowして、省略記号を表示したい

## やりたかったこと
タイトルまんま

## アプローチ
### フレックス
display: flexとjustify-content: flex-endによる実装。

```html:flexBox.html
<div class="box">
    <span class="txt">
        ながぁ〜い文章を左側にoverflowして表示して、省略記号を表示したい
    </span>
</div>
```

```css:flexBox.css
.box {
    position: relative;
    width: 200px;
    height: 200px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    overflow: hidden;
    border: 1px solid #ccc;
    box-sizing: border-box;
}

.txt {
    word-break: break-all;
    white-space: nowrap;
    padding: 0 10px;
}

.txt:before {
    content: 'ellipsis'; 
    position: absolute;
    left: 0;
    padding-left: 10px;
    background-color: #fff;
    z-index: 1;
}
```

IE以外はこれで実現できる。
IEではフレックスコンテナからフレックスアイテムがはみ出した場合、justify-contentやalign-itemsが効かない。

###フロート
float: rightによる実装。

```html:float.html
<div class="box_2">
    <div class="float_wrapper">
        <span class="float_txt">
            ながぁ〜い文章を左側にoverflowして表示して、省略記号を表示したい
        </span>
    </div>
</div>
```

```css:float.css
.box_2 {
    width: 200px;
    height: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    border: 1px solid #ccc;
    box-sizing: border-box;
}

.float_wrapper {
    position: relative;
    width: 100%;
}

.float_txt {
    word-break: break-all;
    white-space: nowrap;
    padding: 0 10px;
    float: right;
}

.float_txt:before {
    position: absolute;
    content: '\02026';
    padding-left: 10px;
    left: 0;
    top: 0;
    background-color: #fff;
    z-index: 1;
}
```

これでIEでもハッピーになれる。

##まとめ
見た目はそれっぽくできるけど、場合によっては文字が欠けたりする。
jsでゴリゴリやって実装する方法もあるみたい。
もっと簡単に実装できる方法ないかなぁ。

##参考
https://stackoverflow.com/questions/218065/overflow-to-left-instead-of-right
https://hugogiraudel.com/2014/12/16/css-riddle-reverse-ellipsis/
redashで参照されているテーブルやフィールドがないかを調べる


データ取得やビジュアライズでredashをよく使っています。
データソースもmysql, log, BigQueryなど多岐に渡って使えるので重宝しています。

が、いろいろとつなげてたくさん利用した結果、テーブル構造を変更したりするときに突然誰かが見ていたビューがエラーになるといったことが起きるので、特定の文字列を含むクエリを探し出せないかと調べたメモ

redash自体のDBにqueryというテーブルがあるのでそこにlike文をかけることで取得できる

## サンプル

```sql
-- redashのデータベースに向けて 
SELECT * FROM queries q 
WHERE query like '%words%'
  AND is_archived = false 
LIMIT 10;
```


## 実行環境

ver 5.0.1+b4851
なぜかRustで言語処理100本ノック ～第1章 後編～

[前編はこちら](https://qiita.com/kbone/items/47d108d361359de6b34c)
# 第1章: 準備運動
## 05. n-gram
> 与えられたシーケンス（文字列やリストなど）からn-gramを作る関数を作成せよ．この関数を用い，"I am an NLPer"という文から単語bi-gram，文字bi-gramを得よ．

単語n-gramと文字n-gramでそれぞれ作る必要がありますが、型が違うだけでほとんど中身は同じなので、文字n-gramの方だけ載せるとこんな感じです。

```rust
pub fn character_n_gram(text: &str, n: usize) -> Vec<String> {
    let max = text.len() - n + 1;
    let mut result = Vec::new();
    for i in 0..max {
        result.push(text.get(i..(i+n)).unwrap().to_string());
    }
    result
}
```

`get`で範囲指定が使えるのがすごく便利です。

## 06. 集合
> "paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ．

`HashSet`を使えばそれで終わりなので、特別に関数を作らずに直接求めてみました。演算子が使えるのは便利ですね。

```rust
let paraparaparadise = prepare::character_n_gram("paraparaparadise", 2).into_iter().collect::<HashSet<String>>();
let paragraph = prepare::character_n_gram("paragraph", 2).into_iter().collect::<HashSet<String>>();
let union = &paraparaparadise | &paragraph;
println!("和集合={:?}, 積集合={:?}, 差集合={:?}, find 'se'={}",
         union,
         &paraparaparadise & &paragraph,
         &paraparaparadise - &paragraph,
         union.is_some()
);
```

## 07. テンプレートによる文生成
> 引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ．さらに，x=12, y="気温", z=22.4として，実行結果を確認せよ．

`format!`を使うだけですが、せっかくなのでジェネリクスの練習も兼ねて関数化してみました。

```rust
pub fn generate_template_text<X: Display, Y: Display, Z: Display>(x: X, y: Y, z: Z) -> String {
    format!("{}時の{}は{}", x, y, z)
}
```

## 08. 暗号文
> 与えられた文字列の各文字を，以下の仕様で変換する関数cipherを実装せよ．

>* 英小文字ならば(219 - 文字コード)の文字に置換
>* その他の文字はそのまま出力

>この関数を用い，英語のメッセージを暗号化・復号化せよ．

文字が英小文字の場合、a→z、z→a、となるので同じ関数で暗号化・復号化できます。

```rust

pub fn encrypt(text: &str) -> String {
    text.chars().map(|c| if c.is_ascii_lowercase() { (219 - c as u8) as char } else { c }).collect()
}
```

## 09. Typoglycemia
> スペースで区切られた単語列に対して，各単語の先頭と末尾の文字は残し，それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ．ただし，長さが４以下の単語は並び替えないこととする．適当な英語の文（例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."）を与え，その実行結果を確認せよ．

第1章最後の問題、少し躓きました。とちゅう、シャッフル部分はrandクレートを使用しています。
まず、文字列を並び替えなければいけないとなると、`str`のままだと難しく、さらに文字列の結合をするときは先頭が`String`で後ろが`str`という形にしないといけないみたいです。また、`String`のスライスが`char`のスライスになってくれればよいのですが、そうはいかずに`u8`になってしまうようで一旦`Chars`に変換するという発想に至るのが難しかったです(ascii文字のみ想定にすればこの必要はないのですが)。

```rust
pub fn typoglycemia(text: &str) -> String {
    text.split_whitespace().map(|s| {
        if s.len() < 5 {
            s.to_string()
        } else {
            let (head, remaining) = s.split_at(1);
            let (body, tail) = remaining.split_at(remaining.len() - 1);
            let mut body: Vec<_> = body.chars().collect();
            thread_rng().shuffle(&mut body);
            head.to_string() + &body.into_iter().collect::<String>() + tail
        }
    }).fold(String::new(), |result, s| if result == "" { s } else { result + " " + &s })
}
```

# 第1章の感想
第1章なので楽かと思いましたが、特に最後はかなり詰まってしまいました。文字列の扱いって簡単そうに見えて(主に文字コード絡みのせいで)ややこしいですよね。
研修でgrepコマンドを使ってみました

#grepコマンドとは
grepコマンドとは、ファイル中の探したい文字を検索するのに役に立つコマンドです。
検索パターンには、"検索したい文字"のようにダブルクオーテーションで囲んで検索するほか、正規表現を用いた検索も可能です。

##コマンドの使い方
コマンドの書式は以下のようになります。

```
grep [オプション] パターン [ファイル1 [ファイル2...]]
```

基本的な使い方は以下になります。

```
grep "検索したい文字" 検索したいファイル名
```

検索したいファイルの中に、検索したい文字があるのか調べたい時に使えます。
例えばこのようなファイルがあったとします。

```student.txt　
Aida Nozomu
相田　望
Inoue Karen
井上　カレン
Uchida Hiroshi
内田　弘
Uchiyama Gorira
内山　ゴリラ
Enomoto Ren
榎本　蓮
Okabe Misuzu
岡部　美鈴
```

「内」がつく人を探したいとします。
（Macのターミナルを使って検索しています）

```
$ grep "内" student.txt
内田　弘
内山　ゴリラ
```

簡単ですね。このように取り出すことができます。

###オプションを使ってみよう
grepコマンドにはオプションがあります。その中のいくつかを紹介します。

####特定の文字以外を検索したい
こういう時は**-vオプション**がオススメです。
**-vオプション**は、マッチしない行を出力してくれます。

例として、「内」がつかない文字列を検索してみます。

```
$grep -v "内" student.txt
Aida Nozomu
相田　望
Inoue Karen
井上　カレン
Uchiyama Renzou
Uchida Hiroshi
Uchiyama Gorira
Enomoto Ren
榎本　蓮
Okabe Misuzu
岡部　美鈴
```

内田　弘と内山　ゴリラが排除されました。
grepコマンドは、指定された文字列が含まれる**行を返します**。
なので、内田　弘というように単語の間に空白があっても、同じ行にあった弘も同じく今回は排除されています。

####複数ファイル検索
ファイルが多く、どのファイルに検索したい文字が書いてあるのかわからない時に役に立ちます。
以下のような構造を例にして説明します。

```
Qiita/
├ fruits.txt
├ teacher.txt
├ student.txt
├ hoge/
   └  hoge.txt

```

```fruits.txt
Apple
りんご
Orange
オレンジ
Lemon
レモン
```

```teacher.txt
Uchihara Marina
内原　まりな
Kakimoto Mikan
柿本　みかん
Sasaki Mika
佐々木　ミカ
Seo Hayami
瀬尾　早見
```

```hoge/hoge.txt
Uchiyama
りんご
フルーツ
Apple
内容は適当です
```

複数のファイルから「内」が含まれるファイルを検索したいと思います。

```
$grep "内" ./*
grep: ./hoge: Is a directory
./sutudent.txt:内山　廉造
./sutudent.txt:内田　弘
./sutudent.txt:内山　ゴリラ
./teacher.txt:内原　まりな
```

この検索方法では、カレントディレクトリの下にあるファイルは検索できても、hogeディレクトリは検索できません。hoge/hoge.txtには「内」の文字があるので検索ヒットしてほしいです。
そういう時に便利なのが、**-rオプション**です。
このオプションは、フォルダ内のファイルを**再帰的**に検索してくれます。

```
$grep -r "内" ./*
./hoge/hoge.txt:内容は適当です
./sutudent.txt:内山　廉造
./sutudent.txt:内田　弘
./sutudent.txt:内山　ゴリラ
./teacher.txt:内原　まりな
```
hogeフォルダの中のファイルも検索してくれました。


####ファイル名を一覧で出して欲しい
こんな時は、**-lオプション**が便利です。
**-lオプション**は、行の内容は出力しません。マッチしたファイル名を出力してくれます。
ファイルの中身は見えなくてもよく、とにかくファイル名を知りたい時に使えます。

```
$grep -lr "内" ./*
./hoge/hoge.txt
./sutudent.txt
./teacher.txt
```

###終わりに

例えば、「内」という文字以外かつ"Uchi"も含まないファイルを出力して欲しい場合、

```
$grep -v "内" | grep -v "Uchi" student.txt
Aida Nozomu
相田　望
Inoue Karen
井上　カレン
内山　廉造
内田　弘
内山　ゴリラ
Enomoto Ren
榎本　蓮
Okabe Misuzu
岡部　美鈴
```

という結果になってしまいます。
期待値としては、「内」と「Uchi」以外が出力されて欲しかったのですが、うまくいきません。
アドバイスいただけますと幸いです。

以上、研修でgrepコマンドを使ってみました、でした！

## 追記
アドバイスをいただき、ようやく解決できました！

```
$grep -v "内" | grep -v "Uchi" student.txt
```
これは最初に私が試したものです。何が悪いのかというと、 "内" が検索されていないことでした。

もし同じような書き方をするのであれば、

```
$ grep -v "内" student.txt | grep -v "Uchi"
```

とすべきだったのです。
パイプラインは、左から見てその結果を右に渡して行きます。
ですので、最初の書き方ですと”内”を除けということは指示してあるのですが、「え？何から探すの？？」状態になってしまっていたと思われます。
まずはこのstudent.txtから "内" を除いてねという指示をした後に、プラス "Uchi" も除いてねとするのが正しかったのですね。

しかし、こんな書き方よりも便利な書き方を教えていただきました！
それは、 **-eオプション**です。

### -eオプションとは？

grepで、複数の文字列を指定する際に便利なオプションです。

書き方は以下になります。

```
$ grep -v -e "内" -e "Uchi" student.txt
```

grep一つで良いですし、パイプラインで繋げずに済みました。

student.txtから "内" と "Uchi" を除いてねという内容になります。
大変勉強になりました。ありがとうございました！
Slackの新規ユーザをチャンネルに誘導する技術

# 前提
現在、600人規模のSlackチームにいるのですが、誰でも気軽にチャンネルが作れるため、大量のチャンネルがあります。
以前はメンバーが手動で新規ユーザにいくつかチャンネルを紹介していたのですが、現在はそれが半自動になりました。
具体的には、Slackのカスタムレスポンスを使ってチャンネルを紹介しています。

# Slackのカスタムレスポンス
Slackでは「カスタムレスポンス」という、予め決められたキーワードに反応して投稿を行う機能があるので、これを利用します。

# 「チャンネル紹介」
「チャンネル紹介」とタイプすることで、以下のようなチャンネルが紹介されます。
![2018-10-16チャンネル紹介.png](https://qiita-image-store.s3.amazonaws.com/0/180861/d251de38-5a2b-bcae-123d-703d763f0126.png)

# 「チャンネルみくじ」
チャンネルみくじはおみくじなのでランダムに運勢とチャンネルが表示されます。現在16個ほどの結果が登録されています。以下は一例です。
![2018-10-16チャンネルみくじ.png](https://qiita-image-store.s3.amazonaws.com/0/180861/99f9d1c8-5f2b-6807-5ed4-0bfcb2cd1391.png)

# 宣伝
雑談Slackは以下のURLから参加できます。
どうぞ気軽に参加してチャンネルみくじを引いてください。
http://samezi-but.com/zdnj.html

# おまけ：失敗例
「#チャンネル紹介」というチャンネルを作ってそこに紹介したいチャンネルを書き込んだりもしていたのですが、このSlackチームは無課金のため、あっという間にログが流れて空白地帯になりました。
ちなみに同様の失敗として「#テーマ」チャンネルもあります。
課金しているチームであればどちらもそれなりにうまく運用が回る気がします。
マイニングしてEtherを採掘する

まず知っておくこと

### Etherbaseとは

これは実際に自分がマイニングした時に報酬を受け取るためのアカウントのこと。

はじめの段階ではeth.accounts[0]と指定されているので、
確認するためにも下記のコマンドをターミナルで実行。
（geth,console起動）

```
$ cd ~/ethereum_data
$ geth --networkid 10 --nodiscover --maxpeers 0 --datadir ./ console console
```

### Etherbaseで設定されているアカウントの確認をする


```
> eth.coinbase
"0x53c21065cce445d95dd0376083aca950f760d71d"
```

ここでもう一つアカウントを作成してみる。

```
> personal.newAccount('password')
"0xfd30920858f4cc882562183cc38cd71c45089088"
```


同一ノード上のアカウント数の確認をしてみると、

```
> eth.accounts
["0x53c21065cce445d95dd0376083aca950f760d71d", "0xfd30920858f4cc882562183cc38cd71c45089088"]
```

こうなっている。


2番目に作ったアカウント→[1]


```
> miner.setEtherbase(eth.accounts[1])
true

> eth.coinbase
"0xfd30920858f4cc882562183cc38cd71c45089088"
```



アカウント内に残高が入ってるかどうか確認してみる。

```
> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0
```

何もしていないので0。これはマイニングに成功した時やコントラクトの実行をしたときなどに増える。

```> eth.blockNumber
0```


### consoleで実行

```> miner.start(1)```


マイニングを実行しているかどうか確かめたいときには
```> eth.mining
true```



その後、

```
> eth.getBalance(eth.accounts[1])
0
> eth.getBalance(eth.accounts[0])
240000000000000000000
> eth.blockNumber
48
```


↑単位はwei

Wei -> Etherへの変換

```
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
240
```



マイニング停止するには
```> miner.stop()```


となる。
Ethereumの開発前準備

#### メモ。

まずHomebrew（パッケージマネージャー）をインストールする

```/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"```

### EthereumとGethのインストール


Go言語で触るためのGeth！

```$ brew tap ethereum/ethereum
$ brew install ethereum```



で、こうなればOK

```
$ geth version
Geth
Version: 1.7.3-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.2
Operating System: darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.9.2/libexec
```



準備完了。
GETHの起動手順。genesis.json

GETHの起動手順。


Gethのローカルプライベートテストネットを使用→起動するまでの準備

何を用意するか。

1　データディレクトリ
「送受信するブロックの情報とかアカウントの情報の保存」

2 genesis.json
「設定ファイル。ローカルプライベートテストネットを使う場合必要。」

では早速始めてみる。下記のコマンドをうつ

```
$ cd ~
$ mkdir Ethereum_data
$ cd Ethereum_data
```

で、これを丸コピー
https://github.com/ethereum/go-ethereum#defining-the-private-genesis-state



genesis.jsonに保存。


## geth初期化

初期化のやり方
```--datadir```

とうつので
```$ geth --datadir ./ init ./genesis.json```


フォルダが生成されているのを確認
```$ ls```


```genesis.json geth keystore```

geth keystoreがあれば良い。


## 指定するnetworkIdとchainIdは揃える必要がある


```$ geth --networkid 10 --nodiscover --maxpeers 0 --datadir ./ console```


/ethereum_data/geth.ipc
このように表示されていれば無事起動。



（ちなみに
--networkidはブロックチェーンネットワークの識別子を指定）
numbaを利用したpythonループの高速化

#目的
データ分析で処理が重たいときはいつもCythonの力に頼っているが、簡単なループについてはnumbaのほうが保守性が高いように思えてきた。
どのくらいの高速化のメリットがあるかを確認し、指標値として覚えておく。

# 環境
Python==3.6.5
numpy==1.14.3
numba==0.38.0

全部anacondaに入っていたもの。

# 試したこと

まずはimport

```python
from numba import jit
import numpy as np
```

通常のnp.arrayで計算した場合の関数

```python
def sum_python(arr):
    arr_size = len(arr)
    result = 0
    for i in range(arr_size):
        result += arr[i]
    return result
```

それをnumbaでjit化して、計算した場合の関数
(初稿時return resultではなく、returnとなっていたため、for文が無視されているとのご指摘をいただきました。以下修正版です。@yoshi123-xyz さん、ありがとうございました！！)

```python
@jit
def sum_numba(arr):
    arr_size = len(arr)
    result = 0
    for i in range(arr_size):
        result += arr[i]
    return result
```

以下、結果。

```python
_arr = np.arange(10000000, dtype=np.int64)

%timeit sum_python(_arr)
1.47 s ± 51.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit sum_numba(_arr)
3.83 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit  np.sum(_arr)
5.03 ms ± 9.18 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

~~なんかおかしい。さすがにsum_numba()が速すぎるような気が。。。~~
(修正後)
というわけで、np.sum()に近い性能を得られることができました。これはかなり使えそう。
homebrewで匿名情報を送信したくない場合

# 匿名情報を送りたくない場合はこちら

```bash
$ brew analytics off
# 確認
$ brew analytics
Analytics is disabled.
```
HomebrewがAnalyticsを導入し使用OS等の情報を集める様になった
https://rcmdnk.com/blog/2016/04/28/computer-mac-homebrew/
homebrewでインストールしようとしてエラーになったときのヒント

```bash
# brewをインストールしようとしてxdodeコマンドラインツールがないと言われたらこれを打つ
xcode-select --install

# brew doctorしてディレクトリが足りないと言われたら作る
brew doctor

sudo mkdir -p /usr/local/Frameworks /usr/local/include /usr/local/lib /usr/local/opt /usr/local/sbin /usr/local/Cellar
sudo chown -R $(whoami) /usr/local/Frameworks /usr/local/include /usr/local/lib /usr/local/opt /usr/local/sbin /usr/local/Cellar
```
awsのamazonLinuxにredmine3.4.6を入れてgoogle認証使えるようにするまで

aws ec2ダッシュボード
インスタンスの作成
Amazon Linux AMI
メモリは2gb以上で。1gbがいい場合は、hddをメモリに使えば問題なし
確認と作成
作成
キーペア選択

セキュリティグループ
インバウント
80もアクセスできるようにする

terminal
chmod 400 hoge.pen
ssh -i /Users/hoge/Downloads/hoge.pem ec2-user@IPアドレス
sudo su
yum -y update
yum -y install wget glibc-devel perl perl-Data-Dumper git
wget https://bitnami.com/redirect/to/326905/bitnami-redmine-3.4.6-3-linux-x64-installer.run
// ここから取得する　https://bitnami.com/stack/redmine/installer
chmod 700 bitnami-redmine-3.4.6-2-linux-x64-installer.run
3　日本語
y
y
y
/opt/redmine
hoge
hoge@hoge.com
hogehoge
14
n メール設定　あとでできる
y 続ける
しばらく待機
y 起動
redmineに接続可能になる

cd /opt/redmine/apps/redmine/htdocs/plugins
wget https://github.com/twinslash/redmine_omniauth_google/files/1851288/redmine_omniauth_google.zip
// どこにあったのかというと、ここ　https://github.com/twinslash/redmine_omniauth_google/issues/43
unzip redmine_omniauth_google.zip
yum groupinstall -y "Development Tools"
yum install -y kernel-devel kernel-headers
yum install -y epel-release
yum install -y ruby ruby-devel libxml2-devel libxslt-devel sqlite-devel
yum -y install gcc

/opt/redmine/use_redmine
これでbashを開くのが大事
cd /opt/redmine/apps/redmine/htdocs/
bundle install --no-deployment

awsのelasticIPで固定する
google認証をするためにはapiのキーが必要
キーを使うにはURLが数字ではだめ
ムームードメインで取得する。
aレコードに固定IPを設定する

https://cloud.google.com/console
プロジェクトを作成
APIとサービス
認証情報
認証情報を作成
OAuth クライアントID
ウェブアプリケーション

OAuth 同意設定
承認済みドメイン にドメインを登録する
承認済みの JavaScript 生成元 　に　独自ドメインを入れる
リダイレクトURL 独自ドメイン/redmine/oauth2callback
idとキーを生成する

redmineに管理者権限でログインする
管理
プラグイン
redmine google plugin
client ID
Client secret　入れる
【baserCMS：初心者向け】アイキャッチ画像の出力の色々

##アイキャッチの出力

シンプルに画像だけを出したい時はコレ

~~~php
<?php $this->Blog->eyeCatch($post, array('link' => false)); ?>
~~~
##アイキャッチに記事へのリンクを貼る
アイキャッチ画像に記事へのaタグリンクをつける時はコレ

~~~php
<?php $this->Blog->postLink($post, $this->Blog->getEyeCatch($post, array('link' => false))); ?>
~~~
'target' => '_blank'なんかも任意でお使いください

##アイキャッチがない時は別画像
アイキャッチ画像が登録されて入ればアイキャッチを表示し、アイキャッチが登録されてなければ任意の画像を表示させたい時はコレ

~~~php
<?php echo $this->Blog->getEyeCatch($post, array('noimage'=>'dummy.jpg','link' => false)); ?>
~~~