OmniAICreator/Qiita-1.07M huggingface dataset:
【学習メモ】AWSでApacheインストールまで進まなかった原因

#概要

```
$ chmod 400 tt-manager-ssh-key.pem
$ ssh -i "[SSH認証キー.pem]" [ユーザー名]@[パブリックIPアドレス]

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

$ sudo systemctl start httpd.service
sudo: systemctl: コマンドが見つかりません
$ sudo systemctl status httpd.service
sudo: systemctl: コマンドが見つかりません
```

#結論

概要欄で既に発覚しているのですが、

EC2インスタンスを作成する際に、AMIを、**Amazon linux2**ではなく、**Amazon linux**で作成していた。。。！！

```
       __|  __|_  )
       _|  (     /   Amazon Linux AMI←←←これ
      ___|\___|___|
```

#解決策

EC2インスタンスを削除し新しくAmazon Linux2で作成し直しました。そのあとは

#ちなみに・・・

Amazon linuxをAmazon linux２にAMIを変更すりゃいいんじゃないの？って思い検索してみました。

「AWS　AMI　変更」
「aws ami linux 変更」
などで検索し、その方法がないか試してみました。

すると、

[Pre-upgrade Assistant for Amazon LinuxのGitHubのREADME](https://github.com/amazonlinux/upgrade-modules/blob/master/README.md)

を見つけて、試しにコマンド打ってみましたが、何も起きませんでした。

おかしいなぁと思いさらに検索してみたところ、

[Amazon Linux 2 の登場と、Amazon Linux との違い、移行方法などをQ&Aから抜粋したメモ](https://michimani.net/post/aws-compare-amazonlinux-2-amazonlinux/)

より、

>Q.既存のバージョンのAmazon LinuxをAmazon Linux 2にインプレースアップグレードすることはできますか？
>>いいえ。既存のAmazon LinuxイメージからAmazon Linux 2へのインプレースアップグレードはサポートされていません。移行する前に、まずAmazon Linux 2の新規インストールでアプリケーションをテストすることをお勧めします。


>既存のAmazon Linuxからの移行に関しては、何かポチっとすれば終わりとはいかないようです。
別インスタンスでAmazon Linux 2を起動して、そこで環境を作って移行する必要があります。

と書いてありました。つまり、「自分で新しくインスタンス作成してAmazon Linux2を設定してね」ということなのかなと理解しました。少し不便ですね。せめて複数のコマンドでできれば良いのに、と思いました。

※もし、こんな方法でできたのに〜というのがあれば、コメントして頂けますと幸いです。

#参考

[Amazon Linux 2 に関するよくある質問](https://aws.amazon.com/jp/amazon-linux-2/faqs/?nc1=h_ls)

[Pre-upgrade Assistant for Amazon LinuxのGitHubのREADME](https://github.com/amazonlinux/upgrade-modules/blob/master/README.md)

[Amazon Linux 2 の登場と、Amazon Linux との違い、移行方法などをQ&Aから抜粋したメモ](https://michimani.net/post/aws-compare-amazonlinux-2-amazonlinux/)

[インプレースアップグレード  【 in-place upgrade 】 
](http://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89.html)
deviceでストロングパラメーターを使いたい！

実は元々deviceでは最初にマイグレーションファイルを生成した時のカラム以外は保存できない仕組みになっている。

ただ後から追加したカラムにもストロングパラメータを適用したい・・・

そんな時はconfigure_permitted_parametersメソッドを使おう！

【記述先】application_controller.rb

```ruby
ass ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end
```

devise_parameter_sanitizer.permit(:アクション名, keys: [:フォームなどで送信したデータのキー])
サインアップアクションに対して:nicknameというキーは許容して保存してあげますよという意味です
JDLAのG検定/E資格が5年〜10年後のキャリアをどう変えるのか（キャリアビジョンの話）

#動画解説
[Youtube動画](https://www.youtube.com/watch?v=QXM5sbjeQok)でも解説しています。
※動画だと1時間かけて説明していますが、5分でわかるようにQiitaにまとめました。

#発表資料
[こちら](https://www.slideshare.net/ssuser0d76f8/626-ge)をご覧ください。2020年6月時点の資料です。

#目次
- [G検定E資格の概要](#g検定e資格の概要)
- [5年から10年後のキャリアにおける3つの方向性](#5年から10年後のキャリアにおける3つの方向性)
- [3つの方向性における人材価値](#3つの方向性における人材価値)

#G検定E資格の概要
- こちらのスライドをご覧ください。[日本ディープラーニング協会の試験実施レポート](https://www.jdla.org/wp-content/uploads/2020/04/JDLA%E8%A9%A6%E9%A8%93%E5%AE%9F%E6%96%BD%E3%83%AC%E3%83%9B%E3%82%9A%E3%83%BC%E3%83%88_202004%E7%89%88v2.pdf)から引用しています。
<img width="623" alt="スクリーンショット 2020-07-23 21.34.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/e7c95ca8-5dcf-6035-73e2-1383255bce08.png">
<img width="625" alt="スクリーンショット 2020-07-23 21.35.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/bec9deb6-0af9-c884-a5e6-84150c74fd29.png">
<img width="625" alt="スクリーンショット 2020-07-23 21.35.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/d28a8672-277c-7084-e236-12a0b194ae6a.png">
<img width="626" alt="スクリーンショット 2020-07-23 21.35.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/73bdc02c-ed6c-55f8-a06f-b68d73df7ed7.png">

#5年から10年後のキャリアにおける3つの方向性
- **G検定がビジネス領域とビジネス⇄エンジニア領域**、**E資格がビジネス⇄エンジニア領域とエンジニア領域**のキャリアに活かせると考えています。

<img width="624" alt="スクリーンショット 2020-07-23 21.34.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/f9dae598-f26d-b040-5201-40ec8f7bd170.png">

- ビジネス領域に書いている「**市民データ・サイエンス**」は、ハイプサイクルを参考にしています。

<img width="623" alt="スクリーンショット 2020-07-23 23.10.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/819ad0f7-3563-ecca-d284-f188f2ac32b7.png">

- 「市民データ・サイエンス」は、**データサイエンスの民主化、一般教養化**のことを指していると考えられます。

<img width="625" alt="スクリーンショット 2020-07-23 23.14.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/dfc0a10e-9a29-bbbe-9cc7-fa24ae926429.png">

#3つの方向性における人材価値
- ビジネス領域のキャリアは、５年間で人材としての価値は上がると考えられますが、データサイエンスの民主化、一般教養化がある程度進んだ5年〜10年後には、**人材としての価値は下がる**と考えられます。

- ビジネス⇄エンジニア領域のキャリアは、**人材としての価値が上がり続ける**と考えられます。ビジネス上の課題とデータサイエンスやAI・機械学習をつなげ、課題解決を遂行できる企画・デザイン型人材が求められてくるので、エンジニア領域の知識やスキルを持ちながら、ビジネスサイドをうまく巻き込める（逆に、ビジネス領域の知識やスキルを持ちながら、エンジニアサイドをうまく巻き込める）人材は貴重です。

- エンジニア領域のキャリアは、**人材としての価値が二極化していく**と考えられます。今後、データサイエンスやAI・機械学習の技術がコモディディ化していくため、コードを書けるだけのエンジニアは人材としての価値が下がっていくことが想定されます。一方で、ビジネスサイドの背景や課題を理解し、エンジニア視点で提案して、実装もできるエンジニアは人材としての価値が上がっていくことが想定されます。
<img width="625" alt="スクリーンショット 2020-07-23 21.34.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676369/6d22df7e-f3a3-6aff-05d1-f038c309b55a.png">

#終わりに
- あくまで私の個人的な考え方なので、ご参考までに捉えていただければと思います。
- 読者であるあなたのキャリアが輝かしいものになることを願っています。
React初心者覚書06 - リストと keyー

[Reactの記事](https://ja.reactjs.org/docs/lists-and-keys.html)を参考に初心者がわからないけど覚書を書いています。

### JavaScript でリストを変換する方法

- これは理解できる

```js_list.js

const numbers = [1,2,3,4,5];//numbers配列
const dobled = numbers.map((number) => number * 2);//map()関数が返す新しい配列をdoubledに格納
console.log(doubled);

```

### 複数のコンポーネントをレンダリング

```react_list.js
const numbers = [1,2,3,4,5];//numbers配列
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

```
### Keyがないと怒られる

```listKihon.js
function NumberList(props){
  const numbers = props.numbers;
  const listItems = numbers.map((number)=>
    <li>{number}</li>
  );
  return(
    <ul>{listItems}</ul>
  );
}

const numbers = [1,2,3,4,5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

下記の[コード](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)でわからないこと。
なぜ、NumberList(props)関数の中に、const numbers = props.numbers;があるのに、
その外にも、const numbers = [1, 2, 3, 4, 5];があって、なんで同じ名前なのかがわからなかった。


##### keyのルール
- 基本ルールとしては、map() 呼び出しの中に現れる要素に key が必要
- key は兄弟要素の中で一意であればよい
- key はReactへのヒントとして使われるが、コンポーネントには渡されない。

```listKeys.js

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];

ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

### なぜ、ローカル定数とグローバル定数を同じ名前にしているんだろう？？
そこでnumbers2にしてみたけど動いた。


```numbers2.js
function NumberList(props) {
  const numbers2 = props.numbers;
  const listItems = numbers2.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

このコードを見たら、色々理解できてないけど、
なんとなく頑張ればページっぽいものが作れそうな気がしてきた。

```Blog.js

function Blog(props){
  const sidebar = (
    <ul>
      {props.posts.map((post)=>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post)=>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return(
  <div>
    {sidebar}
    <hr />
    {content}
  </div>
  );
}

const posts =[
  {id:1,title:'Hello World', contet: 'Welcome to learning React!'},
  {id:2,title:'Instaration', contet: 'install!!'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

```

### ListItemのネスト

```
function ListItem(props){
  return <li>{props.value}</li>;
}

function NumberList(props){
  const numbers2 = props.numbers;
  return(
  <ul>
    {numbers2.map((number)=>
      <ListItem key={number.toString()}
        value={number} />
    )}
    </ul>
  );
}

const numbers = [1,2,3,4,5];

ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

```
クラウドAI開発講座 Microsoftと高専キャリアがコラボ #3

# クラウドAI開発講座
[マイクロソフトと高専キャリア教育研究所が共催するAI開発プログラム](https://online.kosen-career.tech/ai)
**無料**で参加でき、困ったときにはメンターに相談ができるオンラインプログラム


## までのミッション
- [Azure for studens](https://azure.microsoft.com/ja-jp/free/students/?WT.mc_id=azureforstudents-docs-nosuzuk)に登録する（完了）
- [de:code2020](https://www.microsoft.com/ja-jp/events/decode/2020/default.aspx)のコンテンツを視聴して学習する（完了）
 - [学生諸君！ Azure であそぼう！ ～Microsoft の AI を自作アプリに取り入れるまで～](https://www.microsoft.com/ja-jp/events/decode/2020session/detail.aspx?sid=Z01)（完了）
 - [Azure Bot Services を使って Teams bot を開発する](https://www.microsoft.com/ja-jp/events/decode/2020session/detail.aspx?sid=A02)（完了）
- [Microsoft Learn for Students](https://docs.microsoft.com/ja-jp/learn/roles/student?WT.mc_id=BlendedCurriculum-MSLearn-nosuzuk)で学習する
- レッスンを消化する　
 - [ちょまどさん](https://qiita.com/chomado/items/6bda10abde0551f25723)（完了）
 - [おーちょさん](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)（途中）

## 進歩
- レッスンを消化する　
 - [おーちょさん](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)（途中）




## レッスンおーちょさん（途中）
[おーちょさん](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)の記事を参考に**優しい言葉**を返してくれるぼっとを作成中

先週に、[Twitter developersアカウントに登録](https://developer.twitter.com/en)申請をしたのですが、なかなか承認のメールが届きませんでした。確認してみたところ、こちら側がすべての手続きをしていないことが判明！必要な手続きを済ませ、メールでのやり取りの最中です。

作業が遅れるため、[Twitter developersアカウントに登録](https://developer.twitter.com/en)申請の手続きには気を付けてください。

とりあえずLINEボットを作成しましたが、エラーメッセージがそのまま返信となっています

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/7e4d92cb-c0f8-e6b8-a839-d8993e48f453.jpeg" width=50%>


早くツイッターと連携させて、次に進みたい！

待ってる間、[Microsoft Learn for Students](https://docs.microsoft.com/ja-jp/learn/roles/student?WT.mc_id=BlendedCurriculum-MSLearn-nosuzuk)で学習を進めます。





## 高専キャリアONLINEの提供コンテンツ（高専キャリア教育研究所）
[高専キャリアONLINE](https://online.kosen-career.tech/)の提供コンテンツ（[高専キャリア教育研究所](https://kosen-career.tech/)）

- [Business Design Lab](https://online.kosen-career.tech/business-design-lab)
- [クラウドAI開発講座](https://online.kosen-career.tech/ai)（本記事）
- [【高専生/編入生限定】特許活用ビジネスプランコンテスト](https://online.kosen-career.tech/bizdev-weekend)
Windows 10 Insider Program でアップデートできないとき

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/f6c4a732-63c6-53e3-4032-6fb5135e6259.png)
「この Windows ビルドは間もなく期限切れになります」

期限が切れると本当に使えなくなるそうです。
Windows アップデートを手動でやっても実行してくれません。
(；・`д・´) あと10日！

# 方法
私の環境では、設定で Insider Program の頻度を変えて、Windows Update を実行するとできました。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/dde94092-ef74-f5be-dfbe-ff76c2895005.png width=70%>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253995/fb9bf812-62f8-bdf0-5ad8-d097785a9933.png width=70%>
無事 Win10 Ver2004 にアップデートできました。警告も出なくなりました。

# あとがき
本当に Windows アップデートダメな場合は Windows を再インストールしなければいけないようです。Insider Program は途中解約できないらしく、どのみち Windows 再インストールすることになります。定期的にアップデートが必要なのはわかりますが、近年の業務が止まるような巨大なアップデートは勘弁してほしいです。

しっかし、Microsoft は Windows やる気ないのでしょうかね。Windows10X という Arm64版 を出すそうですが、名前で混乱してしまいます。[Windows10Xのエミュレータを起動してみた-Qiita](https://qiita.com/koji4104/items/df306f6dba872245645b)
Surface Duo という Android製の Windows も出すそうですが、MS が Android に 力を入れるならちょっと期待できるかもです。Android か iOS か、または Arm64版Mac か、Arm64 OS でネイティブ開発がやりたいです。
カラムを一発で作成する

普通なら・・・
rails g modelコマンドでモデルと一緒に生成されたmigrationファイルを編集するわけだが面倒くさい。

```ruby
rails g migration Addカラム名Toテーブル名 カラム名:データ型
```

あとはターミナルで
rails db:migrateを実行するだけ。あら簡単。
railsでログインしてないユーザーのアクセスを制限したい！

deviceというログイン機能の実装を簡単にしてくれるGemの導入前提

１．ログインしてるかどうか確かめる
　　user_signed_in?　メソッドを使う
　　true　→　ログインしています！
　　false　→　ログインしてないです！

２.リダイレクトする

```ruby
  before_action :move_to_index, except: [:index, :show]
```

```ruby
  def move_to_index
    unless user_signed_in?
      redirect_to action: :index
    end
  end
```

まずルーティングの振り分けでコントローラーに処理がきた途端にmove_to_indexが実行される
そこでfalseが返り値として確認された途端、ルーティングの振り分けなんかお構いなしでindexへ飛ばされる
binding.pryの使い方【残53日】

binding.pryの使い方がいまいちわかってなかったところ
本日エラー解決のために使用できたので備忘録

新しいチャットルームを作成するというセクションで何度CreateRoomをクリックしてもリロードされる
まあこれはrenderのせいなんだけど
エラー文がでれば解決しやすいものをエラーが出ない
さて困った

ここでbinding.pryの登場

<img width="534" alt="4-1.binding.pry.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678246/5c6ac127-6329-a479-5d1b-88127f41e2c9.png">
createメソッドのところがどうもおかしいと思ったのでpryにかけてみることに

<img width="866" alt="4-3.binding.pry.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678246/7ff5daaf-78c1-bb9f-4733-a1276d562545.png">
ふむ
ここまでは正常

<img width="883" alt="4-4.binding.pry.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678246/0e940256-7b28-97a7-42bd-fb34e0b42c30.png">
むむ
ストロングパラメーターに原因がありそうだ

<img width="612" alt="4-5.binding.pry.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678246/76360284-a421-28c1-2a0f-a6654ad03c01.png">
user_idsは表示されるのにnameない

と思って見返したところ
nameではなくnmaeになってたという世紀の凡ミス

ミススペルというよりミスタイプですね

今回はコントローラー内での使用でしたけど
たしかテストコードでも使用したな

明確なエラー文が表示されないときにはbinding.pryを思い出そう
Selenium でテキストボックスに入力する　vba　python

#Selenium or seleniumbasicテキストボックスに文字列を入力する
##前提
・vbaの場合は seleniumbasic pythonの場合はselenium がインストールされている
・環境はWIndows

##ポイント
1, inputタグに入力する前に消す Clear ※これがないと追記されてしまう。
2, valueの値でSendKeysができてるか確認
3, 早すぎると入力できてるか不安と言われるので sleep　や waitを使う(これは状況に応じて）

以上を考慮し、
inputタグ（テキストボックス）にidのある場合で関数を作成してみました。

##VBAの場合
引渡値 = ①クロームドライバー ②inputタグのid ③inputタグに入力する値
戻り値 = 5秒以内に 成功＝true　失敗=false


```vba:inputタグ(テキストボックス)に入力する
Public Function MoveTextBox(driver As ChromeDriver, id As String, atai As String) As Boolean            
   Dim timeout As Date
   timeout = DateAdd("s", 5, Now)       
   Do Until driver.FindElementById(id).Value = atai
     driver.FindElementById(id).Clear
     driver.Wait 100
     driver.FindElementById(id).SendKeys (atai)
    driver.Wait 100
    If Now > timeout Then
      MoveTextBox = False
      Exit Function
    End If              
   Loop
   MoveTextBox = True        
 End Function


```

##Pythonの場合
引渡値 = ①クロームドライバー ②inputタグのid ③inputタグに入力する値
戻り値 = 5秒以内に 成功＝true　失敗=false
sleepはなくてもよいのですが、あったほうが見ていてわかりやすいと評判がいいです。

```python:inputタグ(テキストボックス)に入力する

import time
def move_textbox(driver, id, atai):
    start = time.time()
    while driver.find_element_by_id(id).get_attribute('value')!=atai:
        driver.find_element_by_id(id).clear()
        time.sleep(1)        
        driver.find_element_by_id(id).send_keys(atai)
        time.sleep(1)

        if time.time()-start > 5 :
            return False
        
    
    return True
```

関数の例はinputタグにidのある場合ですが、
nameの場合は適宜
FindElementByName
find_element_by_name
に変えれば使いまわしがきくと思います
pandasで円グラフ



```
import numpy as np
import matplotlib.pyplot as plt
```


##円グラフ

```
label = ['car', 'bike', 'motorcycle']
x = np.array([200, 100, 50])
plt.pie(x, labels = label)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431266/7ea4914d-9df5-4753-d4a7-707c7d59e479.png)
サイトリライアビリティ ワークブックを読んで 1章 SREとDEVOPS



#DEVOPS
- ITカンファレンスで「あるべき姿、ITの文化」として広がった考え方。
- 開発(DEV)と運用(OPS)の情報共有、共同を主軸においている。
- デプロイや構築の目線

#SRE
- Googleの社内で運用に求められる役割、職種
- 開発(DEV)とは別の運用部門（開発スキルを持った部隊）
- 運用部門といっても、ただし、単純な手作業による運用は 労働の50%以下に抑える。
- SLOの改善や手作業の自動化などを開発スキルを駆使して行うこと職種
- SLOの改善、維持を目的としたもの


# SREとDEVOPSの関係性
 DEVPOSを成立させるための手段の一つとして、SREという職種が存在する。
- DEPOPSは文化、組織としての在り方
- SREは職種　役割
埋め込みURL探し

流石に需要がないか。。。というかこんな記事はありなのか。許してクレメンス。

### 起こったこと
某氏より依頼を受けた。
某氏のお子様が某塾、というか東進だが、のオンライン講義をタブレットで受けている。
で、Androidタブレットでyoutubeとかを見られて困る。と。

Google Family Linkでアプリとchromeアクセスurlを制限すればとアドバイスした。
タブレットは子ども用アカウントととして、大人のスマホでGoogle Family Linkを使ってアクセスを管理する。
で、しばらくはうまく行ったらしい。

だが、今度はchrome君から受講アプリを開けないとのことであった。
どうやらアプリを開くためのurlが、Google Family Linkにアクセス許可依頼で飛んでこないようだ。

そのドメイン名があれば解決するだろうとのことだったが、タブレットではそのアドレスがわからないとのことであった。

## 解決方法

PCのchrome君で動画フレーム近くを右クリック
→フレームのソースを表示

そこに動画のリンクurlが有る。
このドメイン名をGoogle Family Link側の許可リストに入れるだけ。

具体的にドメイン名を書くと起こられそうなので、それは許してください。
HTTPメソッドの４つを簡単紹介

HTTPメソッド

１．GET
　一番使われることの多いメソッド
　サーバーを参照する時などのリクエストで使う

２．POST
　サーバーに情報を送信したい時に使う
　投稿の保存やユーザー情報の登録など

３．DELETE
　サーバーの情報を削除する時に使う
　投稿の削除や退会など

４．PATCH
　サーバーの情報を更新する時に使う
　投稿の編集やユーザー名の変更など
【初心者】rails sが動かない時

rails sと入力すると

```
Address already in use - bind(2) for 127.0.0.1:3000 (Errno::EADDRINUSE)
```
とでてしまい、ローカルサーバーが動かないことがありました。
これは他で3000番を使ってしまっているので立ち上がらないということなので、切ってしまいます。

##やり方
3000番ポートで起動しているプロセスのIDを確認します。

```
＄　lsof -i :3000
```

```
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ruby    24301 ubuntu    6u  IPv4 161869      0t0  TCP *:3000 (LISTEN)
```
このように出てきます。

今回の場合だと

```
＄　kill -9 24301
```

とすればプロセスを停止することができるので、再度rails s を試してみてください。
routefを実行すると何が起きるか

# 概要
**routefコマンドはLinuxのほとんどのディストリビューションに最初から入っているコマンドで、flush routesの略です。これを実行すると警告も無くネットワークの設定を初期化するので、SSHで接続している最中に実行すると死にます。**

`man routef`でも、「これを実行するとネットワークに繋がらなくなるぞ」と丁寧な説明がされていますね...

**なお、再起動するとネットワークの設定は戻るのでご安心を。**


# 何が起きた？
では、具体的にどの設定が初期化されるのでしょうか。仮想環境で試してみました。

```shell
$ ip route
default via xxx.xxx.xxx.xxx dev eth0 proto dhcp metric 100
xxx.xxx.xxx.xxx/24 dev eth0 proto kernel scope link src xxx.xxx.xxx.xxx metric 100

$ ping google.com
# ちゃんと応答が返ってくる

$ sudo routef
# 特に出力も無く正常終了する

$ ping google.com
connect: Network is unreachable

$ ip route
xxx.xxx.xxx.xxx/24 dev eth0 proto kernel scope link src xxx.xxx.xxx.xxx metric 100
# defaultから始まる行が消えたのが分かる

$ ip route add default via xxx.xxx.xxx.xxx
# routef実行前にdefaultの行で宣言されていたゲートウェイのIPアドレスを追加すれば、また繋がるようになる
```

なお、これは一時的なものなので、再起動すると設定が元に戻り、ネットワークに接続できるようになります。


# 終わりに
初対面のコマンドと出会ったらとりあえず実行するのではなく、ちゃんとmanコマンドで確認してから、実行するか考えましょう。
なぜURIではなくPrefixを使うのか

resoucesメソッドでルーティングを設定すると・・・

```ruby
resources :tweets, only: [:destroy]
```

destroyアクションを実行するためのURLわかんないじゃん！
だからPrefixで遷移先を指定した方が便利なんだよ〜

ちなみにURLにidが含まれている時は

```ruby
Prefix_path(変数.id)
```

でparamsできちゃいます
はじめてのGithub メモ

基本的にはこの記事に従う
https://qiita.com/nnahito/items/565f8755e70c51532459

最後、リモートリポジトリにデータをプッシュする際に
エラー文が出たので

```
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```
こちらの通りに対処
http://tusukuru.hatenablog.com/entry/2018/08/29/021651

途中、lessとVimの終了方法が分からなくなったので
[lessの抜け方](https://qiita.com/inokou/items/a73bac8c7e03951d07be)
[Vimの抜け方](https://qiita.com/kon_yu/items/b8864ff566b8b67a9810)
Reactive Web AppにJavaScriptファイルを取り込むチュートリアル

YouTube上に、Reactive Web AppにJavaScriptファイルを取り込んで利用するチュートリアル動画が公開されたので手順を確認してみます。

この動画には簡単な手順のみが示されていて、JavaScriptをReactive Web Appに組み込むための注意事項等はありません。DOMを扱う際の注意事項などについては後続の情報待ち。

対象動画は以下
[How to Use External JavaScript in Your OutSystems Web Application](https://youtu.be/mcfZeThnvOE)

# 確認環境
Personal Environment(Version 11.8.0 (Build 12006))
Service Studio(Version 11.7.15)

# 組み込むJavaScriptファイル
動画中では10数行の簡単なJavaScriptファイルを組み込む手順が示されています。
せっかくなので、ちょっと違うJavaScriptファイルを作ってみました。
Random.randomInt()で1-100の範囲の整数をランダムに返します。

``` JavaScript
var Random = (function(){
    'use strict';
    
    var randomInt = function() {
        return Math.floor(Math.random() * 100) + 1;
    }
    
    return {
        randomInt: randomInt
    }
})();
```

このJavaScriptコードをRandom.jsという名前でコンピュータ内に保存しておいてください。

# テスト画面を用意
まず、Reactive Web Appアプリケーション、その内部にReactive Web Appモジュールを作ります。
用意したモジュールを開き、Emptyテンプレートを使って画面（Screen）を1つ作ります。

ここは普通と違うところがないので省略。

目標は読み込んだJavaScriptファイルの関数呼び出しをテストすることです。
そのため、処理の呼び出し用Buttonを1つと、結果を表示するExpressionを1つ配置してみました。
「乱数」というテキストを表示するボタンは、ダブルクリックしてOn Clickイベントに空のScreen Actionを紐付けておき（以下の画像ではOnClick Action）、ExpressionのValueプロパティにはローカル変数のNumber (Integer型) を設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d31c4e67-3f74-372e-061f-48b474b35ebe.png)

後で、ボタンをクリックしたら、JavaScript関数を実行し、結果をNumber変数に格納してExpressionに表示するようにします。

# JavaScriptファイルをインポートする
JavaScriptコードが独立したファイル形式の場合、Scriptsフォルダにインポートして使います。
こうすれば、モジュール内の複数の画面で簡単に使い回せるので。

1. Service StudioのInterfaceタブを開く
2. 一番下のScriptsフォルダを右クリック
3. コンピュータに保存しておいたRandom.jsを選択して「開く」ボタン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/2b7642f5-94bd-71bb-00e2-b57872498bb6.png)

インポートが終わると、以下のようになり、以降はJavaScriptプロパティで編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5bacd897-f732-47ce-2848-ed651949b1b6.png)

# インポートしたJavaScriptファイルを利用する
まずは、画面にJavaScriptファイルを取り込む設定をします。
画面のプロパティエディタの一番下に、Required Scriptsというプロパティがあるので、右のドロップダウンリストを展開し、インポートしたScripts.Randomを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/25959af6-aae8-9c5b-fbc9-c4b5e1d6c8d4.png)

この設定を入れておくと、画面表示時に自動でJavaScriptファイルを読み込んでくれるようです。

準備ができたので、上で作っておいたButtonのScreen ActionにJavaScript要素を配置してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a12c924b-2238-acda-1b22-44a528deb7ff.png)

JavaScript1の中で、出力変数Out1 (Integer型) を定義し、JavaScriptファイルに定義したRandom.randomInt()の結果を格納しています。
その後のAssignで、Expressionに紐付けたNumber変数にその結果を渡すという流れ。

$parameters内には、JavaScript要素で定義した各種変数が自動的に入ります。

``` JavaScript
$parameters.Out1 = Random.randomInt();
```

# テスト
以下の通り、ボタンをクリックするたびにJavaScriptファイル内の関数が実行され、結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5b45f7ed-601c-d83e-f5c2-3f90d8d50d47.png)
僕はバリデーションをかけたい！！

データベースに制限をかけたい
つまり管理役であるモデルに指示をする

validates :カラム名, 設定したいルール: true

「このカラム名にこのルールを設定したいんだけど？」
という意味。

app/models/tweet.rb

```ruby
class Tweet < ApplicationRecord
  validates :text, presence: true
end
```
find, find_by, find_by_sqlメソッドの違いについて

railsの学習を進めていく上で似たようなメソッドが出てきたのでまとめたいと思います。


##findメソッドとは

指定したモデルの`idを引数に設定することでレコードを取得するメソッド`です。

例えば↓↓↓

```ruby
pry(main)> Tweet.find(1)
   (0.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  Tweet Load (0.3ms)  SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`id` = 1 LIMIT 1
=> #<Tweet:0x00007fa3fd3800d8
 id: 1,
 text: "aaaaa",
 image: "",
 created_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
 updated_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
 user_id: 1>
```

id1のレコードを取得出来たことが分かりますね。

##find_byメソッドとは

指定したモデルの`id以外の条件でも取得することができるメソッド`です。（もちろんidでも検索取得可能）

例えば上で記述のレコード内容を見てみるとtextカラムには"aaaaa"という値が入ってますね。これを取得したいと思います。

```ruby
pry(main)> Tweet.find_by(text: "aaaaa")
  Tweet Load (0.4ms)  SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`text` = 'dv sdvdfsv' LIMIT 1
=> #<Tweet:0x00007fa3db12bd90
 id: 1,
 text: "aaaaa",
 image: "",
 created_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
 updated_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
 user_id: 1>
```

引数にtextカラムを指定して値"aaaaa"が入っているレコードを検索取得してますね。

##find_by_sqlメソッドとは

`SQL文を使用し、データを検索し取得する際に使用するメソッド`です。id1のレコードを取得した時

```ruby

SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`id` = 1
```
というselect文が発行されていました。
今回はこの文を変数に代入してレコードを取得してみようと思います。

```ruby
pry(main)> query = "SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`id` = 1"
=> "SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`id` = 1"
[9] pry(main)> Tweet.find_by_sql(query)
  Tweet Load (0.3ms)  SELECT `tweets`.* FROM `tweets` WHERE `tweets`.`id` = 1
=> [#<Tweet:0x00007fa3bc0e36e0
  id: 1,
  text: "aaaaa",
  image: "",
  created_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
  updated_at: Mon, 13 Jul 2020 06:42:56 UTC +00:00,
  user_id: 1>]
```

取得できていますね！！

正直find_by_sqlって使うときのイメージが湧かないんですが今後使うことはあるのだろうか。。。。
AWS Honeycodeを評価してみる

いつも忘れないように、コンセプトから。

###コンセプト
・お金かけてまでやりたくないのでほぼ無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ

今回はAWSのHoneycodeを試してみたので、その評価をまとめます。

###簡単な流れから

まず、Honeycodeのアカウントですが、AWSのアカウントとは別になっています。β版なので、正式版になると統合されるかもしれませんが、現状では全く別です。なので、Honeycodeにアクセスして新規アカウントを作成するひつようがあります。

作成すればサインインすることができます。現状ではAWSアカウントのようにMFAなどの設定はできないようです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/b4568525-8db0-d8c7-7734-521866cb6e75.png)

サインインしたあとはすぐにアプリを作ることができます。感覚を掴むためにまずはサンプルを作ってみましょう。画面ではToDoリストを選んでいます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/1f590578-658d-1165-0053-436d19180371.png)

すぐにサンプルアプリが展開されます。HoneycodeはTables、Builder、Automationsという３つのセクションに分かれています。TablesはDBみたいな感じのスプレッドシートです。現状RDSとかは使えないようですが、すぐに使えるようになるでしょう。TablesはDB＋Excelのような感じですね。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/6f70a338-2c6e-c5a5-03e2-418e4194e699.png)

Builderが実際の画面です。Web形式とモバイルの両方が既にあります。画面設計をしつつ、Tablesから値を取ってきたりします。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/06bf0265-4667-0dc5-88b7-07a1102baa6c.png)

Automationsは自動で何かをさせるような処理ですね。cronで何か仕込んだり、連携に使ったりする感じです。ここも現状ではメール転送くらいしかないですが、すぐにAWSのサービスと連携されていくと思います。Slackもすぐに使えるようになるんじゃないかとも思います。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/9b611b98-bc95-e1c5-46bd-c67c3ab63d75.png)

流れはこれだけです。超簡単。

###モバイルからアクセス

では、モバイルからアクセスします。スマホにHoneycodeのアプリをインストールして起動します。

そうすると、同じようにIDを入れる画面になります。
<img width="375" alt="6.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/0923d698-36ce-1625-038a-98d3989ce77f.jpeg">

サインインすると作成済みのアプリを選べるので、サンプルで作成したTodoを呼びます。モバイルからは今のところ使うだけです。ADD　TASKボタンを押すとタスク追加できます。実際にPCのブラウザから開発画面として入ると、先ほどのスプレッドシートにデータが入ります。
<img width="375" alt="7.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/7278c6c1-6339-510a-33d2-0f1dacae798b.jpeg">

ちなみに、スプレッドシートはマルチバイト対応されていて、ちゃんと日本語も入りました。あと、モバイルからブラウザー経由でアクセスしても、開発画面には入れませんでした。この辺は現状の仕様だと思います。個人的にiPadから開発できるといいなと思ったんですが、ダメでした。

こんな感じでちょっとしたアプリを作るのは非常に楽です。スマホで使う場合もHoneycodeのアプリを入れるだけで簡単に使えます。ちなみに、ちょっと試した感じではインターネットアクセス前提で、オフラインでは使えません。試しに機内モードにすると、ネットワーク接続できないので確認するように促されます。

現状ではβ版という感じですが、AWSのサービスを考えると非常に魅力的ですし、将来性も感じます。有償版になるとLambda連携もできるようなので、今後試していきたいと思います。

　
　
　
※追記
コミュニティの記事で便利そうなものを追記しました。
https://qiita.com/auf/items/b3a239adda19f7d8079f
ストロングパラメーターの単語をひとつづつ日本語翻訳


params.require(:モデル名).permit(:キー名, :キー名)
※モデル名は小文字の単数形
※キー名はカラム名がほとんど

params パラメーター（数値や文字を意味する）の複数形
require　命じる
permit　許可

つまり・・・

「このモデル名の許可したキーだけちょうだい！」

という事。

```ruby
 def create
    Tweet.create(tweet_params)
  end

  private
  def tweet_params
    params.require(:tweet).permit(:name, :image, :text)
  end
```

ちなみにストロングパラメーターはクラス外で使うことはないのでプライベートメソッドを利用する
swift5で手っ取り早くタイマー処理を実装する


# 初めに
今回はタイマー処理を実装したいと思います。
タイマー処理はアニメーション処理などで器用されたり、連続でボタンを押さないように制御に使うことがあります。(ボタン連続押下防止は多分違う方法あると思います)
## 実装
```swift:MainController.swift
//タイマー処理
Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(MainController.timerUpdate), userInfo: nil, repeats: false)
//タイマーの実行メソッド
@objc func timerUpdate() {
　　//タイマーで実行したい何かの処理をここにかく
}
```
# 終わりに
簡単ですね。
引数のtimeIntervalの値を変えれば時間も変わります。
EChartsでgridを使うための基本概念

EChartsを使い複数のグラフを表示したくてgridを使おうと思ったけど、ドキュメントを見ても使い方がよくわからず調べたのでメモ

# まず概念、部品を理解する
どういう概念、部品があるかを理解するとわかりやすいです。
gridとxAxis,yAxisとseriesの3つの概念/部品をわかっておけばいいでしょう。

gridはチャートを描く土台となる部分。
xAxis,yAxisはgridの横についている目盛り部分。
seriesは実際のチャート部分 (折れ線グラフだったら線の部分)。

これだけわかっていれば良いと思います。

これら3つが組み合わさって1つのグラフを作ります。
組み合わせ方 (ひも付き方) は、**gridがあって、gridにxAxisとyAxisがついていて、xAxisとyAxisにseriesがつく**、という形です。

# 実例
EChartsの公式ページの↓のグラフを例にして説明します。
https://echarts.apache.org/examples/en/editor.html?c=line-gradient

## コード抜粋
説明のため、上のリンクの例のoption部分のみを抜き出し、さらにコメントを追加したものが↓になります。

2つの折れ線グラフを定義するためのoptionです。見てわかるように、**gridを2つ定義し、それらにxAxis, yAxisを定義して紐付けて、さらにseriesをxAxis, yAxisに紐付けるよう**にしています。

```javascript

option = {
    // gridを2つ定義する。
    grid: [{ 
        bottom: '60%' // 1つ目のgridを定義
    }, {
        top: '60%' // 2つ目のgridを定義
    }],
    // xAxisを2つ定義してgridと紐付けます
    xAxis: [{
        data: dateList
        // gridIndexを指定しないと0を指定したのと同じ
        // 上で定義したgridのインデックスが0(つまり1番目)のgridを紐付けることになります
    }, {
        data: dateList,
        gridIndex: 1 // インデックスが1のgridに紐付ける
    }],
    // yAxisを2つ定義してgridと紐付ける
    yAxis: [{
        splitLine: {show: false} // gridIndexを指定しないと0を指定したのと同じ
    }, {
        splitLine: {show: false},
        gridIndex: 1 // インデックスが1のgridに紐付ける
    }],
    // seriesを2つ定義してxAxisとyAxisに紐付ける
    series: [{
        type: 'line',
        showSymbol: false,
        data: valueList
        // xAxisとyAxisを指定しないと、どちらもインデックス0を指定したことになります。
        // なので、上で定義したxAxisとyAxisどちらもインデックス0のものを紐付けることになります。
    }, {
        type: 'line',
        showSymbol: false,
        data: valueList,
        xAxisIndex: 1, // インデックス1のxAxisIndexを紐付ける
        yAxisIndex: 1  // インデックス1のyAxisIndexを紐付ける
    }]
};
```
Visionの顔認識で顔のパーツを切り抜く（眉、目、鼻、口）

#美容系アプリや顔パーツのデータセットに
Visionの顔ランドマーク検出（face landmark detection）で、眉、目、鼻、口などのポイントを取得できます。今回は、それらのポイントを利用して各パーツをクロップします。
<img width="150" alt="スクリーンショット 2020-07-23 22.23.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/558793e5-b2b3-654c-2356-a27b06ef46ba.png">

#元画像の座標に変換する
landmarks のnormalized CGPointは顔の境界ボックス内の正規化された座標なので、クロップするためにVNImagePointForFaceLandmarkPointで画像全体の中の座標に変換します。

```swift
extension CGPoint {
    func convertToImagePoint(_ originalImage:CIImage,_ boundingBox:CGRect)->CGPoint {
        let imageWidth = originalImage.extent.width
        let imageHeight = originalImage.extent.height
        let vectoredPoint = vector2(Float(self.x),Float(self.y))
        let vnImagePoint = VNImagePointForFaceLandmarkPoint(vectoredPoint,boundingBox, Int(imageWidth), Int(imageHeight))
        let imagePoint = CGPoint(x: vnImagePoint.x, y: vnImagePoint.y)
        return imagePoint
    }
}
```
あとは、とったポイントのx,yの最大値と最小値を求めて、CGRectにしてオリジナル画像から切り抜くだけです。
そのままのポイントを使うと、ぴったり切り抜きすぎてわかりにくいので、パディングを入れた方がなんのパーツかわかりやすいです。

```swift
    func cropParts(partsPoints points:[CGPoint],horizontalSpacing hPadding:CGFloat, verticalSpacing vPadding:CGFloat, originalImage image:CIImage)->UIImage?{
        if let Minx = points.min(by: { a,b -> Bool in
            a.x < b.x
        }),
            let Miny = points.min(by: { a,b -> Bool in
                a.y < b.y
            }),
            let Maxx = points.max(by: { a,b -> Bool in
                a.x < b.x
            }),
            let Maxy = points.max(by: { a,b -> Bool in
                a.y < b.y
            }) {
            let partsWidth =  Maxx.x - Minx.x
            let partsHeight = Maxy.y - Miny.y
            let partsBox = CGRect(x: Minx.x - (partsWidth * hPadding), y: Miny.y - (partsHeight * vPadding), width: partsWidth + (partsWidth * hPadding * 2), height: partsHeight + (partsHeight * vPadding * 2))
            let croppedImage = image.cropped(to: partsBox)
            guard let final = ciContext.createCGImage(croppedImage, from: croppedImage.extent) else {return nil}
            let partsuiimage =  UIImage(cgImage: final)
            return partsuiimage
        } else {
            return nil
        }
    }
```

#複数人数の画像に注意
VisionのVNDetectFaceLandmarksRequestは一枚の画像から複数の人を同時に処理します。僕は3人までしかとったことがありませんが、それくらいの人数なら綺麗にランドマークがとれます。ただし、背景に映り込んだ人なども検出してしまうことがあり、それを防ぐにはBounding Boxの大きさでフィルターをかける必要があるでしょう。

#この技術を使った自作アプリ
[かわいいタイプ診断BeautyCaption](https://apps.apple.com/us/app/id1485839081)

機械学習関連の情報を発信しています。
https://twitter.com/JackdeS11

Core MLやCreate ML、Visionを使ったアプリを作っています。

rockyshikoku@gmail.com　　　　　　　　　　　　↓
pygameでn秒おきに音が鳴るタイマーを実装する

# はじめに
pygameというライブラリを使って、
指定時間おきに音楽が再生されるコンソールアプリを開発します。

# 背景


適性試験CABの対策を目的に作成しました。
これは大量の問題を高速で処理していかなければならないものなので、
1問あたりに何秒の時間をかけるか？という、時間の管理は非常に大切です。

この試験の対策をするにあたって、
例えば、30秒経ったよ！1分経ったよ！いま1分30秒！...のように、
経過時間を音で知らせてくれるアプリがあれば、『効率的に試験を解く』練習がしやすいと考えました。

というわけで

**n秒おきにアラームが鳴るコンソールアプリケーションを開発します。**

# 開発環境

- Python 3.8.3
- pygame 1.9.6

# ソースコード

とりあえず動いたら（使えたら）いいやという観点から作っているので、
指摘されるべき点はたくさんあると思います。

例：While Trueが終わらない

再生する音楽（音）はこちらでお借りしました。
[魔王魂](https://maoudamashii.jokersounds.com/archives/se_maoudamashii_onepoint26.html)

```Python
from mutagen.mp3 import MP3 as mp3
import pygame
import time

filename = 'hoge.mp3'  # 再生したいmp3ファイル
interval_time = 0  # 再生間隔を秒数で指定する

interval_time = int(input("アラーム間隔を秒数で設定せよ >>"))
print("開始　終了したいときはCtrl+C")


pygame.mixer.init()
pygame.mixer.music.load(filename)  # 音源を読み込み


while True:
    pygame.mixer.music.play()
    time.sleep(interval_time)

pygame.quit()
```

# さいごに

キーボードをたたくとか、任意の処理で簡単に処理を中止できるようにするとか、
GUIアプリケーションにするとかできたら、もっと便利かなと（他の人も使いやすいかなと）考えています。

Tkinter x pygameとか。


# 参考

-  [PythonでMP3音源を再生する](https://qiita.com/kekeho/items/a0b93695d8a8ac6f1028)
-  [Pygameドキュメント](http://westplain.sakuraweb.com/translate/pygame/Music.cgi)
-  [pygameでタイマー機能を実装する](https://qiita.com/cordy/items/49dd94762ade8d5d34ad)
[C#]  .NETアプリのデータ保存に最適な軽量ローカルDB、「LiteDB」の紹介

# はじめに

C#プログラマの皆さんは、アプリのデータの永続化はどうしていますか？

* JSONやXMLにしてテキストファイルに保存
* SQLiteに保存
* MySQLやSQLServer等のDBサーバーを構築

などほかにも様々な方法が考えられます。

WinUIや、デスクトップアプリ、MAUIなどのアプリ開発でちょっとしたデータを保存したいけど、JSONだと物足りない、SQLiteはSQL書くのめんどくさい。かといってEFCoreよりも手軽にしたいなんてことはありませんか？

今回はアプリ等のデータをローカルに簡単に保存するのに最適なオープンソースのローカルNoSQLデータベース「LiteDB」を紹介したいと思います。

[Githubのリポジトリ](https://github.com/mbdavid/LiteDB)
[公式サイト](http://www.litedb.org/)

## LiteDBのいいところ

* 100%すべてC#で作られている
* クロスプラットフォーム
* 単一ファイルデータベース
* ライブラリ自体も300KB程度の単一ファイル（LiteDB.DLL）
* DBサーバー不要
* Unityでも使える
* NoSQL
* スレッドセーフ
* 暗号化対応
* そこそこ高速そう　([Githubにベンチマークがあります](https://github.com/mbdavid/LiteDB-Perf))

一応GUIのクライアントアプリもあるみたいですし、ネットワークに接続しないアプリ等で使用する際にはこれで十分そうですよね。

## SQLiteとLiteDBの比較
いくつかの特徴はSQLiteともかぶっていると思いますが、個人的には以下の場合はLiteDBを使います。

* SQLiteはライブラリ自体インストールするだけで約5MBくらいあったので全然Liteじゃなく実行ファイルを小さくしたい
*  SQLiteは良くも悪くもC言語のネイティブライブラリのラッパーであるのでクロスプラットフォームで利用することを考えると場合LiteDBのほうが扱いやすい

ただ、パフォーマンスのや信頼性の観点からいうとSQLiteのほうがいいんじゃないかと思います。
SQLiteはMySQLとかSQL Serverと張り合えるくらいには高速ですし実績も多いのですし。
大量のI/Oが起きる場合、数100万レコードの単位のデータを扱う場合、信頼性重視の場合はSQLiteを採用するほうが無難でしょう。

## インストール

```
NuGetの場合
> Install-Package LiteDB
```

```
.NET CLIの場合
$ dotnet add package LiteDB
```

## とりあえず公式のサンプルを参考に動かしてみる

とりあえずエンティティを用意

```C#
public class Post{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
}
```

使ってみる

```C#
// コンストラクタ引数はファイル名
using var context = new LiteDatabase("./data.db");

// エンティティ
var post = new Post()    {
    Title = "たいとるうううう",
    Body = "ぼでえええええええ"
};

// DBへ接続
var posts = context.GetCollection<Post>("posts");

// Titleをユニークインデックスにする
posts.EnsureIndex(x => x.Title, true);

// 作成
posts.Insert(post);

post.Title = "更新したよおおおお";

// 更新
posts.Update(post);

// 検索
// Titleが「更」で始まるもの
var results = posts.Find(x => x.Title.StartsWith("更"));
```

# まとめ

超簡単にデータの永続化ができましたね！！
これならそんなに規模の大きくないアプリ開発では十分に力を発揮できそうです。

リレーションやインデックス等、詳しくは公式を参照してください。
[Githubのリポジトリ](https://github.com/mbdavid/LiteDB)
[公式サイト](http://www.litedb.org/)
【初心者でもわかる】HTML（HTML5）で閉じタグがいらない要素の一覧

# どうも7noteです。HTML（HTML5）で閉じタグの記述がいらないタグがある話。

どうも7noteです。
この記事は以下へ引っ越しました。



https://naruweb.com/coding/endtag/
Laravel tinker データベースの接続できるか疎通確認する

```
$ php artisan tinker
```

## データベースに接続できるか確認する

一番簡単なのはSELECT文が通るかSQL実行して確認します。

```shell-session
>>> DB::select('select 1');
=> [
     {#3046
       +"1": 1,
     },
   ]
```

このような結果が返れば、少なくともデータベースに接続できています。

## データベースに接続できない場合

データベース接続設定内容を確認します。

```shell-session
$ php artisan tinker
>>> config('database.default')
=> "mysql"

>>> config('database.connections.mysql')
=> [
     "driver" => "mysql",
     "url" => null,
     "host" => "db",
     "port" => "3306",
     "database" => "laravel_local",
     "username" => "phper",
     "password" => "secret",
     "unix_socket" => "",
     "charset" => "utf8mb4",
     "collation" => "utf8mb4_unicode_ci",
     "prefix" => "",
     "prefix_indexes" => true,
     "strict" => true,
     "engine" => null,
     "options" => [],
   ]

>>> DB::connection()->getConfig();
=> [
     "driver" => "mysql",
     "host" => "db",
     "port" => "3306",
     "database" => "laravel_local",
     "username" => "phper",
     "password" => "secret",
     "unix_socket" => "",
     "charset" => "utf8mb4",
     "collation" => "utf8mb4_unicode_ci",
     "prefix" => "",
     "prefix_indexes" => true,
     "strict" => true,
     "engine" => null,
     "options" => [],
     "name" => "mysql",
   ]

>>> DB::connection()->getPdo();
=> PDO {#3051
     inTransaction: false,
     attributes: {
       CASE: NATURAL,
       ERRMODE: EXCEPTION,
       AUTOCOMMIT: 1,
       PERSISTENT: false,
       DRIVER_NAME: "mysql",
       SERVER_INFO: "Uptime: 859  Threads: 3  Questions: 42  Slow queries: 0  Opens: 116  Flush tables: 3  Open tables: 36  Queries per second avg: 0.048",
       ORACLE_NULLS: NATURAL,
       CLIENT_VERSION: "mysqlnd 7.4.4",
       SERVER_VERSION: "8.0.19",
       STATEMENT_CLASS: [
         "PDOStatement",
       ],
       EMULATE_PREPARES: 0,
       CONNECTION_STATUS: "db via TCP/IP",
       DEFAULT_FETCH_MODE: BOTH,
     },
   }
```

この結果と `.env` 等の設定を比較して正しい設定が行われているか確認します。

## 参考

https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4#comment-e3143e52bdf87c1593f5
CakePHP4 のエンティティでテーブルを使う

# 環境
- CentOS 6
- PHP 7.2
- CakePHP 4.1.0

# やりたかったこと
エンティティの中でテーブルオブジェクトを扱いたかっただけなんですけどね…。CakePHP3 系で使っていた TableRegistory が非推奨のようで、PhpStorm で打ち消し線を引かれてて (´・ω・｀) となったので、ちゃんと推奨されたの使いたいな、と思っただけです。ほぼ自分用メモ。

# 結論

Cake\ORM\Locator\LocatorAwareTrait　を使うそうです。

ちなみに、Docs には
>Deprecated:
>4.1.0 Use \Cake\ORM\Locator\LocatorAwareTrait::getTableLocator() or \Cake\Datasource\FactoryLocator::get('Table') to get the table locator instance instead.

とありました。
どっちでもいいんですな。

今回は Cake\ORM\Locator\LocatorAwareTrait を使ってみます。

```php

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Cake\ORM\Locator\LocatorAwareTrait; # これが必要

class Hoge extends Entity
{

    use LocatorAwareTrait; # これが必要

    public function fuga()
    {

        $table = $this->getTableLocator()->get('TableName');
        .
        .
        .

    }
    .
    .
}
```

現時点（2020/07/23) の本家日本語ドキュメントでは CakePHP3 での使い方がそのまま載っているようでした。
英語の方にはきちんと新しい方の使い方が載ってました。そんなんあるんかい………＼(^o^)／

▼本家 CookBook [ Entities -4.x- ]
[https://book.cakephp.org/4/en/orm/entities.html#namespace-Cake\ORM](https://book.cakephp.org/4/en/orm/entities.html#namespace-Cake\ORM)
超初学者向け！resourcesメソッドの書き方！

resourcesを使うと・・・
７つのアクションへのルーティングを一度に自動生成できる！

resources :コントローラー名
※コントローラー名だから小文字でs付き

```ruby
Rails.application.routes.draw do
  resources :tweets
end
```

特定のアクションだけ生成させたい！
resources :コントローラー名, only: :アクション名


```ruby
Rails.application.routes.draw do
  resources :tweets, only: [:index, :new]
end
```


特定のアクション以外だけ生成させたい！
resources :コントローラー名, except: :アクション名
【ポートフォリオ を作成される方へ】font-awesome-railsの使い方

##font-awesome-railsとは
webフォントアイコンを無料で使えるFont Awesomeを簡単にrailsで使えるライブラリ
Font Awesomeは拡大してもぼやけたりしないことが特徴です。
自分の好みの色やサイズに変更できます。

※font-awesome-railsは最新版に対応していないため、使えるアイコンが少し少ないです。
そんな方にはfont-awesome-sassがおすすめです。

##font-awesome-rails導入
```ruby:Gemfile

gem 'font-awesome-rails'
```
```
$ bundle install
```

application.cssの場合

```
*= require font-awesome
```

application.scssの場合

```
@import "font-awesome";
```

準備完了

##使い方
基本

```
<i class="fa fa-アイコン名"></i>
```

サイズ変更

```
<i class="fas fa-アイコン名 fa-lg"></i>
```
fa-lg (1.333…倍)
fa-2x (2倍)
fa-3x (3倍)
fa-4x (4倍)
fa-5x (5倍)

その他のサイズや色に変更したい時はcssに書けばできます。


##参考
https://fontawesome.com/v4.7.0/icons/
[JavaScript] URLクエリパラメータの値を簡単に取得する方法

## 前置き

ReactでSPAをつくっているときURLクエリパラメータの値を取得したいと思いました。(検索機能実装とか)

今回自分がやってみたJavaScriptでクエリパラメータの値を簡単に取得する方法を残します。

> //example.com?id=amanojs
> この ? 以下の文字列がクエリ文字列です

## 実際のコード

```tsx
const params = new URLSearchParams(window.location.search)
const value = params.get('key名') // key名の値
```
こんな簡単にクエリパラメータの値を取得することができます。

## なぜ
``URLSearchParams``クラスはURLのクエリー文字列の操作に役立つメソッドを提供してくれます。
コンストラクタに操作したいクエリー文字列を渡すことで、そのクエリー文字列を操作するためのオブジェクトを返してもらえます。

``window.location``オブジェクトの``search``プロパティは現在ページURLのクエリ部(?以下の文字列)を参照できるので、今回はこれをURLSearchParamsクラスに渡して操作するという流れでした。

##最後に

componentがマウントされてから実行することを推奨します。
しかしながらReactで開発するときは``window``オブジェクトを参照するのはあまり良くないのかなぁとか思います。(テストツールの関係上)
もっといいやり方があったらぜひ教えてくださると嬉しいです。

以上
（修正）VSCodeのLanguage Support for Java(TM) by Red Hatの最新版(0.65.0)でJava8を使っているとエラーが発生する。

## (はじめに追記）バグだと思ったら仕様でした。

Language Support for Java(TM)のバージョン（0.65.0)以降ではJava11以上が必須となった関係で、Java8の環境ではエラーを吐いてしまいます。当初はバグだと思ってたのですが、仕様だそうです。（コメントで教えていただきました、ありがとうございました！）

VSCodeのJavaチュートリアルでもJava11以上でないと動かないとのこと。
https://code.visualstudio.com/docs/languages/java

<img width="1276" alt="スクリーンショット 2020-07-29 22.25.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270149/62128666-7450-d53f-801c-236323b88983.png">

解決策としては下記URLを参照してください。
https://github.com/redhat-developer/vscode-java/wiki/JDK-Requirements#setting-the-jdk

具体的には、
```
"java.home": "c:\\java\\jdk-11",
"java.configuration.runtimes": [
    {
        "name": "JDK-1.8",
        "path": "C:\\java\\Java1.8.0_151",
        "default": true
    },
],
```
こんな感じでJava_Homeにjdk-11を設定して,runtimesでjdk-8をdefaultにすれば良いと思います。


## (元記事)VSCodeのLanguage Support for Java(TM) by Red Hatの最新版(0.65.0)でバグが発生する(2020年7月23日)
VSCodeを使ってJavaを書いているのですが、プロジェクトのテンプレートを作成する。Java:Create Java Projectが効かなくなり、次のようなエラーが出るようになりました。

<img width="622" alt="スクリーンショット 2020-07-23 9.57.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270149/11dc37f2-b00b-960f-a034-30f198c12d7a.png">

```Java 11 or more recent is required to run. Please download and install a recent JDK```

これが出てから普通に実行もできなくなりました。困った。
環境はRemote-Containerを用いたopen-JDK8を使っていて、昨日までは機嫌良く動いてました。JAVA_HOMEの設定も問題ない。

何でかなーと4時間くらい彷徨ったのですが、原因は前日に更新されたLanguage Support for Java(TM) by Red Hatのver0.65.0。
同じ症状が出ている人の投稿を発見してようやく対応できた。感謝。

[URGENT- "Java 11 or more recent is required to run. Please download and install a recent JDK" #852
](https://github.com/microsoft/vscode-java-debug/issues/852)


とりあえず当該の拡張機能をダウングレードして対応待ちです。もし同じ状況の人がいたときのために残しておきます。
<img width="610" alt="スクリーンショット 2020-07-23 16.20.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270149/6e7204f6-2b2c-e540-40e8-e2545075ceed.png">
WTFormsのSelectFieldを動的に使う。

FlaskでWTFormsでフォームを作った場合SelectFieldを動的に使いたいことがある。

# データ

`<option></option>`を動的に作る方法。



```html:htmlで記述した場合
<select id="users">
    <options value="1">日本 太郎</option>
    <options value="2">山田 太郎</option>
    <options value="3">山田 花子</option>
</select>
```
```jinja:jinjaでの記述した場合
<form method="post>
    {{ form.csrf_token }}
    {{ form.name(id='users') }}
    {{ form.submit }}
</form>
```

```python:forms.py
class UserForm(Form):
    name = SelectField('ユーザ名', coerce=int) # coerceにはstrで文字列でも値を格納できる。
    submit = SubmitField('登録')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._set_users()

    def _set_users(self):
        users = Users.query.all()
        # DBから取得したデータをchoiesにタプルで　(valueの値, textの値)　と格納するだけ。　
        self.users.choices = [(user.id, user.name) for user in users]
```




# 属性
動的に作られた`<option></option>`に属性を追加する方法。
これが意外と苦戦したところ。

```python:widgets.py
from wtforms.widgets.core import HTMLString, html_params, Markup, escape, text_type

class MySelect(object):
    def __init__(self, multiple=False):
        self.multiple = multiple
        
    def __call__(self, field, **kwargs):
        kwargs.setdefault('id', field.id)
        if self.multiple:
            kwargs['multiple'] = True
        if 'required' not in kwargs and 'required' in getattr(field, 'flags', []):
            kwargs['required'] = True
        html = ['<select %s>' % html_params(name=field.name, **kwargs)]

        # 選択できない初期値を追加する
        html.append(self.render_option(value='', label='選択してください', selected=False, disabled=True))

        for val, label, selected in field.iter_choices():
            # 各<option></option>にstyleを適用させることが可能に。
            html.append(self.render_option(val, label, selected, disabled=False, style='background-color:black'))
        html.append('</select>')
        return Markup(''.join(html))

    @classmethod
    def render_option(cls, value, label, selected, disabled, **kwargs):
        if value is True:
            # Handle the special case of a 'True' value.
            value = text_type(value)
        options = dict(kwargs, value=value)
        if selected:
            options['selected'] = True

        # hiddenをここで追加。
        if disabled:
            options['hidden'] = True

        return Markup('<option %s>%s</option>' % (html_params(**options), escape(label)))

```


```python:forms.py
from widgets.py import MySelect

class Color(Form):
    name = SelectField('ユーザ名', coerce=int, widget=MySelect()) # widgetを指定するだけ。
    submit = SubmitField('登録')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._set_users()

    def _set_users(self):
        users = Users.query.all()
        self.users.choices = [(user.id, user.name) for user in users]
```
CRUDってなんぞ？

データの取り扱いの基本処理をまとめたジャンルだよ！
そしてrailsでは基本処理が７つ存在する！

C．create 生成
　（１）new　生成
　（２）create　生成

R．read   読み取り
　（３）index　一覧表示
　（４）show　詳細表示

U．update 更新
　（５）edit　編集
　（６）update　更新

D．delete 削除
　（７）destroy　削除

そしてこの基本アクション７つはresoucesメソッドを使用して一度にルーティングを設定できる！
AWS MFA 設定で「エンティティは既に存在しています」エラーの解決方法

# 概要

AWS MFA 設定中に中断した結果「エンティティは既に存在しています」というエラーが発生したときの解決方法をご紹介します。

![aws-mfa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4798/f61f603c-5839-56c8-7cbc-bad68270408a.png)

# 「エンティティは既に存在しています」エラーの解決手順

## list-virtual-mfa-devices で問題の SerialNumber を特定する

- [list\-virtual\-mfa\-devices — AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/iam/list-virtual-mfa-devices.html)

```shell
aws iam list-virtual-mfa-devices
```

**aws iam list-virtual-mfa-devices の結果 (JSON)**

```json
{
    "VirtualMFADevices": [
        {
            "SerialNumber": "arn:aws:iam::012345678990:mfa/sample-username"
        },
        {
            "SerialNumber": "arn:aws:iam::012345678990:mfa/root-account-mfa-device",
            "User": {
                "UserId": "012345678990",
                "Arn": "arn:aws:iam::012345678990:root",
                "CreateDate": "2020-06-17T14:05:18+00:00",
                "PasswordLastUsed": "2020-07-21T02:39:58+00:00"
            },
            "EnableDate": "2020-06-17T14:14:35+00:00"
        },
    ]
}
```

## delete-virtual-mfa-device で削除する

- [delete\-virtual\-mfa\-device — AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/iam/delete-virtual-mfa-device.html)

```shell
aws iam delete-virtual-mfa-device --serial-number "arn:aws:iam::012345678990:mfa/sample-username"
```

以上、AWS MFA 設定で「エンティティは既に存在しています」というトラブルシューティングをした、現場からお送りしました。
マイグレーションファイルを編集してカラムを追加しよう！

t.データ型 :カラム名
途中に "," は必要ないよ！

```ruby
class CreateTweets < ActiveRecord::Migration[6.0]
  def change
    create_table :tweets do |t|
      t.string :name
      t.string :text
      t.text :image
      t.timestamps
    end
  end
end
```
分散合意アルゴリズムとビザンチン将軍問題[WIP]

## はじめに
　タイトルにも挙げた二つのワードですが、あまり聞きなれない方もいるのではないかと思います.かくいう私も最近勉強し始めた内容なんですけども・・・
　この記事はそんな初心者のちょっとしたアウトプットとして読んでいただければ幸いです.
## 分散合意アルゴリズム
　そもそも「合意」ってどんな意味なんでしょうね？言葉は知ってるけど、日常では滅多に使わない言葉ですよね.調べてみると色々出てきますが、大体こんな意味みたいですね

> 二人以上の者の意見が一致すること

という事で,言葉から読み取るには分散している環境で意見を一致させるアルゴリズムなんだという事なんですね.

###つまりどういうこと？
　このアルゴリズムが活躍しているのは分散された環境です.世の中色んなシステムが分散できますよね.DBとか最近よく耳にするKubernetesとか、僕たちが目にしない日なんてないwebも分散してますね.
　そして、分散しているからといってシステムを構成しているマシンが各々好き勝手にデータの保持だったり命令を実行してたら一つのシステムとして機能しません.
　分散合意アルゴリズムは、分散システムでそういったことが起こらないように、一貫性だったり可用性、耐故障性を実現するためのアルゴリズムです.合意の意味に沿って言うと、分散システムを構成している二つ以上のプロセスが、持っているデータや実行する命令などを同一にするっていう感じになると思います.


### 例えばどんなの
####Raft
　Kubernetesの分散KVSであるetcdを動かしている分散合意アルゴリズムです.qiitaを使わせていただいている限りだと、Raftを解説するコンテンツが豊富で,論文を読まなくても基本的な部分は理解させていただけます.先人の方々の解説記事がとても優秀なのでもしこの記事を読んで興味がわきましたら探して読んでみてください
####Paxos
　合意アルゴリズムの金字塔 とRaftの論文でも言われている通り、とても有名な合意アルゴリズムです.様々な合意アルゴリズムが,このPaxosを元に生まれていきました.
とても素晴らしいアルゴリズムという事なのですが,如何せん論文が難解であり,アルゴリズムを理解するのが難しいとのことです.私も先人の方々の解説を拝見させていただいてるのですが,まだ私のポンコツ脳は完璧には理解できていません.
　上のRaftは「Paxosは理解するの難しいから実装方法も統一されないし・・・だったらもっと理解が簡単で同じくらいの性能のやつ作ろう！」みたいなスタンスで生まれた感じです.Raftの論文でもこの名前は序盤に結構出てきます.それだけ、意識されるくらいの存在感があるってことなんだと思います.
ちなみに、考案者はレスリー・ランポート先生という方なのですが、この方はLaTeXを作った方でもあります.
## ビザンチン将軍問題
時はさかのぼること幾星霜、舞台のビザンチン帝国で9人の将軍が攻撃か撤退かを多数決で決める事になりました。過半数以上が攻撃なら全員で攻撃,過半数以上が撤退なら全軍撤退.さて、ここで賛成4人,反対4人になっている状態です.9人目のあなたが裏切り者で,ビザンチン帝国を負けさせたい場合,どうしますか？

みたいな感じの話が元ネタ(?)の問題です.作戦を失敗にする方法は,考えればいろいろ出てくると思います.賛成4人に賛成,反対４人に反対の意見を送ったりとかetc
### 概要
間違った情報を伝達する存在(裏切り者)がいる場合に全体として正しい合意を形成できるかを問う問題を一般的にビザンチン将軍問題といいます.

　そして、このようなビザンチン将軍問題に帰結される故障や障害をビザンチン故障、ビザンチン障害と言い、これらに耐性がある事を一般にビザンチン故障耐性(Byzantine Fault Tolerance：BFT)があると言います

　先ほど名前の挙がったのレスリー・ランポート先生を含めた3人の方々が1980年頃に出した「The Byzantine Generals Problem」という論文で分散コンピューティング上の問題として定義されました.論文中では,裏切り者が3分の1以下であればBFTが達成できるといわれています.
## まとめ
最近では,ブロックチェーンの分野でよく取り上げられるワードたちだと思います.ブロックチェーンの合意アルゴリズムは、ビザンチン障害にも耐えられるように設計されています.仮想通貨などのお金を扱うシステムに多く取り入れられているので悪意のあるものからの攻撃に晒される機会が多いからなのかなと思います.
## おわりに
　分散合意アルゴリズムとビザンチン将軍問題について触れてみました.このアルゴリズムを覚えれば直接何かの役に立つとは言いにくいですが、今日の情報社会では分散システムは無くてはならないシステム形態です.システムのいつもより中の部分について知るというのも面白いのかなとは思います.

　記事は以上になります。お疲れさまでした。

##参考
[Raft](http://pages.cs.wisc.edu/~remzi/Classes/739/Spring2004/Papers/raft.pdf)
[Paxos](https://www.slideshare.net/tyonekura/paxos-63835103)
[ビザンチン将軍問題](https://www.microsoft.com/en-us/research/publication/byzantine-generals-problem/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fum%2Fpeople%2Flamport%2Fpubs%2Fbyz.pdf)