OmniAICreator/Qiita-1.07M huggingface dataset:
Railsでincludesをwhereで絞り込みをする

has_manyの第2引数にscopeを渡すよい

```ruby
class User < ApplicationRecord
  has_many :published_articles, -> { where(state: 'published') }, class_name: Article
end

User.includes(:published_articles).published_articles
```


# 例
## リファクタリング前
```ruby
class User < ApplicationRecord
  has_many :articles
end

class Article < ApplicationRecord
  belongs_to :user
end

class UsersController < ApplicationController
  def index
    @users = User.includes(:articles)
  end
end
```

```slim
- @users.each do |user|
  - articles = user.articles.select { |article| article.state == 'published' }
  - articles.each do |article|
    p = article.title
```
## リファクタリング後

```ruby
class User < ApplicationRecord
  has_many :articles
  has_many :published_articles, -> { published }, class_name: Article
end

class Article < ApplicationRecord
  belongs_to :user
  scope :published, -> { where(state: 'published') }
end

class UsersController < ApplicationController
  def index
    @users = User.includes(:published_articles)
  end
end
```

```slim
- @users.each do |user|
  - user.published_articles.each do |article|
    p = article.title
```
rubyアウトプット

順不同
#式展開
既存の式の中で新しく式を追加して表示させたい場合＃{式}を間に挟み成立させる
例：name = "佐藤"

  puts "わたしの名前は#{name}です。"
  puts "1と3を足した値は#{(1 + 3)}です"

#繰り返し処理
掲示板などのサイトの場合、投稿が完了した後に元のトップページに戻るようにするための処理
while @@@ do
   ※この間の処理を＠＠の条件の間永遠に続ける。
end

#条件分岐
1~2を記載する
input = gets.to_i(.to_iは数字列に変換機能)
if  input=1　　then
＝＞　１ならここに処理を記載
elsif　input=2
=> 2ならここに処理を記載
else　
=> それ以外ならここに記載
end


#変数
変数とはオブジェクトと言う物に対してかわりの名付けを行う行為
そうすることによって繰り返し使うものに対し名付けを行いコードを短縮、また変更時も大元を
変えるだけで全部が変えられるので変更が楽、途中でも変えれる

また、絶対に変えないものに対しては、変数ではなく定数を用いる

変数には規則があり
小文字から
スペース不可
予約語不可

#ハッシュ
複数のオブジェクト（データ）を持てるよ。
そしてそのデータをキーで紐つけしてから、ネームつけるよ
キーを入力したらデータが釣れます♪

######紐つけ時
ネーム　＝　{タイトル: "君に届け"}
君に届け　が　タイトル　にひも付けされたよ　そしてネームつけるよ

######釣る時　
puts ネーム[:タイトル]

以上
RailsでSQLを発行するメソッドと発行しないメソッド

SQLが発行されるActiveRecordのメソッド、SQLが発行されないRubyのメソッドをまとめました
これであなたもRailsスペシャリストです!!!

スタートアップの段階では、SQLを発行した方が早いケースもありますが、経験上不必要なクエリの発行は控えた方がよいです。
**ここでは`ActiveRecord::Relation`のことも配列と言ってます**


## 配列の絞り込み

### SQLが発行されるパターン: AR.where
```ruby

class Article < ApplicationRecord
  enum ['published', 'unpublished']
end

```


```ruby
published_articles = Article.where(state: 'published')
unpublished_articles = Article.where(state: 'unpublished')

Select *
from articles
where state = published

Select *
from articles
where state = unpublished


```


### SQLが発行されないパターン: Array.select
```ruby
articles = Article.all

articles.select { |a| a.state == 'published' }
articles.select { |a| a.state == 'unpublished' }

Select *
from articles
```

リファクタリング前のコード
```
# controller
@user = User.all

- @user.each do |user|
  - user.articles.where(state: 'published').each do |article|
    p = article.title
```

リファクタリング後のコード
```
# controller
@user = User.all

- @user.each do |user|
  - user.articles.select { |a| a.state == 'published' }.each do |article|
    p = article.title
```


## 配列から絞り込んで一つの要素取り出し

### SQLが発行されるパターン: .find_by, .find
```ruby
Article.find_by(title: 'ラーメンの美味しい食べ方')
```

### SQLが発行されないパターン: .detect
aliasにfindがあり、ブロックの違いで分かりはしますが、ActiveRecordのメソッドと混同されるのでdetectを使うのがよいです

```ruby
Article.all.detect { |article| article.title ==  'ラーメンの美味しい食べ方' }
```

## 配列をグルーピング

### SQLが発行されるパターン: .group_by

```ruby
group_by(&:state)['published']
```

### SQLが発行されないパターン: .index_by
```ruby
index_by(&:state)['published']
```

## 配列を並び替え

### SQLが発行されないパターン: .order
```ruby
order(id: :asc)
```

### SQLが発行されるパターン: .sort_by
```ruby
sort_by(&:id)
```

## 複雑な条件を1回で取得する

### 2回SQLが発行される例
```ruby
published_articles = Article.where(state: 'published')
other_articles = Article.where.not(state: 'published')
```

### リファクタリング後、1回のSQLで取得
```ruby
published_articles, other_articles = Article.all.partition { |a| a.state == 'published' }
```
Mac Server にパスワード認証で SSH 接続できない

## Overview

Mac Server の SSH 設定でとてもとてもハマったので備忘録を残します。

## 何が起こったか？

ある Mac Server に、パスワード認証でログインできなくなった。


```
$ ssh dareka@mac-001.co.jp
dareka@mac-001.co.jp's password:
Permission denied, please try again.
dareka@mac-001.co.jp's password:
Permission denied, please try again.
dareka@mac-001.co.jp's password:
jibun@mac-001.co.jp: Permission denied (publickey,password,keyboard-interactive).

$ ssh dareka@mac-002.co.jp
Password:
mac-002:~ dareka$　# 別の機体はすんなりログインできる...

$ ssh jibun@mac-001.co.jp 
mac-001:~ jibun$　# また自分の private key を使えばすんなりとログインできる...
```

## 原因究明

パスワード聞かれる時の表示が若干違うし、最初は困惑しましたが原因は `/etc/ssh/sshd_config` の設定で、この `UsePAM yes` がコメントアウトされていたことが原因でした。

```bash
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# UsePAM yes
```

コメントアウト外せばパスワード認証できるようになりました。
ざっくり訳してみると以下みたいなかんじ。

```
この設定を有効にすると、ChallengeResponse　認証とパスワード認証を通して PAM 認証が許可されます。PAM の設定によっては、ChallengeResponse 認証経由の PAM 認証はパスワードなしの RootLogin 設定の迂回路となってしまうかもしれません。ただ PAM 認証なしで PAM アカウントとセッションのチェックがしたいだけだったら、この設定は有効にして PasswordAuthentication と ChallengeResponseAuthentication は no にしてください。
```

PAM 認証とは、
`Pluggable Authentication Module`: 各種の認証処理を実行するモジュール群と、それを利用するための標準的なAPI を備えたライブラリからなるユーザー認証システム。
OS によるユーザ認証を独立させ、各アプリケーションが使用できる共通部品としてモジュール化したものをPAMと呼び、PAM は Solaris、HP-UX、FreeBSD、Linux など幅広いシステムで使用されている。
とのことらしいです。

sshd を再起動した方がいいよー、という記事も見かけましたが自分は特に再起動しなくても反映されました。

```bash
sudo launchctl stop com.openssh.sshd
```

ちなみに、`/private/etc/ssh` にも `sshd_config` がありますが、こちらが実態でルートの方が symlink みたいです。(linux との互換性を考慮してかな...？ 詳しい方教えてください :bow: )

```bash
mac-001:~ jibun$ ls -l /etc
lrwxr-xr-x@ 1 root  admin  11  9  2 15:13 /etc -> private/etc
```

`/private/etc/` の直下にも `sshd_config` ありましたが、このファイルを変更しても変更内容が反映されませんでした。編集対象は `/private/etc/ssh` の下の `sshd_config` ということに注意が必要そうです。

## 知っておいた方がよかったこと

問題は解決しましたが、もっと知っておいた方がよかったなー、と思ったことを書いておきます。

#### SSH の種類

- パスワード認証
- 公開鍵（+秘密鍵）認証
- SSH1 における rhosts 認証
- SSH1 における ChallengeResponse(TIS) 認証
- SHS2 における keyboard-interactive 認証 (パスワード認証とほぼ同意？)

パスワード認証と公開鍵認証は必須。

#### 公開鍵認証時の注意点

- `.ssh` ディレクトリの permission は `700`
- `authorized_keys` の permission は `600`
- `authorized_keys` の owner は `root` になっていないか

#### SSH の設定ファイル

- `/etc/ssh/ssh_config` → クライアント側の設定ファイル
- `/etc/ssh/sshd_config` → サーバー側(SSHされる側・デーモン)の設定ファイル

#### sshd_config の設定

- 公開鍵認証のみ有効にしたい場合は `ChallengeResponseAuthentication` と `PasswordAuthentication` を `no` にする
Leetcode #753: Cracking the Safe

```swift
import Foundation

class Solution {
    func crackSafe(_ n: Int, _ k: Int) -> String {
        var totalSize = Int(pow(Double(k),Double(n)))
        var str = ""
        for _ in 0..<n {
            str += "0"
        }
        var visited: Set<String> = [str]
        if dfs(&str, totalSize, n, k, &visited) {
            return str
        }
        return ""
    }
    
    private func dfs(_ str: inout String, _ totalSize: Int, _ n: Int, _ k: Int, _ visited: inout Set<String>) -> Bool {
        if visited.count == totalSize {
            return true
        }
        for i in stride(from: 0, to: k, by: 1) {
            var tmp = String(str.suffix(n-1)) + String(i)
            if !visited.contains(tmp) {
                str += String(i)
                visited.insert(tmp)
                if dfs(&str, totalSize, n, k, &visited) {
                    return true
                }
                str = String(str.dropLast())
                visited.remove(tmp)
            }
        }
        return false
    }
}
```
ubuntu 16.04 kvm vm内にコンテナを作成して、物理ホストからブリッチのアドレスをコンテナにそのまま付けたい

#VM上にコンテナを作成して,物理ホストのアドレスを付けたい.
https://lxd-ja.readthedocs.io/ja/latest/containers/

物理ホストから作成したVMのインターフェース（ブリッチ）からlxdコンテナにアドレスを降らせたいけど、アドレスが付けられない.
なんとかして付けたい.

lxdbr0を変更して,"nictype:physical"を使用する.
物理デバイスそのものをパススルー.対象のデバイスはホストから消失して、コンテナ内に出現する.
この方法でやりたいことはできたが,新たな問題発生
アドレスをそのまま持ってくるから
インターフェース１個ーコンテナ１個みたいな感じになる.

でも、やりたいことはできたからやり方メモ

コマンド

```
 lxc profile edit default
```

parent:そのまま持ってきたいアドレスのインターフェース名
nictype:physical

に変更する.

コンテナに入って
リンクアップしたらアドレスがつく
Gitコマンドのメモ

#はじめに
いちいち調べるのが面倒なので調べてしまったコマンドや動作を残しておく場所として使っています。

#本編

```
$ git commit --amend　　　　直前のコミットの修正→上書きをしてくれる

$ git stash           　　 作業中の内容を一時避難

$ git stash list      　　 stashされている内容の確認

$ git stash pop       　　 一時避難されているファイルの復元

$ git checkout -b 名前　　　ブランチの作成と作業ブランチの変更

$ git branch -m 古　新　　　ブランチの名前変更
```

#参考サイト
https://backlog.com/ja/git-tutorial/reference/
Angularでサーバ立ち上げ後に検証ツールでStaticInjectorErrorが出る時の対処法

Angularで以下のようなコードを書き、

```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

ng serveしてlocalhost:4200をブラウザで開き、検証ツールを開いたところ以下のようなエラーが出ました。

```typescript

StaticInjectorError(AppModule)[RouterOutlet -> ChildrenOutletContexts]: 
  StaticInjectorError(Platform: core)[RouterOutlet -> ChildrenOutletContexts]: 
    NullInjectorError: No provider for ChildrenOutletContexts!

```

検索すると以下の記事が見つかりました。

https://stackoverflow.com/questions/47606310/error-no-provider-for-childrenoutletcontexts

>1:Import the RouterModule (or any of the "versions" of it generated by forRoot or >forChildren methods) into the module that declares components that use the >directive.
>2:The forRoot method of the RouterModule has to be called. Otherwise the services >required by the directive wont be initialized.

と記載してあったので、以下のように編集しました。

```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    RouterModule,
    RouterModule.forRoot([])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

エラー解消できました。
React Nativeでアプリを作る【1/?回】

嬉しい事にアプリの制作案件が入った。
作るシステムは、勤怠システム。
しかし実際のところ、アプリなんてどう作って良いか分からなかった。
知っているのはSwiftとJavaぐらい。これで作るか。。
もともとJavaエンジニアなので、Javaで作るのはどうって事ないが、保守的に考えるといちいちSwiftなんて触ってられない。。

あ、[React Native](https://facebook.github.io/react-native/)。これは良さそう。

## React Nativeざっくり解説
React Nativeとは、モバイル版のReact。
Reactのコードでネイティブアプリを作れる。そんな感じ。
良いところは1つのコードでiOSとAndoroidどっちのアプリも作れてしまうところ。素晴らしい。

## 立ちはだかる壁
まず立ちはだかったのは、nodeのインストール。
これがなぜか出来なかった。だがわかったのは、homebrewがインストールされてなかった？ぽい。
下記が環境構築であるが、なぜかwatchmanのインストール,react-native-cliのインストールでエラーが起きるのでとりあえず別の方法を考える事に。

```terminal:ターミナル
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
[node.jsのインストール](https://nodejs.org/ja/)

```terminal:ターミナル
brew install watchman
```

```terminal:ターミナル
npm install -g react-native-cli
```

### 見つけた！IDE！
そうして出会ったのが、[Deco IDE](https://www.decoide.org)。
これは簡単にアプリ開発環境を整えてくれるIDE(総合開発環境)で、ドラッグ&ドロップで簡単な機能は実装出来るというものだ。(ざっくりいうとね)
必要なものはXcode。要はmac用のツールです。
少し使ってみたが、インストールしてnew projectを押すと必要なファイル等を整えてくれて簡単すぎ。
<img width="1440" alt="スクリーンショット 2019-09-02 14.48.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/773491d6-5710-65d3-6c77-8923b30cad5e.png">
画面もいい感じ。とりあえずはこれで開発していこうと思います。

正直言って、色々知らんこと多いけど、頑張ろうと思う。久々に開発楽しめそう。
あんま公開出来ないかもしれないけど、一応【1/?回】にしたんで、次回もある、でしょう。。
開発者としてお金を稼ぐ方法のアイデア

以下は[Florin Pop](https://dev.to/florinpop17)による記事、[Ways to make money as a developer](https://dev.to/florinpop17/ways-to-make-money-as-a-developer-11fb)の日本語訳です。


# Ways to make money as a developer

開発者としてお金を稼ぐ方法のアイデアを一覧に書き出しました。
私はこのリストをしばらく前に作ったのですが、これに価値を見いだす人がいるかもしれないので、共有することにしました😄


* 最も一般的なのは、**就職する**か、**フリーランサーとして働く**こと。
* 何らかの**デジタルプロダクトを作成**し、販売する。プラグイン、コンポーネント(React、Angular、Vue、Bootstrap他)、テーマなどなど。
* SaaSを構築する。
* **広告**や**アプリ内購入**のできる**Webアプリ**、**モバイルアプリ**、**デスクトップアプリ**を作る。
* **ブログ**を作ってマネタイズ。
    * Google Adsense、carbonadsなどの広告。
    * スポンサーを付ける。
    * アフィリエイトで商品を宣伝する。
    * 自社製品を宣伝する。
    * 出版物の記事を書いて対価をもらう。
* **電子書籍**、あるいは**物理書籍**を書いて販売する。
* **Youtubeにチャンネル**を作成する。
    * Youtube広告を貼る。
    * スポンサーを付ける。
    * アフィリエイトする。
    * 自社製品を宣伝する。
* **オンラインコース**や**オンラインプログラム**を作成する。
* TwitchやYoutubeなどでライブストリームを行う。
    * 寄付を募る。
    * 月額サブスクリプションにする。
* **podcast**を公開する。
    * スポンサーを付ける。
    * 自社製品を宣伝する。
* オープンソースプロジェクトにコントリビュートし、**寄付**や**スポンサー**をゲットする。
* **Patreon**にページを作成し、他者があなたをサポートできるようにする。
* **ジョブボード**を公開し、開発者やデザイナーと共に企業から仕事を受ける。
* **swag**を売る。
* **ニュースレター**を売る。
* 対面で**コーチング**する。
* **トレーディングBOT**を作成する。
* 報酬の出るコーディングチャレンジに参加する。
* バグバウンティングプログラムに参加する。


リストに追加できそうなものがあれば気軽にコメントください！😄
よかったら[ここから](http://eepurl.com/c28cHT)ニュースレターに登録してください。


# コメント欄

「著名なインフルエンサーはだいたいひとつ以上のことを実行してるよね。」
「最近OSS始めて主にバグ報告してるけど、GitHubから報酬もらえない。」「GitHubは報酬くれないよ。プロジェクトからもらう。でもよっぽど貢献しないと難しい。」
「Youtubeはチャンネル登録者が10万人はいないとまともな稼ぎにならない。」「そうかもしれないが、でもいきなり10万人から始まった人はいない。」「100人未満のチャンネルやってるけど、うまく宣伝して[何千ドルもゲットした](https://medium.com/@garrettmickley/gaming-for-fun-and-profit-2dbc7a113323)よ。」
「オンラインコースを作成して売るのがいいと思います。継続して努力する必要がなくて、一度作るだけで稼ぎ続けることができます。このことについて[ブログを書いた](https://javarevisited.blogspot.com/2019/06/why-programmers-should-create-and-sell.html)よ。」「同意だが、ただ最初にコースを作るときに多大な努力が必要。」
「トレーディングBOTで稼いでる人なんて本当にいるの？」「[この人](https://youtu.be/sgz5dutPF8M)とか。」
「報酬の出るコーディングチャレンジなんてあるの？」「HackerRankとか。」
「忘れてるぞ。『ゼロデイ脆弱性を探してダークウェブで売る』。もしくは『Hackeroneに提出して正当な対価を得る』。」
「Webサイトをハッキングしてユーザ情報をダークウェブで売ろう。」
「アドバイスどおりにトレーディングBOTを作ったんだけどバグが取れません！このエラーが出続けます！『ギブミーマネー！！！』」「それはトレーディングBOTに共通するバグです。」「これは仕様です。」


# 感想

あなたは、なぜエンジニアの仕事をしているのですか？

私？
そんなの仕事だからに決まってるだろ(循環参照)
仕事なんて[趣味に](https://togetter.com/li/1397806)[使う金](https://togetter.com/li/1322447)[を稼ぐ](https://togetter.com/li/1394663)ための手段でしかありません。
金さえあれば仕事なんて即座に投げ捨てるね。

そんなわけで何か楽して稼げる裏技でも載ってないかなあと思って訳し始めたのですが、思っていたより真っ当でリーガルな記事でした。
単に何も考えずにこれをやれば儲かるというものではなく、色々なアイデアを示してはいるものの、最終的には自分に合ったものを自分で選ばないといけません。
その方法もグレーやブラックなものではなく、裏技的なものですらなく、正当なルートしか示していません。
まさにアイデア集ですね。
マネタイズを考えている人は参考にしてみてはいかがでしょう。


なお、個人的にはあまり役に立たない内容でした。

私は個人情報を出していないし今後も出すつもりはないので、YouTubeやPatreonのようなルートは対象外です。
リアルにも紐付けていない(リアル友人はほぼ全員このアカウントを知らない)ので、転職やフリーランスに役立てることも難しいです。
継続的な努力なんてやりたくないのでアフィやOSSコントリビュートはできません。
SaaSやデジタルプロダクトにに手を出すにはアイデアが足りず、バグハンターになったり書籍を作るには能力が足りません。
多少なりとも秀でてそうなものといえばQiitaのContribution数くらいですが、顔出しせずにQiitaにいくら記事を書いても1円にもならないので、全く意味がありません。

もっとこう、[寝てるだけでお金が入ってくる](https://srad.jp/story/08/05/09/1745239/)ような方法はないものですかね。
Cloudflare＋Herokuで運用しながら、メールはレンタルサーバー（Mixhost）を利用する方法

Herokuで運用していても、Herokuにメールサーバーを建てるのは面倒なので、別のメールサーバー（私はMixhost）を利用したいってことありますよね。

**メールとWEBをわけるにはDNSサーバーでMXレコードを追加して切り分ければOKです。**
DNSサーバーはCloudflareなのでここにMXレコードを追加して運用する方法を記述します。

###現在の状態

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/7e3536c2-ab56-3512-6f5a-4363eb882649.png)

###MXレコードを追加
Mixhostの登録情報から

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/7233b8d9-5c9d-e736-9e1b-8076035fa5df.png)


MXレコードを追加していきます

Type:MX
Name:@
Mail server: xxxx.mixhost.jp
Priority:1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/51eb960f-6b19-a36c-fd58-fcb2ff97af9e.png)


##Mixhostでドメイン登録＆メール設定を行う

###cPanelでドメインの登録をします
MixhosutのcPanelを開いて、アドオンドメインで登録していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/c7726833-9d7d-71cb-e802-dffcb210cf02.png)


新しいドメイン名:xxxx.com
サブドメイン:xxxx
ドキュメントルート:xxxx

※ドキュメントルートのフォルダ名が存在しない場合は、自動作成してくれる



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/a8bbd969-3c97-a8b8-2ced-d68cdaee1d2a.png)

###cPanelでメールの登録をします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/6467c4c5-0171-c7d8-fc06-833fed9844e4.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/7d42b9a2-d3d3-7452-b788-eea4fcb5b9cb.png)


###メールをチェック
電子メールアカウントのCHECK EMAILをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/38bd9471-6b0c-82ae-b997-31af8adb12b3.png)

roundcubeでチェックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/b1325e1e-2ec9-3487-d7eb-0661f5d1a27b.png)


続く....

※この方法ではうまくいきませんでした。。。すみません
機会があれば再度チャレンジします。
知ってる方いたら教えてください！


参考：https://support.google.com/a/answer/7174013?hl=ja
参考：https://koskywalker.com/mixhost-domain/
参考：https://koskywalker.com/mixhost-mailaddress/
AZURE Functionsを運用して分かったこと

# そもそもAZURE Functionsとはなんぞや

最近、よく聞くサーバレスアーキテクチャの思想を元にMicrosoftが提供しているフレームワーク。

サーバレスアーキテクチャとは、まるでサーバーが無いかのような振る舞いをするサーバーアプリのこと
詳しくは先人様か公式ドキュメントを参考に。
※Microsoftの公式ドキュメントって、読みづらいよね…

## 運用して気づいた(ハマった)こと

[1. たまに403でエラーが返却される](### 1. たまに403でエラーが返却される)
[2. Web.Configとかがない](### 2. Web.Configとかがない)
[3. たまにTCPが繋がらず、タイムアウトになる](### 3. たまにTCPが繋がらず、タイムアウトになる)
[4. 稀に勝手に再起動する](### 4. 稀に勝手に再起動する)
[5. Kuduは利用可能](### 5. Kuduは利用可能)
[6. サーバの監視はApplication Insight](### 6. サーバの監視はApplication Insight)

## 運用して気づいたことの詳細

完全な対策と理由は未だに理解できてません。。。
ご存知の方がいらっしゃったら、教えて頂きたく。

### 1. たまに403でエラーが返却される
Functionsが20分以上稼働していない状態でAPIが叩かれるとたまに発生する。
原因は、サーバーが立ち上がりきっていないため。
IPアドレスの制限をかけている場合に、許可していないIPから飛んできたときにも403で返す。
`「指定範囲の対象外だから、権限ないよ！」`
って感じで403になるらしい。

### 2. Web.Configとかがない
代わりにアプリケーション設定が複数に分かれている。
環境変数とDB接続文字列で一つ。
Functions自身の設定で1つ。
  →Functionsのバージョン指定やタイムアウト時間などの設定。

### 3. たまにTCPが繋がらず、タイムアウトになる
これに関してはNode.jsを使って夜間にバッチ処理をしているとたまに出る。
20秒以上、接続出来ないとエラーとなる。
原因は不明。
POSTMANやRestletで送ると発生しない。
RESTの発行数は2000件/1時間なので、問題ないはず。。。

### 4. 稀に勝手に再起動する
  以下の状況下で発生した。

========================= やってること =========================
1. Functionsの自作APIをコール
2. 自作API内で別スレッドを起動
3. 別スレッドは起動したままで、クライアントにレスポンスを返す

============================================================

別スレッドが起動している状態にも関わらず、`Initialize Host.`とかふざけたログが出力される。
※これに関しては、Durable-Functionsを入れていることによる弊害かもしれない。
　それにしても、強制終了されるのは辛み。。。

[参考サイト](https://github.com/Azure/azure-functions-host/issues/4186)

### 5. Kuduは利用可能
Azure Functionsの`概要`タブの横にある`プラットフォーム機能`タブを開くと左下のほうにKuduがある
これは今まで通りの使い方ができる。
※ただし、Kuduで表示されているファイル等は`ストレージアカウント`に登録されているので、容量によって料金が変動する点に要注意。

### 6. サーバの監視はApplication Insight

AZURE Functionsのサーバ状態を監視するのには、`Application Insight`を利用しましょう。
これが無いとエラーが起きた時に「サーバが再起動した！」とかのログを取得できないので、めちゃくちゃ不便です。
※ただし、初期設定のままだと、クライアントIPが「0.0.0.0」で来るので注意です！
　理由は`Data protection in the EU`、日本語名：`EU一般データ保護規則`が原因です。
　Functions V2 での設定方法については[こちらの記事](https://blog.shibayan.jp/entry/20180319/1521463039)を参考にしてください。
【Python】Enumで静的データ管理

## 背景

簡易なプログラムを書く際、わざわざデータベースを立てたり設定ファイルから定数を取得するのも面倒な時は、データをプログラムにハードコーディングしてしまう場合もしばしばあります。
ただ、この場合もできるだけスマートに書きたいですよね。そこで自分が調べたり検証した内容をまとめます。
結論として、Enumを使うといい感じに書けます。

なお、ほとんど公式ドキュメントに書かれている内容です。
https://docs.python.org/ja/3/library/enum.html

## シンプルなEnum

PythonのEnumはClassとして定義します。

>列挙型は読み書きが容易になるよう class 文を使って作成します。もうひとつの作成方法は 機能 API で説明しています。列挙型は以下のように Enum のサブクラスとして定義します:



```.py
from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

if __name__ == "__main__":
    print(Color.RED)
    print(Color.GREEN)
    print(Color.BLUE)
```

```
1
2
3
```


## Enumにフィールドをもたせる
Enumのメンバー値以外に値をもたせたい場合があります。
例えば日本語名とか。

そういった場合はコンストラクタで値を設定します。

```.py
from enum import Enum

class Color(Enum):

    RED = (1, '赤')
    GREEN = (2, '緑')
    BLUE = (3, '青')

    def __init__(self, id, ja):
        self.id = id
        self.ja = ja


if __name__ == "__main__":
    print('#=== ja ===#')
    print(Color.RED.ja)
    print(Color.GREEN.ja)
    print(Color.BLUE.ja)
```

```
#=== ja ===#
赤
緑
青
```

なお、Enumのメンバー値はintに限らず何でも良いです。

>メンバー値は何であっても構いません: int, str などなど。 正確な値が重要でない場合は、 auto インスタンスを使っておくと、適切な値が選ばれます。 auto とそれ以外の値を混ぜて使う場合は注意する必要があります。

ここでのメンバー値はvalueの値の通りになってます。

## Enumにメソッドやプロパティをもたせる

全メンバーを取得したり、メソッドやプロパティも持たせたくなりますね。

```.py
from enum import Enum

class Color(Enum):

    RED = (1, '赤')
    GREEN = (2, '緑')
    BLUE = (3, '青')

    def __init__(self, id, ja):
        self.id = id
        self.ja = ja

    # tagとしてidとjaを連結した文字列を取得する
    @property
    def tag(self):
        return "{}_{}".format(self.id, self.ja)

    # 全メンバーを取得する
    @classmethod
    def members_as_list(cls):
        # Order dictionary -> list
        return [*cls.__members__.values()]

    # idを指定して取得する
    @classmethod
    def get_by_id(cls, id):
        for c in cls.members_as_list():
            if id == c.id:
                return c
        # default
        return Color.RED


if __name__ == "__main__":
    print('#=== members ===#')
    print(Color.members_as_list())

    print('#=== enum ===#')
    for c in Color.get_all():
        print(c)

    print('#=== ja ===#')
    for c in Color.get_all():
        print(c.ja)

    print('#=== id ===#')
    for c in Color.get_all():
        print(c.id)

    print('#=== tag ===#')
    for c in Color.get_all():
        print(c.tag)

```

```
#=== all ===#
[<Color.RED: (1, '赤')>, <Color.GREEN: (2, '緑')>, <Color.BLUE: (3, '青')>]
#=== enum ===#
Color.RED
Color.GREEN
Color.BLUE
#=== ja ===#
赤
緑
青
#=== id ===#
1
2
3
#=== tag ===#
1_赤
2_緑
3_青
```


いかがでしたか？
結構色々できて便利ですね！
ただし書き方が独特で慣れるまで大変そうです。

## 参考
[enum --- 列挙型のサポート](https://docs.python.org/ja/3/library/enum.html)
[要素数 どのようにpython enumクラスからすべての値を取得するには?](https://code.i-harness.com/ja-jp/q/1c22f6b)
ROS topicを読み取ってcsvに保存する

# はじめに
Rosbagで取ったデータをぱぱっとExcelとかLibre Office Impressに入れてグラフ書きたいなと思って，ささっと書いたコードです．役に立ったら嬉しいです．


# 環境
Ubuntu 16.04
ROS kinetic


# コード

```python:topic2csv.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
from std_msgs.msg import Float32
import os

path = "my_message.csv"
count = 0

def callback(msg):
    global count
    global value
    value = msg.data
    rospy.loginfo("value: %f", value)

    buf = str(count) + "," + str(value) + "\n"
    with open(path, mode='a') as f:
        f.write(buf)
    count+=1



def listener():

    rospy.init_node('getter', anonymous=False)
    rospy.Subscriber("/my_message_topic", Float32, callback)

    rospy.spin()




if __name__ == '__main__':
    # csv fileが存在してなかったら作る
    if not os.path.isfile(path):
        f = open(path,'a')
        f.close()

    listener()
```

# 実行方法(2020/1/1追記)
実行の時は，

```
$ python topic2csv.py
```

という感じで実行してください．rosrunで実行するとうまく結果のファイルが作成されません．


# 結果のcsvファイル
別のターミナルで

```
$ rostopic pub -r 10 /my_message_topic std_msgs/Float32 32.5
```
とやったのを記録した結果です．

```
0,32.5
1,32.5
2,32.5
3,32.5
4,32.5
5,32.5
6,32.5
7,32.5
8,32.5
9,32.5
10,32.5
11,32.5
12,32.5
13,32.5
14,32.5
15,32.5
16,32.5
17,32.5
18,32.5
19,32.5
20,32.5
21,32.5
22,32.5
23,32.5
24,32.5
25,32.5
26,32.5
27,32.5
28,32.5
29,32.5
30,32.5
31,32.5
32,32.5
33,32.5
34,32.5
```

こんな感じです．
pandasのmemo

###比較演算子
=ってどっちにつく？・・・常に右側！

```python
<=       >=
```


###条件を満たさないSeriesの要素（値）を削除する
srr[ここにTrue or Falseのリストを渡せば良い]

```python
#100未満のものは削除。query()はデータフレームのみ使用可能。
srr = srr[srr >= 100]
```

### DFを辞書から作る

```python

data = {"year": [2010, 2011, 2012, 2013],
        "score":[100, 80, 90, 80]}
df = pd.DataFrame(data)
```


### エクセル読み込み

```python

df=pd.read_excel(path,sheet_name=sh_name,skiprows=range(4),index_col=None,header = 0)
#skiprows = [リスト]読み込まない行
#index_col = None（インデックス列を指定。Noneはインデックス列なし。）
#header = 0(先頭（0番目の行）をヘッダーにする)
```

###データフレームをエクセルとして出力

```python
df.to_excel(r"\\パス\name_df_.xlsx")
```

###DFの特定の行を破壊的にインデックスとする。日付とか
```python
df.set_index('date',inplace=True)
```

###文字列、数値混在のデータフレーム　→　文字列をNaNに置換
要オプションのerror='coerce'。downcast = ''でデータ型も指定。

```python
df['env']=pd.to_numeric(df['env'],errors='coerce')
```

###文字列、数値混在のデータフレーム　→　文字列をNaNに置換
lambdaとapplymap使用

```python
    def remove_Char(self):
        str2nan = lambda x: np.nan if type(x) == str else x#lambda式。データ型が文字列はNaNに置換
        self.df = self.df.applymap(str2nan)
```

###applymapで、DFの各要素に関数を適用。
例として文字列をNaNに、値を2倍してみる。applymapの引数の関数はかっこなし。

```python
import pandas as pd
import numpy as np

data = {"age": [90, "はたち", 30,28],
        "score":[100, 80, 90, 80]}
df = pd.DataFrame(data)

def str2nan(value):
    if type(value) == str:
        return np.nan
    else:
        return value
    
def 2bai(x):
    return x*2

#inplaceオプションなし。
df = df.applymap(str2nan)
df = df.applymap(2bai)
```

|  |age  |score  |
|---|---|---|
|0  |90  |100  |
|1  |はたち  |80  |
|2  |30  |90  |
|3  |28  |80  |
age      object
score     int64
dtype: object
↓

|  |age  |score  |
|---|---|---|
|0  |180.0  |200  |
|1  |NaN  |160  |
|2  |60.0  |180  |
|3  |56.0  |160  |
age      float64
score      int64
dtype: object

###mapで、DFの特定の列の各要素に関数を適用。

```python
df["score"] = df["score"].map(2bai)
```

###DFのカラム名のリスト取得
```python
df.columns.values
```

###データフレームの一括で型変換

```python
df_f = df.astype('float16')
```

###queryメソッドで期間抽出

```python
#年のみだと、1月1日を表すみたい。2019は20190101
f.query('20001231 < date < 20190101')
```

###特定の月だけ抽出（インデックスが日付のDF）

```python
df[df.index.month.isin([6,7,8,9,10])]
```

###データフレームから特定の列を複数抽出

```python
df[list]

#例
str_list = ['a','b','c']
df[str_list] #[[]]大カッコが２重なので注意
```

###データフレームの特定列（Series）のユニーク要素のリスト取得
```python
df['name'].unique().tolist()
```
###データフレーム結合
df1とdf2を列方向（横）に結合することを考える。インデックスが日付で、データ数（行数）が少ないdf1に合わせるとする。

```python
df_concat = pd.concat([df1,df2],join='inner',axis=1)
```
Railsで単体テストを行うための下準備方法と主なgem

#初めに
Railsで単体テストで行っていくにあたって必要な下準備についてまとめました。
内容としてはgemのRSpecを使用していく場合で書いています。

##この記事で使うgem
###rspec-rails
Railsで単体テストを行う際に、主に使われるgem。
このgemを導入すれば単体テストを行うことができます。

###以下あれば便利なgem(必須ではない)
###factory_bot_rails
単体テストを行う際に使用するインスタンスをあらかじめ
登録しておくことができるgem。
各exampleの度にインスタンスを生成しなくて済むので
便利。なくても単体テストはできます。

###rails-controller-testing
コントローラを単体テストする際に使用するgem。
導入することで、コントローラを単体テストする際に便利な
マッチャやメソッドが使用できるようになります。

※こちらのgemを使用するのはおすすめしません。gemとして古いものであるためです。
詳しくは以下の記事を参考にしてください。
https://qiita.com/t2kojima/items/ad7a8ade9e7a99fb4384
簡単な単体テストをする上では、大きな問題はないと思うので
rails-controller-testingを使用しています。

###faker
単体テストを行う際に生成するインスタンスの値をランダムで
自動再生してくれるgemです。
インスタンスごとに自分で値を考える必要がないので便利です。

##単体テスト下準備手順
1.単体テストを行うために必要となるgemを導入していきます。
Gemfileに以下のようにgemを追記します。
テストのため、開発、テスト環境であるgroup :development, :testに追記していきます。

~~~ruby:gemfile
group :development, :test do
  gem 'rspec-rails'
  gem 'rails-controller-testing'
  gem 'factory_bot_rails'
  gem 'faker'
end
~~~

Gemfileに追記したので、ターミナルで以下のコマンドを
実行します。

~~~
$ bundle install
~~~

2.1.の段階だとまだrspecは使用できません。rspecを使用するには、別途インストールコマンドを実行する必要があります。
以下の用にコマンドを実行してください。

~~~
$ rails g rspec:install
~~~

コマンドを実行すると.rspecファイルが作成されるので
.rspecファイルに以下の文言を追記してください。

~~~ryby:.rspec
--format documentation
~~~

※上記の文言の追記は単体テストを行う上で必須ではありませんが
追記することで、ターミナルでのテスト結果が見やすくなるので
追記しておくといいかもしれません。
詳しくは以下参考に
https://shinkufencer.hateblo.jp/entry/2019/01/21/233000

3.ここまでの手順で、単体テストを実行することができますが
下準備として単体テストで使うファイルを管理しやすいように
ディレクトリを作成していきます。

単体テストで使うファイルはspecディレクトリ以下に作成していきます。
管理しやすいよう以下の様にディレクトリを作成します。

-spec
|-models←モデルを単体テストするspecファイルを管理
|-comtrollers←コントローラ-を単体テストするspecファイルを管理
|-factories←factory_bot_railsでのインスタンスの値の設定をするファイルを管理


#おわりに
ここまでの内容で、単体テストを行っていくための下準備を行うことができました。

単体テストを行うためのコードの書き方、構文につきましては他の記事を参考にしていただければと思います。
以下参考記事です。
https://qiita.com/jnchito/items/42193d066bd61c740612

・rspec-railsのGitHub README
https://github.com/rspec/rspec-rails
AWSでサービス構築する際に、拡張しておいたほうがよいリソース

AWSのサービス運営において、リソースが初期値のままでは不足してしまったリソースを洗い出してみました。

# AWS公式記事
こちらに初期値の一覧が記載されています。  
AWS サービスの制限
https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html

# 開発において拡張したリソース
## VPC関連
### Elastic IPs
初期値 `5`
主な利用用途：EC2、ALBなど
グローバルIPアドレスを使用するEC2インスタンスなどを、多く作成するとすぐに上限に到達してしまいます。

### リージョン当たりの VPC
初期値 `5` 
主な利用用途：AWSのネットワーク構築
1アカウントで複数のシステムを管理する場合や、システム環境単位にVPCを分割する場合は、VPCが不足すると思います。

### アベイラビリティーゾーン当たりの NAT ゲートウェイ数
初期値 `5`
主な利用用途：VPCでのネットワーク構築

# リソース上限の拡張方法
[AWSサポートセンタ](https://console.aws.amazon.com/support/home) から、リソース上限の拡張申請を出します。
申請から反映にはリードタイムがあるので、新規構築の場合は早めに拡張申請しておくとあわてずに済みます。

# 所感
3システム以上稼動させるなら、リソースが上限値になることが増えてきます。
あらかじめ分かっている場合は、あらかじめ拡張しておくとよいでしょう。

# 他に
これもあったほうが良いよ！などありましたらコメント頂ければ幸です。
[Golang]HTTP接続してページ情報を取得する際、http.Get関数が一撃で簡単な件

# いきなり結論のコード

```golang:http接続のサンプル
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	res, _ := http.Get("http://example.com") // ←これ
	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

```text:実行結果
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 50px;
        background-color: #fff;
        border-radius: 1em;
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        body {
            background-color: #fff;
        }
        div {
            width: auto;
            margin: 0 auto;
            border-radius: 0;
            padding: 1em;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You may use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
```

ちゃんと、`http://example.com`のページ情報が返ってきています。

# 解説
## したこと

- 今回は`http://example.com/`に接続し、取得したページ情報を`body`という変数に格納しています。
- コードの最後では、この`body`を出力して、内容の確認としております。

## `res.Body.Close()`でクローズ

```golang
defer res.Body.Close()
```

- 接続をクローズしています。
- `defer`を使うことで、ここに書き込んでいますが、実行されるのは`main`関数の一番最後になります。可読性も高いですし。便利です。

## `ioutil.ReadAll(res.Body)`で読み込む

```golang
body, _ := ioutil.ReadAll(res.Body)
```

- `res`には取得したページデータが入っています。
- `res.Body`とすることで、ページデータの本体を指定しています。
- `ioutil.ReadAll()`で、上記のものを読み込みます。この読み込みの際、byte型で読み込むので、後の処理に注意が必要です。

## `string(body)`でString型にキャストして出力

```golang
fmt.Println(string(body))
```

先述の通り、`ioutil.ReadAll()`では、byte型で読み込むので、今回は念のために、出力のタイミングでstring型にキャストしています。

# さいごに
最後まで読んで頂いてありがとうございます。
とてもシンプルなコードですが、接続の確認の際によく使いそうなので、共有させて頂きました。
Tailwindによるレスポンシブ対応

# Tailwindを用いたレスポンシブ設定
## Tailwindとは
[公式ドキュメント](https://tailwindcss.com/)
Tailwindの使い方などは、こちらの記事を参考にしてみてください。
https://qiita.com/zzzzz/items/68461080515ec1012980
## レスポンシブとは
[レスポンシブデザインとは](https://www.yamatofinancial.jp/learning/know-how/what-is-responsive-web-design.html)
簡単に説明すると
PC版、タブレット版やスマートフォン版などのページレイアウトを複数のページに分割することなく、一つのページにまとめて描く方法です。

## Tailwind内に置けるレスポンシブ幅
> sm: min-width:640px;
md: min-width:768px;
lg: min-width:1024px;
xl: min-width:1280px;

と設定されています。
ちなみに、768pxはiPad/mini/airと同じ画面幅です。また、1024pxはiPad Pro 12.9と同じ画面幅となります。（iPad/mini/airの横向きと同じ）
そして1280pxは Android Tablet　Fire HD 10 10インチと同じ画面幅になります。
とこのように、Tailwindはこれらの機器を想定したレスポンシブ設定となっていることがわかります。

## レスポンシブの使用方法
tailwindの使用方法はclass名に対応する名前を設定していく方法です。
例えば、`<h1>`の文字サイズを変更したいときには`h1 {font-size: 16px;}`と指定することで実装できます。tailwindを用いると、
```<h1 class="text-base">```
と言うように書くことができます。
ここで、レスポンシブの記述を追加します。
```<h1 class="md:text-base">```
先ほどの記述との違いは```md:```が付いたことです。
ちなみに、これは画面幅が768px<font color="red">以上</font>のときにはこのtailwindのCSSが働くという意味になります。（以下のときに記述されると言う記述はできないので注意）

## 【余談】`container`について
tailwindのクラスに`container`をつけると以下のCSSが働きます。[参考](https://tailwindcss.com/docs/container/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491250/55b595d6-7770-c6a8-a1b6-f00925d9bb00.png)

こちらは先ほどのレスポンシブと対応していることがわかります。
この`container`はページの大枠につける場合が多いです。
例えば、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491250/e6cb0ef9-9e03-daa9-b921-859f2bb9e8d3.png)

このページのように左右の余白をつけたいときにはこの`container`のクラスを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491250/9f71340e-3c5d-78bd-e387-ebb35211e7c2.png)


そして、おそらくこのページのヘッダーに揃っているので、この大枠のエレメントに`container`クラスを設定しているものと考えられます。
このように、ページ全体の余白を設定するときにこのクラスを指定することができます。
## まとめ
### tailwindは実機ベースでメディアクエリが設定されている。
### tailwindのCSSを使う際には、レスポンシブと`container`が対応しているので組み合わせて使うと便利。
プルアップ抵抗のメモ

## はじめに
自作キーボードをやっているとプルダウン、プルアップ抵抗が出てきます。
プルダウン抵抗はわかりやすいのにプルアップ抵抗マジ意味わかんなかったけど、ようやく理解できたのでそれのメモです。

## プルアップ抵抗とは
スイッチ押して無い時に電圧がかかって、押した時に電圧が消える

例
押して無い時
<img width="518" alt="スクリーンショット 2019-09-02 18.18.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/bd431ca6-d4a6-8ec6-adb6-79afe1adadc0.png">

押した時
<img width="509" alt="スクリーンショット 2019-09-02 18.18.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/f51a8af8-40e6-009c-c235-411b41b78c0e.png">


## inputピン
inputピンの中には抵抗が入っていて、それがinputモードのときはGNDと繋がっている


## 直列回路
直列回路の抵抗計算
R=R1+R2
I=I1=I2
このように抵抗を1つの抵抗として計算するのを合成抵抗と言う

![S__14630990.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/97dcce71-33d4-387a-bd71-508b0f9e8115.jpeg)

各抵抗に流れる電流は同じ
各抵抗にかかる電圧の計算式
V=Rn*I

例:
R1 = 10
R2 = 20
V = 5
I = 5 / 30

![S__14630991.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/55693146-5361-49eb-c9df-9a1f05cb4402.jpeg)

直列回路の特徴として抵抗が大きいほうが電圧を持っていく
![S__14630965.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/a093b791-cab6-d6e0-c829-ecb17f26ae36.jpeg)


## 並列回路
並列回路は電源に複数の抵抗が並列に繋がっている回路

I=I1+I2

![S__14630992.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/aaf40921-3eb9-ac11-681b-dfadd7f97452.jpeg)

これも合成抵抗としてまずは並列な部分を１つの抵抗として抵抗値を出す。

計算式は以下の通り

```math
\frac{1}{R} = \frac{1}{R1} + \frac{1}{R2}
```

特徴として、合成抵抗の抵抗値は必ず並列回路の合計の抵抗値よりも低くなる
抵抗値が低くなると流れる電流が増える
イメージとしては2つの抵抗に十分な電流を流そうとする働きがあるので、全体に必要な電流が増える

電流は抵抗値が大きい程小さくなる

```math
I = \frac{V}{R}
```

## プルアップ抵抗の仕組み
![S__14630993.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/68f3911f-d294-257c-61ed-12910f5e0f71.jpeg)

```math
V=5V \\
R1=10 \\
R2=1K \\
R3=1
```

の場合
R1とR2の直列回路だけで、R3がなければ、合成抵抗は

```math
R=1000 + 10 \\
R=1010Ω
```

合成電流は

```math
I=\frac{5}{1010} \\
I=0.004950495049505 A \\
I=4.950495049505 mA
```

R1の電圧V1は

```math
V1 = 0.004950495049505 * 10
V1 = 0.04950495049505
```

R2の電圧V2は

```math
V2 = 0.004950495049505 * 1000
V2 = 4.950495049505
```

の様に、殆どの電圧を持っていっている

また、電流は
I=V/Rなので、

```math
I1=0.04950495049505/10 \\
I1=0.004950495049505A \\

I2=\frac{4.950495049505}{1000} \\
I2=0.004950495049505
```

直列回路はIが同じなので正しい計算値ですね。

電圧はR3が登場すると逆転する

R2とR3を並列の合成抵抗として

```math
R1=10 \\
R2R3=1000/1001 \\
R2R3=0.999000999000999 \\
R=10+1000/1001 \\
R=10.999000999000999
```

抵抗値が1010からだいぶ小さくなりましたね

```math
I=\frac{5}{10.999000999000999} \\
I=0.454586739327884A
```

これが全体を流れる電流です

ちなみにR1単体の場合は0.5Aになります。
R1は比例定数なのでこれが大きいほど今回発生した約0.045の誤差は小さくなります。 

R1にかかる電圧V1は

```math
V1 = 0.454586739327884 \times 10
V1 = 4.54586739327884
```

混合回路の場合電流は、R2とR3は1000対1で、比が逆になった分が流れるので、1対1000の電流で、R3に流れる電流の1000分の1だけがR2に流れる

<img width="509" alt="スクリーンショット 2019-09-02 18.18.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/f51a8af8-40e6-009c-c235-411b41b78c0e.png">

なので、混合回路で抵抗をつないでない導線をGNDに繋げるとほとんどの電圧が10Kの抵抗に取られるし、導線の抵抗は限りなく低いため、10000000対1とか、もっと凄い数値かもしれないが、ほぼ全ての電流は導線側を流れていって、inputピン側には電流は全然流れないって事なんだとか
#MicrosoftFlow で リレーションシップを張った CommonDataService の エンティティに対して登録をする方法

# こちらの記事の続きです。

[#MicrosoftFlow で CommonDataService の 特定レコードを操作する方法](https://qiita.com/rnakamuramartiny/items/a96fe14bae498e414078)

というか、これをやってて思いついたというほうが正しいかも。

# CDSのエンティティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/add15974-5c53-b68a-c4ee-326c0f33174a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/382624aa-c583-0610-b0ba-9ddd8cce79d9.png)

ちなみに、多対一というのは
複数のレコードの中から１レコードを選択して入れるという考えでよろしいかと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/8f086e90-8591-90a3-14c8-92f3ff561769.png)
→最近すごくわかりやすくなりましたよねここ。

今回は、特定の名称にユーザーを割り当てるというエンティティを制御してみます。

## とりあえずFlowを作ってみる。

ユーザーのエンティティは、フルネームやらUPNやらあるので、とりあえずそれっぽいデータ入れておけば大丈夫かなと思って、こんな風にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/fe6c7ba3-c5ae-3dc5-cd08-f3a99dbc18dd.png)

### 怒られた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/2532552c-5bc5-8f69-fba7-efc5099a19f3.png)

やはり、安易にパラメータをぶち込んでもダメなようです。

## 前回の記事と同様なことをしてみる。

要は、入力したいユーザーを、ユーザーエンティティから検索して、そのIDを入れるようにすればいいんじゃないかってことです。

というわけで、こんな風にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/bd1c8cba-62bc-257f-f1f5-6d5244400344.png)

### うまくいきました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/5b44cfb2-911a-35a5-6284-14d54327e477.png)

### データのほうは・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/fe1240f9-ad75-09db-888b-798c793e51b8.png)

ごらんのとおり、正しく登録されています。

# まとめ

CDSのエンティティはリレーションを使ってこそ、そのパワフルなデータモデルを活用することができます。
ぜひ、本記事を参考にして、CDSをもっと楽しく有効に活用しましょう！！
VuexをTypeScriptでモダンに書ける "vuex-module-decorators" の使い方

Vuexのstate, action, mutation, getterをそれぞれ公式に書いてある通り記述していき、それらを使用するときはstoreから読み込んで操作をするのが通常の書き方です。TypeScriptを使用しないVueプロジェクトであればそれでも良いですが、TypeScriptを使用して型定義をしっかりおこないたい場合は、vuex-module-decoratorsを使用して堅牢なファイル構成を実現できます。

それでは早速使用していきましょう！

## vuex-module-decoratorsって何？
簡単に言うと**Vuexをclass構文で書くことができるツール**です。

## 通常の書き方と何が違うの？
通常のstoreは下記のような書き方になるかと思います。

```ts:store.ts
import Vue from 'vue'
import Vuex, { StoreOptions, Plugin } from 'vuex'

const store: StoreOptions<RootState> = {
  state: {
    hoge: ''
  },
  getters: {
    hogehoge(state) {
      return state.hoge + 'hoge'
    }
  }
  mutations: {
    add(state, payload) {
      state.hoge = state.hoge + payload
    }
  }
}

Vue.use(Vuex)

export default new Vuex.Store<RootState>(store)
```

これをvuex-module-decoratorsを使用すると下記のように書き換えができます。

```ts:store/hoge.ts
import { Module, VuexModule, Mutation, getModule } from 'vuex-module-decorators'
import store from '..';

@Module({
  dynamic: true, store, name: 'HogeModule', namespaced: true,
})
class HogeModule extends VuexModule {
  public hoge: string = ''

  public get hogehoge(): string {
    return this.hoge + 'hoge'
  }

  @Mutation
  public add(payload: string): void {
    this.hoge = this.hoge + payload
  }
}

export default getModule(SearchBookModule)
```

```ts:store.ts
import Vue from 'vue';
import Vuex from 'vuex';
import { RootState } from './types';

Vue.use(Vuex);

export default new Vuex.Store<RootState>({});
```

まず、stateでデータの初期化をしていた部分は class HogeModule のプロパティとして使用しています。
gettersで取得していた hogehogeも getプロパティに置き換えることができます。

mutationsは　＠Mutationというデコレーターをvuex-module-decoratorsから読み込み、その下にメソッドのように記述すれば良いです。このとき、stateにあったhogeはthis.hogeで参照することが可能になるので、引数にstateを置いてあげる必要も無くなりました。

また、最終的に一つのstoreにまとめていた部分を、getModuleを使用して個々に登録しています。これでstoreに登録できた状態となります。

## どういったメリットがあるの？

通常のvuexの書き方では、使用するときに型が曖昧な状態なので本来宣言している型と違う型のデータをmutationやactionに送ったり、getterで取得しても通ってしまいます。これではTypeScriptで書いている恩恵がありません。
しかし vuex-module-decorators を使用すればクラス構文内で型宣言をしているので、使用するときも型が一致していないと通りません。ここは実際に使用したものを触ってみたほうがわかりやすいかと思います。

## 実際に使用してみましょう
今回実際に使用できるようにサンプルコードをGitHubのリポジトリにあげています。内容はGoogle書籍検索APIを使って、書籍検索機能を作っています。よかったら参考にしてください
https://github.com/niyou0ct/Google-Books-API

説明文をまとめることができればvuex-module-decoratorsの詳しい使用方法を追記していきます。
SSH経由でMySQL接続->SQL実行を1発でやろうとしてハマった話

SSH経由でMySQL接続->SQL実行を1発でやったるでー！！（｀Δ´）

1.まずは、踏み台サーバにアクセスするから

```
ssh -i {秘密鍵} {ユーザ}@{ホスト}
``` 

2.次に、mysqlに接続したいから(パスワードも一気にいれたろ...)

```
mysql -h {DBホスト} -P {ポート} -u {DBユーザ} -p{パスワード}
```
3.最後に、実行したいSQLは

```
select * from sample_table
```
4.この3つを一発でやりたいから、こうじゃ！！(⊙ꇴ⊙)

```
ssh -i {秘密鍵} {ユーザ}@{ホスト} mysql -h {DBホスト} -P {ポート} -u {DBユーザ} -p{パスワード} sample_db -e "select * from sample_table"
```

ほい！実行！！
![コマンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181741/2dea54bb-101f-ffba-e6ff-2654bdb2795b.png)


...(゜▽゜)
なんか思ってるのと違う...


じゃ、じゃあ、1発でやらないで一個一個やると？

...

上手くselectされるぞ？どゆこと？？ヽ(；▽；)ノ

コマンドの間違いじゃなさそう...
なら、【-V】でバージョン見てみるか

```
mysql  Ver 15.1 Distrib 5.5.62-MariaDB, for Linux (x86_64) using readline 5.1
```

...バージョンでるやんけ

ってことは、こいつが怪しい?

```
-e "select * from sample_table"
```
まさか、【"】を【'】に変えるとか？

```
ssh -i {秘密鍵} {ユーザ}@{ホスト} mysql -h {DBホスト} -P {ポート} -u {DBユーザ} -p{パスワード} sample_db -e 'select * from sample_table'
```

...


selectされた( ﾟ∀ ﾟ)

一発で実行するときは【'】じゃないとダメなのね...
Docker環境のRailsで「Chrome version must be between 71 and 75 error」が出た時の対処法

## はじめに
コンソールでChromeDriver.initを実行した時に下記のエラーがでる場合の対処法になります
Chrome version must be between 71 and 75 error

## 手順

#### １、コンテナの中に入る
docker exec -i -t [コンテナ名] bash

####  ２、コンソールに入る
$ rails c

####  ３、アップデートコマンドを入力
$ Webdrivers::Chromedriver.update

####  ４、initする
ChromeDriver.init
正常にインスタンスが作られれば成功です

もし失敗した場合は
/root/.webdrivers/chromedriver
にあるchromedriverファイルを削除して手順３からやり直してください
openSUSE Leap 15でポートを開ける

2019/09時点の情報です．
SSHの際に22以外のポートを使おうとしたときにハマったのでメモ．
IPアドレス等の設定はしてある前提です．

# 解決法
```Fish
sudo vim /etc/ssh/sshd_config
```
で

```
Port (好きなポート番号)
```
と書き込む．Port 22も使いたい場合は

```
#Port 22
```
のコメントアウトを外すなりしておく．
PCを再起動すると設定が有効になる．確認していないが再起動する代わりに

```
systemctl restart sshd
```
とコマンドを打つと設定が有効になるかも？

次にファイヤウォールの設定．

```
firewall-cmd --list-all
```
と叩くと

```
public
  target: default
  icmp-block-inversion: no
  interfaces:
  services: dhcpv6-client ssh
  ports: 
  protocols:
    ・
    ・
    ・
```
みたいなのが表示される．
port: に使いたいポートがないとsshd_configでポートを追加してもSSHができない．
(この状態でも同じネットワーク内なら22番ポートが開いていれば22番ポートでSSHは可能なはず)

```
firewall-cmd --zone=public --add-port=(ポート番号)/tcp
```
とコマンドを打つと

```
public
     ・
     ・
     ・
  ports: (ポート番号)/tcp
     ・
     ・
     ・
```

となりSSHができるようになる．

#参考文献
[Small Office & Simple IT/openSUSE leapでSSH接続を行うための設定変更]
(https://usado.jp/spdsk/2017/08/04/post-1870/)
[openSUSE forum/Opening port in the new YaST2 Firewall](https://forums.opensuse.org/showthread.php/533831-Opening-ports-in-the-new-YaST2-Firewall)
Docker for Macでinotifyがコンテナ側に伝わらないときの対処法

EdgeのDocker for Macをインストールする。

[Docker Desktop for Mac Edge release notes | Docker Documentation](https://docs.docker.com/docker-for-mac/edge-release-notes/)の、 `Download`リンクからダウンロードする。

## 参照

* [Missing file system events on mounts · Issue #2216 · docker/for-mac](https://github.com/docker/for-mac/issues/2216)
Terraformでmap内の未定義keyを判定する

Terraformでmap内にある未定義のkeyをifで判定する方法。
Terraform v0.12系でしか動作しない。

## サンプル
```
variable item {
  default = {
    id           = 1
    empty_column = "not_empty" # この行をコメントアウトしたりすると検証できる
  }
}

locals {
  empty = "empty"
  item = merge({
    "empty_column" : local.empty
  }, var.item)
}

output item {
  value = local.item
}
```

- コメントアウトなし

```
Outputs:

item = {
  "empty_column" = "not_empty"
  "id" = 1
}
```

- コメントアウトあり

```
Outputs:

item = {
  "empty_column" = "empty"
  "id" = 1
}
```

## 使い道

DynamoDBでカラムそのものが存在しないケースとか使える

```
resource "aws_dynamodb_table" "basic-dynamodb-table" {
  name           = "table_name"
  read_capacity  = 1
  write_capacity = 1
  hash_key       = "id"

  attribute {
    name = "id"
    type = "N"
  }
}

resource "aws_dynamodb_table_item" "main" {
  table_name = "table_name"
  hash_key   = "id"

  item = <<ITEM
{
  %{if local.item["empty_column"] != local.empty} # ここがポイント
    "empty_column": { "S": "${local.item["empty_column"]}"},
  %{endif}
  "id": { "N": "${local.item["id"]}" }
}
ITEM
}
```

## 他の方法について

indexは存在しないキーを指定した場合はエラーが返るので使えなかった
https://www.terraform.io/docs/configuration/functions/index.html

lookupでもできるかもかもしれない
https://www.terraform.io/docs/configuration/functions/lookup.html
AngularでCan't resolve 'rxjs/add/operator/toPromise'と言われた時の対処法

Angular8で学習をしていたらコンソールで「Can't resolve 'rxjs/add/operator/toPromise'」とエラーが出た。


```typescript
import { Injectable, Inject } from '@angular/core';
import { GitSearch } from './git-search';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
```

が、https://stackoverflow.com/questions/50552653/angular-6-module-not-found-error-regarding-rxjs/50552695
を参考すると、
>toPromise method is now a permanent method of Observable.

とのことで以下の通り変更

```typescript
import { Injectable, Inject } from '@angular/core';
import { GitSearch } from './git-search';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs';
```
エラー解消しました。
すぐできるDokerサンプルにpythonを追加した

知り合いが`python`を触りたいとうことで、
すぐできるDockerサンプルにも`python`の2系と3系を追加した。

# 追加したやつ

https://github.com/tubutubumustard/samplecode_docker

# pythonを追加

```:directory
~/
  docker-compose.yaml
  php_sample.php
  python_sample.py
  ruby_sample.rb
```

```:docker-compose.yaml
~略~
  python3.7: # docker-compose run python3.7
    image: python:3.7
    volumes:
      - ./python_sample.py:/python_sample.py
    command: python python_sample.py
  python2.7: # docker-compose run python2.7
    image: python:2.7
    volumes:
      - ./python_sample.py:/python_sample.py
    command: python python_sample.py
```

```:python_sample.py
# -*- coding: utf-8 -*-

import platform

print(platform.python_version())
print('パイソンだよ')
```

# 実行結果

```:sh
$ docker-compose run python2.7

2.7.16
パイソンだよ
```

```:sh
$ docker-compose run python3.7

3.7.4
パイソンだよ
```

#　終わり

ちなみに、`# -*- coding: utf-8 -*-` は、
`3.7`では無くても怒られなかったが、`2.7`では、怒られた。

```:sh
$ docker-compose run python2.7

  File "python_sample.py", line 4
SyntaxError: Non-ASCII character '\xe3' in file python_sample.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
```
Laravelパッケージ開発ハンズオン〜テスト導入編〜

前回の [Laravelパッケージ開発ハンズオン〜環境編〜](https://qiita.com/ucan-lab/items/d09ba1745c6bb45972a0) 続きの記事です。

## Laravelテスト導入

- [sebastianbergmann/phpunit](https://github.com/sebastianbergmann/phpunit)
  - PHPの単体テストフレームワーク
- [orchestral/testbench](https://github.com/orchestral/testbench)
  - Laravelのパッケージ開発用のユニットテストヘルパー
  - パッケージのテストでLaravelのコアクラスを利用できる

## 作業場所

```shell-session
$ cd docker
$ docker-compose exec app ash
$ cd /packages/laravel-hello-world
```

## 作成するファイル・ディレクトリ

```shell-session
$ touch .gitignore
$ touch phpunit.xml
$ mkdir tests
$ touch tests/TestCase.php
$ touch tests/ExampleTest.php
```

空のファイル・ディレクトリを作成しておきます。

## .gitignore を編集

```
/vendor
/composer.lock
/.phpunit.result.cache
```

## テストライブラリの導入

```shell-session
$ composer require phpunit/phpunit --dev
$ composer require orchestra/testbench --dev
```

### phpunit のバージョン確認

```
$ ./vendor/bin/phpunit --version
PHPUnit 8.3.4 by Sebastian Bergmann and contributors.
```

## composer.json を編集

```json
    "autoload-dev": {
        "psr-4": {
            "UcanLab\\LaravelHelloWorld\\Test\\": "tests/"
        }
    }
```

※カンマ(,)に注意

## オートローダ生成

```shell-session
$ composer dump-autoload
```

## phpunit.xml を編集

```xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         verbose="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="MyPackage Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory suffix=".php">src/</directory>
        </whitelist>
    </filter>
</phpunit>
```

## テストの作成

### tests/TestCase.php

```php
<?php

namespace UcanLab\LaravelHelloWorld\Test;

use Orchestra\Testbench\TestCase as OrchestraTestCase;

abstract class TestCase extends OrchestraTestCase
{
}
```

### tests/ExampleTest.php

```php
<?php

namespace UcanLab\LaravelHelloWorld\Test;

class ExampleTest extends TestCase
{
    /**
     * @return void
     */
    public function testResolve()
    {
        $this->assertTrue(true);
    }
}
```

## テストの実行

```shell-session
$ ./vendor/bin/phpunit
PHPUnit 8.3.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.8 with Xdebug 2.7.2
Configuration: /packages/laravel-hello-world/phpunit.xml

.                                                                   1 / 1 (100%)

Time: 1.18 seconds, Memory: 12.00 MB

OK (1 test, 1 assertion)
```

## 参考

- [Getting started on Laravel package development](https://medium.com/@lasselehtinen/getting-started-on-laravel-package-development-a62110c58ba1)