OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】Lambda+Amazon SNSでSMSを送信する

#やりたいこと
AWS LambdakからAmazon SNSを利用して、任意の電話番号あてにSMSを送信します。


#Amazon SNSって？
Amazon Simple Notification Service
任意の通知をいろんなプロトコルで送信できるよ。
事前にトピックっていう通知カテゴリみたいなの作って、そいつに紐づくサブスクリプションを作成しておくと、
トピックが叩かれたときに紐づいているサブスクリプションにメッセージが送信されるよ。
で認識合ってる？

| プロトコル/トランスポート |
|:-:|
| HTTP/HTTPS  |
| Email  |
| Email-JSON  |
| Amazon SQS  |
| AWS Lambda  |
| Platform application endpoint  |
| SMS  |

[公式の概要](https://aws.amazon.com/jp/sns/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc)
[Black Beltのスライド](https://aws.amazon.com/jp/blogs/news/webinar-bb-amazon-sns-2019/)


#コードとかより注意しておきたいこと
###送信制限について
SNSでのSMS送信は送信制限が厳しめに設定されています。
利用料金の上限が1USD/月に設定されていて、東京リージョンにおいては12,3通/月しか送れません。
テスト送信だけで上限に達する可能性もあるので、必要があれば上限緩和申請を出しましょう。

###宛先指定について
SNSでSMSを飛ばす分にはトピックを作成しなくても送信が可能です。

SMSじゃなくてE-Mailを送信したいという場合、
SNSでは事前にE-Mailの検証（実際にメールを送って、受信者が認証する）が必要です。
Lambdaでメールアドレスを指定してメール送信したいときにはAmazon SESを使いましょう。



#構成
AWS LambdaとAmazon SNSのみです。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/588ee7b3-5e30-51bc-400f-1f3ebfc32377.png)

#Lambda関数
事前にLabmda実行ロールにSNS実行ポリシーをアタッチしましょう。
とりあえずテストなのでAmazonSNSFullAccessをアタッチしておきます。

###コード
ランタイムはNode.js 12.xです。

```TestSendSMS.js
var AWS = require("aws-sdk");
var SNS = new AWS.SNS();

exports.handler = function(event, context, callback){
    
    // メッセージ情報を設定
    var param = {
        PhoneNumber: 'E.164形式の電話番号',
        Message: 'This is test message.',
        MessageAttributes: {
            'AWS.SNS.SMS.SMSType': {
                DataType: 'String',
                StringValue: 'Transactional' // 信頼性を重視する場合はこちらを
              //StringValue: 'Promotional'   // コストを重視する場合はこちらを
            },
            'AWS.SNS.SMS.SenderID': {
                DataType: 'String',
                StringValue: 'TEST'  // 端末に表示される送信元名
            }
        }
    };
    
    // メッセージを送信する
    SNS.publish(param, function(err, data){
        if(err){
            context.done(null, err);
        }
        context.done(null, data);
    });
};
```

多分これでいけます―
Qiita記事投稿用テンプレート

#概要
Qiitaの記事作成の際、いちいちMarkdown書いていくのもめんどくさかったので、テンプレートとしてこの記事に残す。
この記事をコピペしながら書き進めることで時短を狙う。

#テンプレート本体
```
# はじめに
<!-- 発端や概要を記載 -->

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Chapter1](#Chapter1)
1. [Chapter2](#Chapter2)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# Chapter1

<a id="#Chapter2"></a>
# Chapter2

<a id="#reference"></a>
# 参考文献
- [リンクテキスト](URL)
- [リンクテキスト](URL)

```
#頻出部品
<pre>
<!-- 下記、コピペ用部品 -->

```言語名:ファイル名.拡張子
コードブロック
```

`インライン表示`

>引用文

[リンクテキスト](URL)

| No |    内容     |    備考    |
|---:|-------------|------------|
| 1  |             |            |
| 2  |             |            |
</pre>
Webを支える技術（REST）

[Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)を読んだので、知識の整理も兼ねて、学んだことをご紹介いたします。

#**REST**とは
**REST**とはWeb全体のアーキテクチャスタイル（システムを設計するための指針）です。
RESTにしたがって個別のWebサービスを作ることで、Webは全体としてより良くなります。
RESTは次の６つを組み合わせたアーキテクチャスタイルになります。

###クライアント/サーバ

>クライアントはサーバにリクエストを送り、サーバーはそれに対してレスポンスを返します。

クライアントとサーバに分けることで、単一のコンピュータで処理するのではなく、分離して処理できます。そのため、クライアントは色々な種類のデバイスからアクセスできます。
また、データストレージの機能を持つサーバを複数組み合わせることで可用性をあげることができます。

###ステートレスサーバ
ステートレス（Stateless）とは状態を持たないという意味です。
ステートレスサーバとは、クライアントのアプリケーション状態をサーバで管理しないことを意味します。
利点はサーバの実装を簡略化できます。また、クライアントのリクエストに応えたあとすぐにサーバの計算機リソースを開放できます。

###キャッシュ
一度取得したリソースをクライアント側で再度利用する仕組みです。
サーバとクライアントの通信を減らすことで、効率的に処理できるようになります。

###統一インタフェース

>統一インタフェースとは、URIで指し示したリソースに対する操作を、統一した限定的なインタフェースで行うアーキテクチャスタイルのことです。

HTTPではGETやPOSTなどの８個のメソッドが定義されています。
限定的にすることで、全体のアーキテクチャがシンプルになり、クライアントとサーバの実装の独立性が向上します。

###階層化システム
先ほどの統一インタフェースの利点のひとつに、システム全体が階層化しやすいことがあります。
クライアントとサーバの間にロードバランサを設置して負荷分散したり、
プロキシを設置してアクセスを制限したりします。

###コードオンデマンド
>プログラムコードをサーバからダウンロードし、クライアントでそれを実行するアーキテクチャスタイルです。

JavaScriptやFlash、Javaアプレットなどが該当します。
利点は、クライアントプログラムに新しい機能を追加することができます。

###RESTとはつまり
>・クライアント/サーバ　：　ユーザインタフェースと処理を分離する
・ステートレスサーバ　：　サーバ側でアプリケーション状態を持たない
・キャッシュ　：　クライアントとサーバの通信回数と量を減らす
・統一インタフェース　：　インタフェースを固定する
・階層化システム　：　システムを階層に分離する
・コードオンデマンド　：　プログラムをクライアントにダウンロードして実行する

上記のRESTの制約にしたがって、RESTらしいことをRESTfulと呼びます。
draw.ioがVScodeで使えるようになった

# draw.ioとは
draw.ioは**フローチャート**をはじめクラス図やアクティビティ図などの**UML**など、さまざまな図が書ける無料の**Webアプリツール**のことです。

無料とはいえ、実用性が高いので設計やコーディングなどで簡単な図を書きたいという時には、かなり使えるツールです。

私事ですが、asta community が使えなくなって以降、私もdraw.ioを使うようになりました。

以下が、draw.ioのサイトです。

[Draw.io](https://app.diagrams.net/:title)

英語が苦手な方は、右下の地球儀マークから言語変更できるので試しに使ってみてください。

# VScodeとは
Microsoftが提供する**コードエディタ**です。

デフォルトでは必要最低限の機能しか備わっていませんが、非常に軽量で動作が軽快です。

カスタマイズの拡張性が非常に高いため、自分の**お気に入りの開発環境に仕立てることもできます**(それなりに勉強は必要ですが・・・)。

現在主流になっているエディターの一つではないでしょうか。

# VScodeでdraw.ioを使う

いつも通り、拡張機能を検索する箇所で**draw.io Integration**と入れて検索。

そして、**インストールすれば使える**ようになるみたいです。

その後、ファイルを作成しそのファイルの拡張子を`.drawioまたは.dio`にすれば使えます。 

 VScodeでdraw.ioを導入する方法を分かりやすく説明されている記事へのリンクを貼っておきますね。参考にしてみてください。

[VSCodeでDraw.ioが使えるようになったらしい！](https://qiita.com/riku-shiru/items/5ab7c5aecdfea323ec4e:embed:cite)
SwiftUIで「式が複雑すぎる」「式を分解しろ」と言われたら

##解決できるかもしれないエラー
`The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions`

このエラーによく遭遇するのですが、具体的な解決法が分からず毎度苦戦します。fizzbuzzのような2つの条件を扱おうとするだけでも出現するエラーです。とても厄介。ここでは一つの解決策を共有できればと思います。[参考](https://medium.com/@apppeterpan/swiftui-的-the-compiler-is-unable-to-type-check-this-expression-in-reasonable-time-問題-3304cbe0f8a4)

##エラー例


```swift
import SwiftUI

struct test: View {
    var body: some View {
        List(0..<100) { number in
            if number % 3 == 0 || number % 5 == 0 {
                Text("number\(number) は3または5の倍数")
            } else {
                Text("number\(number)3と5の倍数のいずれでもない")
            }
        }
    }
}

struct escape_Previews: PreviewProvider {
    static var previews: some View {
        test()
    }
}
```

`if number % 3 == 0 || number % 5 == 0`に問題があるようです。複雑というよりも、**処理が一度に複数ある**イメージでしょうか。
解決するために,`if number % 3 == 0 || number % 5 == 0`を関数にします。

```swift
import SwiftUI

struct escape: View {
    func check(number: Int) -> Bool {
        number % 3 == 0 || number % 5 == 0
    }
    var body: some View {
        
        List(0..<100) { number in
            if self.check(number: number){
                Text("number\(number) は3または5の倍数")
            } else {
                Text("number\(number)3と5の倍数のいずれでもない")
            }
        }
    }
}

struct escape_Previews: PreviewProvider {
    static var previews: some View {
        escape()
    }
}
```
cargo editを試すついでにwebframework[rocket]を試す

# rustデビューしたてで cargo editを教えて貰った
- 最近ブロックチェーンのsubstrateをやりたくなったのでrustを学び始めた
- なかなか難しい
- cargo.tomlを自分で書かなくて良いツールを教えて貰った

# cargo editを試したいが題材がないので「rocket」
- `[このサイトを参考にさせて頂きました。](https://qiita.com/kenmaro/items/07735625858e9333fc83)ありがとうございます。
- rustのWebFrameworkであるrocketのHello worldをやってみました。

# cargo editを導入する
```
cargo install cargo-edit
```

# rocketのプロジェクトを作成して、必要なものをcargo editで追加する
```
cargo new rocket_test1
cd rocket_test1
cargo add rocket@0.4
cargo add rocket_contrib@0.4
cargo add serde@1.0
```
- 確認してみると、入ってる
- 凄く便利

```
cat cargo.toml
```
```
[package]
name = "rocket_test1"
version = "0.1.0"
authors = ""
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = "0.4"
rocket_contrib = "0.4"
serde = "1.0"
```
# ソースをコピーして動かしてみる
- main.rsとroutes.rsのhello_worldに必要な部分をコピーさせて頂いて、cargo run・・・
- 動きません。
- ネットを検索して、cargo +nightly runで実行するべきを知りました。

```
cargo +nightly run
curl http://localhost:8000

Hello world!
```

## 無事、確認出来ました。

- main.go

```
#![feature(proc_macro_hygiene)]
#![feature(decl_macro)]

#[macro_use]
extern crate rocket;

mod routes;

// WebAPIのURLルーティングはroutes.rsに移動する
use routes::*;

// rocketにルーティングをマウントして、開始する。
fn main() {
    rocket::ignite()
        .mount(
            "/",
            routes![index],
        )
        .launch();
}
```
- routes.rs

```
#[get("/")]
pub fn index() -> &'static str {
    "Hello world!"
}

```
Redux-toolkitで何が便利になるか

どうも、ウマシバ([@UMASHIBA](https://twitter.com/UMASHIBA))といいます。[redux-toolkit](https://redux-toolkit.js.org/)を触ってみたので何が便利になったのかという点を備忘録のために雑にまとめたいと思います。

# redux-toolkitとは
最近できたreduxを簡単に書くためのライブラリです。
Reduxの公式ページでも[紹介](https://redux.js.org/introduction/getting-started#redux-toolkit)されているライブラリです。

- configureStore
- createAction
- createReducer
- createSlice

といったような簡単にreduxを書くための関数が用意されています。

詳しくは[こちら](https://redux-toolkit.js.org/)

# [configureStore](https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-configurestore)

```javascript
// Before:
const store = createStore(counter)

// After:
const store = configureStore({
  reducer: counter
})
```

reduxのcreateStoreとほとんど書き方は変わりません。
ただ[Redux DevTools Extension](https://github.com/zalmoxisus/redux-devtools-extension)みたいな便利なミドルウェアをデフォルトでいれといてくれます。このミドルウェアをデフォルトで入れておいてくれる機能は便利だと思います。

# [createAction](https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-createaction)

```typescript
// Original approach: write the action type and action creator by hand
const INCREMENT = 'INCREMENT'

function incrementOriginal() {
  return { type: INCREMENT }
}

console.log(incrementOriginal())
// {type: "INCREMENT"}

// Or, use `createAction` to generate the action creator:
const incrementNew = createAction('INCREMENT')

console.log(incrementNew())
// {type: "INCREMENT"}
```

typeとactionの定義が同時にできるので便利
これで大量のactionとtypeを別々に書いてエクスポートしていたのが一つで済むようになりそうです。

# [createReducer](https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-createreducer)

```typescript

const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')

//BEFORE
function counter(state = 0, action) {
  switch (action.type) {
    case increment.type:
      return state + 1
    case decrement.type:
      return state - 1
    default:
      return state
  }
}

//AFTER
const counter = createReducer(0, {
  [increment.type]: state => state + 1,
  [decrement.type]: state => state - 1
})
```

上のコードを見てみると相当コードを書く量が減っています。
書くコード量が多くなってしまうReduxにおいてこの利点は相当大きいと思います。

# [createSlice](https://redux-toolkit.js.org/tutorials/basic-tutorial#introducing-createslice)

```typescript
const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: state => state + 1,
    decrement: state => state - 1
  }
})

const store = configureStore({
  reducer: counterSlice.reducer
})

document.getElementById('increment').addEventListener('click', () => {
  store.dispatch(counterSlice.actions.increment())
})
```

createSliceはaction, type, reducer全てを定義してくれます。
上記でやったcreateAction, createReducerを合わせたような関数です。
すごく書くコードの量が減る。便利！

更にすごいのはこのcreateSlice関数を使った場合返す値がイミュータブルであるか気にする必要がありません。
createSliceで勝手にimmutableにしてくれます。つまり元の`state`に対して`Array.push`メソッドとかが使えます。


# まとめ
redux-toolkitは`コード量を少なくReduxを書くためのライブラリ`という風にまとめられると思います。
Reduxの公式ページにも紹介されておりGitHubのStarも2020/5/16時点で3000以上あり廃れにくそう。
【Git】ブランチの命名規則を調べてたらIssueドリブン開発という存在を知った

# はじめに

gitでブランチを切るときに毎回、「ブランチ名どうしようか…」と悩んでいたので、良さげな命名規則がないか調べてみた
その中で、便利そうなIssueドリブン開発というものを知った

本記事では、上記の2点についてまとめる

## ブランチの命名規則

|ブランチ名|役割|派生元|マージ先|
|---|---|---|---|
|master|公開するものを置くブランチ|||
|develop|開発中のものを置くブランチ|master|master|
|release|次にリリースするものを置くブランチ|develop|develop, master|
|feature-*|新機能開発中に使うブランチ|develop|develop|
|hotfix-*|公開中のもののバグ修正用ブランチ|master|develop, master|

``feature-*``や``hotfix-*``は、``*``には適当な名前をつける

## Issueドリブン開発

Issueとは、Github上で作成できる、ToDoリスト的なもの

### 使い方

1. Webサイトのメニューバーをハンバーガーメニューに変更したい
2. Github上で、１の旨を記載したIssueを立てる
    3. マークダウンでコメントを書けるので便利
    4. 画像も載せられるので、こんなメニューにしたい、というイメージ図も載せておける
5. ``feature/#12_replace_to_hamburger_menu``というブランチを作成
    6. Issueを立てるとそのIssueに番号、例えば``#12``が割り振られるので、それをブランチ名に含める
7. 開発進める
8. 開発完了
9. Issueに書いた内容のタスクが完了したので、developブランチにマージコミットする
    10. **この際、``close #12``などとコミットメッセージに記述すると、自動的にIssueが閉じられる**

### Issueを使うメリット

- Github上でタスク管理できる
- コミットするとIssueも自動的に閉じることができるのは便利

# おわりに

ざっと調べたことを、自分の理解した形でまとめてみた
間違いなどあれば、随時修正していく

# 参考記事

- [gitのブランチの命名規則](https://qiita.com/luccafort/items/c91e817e78f1167221cc)
- [Gitブランチの名前の付け方](https://gist.github.com/tiijima/9854122dafa5eeb9bf7a)
- [【メモ】Issueの書き方](https://gist.github.com/BcRikko/6af0b248148c12d3ab90)
Lraravelヘルパ関数の配列とオブジェクトについて

##はじめに
今回はLraravelヘルパ関数の配列とオブジェクトについてまとめます。

##連想配列の関数について（抜粋）
Arrクラスは配列を操作する時に便利に使えます。

①Arr::addメソッドは指定キー／値のペアをそのキーが存在していない場合とnullがセットされている場合に、配列に追加します。


```php:
use Illuminate\Support\Arr;
$array = Arr::add(['name' => 'skirt'], 'price', 5000);
// ['name' => 'Desk', 'price' => 5000]
$array = Arr::add(['name' => 'skirt', 'price' => null], 'price', 5000);
// ['name' => 'Desk', 'price' => 5000]
```

②Arr::getメソッドは「ドット」記法で指定した値を深くネストされた配列から取得します。

```php:
use Illuminate\Support\Arr;
$array = ['products' => ['skirt' => ['price' => 5000]]];
$price = Arr::get($array, 'products.skirt.price');
// 5000
```

③Arr::forgetメソッドは「ドット記法」で指定キー／値のペアを深くネストされた配列から取り除きます。

```php:
use Illuminate\Support\Arr;
$array = ['products' => ['skirt' => ['price' => 5000]]];
Arr::forget($array, 'products.skirt');
// ['products' => []]
```

##終わりに
いかがでしたでしょうか。
よく使いそうなものを抜粋しましたが公式ドキュメントに他にも記載してあるので確認してみてください。

参考：[ヘルパ 7.x Laravel](https://readouble.com/laravel/7.x/ja/helpers.html)
Git&GitHubメモ - SourceTreeインストール

# Git&GitHub 備忘① SourceTreeインストール
## 目的
* 自分の作った手順書、スクリプトをメンバーに共有（閲覧してもらうレベルで良い）したい
* 過去使ったことがありますが、かなり忘れていたので丁寧に記録する目的

## Gitの特徴
* バージョン管理システム
* 何を管理？プログラムだけでなく文書も管理できる
  * プログラム
  * 設計書
  * マニュアル
* Gitの利用パターン
  * PCのローカルにインストールして使うパターン
  * サーバに入れて共有するパターン
* GitとGitHubは別物
* GitHUBはGitサーバのオンラインサービス


## 必要なツール
* テキストエディタ
* Sourcetree
  * Gitの機能を組み込んだアプリケーション。他のアプリケーションとの比較はしてない。GitをGUIで扱うことができるということでなんとなく使ってる

## Sourcetreeインストール
* ウィザードに従うだけですが、微妙に難しいので、細かく記録しておきます。
* SourceTree公式ページ：https://ja.atlassian.com/software/sourcetree
* 「Windows 向けダウンロード」をクリック
![img001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/7c72bc36-60b3-2b6e-c3b4-8fc8af49712c.png)

* ライセンスに同意し「ダウンロード」
![img002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/ff8f744b-aa66-cf76-367a-278f2fccffd9.png)
  
* ダウンロードしたファイル「SourceTreeSetup-3.1.2.exe」を実行
![img003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/9463fe57-b40a-0e8b-813a-9ef21d35c010.png)

* アカウント未登録であれば「Create one for free」をクリックして登録
![img004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/a81bb9c2-c4eb-bcae-ca8b-1b8eb54e0091.png)

* すでに登録済みでしたので「Bitbucket」クリックして進みます。
* ログインします
![img007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/a5eab333-8863-358c-9cef-33778542ed84.png)

![img011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/718d35d2-1af1-6a3a-c97f-5810b741d5fc.png)


* Gitで管理したいのでGitのみチェックを入れて「次へ」
)![img012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/c8baff58-d6cf-1152-8ba0-91b043ab711c.png)

![img014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/b32074e8-64c3-4301-d838-de8f0d43e3f1.png)

* Preferenceの画面
  * この詳細をすべてのリポジトリに使用する > いったんチェック無効
    * ユーザ名とパスワード
  * 匿名化した使用状況を開発者へ送信して開発に役に立てる設定 >お好みでチェック
![img015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/a3559c99-f7d2-7496-b88d-276d00b5f922.png)

* SSHキーの取り込みは「いいえ」。後で設定できるため
![img016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/344a4dcd-ddff-8cbd-9c50-29b9caca6b1f.png)  

* SourceTreeが起動され、インストールが完了しました。
![img017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543420/ce6469b8-35ef-50e8-4f8f-39e2158b41ab.png)
Geniusで歌詞を取ってくる方法


#はじめに
現在作成中のアプリで、歌詞を取ってくる機能を実装したいと思い
そのようなAPIがないのか探したところGeniusと言うAPIが存在することを
知りました。
ですが、日本語での解説記事に全然巡り合えなかったので、今回は
Geniusの使い方を記載させてもらえたらと思います。
以下Geniusの使い方、また詰まったところを解説します。
※デモgifです
![キータgenius.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427892/ebb4dcab-a76f-c9bc-7a60-c1ba46eac318.gif)

#詰まった点
英語のドキュメントしか巡り合えなかったため、英文を読む or Google翻訳なりで
訳して理解するかのどちらかだと思うが、自分は前者を採用して頑張って
英文を理解することにした。
難しい英文ではなかった事と、ドキュメントのAPI使用法の解説が丁寧であった
事から一応読めた。
ドキュメントを読むうちにこの英文はこういう意味では？と思ってコードを書いても
実際は全然理解が違ったりしたのが詰まった点。
全く関係ないライブラリをダウンロードして実装していたりとドキュメントの意味を
間違えてかなり時間を食ってしまった。
逆に言うと、英語を難なく理解できる人であればたやすく利用できるのではないのか？
と感じた。
やはり英語が出来るのは強いと感じた。
あと、自分が参考にしたのは100％公式のドキュメントだった。
公式ドキュメントは何と言ってもそのAPIを作成した人たちが書いているので、
一番強いと思っている。

#使用法
まず、Geniusのページ(https://genius.com/developers)
に飛んでサインアップして自分の作成するアプリを登録して
CRIENT_ID,CRIENT_SECRET,CRIENT_ACCESS_TOKENの3つを取得します。
※歌詞を取得する際に使うのはCRIENT_ACCESS_TOKENだけです。

そして、Geniusのアノテーションを作成しているアプリに埋め込みます。
↓こちらがGeniusのアノテーション

```php:sample.php
<script src="https://genius.codes"></script>
```

アノテーションはmetaタグの次に埋め込むと良いと思います。
そうした後は、composerを使用して
コマンドプロンプトやターミナルでアプリのディレクトリにて
composer require simivar/genius-php php-http/message php-http/guzzle6-adapter
を打ち込んで、Geniusのパッケージをダウンロードします。
Geniusからは、楽曲に関する様々な情報が取得できます。
歌詞以外に関する情報はこちらには記載しないので、公式ドキュメント
(https://docs.genius.com/#/getting-started-h1)
を参照していただければ、と思います。
実際のコードを載せます。

```php:sample.php
require 'vendor/autoload.php';
  $authentication = new \Http\Message\Authentication\Bearer($_ENV['CLIENT_ACCESS_TOKEN']);
  $genius = new \Genius\Genius($authentication);
  $getSongId = $genius->getSearchResource()->get('lemon 米津')->response->hits[0]->result->id;
  $searchSong = $genius->getSongsResource()->get($getSongId,'html')->response->song>embed_content;
```

2行目のCLIENT_ACCESS_TOKENには、アプリ登録時にGeniusから送信されたアクセストークンを設定します。
そのあと

```php
$getSongId = $genius->getSearchResource()->get('lemon 米津')->response->hits[0]->result->id;
```

でget()の中に入れた文字列(ここではヒットしやすいように入れた米津玄氏さんのlemon)をもとに
曲のidを取得しています。
そしてそのidをもとにして、ヒットした歌詞を表示しています。

```php
$searchSong = $genius->getSongsResource()->get($getSongId,'html')->response->song>embed_content;
```

getの2つ目の引数には、dom,plainそしてhtmlなど様々な引数を代入できますが、
歌詞を取ってくるにはhtmlじゃないとキツそうだったので僕はhtml
を選択しました。

そのあと、取ってき歌詞を表示するためにhtmlを生成してあげればOKです。

```php
<?php print($searchSong);?>
```

#おわりに
外部APIを使用すると段違いに実装できる内容が増えて、よりアプリの利便性を
高めてくれる事を実感しました。
これからも面倒くさがらずに、英語のドキュメントに挑戦して
外部APIを使用していきます。
Ubuntu 20.04にDjango+PostgreSQLの開発環境を作成

#下準備
sudo apt update
(sudo apt-get install vim)

#PythonとPostgreSQL関係をインストール
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib

#Virtual Environmentをインストール
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv

#Virtual環境を「django」というフォルダの中に作成してActivate
mkdir django
cd django
virtualenv venv
source venv/bin/activate

#Django関係をインストール
pip install django psycopg2-binary


#完了




（といいつつ実はこれ現Django開発環境からの移行先だったので、django配下にプロジェクトをコピペで持ってきた後に、以下も実行が必要だった）
pip install django-allauth
pip install django-cleanup
pip install pillow

python manage.py makemigrations
python manage.py migrate
python manage.py runserver
キーワード引数の辞書化

```
def menu(entree='beef', drink='wine'):
    print(entree, drink)

menu(entree='beef', drink='coffee')

#上にdessertとかを追加したくなった場合は？

def menu(**kwargs):
    print(kwargs)
menu(entree='beef', drink='coffee')

def menu(**kwargs):
    for k, v in kwargs.items():
        print(k, v)
menu(entree='beef', drink='coffee')

def menu(**kwargs):
    for k, v in kwargs.items():
        print(k, v)
d = {
    'entree': 'beef',
    'drink': 'ice coffee',
    'dessert': 'ice'
}
menu(**d)

def menu(food, *args, **kwargs):
    print(food)
    print(args)
    print(kwargs)

menu('banana', 'aplle', 'orange', entree='beef', drink='coffee')

```
beef coffee
{'entree': 'beef', 'drink': 'coffee'}
entree beef
drink coffee
entree beef
drink ice coffee
dessert ice
banana
('aplle', 'orange')
{'entree': 'beef', 'drink': 'coffee'}
eclipse.iniに-vmを指定する方法


Eclipseを実行するJVMをeclipse.iniに`-vm`オプションで指定する。
が、CentOSでOpenJDK11の`javaw.exe`がなかった、ので調べてみた。

- 参考 : [Eclipse を起動する Java VM を指定する :Tips &amp; FAQ | arbk-works Blog](https://aruo.net/arbk/blog/article/specifying_java_vm_for_eclipse_ide_to_run)
- 凡例 : `JAVA_HOME` : javaのインストールディレクトリ

# 実行ファイルのパスを指定する方法
これまでこの方法でしか指定したことがなかった、しかも`javaw`がWindows用って知らなかった。

> javawはどうもWindowsのために用意されたコマンドみたいですね。Windows環境向けの記事でjavaw.exeを使う解説があった場合、Linux/Mac環境では素直にjavaコマンドに置き換えましょう。
> [Linux/Mac に javaw コマンドがない…だと…](https://qiita.com/wukann/items/c526a77ad230ea8e8ad5)

```ini
; Windowsの場合
-vm
JAVA_HOME¥bin¥javaw.exe

; Linuxの場合(CentOS)
-vm
JAVA_HOME/bin/java
```

# ディレクトリパスを指定する方法

```ini
; Windowsの場合
-vm
JAVA_HOME\bin

; Linuxの場合(CentOS)
-vm
JAVA_HOME/bin
```

# 共有ライブラリのパスを指定する方法
Java11より前だと若干パスが違うようだ。
[OpenJDK 11 - Change in `libjvm.so` default location ? · Issue #137 · LeeKamentsky/python-javabridge](https://github.com/LeeKamentsky/python-javabridge/issues/137)

```ini
; Windowsの場合
-vm
JAVA_HOME\bin\client\jvm.dll
; または
JAVA_HOME\bin\server\jvm.dll

; Linuxの場合(CentOS)
-vm
JAVA_HOME/bin/libjvm.so
; または
JAVA_HOME/lib/server/libjvm.so
```
【備忘録】ブログ作成 (Hugo + Netlify)

## はじめに
この間、自分のブログを作成する際に、Hugo+Netlifyを用いました。
今回は、その手順を備忘録として記事を書きました。
基本的に、hugoの公式サイトの[クイックスタート](https://gohugo.io/getting-started/quick-start/)通りです。

## インストール (Hugo)

```
sudo apt install hugo
```

## サイト作成

```
hugo new site (サイト名)
```

## テーマ追加
今回はテーマとして[tranquilpeak](https://themes.gohugo.io/hugo-tranquilpeak-theme/)を利用。

```
cd (サイト名ファルダ)
git init
git submodule add https://github.com/kakawait/hugo-tranquilpeak-theme.git ./themes/tranquilpeak
echo 'theme = "tranquilpeak"' >> config.toml
```

## 記事追加

```
hugo new post/(ファイル名).md
```
ここで注意として、**post**と表記することです。
[公式](https://gohugo.io/getting-started/quick-start/)だと**posts**ですが、そうすると上手くいきませんでした。

## デプロイ

```
hugo server -D
```

## Netlifyでのホスト
これも、hugoの[公式サイト](https://gohugo.io/hosting-and-deployment/hosting-on-netlify/)に方法が記載されているので、そのとおりに行います。
以下に簡単な概略を示しています。自分の場合は、githubと連携させました。
#### 概略
1. Netlifyのアカウント作成
2. サイト作成 (githubとの連携)
3. 設定ファイル作成　（テンプレート通り）
4. ビルド

ただし、このままだと、themeが上手く反映されないと思います。
原因は、URLパスの未設定(*config.toml*の**baseURL**)です。
独自ドメインを持っている場合だと、
baseURLの修正 & Netlifyのドメイン設定をすればOKだと思います。
もし、持っていない場合は、NetlifyでデプロイしたURLを書けばOKです。
(URL例：https://(任意の文字列).netlify.app/)

## Netlifyのドメイン設定
私は以下のサイトを参考に行いました。
[【簡単】Netlifyにお名前ドットコムで取得したドメインを設定しよう！【たったの10分】](https://jamstack.jp/blog/how_to_set_custom_domain/)
おそらく、そのまま読めば理解できると思います。
ただし、https化に関しては、何もしなくても、
Netlify側で自動で反映されると思います。
fields_forはこうやって使う

#手順

1.モデルの編集

```item.rb
has_many :images
accepts_nested_attributes_for :images
```

```image.rb
belongs_to :item, optional: true  #外部キーのnilを許可する
mount_uploader :image, ImageUploader
```

2.コントローラーの編集

```item_controller.rb

def new
  @item = Item.new
  @item.images.build
end

def create
  @item = Item.new(item_params)
  redirect_to root_path
end

def edit
  @item = Item.find(params[:id])    
end

def update
  @item = Item.find(params[:id]) 
  @item.update(update_item_params)
  redirect_to root_path
end

def item_params
  params.require(:item).permit(:name, :infomation, :price, images_attributes: [:image] )
end

def update_item_params
  params.require(:item).permit(:name, :infomation, :price, images_attributes: [:image, :_destroy, :id] ) #編集時はdestroyとidを配列に入れておく必要がある
end

```

3.ビューの編集

```html
<%= form_for @item do |f| %>

  <%= f.text.field :name %>
  <%= f.text.field :infomation %>
  <%= f.text.field :price %>

  <%= f.fields_for :image do |i| %>
    # 画像があれば表示する
    <%= image_tag(i.object.content) %> 
    <%= i.file_field :image %>

  <%= f.submit %>

<% end %>
```

以上
[Flutter]popUntilメソッドで初期画面に遷移させる

#はじめに
Flutterで画面遷移させる方法には2種類あります。
1.事前に定義したルートに遷移（Navigator.pushNamed）
2.事前に定義せずに遷移（Navigator.push）

どちらも一つ前の画面に戻るときは Navigator.pop ですが、初期画面（ルートページ）に戻る方法が異なるため、方法をまとめます。

<img width="500" alt="スクリーンショット 2020-05-16 17.08.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135663/f66d68ca-321e-d595-99f5-73fc97f94343.png">


# 1.pushNamedを使っている場合
例えば初期画面に /home と名付けている場合、以下の記述で初期画面に戻ることができます。初期画面ではなく途中で止めたい場合も、同様にwithNameの引数にすることで実現できます。

```dart

Navigator.popUntil(context, ModalRoute.withName("/home"));
```

# 2.pushを使っている場合

上と比べると少し複雑ですが、下記コードで名前を指定していなくとも初期画面まで戻ることができます。

```dart

Navigator.popUntil(context, (Route<dynamic> route) => route.isFirst);
```
また、以下の書き方でも同じことが実現できます。

```dart

Navigator.of(context).popUntil((route) => route.isFirst);
```

#参考
■公式ドキュメント
https://flutter.dev/docs/cookbook/navigation/navigation-basics
https://flutter.dev/docs/cookbook/navigation/named-routes
https://api.flutter.dev/flutter/widgets/Navigator/popUntil.html
■stack overflow
https://stackoverflow.com/questions/49672706/flutter-navigation-pop-to-index-1/51562273
Kernelモジュールについて


普段何気なく使っているputsは、なんでどういった仕組みで使えるんだろうと気になったので、調べてみました。


**結論としては、Kernelモジュールが1枚噛んでいました。**

```ruby:Kernelモジュールが提供するメソッド
puts
p
print
require
gets
```

上記のようなメソッドは、Kernelモジュールで定義されているらしい。

String、Numeric、Array、Hashなどのクラスは、全てObjectクラスを継承しているみたいです。



```ruby:親クラスの確認
$ rails c

>> String.superclass
=> Object
>> Numeric.superclass
=> Object
>> Array.superclass
=> Object
>> Hash.superclass
=> Object
```

もともと、**ほぼ全ての親クラスであるObjectクラス(superclassは、BasicObject)は、Kernelモジュールをincludeしている**ので、
putsメソッドを平然と何も考えなくとも、デフォルトでどのクラスでも使えるみたいです。

以下に具体的に、Kernelモジュールで定義されているメソッドの一覧が載ってます。

>[module Kernel](https://docs.ruby-lang.org/ja/latest/class/Kernel.html)
UIElementsで要素を水平に配置する方法

UIElementsのUSSで要素を水平に配置する方法。

水平配置したい要素を囲う要素を作って horizontal クラスをつけてあげる。


```elements.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
    <ui:VisualElement name="Layout">
        <Style src="style.uss" />
        <ui:Label text="垂直" />
        <ui:Label text="垂直ボタン1" />
        <ui:VisualElement name="HorizontalLayout" class="horizontal">
            <ui:Label text="水平1" />
            <ui:Label text="水平2" />
            <ui:Button text= "水平ボタン"/>
        </ui:VisualElement>
        <ui:Label text="ここからまた垂直" />
        <ui:Button text= "垂直ボタン2"/>
    </ui:VisualElement>
</ui:UXML>
```

``` style.uss
.horizontal {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}
```


```ExampleEditorWindow.cs
using UnityEditor;
using UnityEngine.UIElements;

public class ExampleEditorWindow: EditorWindow {
	[MenuItem("Window/Example")]
	public static void Open() => GetWindow<ExampleEditorWindow>("Example");

	private void OnEnable() {
		var root = rootVisualElement;
		root.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Editor/style.uss"));

		var tree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/elements.uxml");
		root.Add(tree.CloneTree());
	}
}
```
wip_OAuth,OIDC,SSOについて理解したこと纏めます


#❏背景
案件で認証周りを見る機会があったので詳細に理解したい
【GOAL】
とりあえず案件内で出てきたワードについて「内容」「違い」を理解する
- SSO
- OIDC
- OAuth
※詳細な仕様ではなく、ざっくり仕組みを理解することに重点を置く

#❏本題
##◆OAuth（2.0）
権限の受け渡し=認可 を行う仕組み
基本概念は以下

- 1.あらかじめ信頼関係を構築したサービス間で
- 2.ユーザの同意のもとに
- 3.セキュアにユーザの権限を受け渡しをする

###★何ができるか
サービス間で認可情報を受け渡せると、あるサービスが別のサービスの情報を操作できるようになる。
これにより、例えば、instagramでfacebookでも同時に投稿できるようにするみたいなもの

###★実現方法
ID/PWをクライアントに渡すのではなく、ある情報に対しての操作権限と有効期限等を定義したアクセストークンを渡すことにより
実現させている。
→ これにより、「リソースへの権限を持ったクライアントのみ」リソースを取得できる
###★登場人物と流れ
- ユーザ：一般ユーザ
- 認可サーバ：サービスプロバイダへのリソースへアクセスする権限を与えるサーバ
- サービスプロバイダ：リソースを持っているサービス（例示でいうinstagram）
- クライアント：サービスプロバイダの情報にアクセスしたいサービス（例示でいうfacebook）

一つ一つ見ていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284312/38b13446-18da-f03d-d3e0-3abcd21951bf.png)
**0.事前準備**
　クライアントがサービス情報を登録し、cliant_id（クライアント識別子）を取得。
**1.ユーザがクライアントに認可が必要なアクションを起こす**
　例示の場合、facebookで投稿 のようなもの。
**2.クライアントが認可サーバに0で取得したcliant_idを付与して「認可要求」**
　サービスプロバイダへのアクセストークンを渡す対象かをユーザに尋ねに行く。
  「○○への権限を渡しますか？」画面の表出→サービスプロバイダのID/PWでログインののち、
　OK「認可承認」でアクセストークンを発行「認可成功」
**3.クライアントがサービスプロバイダにアクセストークンを付与してリソースデータをリクエスト**

##◆OIDC
Open ID Connectの略
認可と認証をサポートした仕組み
※OAuthでも、アクセストークンを取得する際に認可サーバ経由で**「認証」**していなかったっけ（ログインって書いたし）？
→ この認証はアクセストークンを取得するためだけのものであり、アクセストークンからでは**だれ（エンドユーザ）がサービスプロバイダにアクセスしているのかがわからない。**
仮に、その一回取得したアクセストークンを別のユーザが使用してアクセスしにかかってもリソースをとってこれてしまう
=**大きな問題**
このため、サービスプロバイダにアクセスしにかかる際に、毎回**「確からしいエンドユーザ」**が**「許可を得て」**いるのかを検証するにはOIDCの仕組みを利用しなければならない。 ...という自身の見解(ここがOAUthとの差分)

###★何ができるか
GoogleのID連携などにより、GoogleのIDを使って別サービスにログインできたりできる

###★実現方法
ある情報に対してのアクセストークンに加え、ユーザの本人証明としてID Tokenを渡すことで、実現させている。
→ これにより、「承認されたユーザ」が「リソースへの権限を持ったクライアントを使って」リソースを取得できる。
###★登場人物と流れ
- ユーザ：一般ユーザ
- OpenIDプロバイダ：サービスプロバイダへのリソースへアクセスする権限とID Tokenを与えるサーバ
- サービスプロバイダ：リソースを持っているサービス（例示でいうgoogle）
- クライアント：サービスプロバイダの情報にアクセスしたいサービス

一つ一つみていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284312/cca934bc-fd46-81ce-b604-fb48a6756090.png)
**0.事前準備**
　クライアントがサービス情報を登録し、cliant_id（クライアント識別子）を取得。
**1.ユーザがクライアントに認可が必要なアクションを起こす**
　例示の場合、googleでログイン のようなもの。
**2.クライアントが認可サーバに0で取得したcliant_idを付与して「認可・認証要求」**
　サービスプロバイダへのアクセストークンを渡す対象かをユーザに尋ねに行く。
  「○○への権限を渡しますか？」画面の表出→サービスプロバイダのID/PWでログイン「認証」ののち、
　OK「認可承認」でアクセストークンとIDトークンを発行「認可・認証成功」
**3.IDToken検証により改ざんがないかを確認**
別ユーザがアクセストークンだけ取得してきた際に「別ユーザ」と認識できるように
アクセストークンとのマッピングで判断？（このあたりが理解しきれてないです）
**4.クライアントがサービスプロバイダにアクセストークンを付与してリソースデータをリクエスト**

##◆SSO
Single Sign Onの略
一つのID/PWで複数のサービスに同時にログインする仕組み。
→ Aサービスでログイン処理を済ませたのち、Bサービスを開いたらすでにログインされている！（ログイン不要）

******************wip*******************

###★実現方法

#❏まとめ
それぞれの違い、関係性について
作って理解するOSのためのMakefileを作ってみた (Ubuntu18.04)

#はじめに
[作って理解するOS](https://gihyo.jp/book/2019/978-4-297-10847-2)で使っている[ソースコード](https://gihyo.jp/book/2019/978-4-297-10847-2/support#supportDownload)はWindows環境で動くように書かれていますが、これをUbuntu18.04のMakefileで動かします。
といっても[30日でできる！　OS自作入門](https://book.mynavi.jp/supportsite/detail/4839919844.html)と違い独自ツールなどを使っていないので、コードは変更せずに実行コマンドを変えるだけで良いようです。

#環境
```bash
$ uname -a
Linux furble 5.3.0-51-generic #44~18.04.2-Ubuntu SMP Thu Apr 23 14:27:18 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ nasm -v
NASM version 2.13.02

$ qemu-system-x86_64 --version
QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.23)

$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
```
#14_keyboard_ledまでのMakefile
14_keyboard_ledまではファイルが一つだけなので、以下のMakefileで実行できます。

```:Makefile
MAKE     = make -r
NASM     = nasm
ASM_FILES	= boot
IMG	= haribote.img

# デフォルト動作
default :
	$(MAKE) img

# ファイル生成規則
$(ASM_FILES).bin : $(ASM_FILES).asm Makefile
	$(NASM) $(ASM_FILES).asm -o $(ASM_FILES).bin -l $(ASM_FILES).lst

$(IMG) : $(ASM_FILES).bin Makefile
	cat $(ASM_FILES).bin > $@

# コマンド
asm :
	$(MAKE) $(ASM_FILES).bin

img :
	$(MAKE) $(IMG)

run :
	$(MAKE) img
	qemu-system-x86_64 -usb -drive file=$(IMG),format=raw

#install :
#	sudo dd if=./$(IMG) of=/dev/sde

clean :
	-rm *.bin
	-rm *.lst

src_only :
	$(MAKE) clean
	-rm $(IMG)
```

ここではアセンブリファイルの拡張子をgasの.sからnasmの.asmに変えていますが、別に変えなくても動くはずなので、面倒であればそのままで良いと思います。
変える場合は、コード内%includeディレクティブのファイル名と、それの指す元ファイルの拡張子をすべて.asmに変えます。

##usbメモリへの書き込み
上のMakefileのinstallの箇所ではimgファイルを/dev/sdeへ書き込んでいますが、これは自分の場合なので各々の環境に合わせて変えてください。fdiskコマンドでデバイス名が調べられます。
今回は2GBのUSBを使っているので、/dev/sdeがusbメモリだと分かります。

```bash
$ sudo fdisk -l
（中略）
Disk /dev/sde: 1.9 GiB, 2021654528 bytes, 3948544 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
```
なおこのddコマンドは指定デバイスを間違えると**HDDやSSDの内容がすべて消えてしまう**可能性があるので、慎重に行ってください。

#15_load_kernel以降のMakefile
作って理解するOSの15_load_kernelでは、ソースファイルがboot.sのみと、kernel.sもある場合の両方に対応するバッチファイルを作っています。
そこで、これをMakefileで作りました。

```:Makefile
MAKE     = make -r
NASM     = nasm
IMG	= haribote.img
ASM_FILES = boot.asm $(shell ls | grep -x kernel.asm) #kernel.asmが存在したら含める
OBJ_FILES = $(ASM_FILES:asm=bin) #拡張子をasmからbinに書き換える

# デフォルト動作
default :
	$(MAKE) img

# ファイル生成規則
%.bin : %.asm Makefile
	$(NASM) $< -o $@ -l $*.lst

$(IMG) : $(OBJ_FILES) Makefile
	cat $(OBJ_FILES) > $@

（以下同じ）
...
```

#includeしているファイルを依存関係に含める
ここまでのMakefileでは、includeしているファイルに変更があっても再コンパイルは行われません。そこで、指定フォルダ以下にあるファイルを依存関係に含めるようにします。

```:Makefile
MAKE     = make -r
NASM     = nasm
IMG = haribote.img
ASM_FILES = boot.asm $(shell ls | grep -x kernel.asm) #kernel.asmが存在したら含める

INC_FILES = $(shell find ../include/ ../modules/ -type f)

OBJ_FILES = $(ASM_FILES:%.asm=%.bin) #拡張子をasmからbinに書き換える

# デフォルト動作
default :
	$(MAKE) img

# ファイル生成規則
%.bin : %.asm $(INC_FILES) Makefile
	$(NASM) $< -o $@ -l $*.lst

$(IMG) : $(OBJ_FILES) Makefile
	cat $(OBJ_FILES) > $@

（以下同じ）
...
```
これで../include/と../modules/以下に存在するファイルが更新された場合に、再コンパイルされるようになります。
(docker) XRDP + 日本語入力可能なUbuntuイメージ作りました (Raspberry Pi 3以降にも対応)

## 概要

* https://github.com/tukiyo/docker-xrdp
* DockerHub
    * [x86_64版](https://hub.docker.com/repository/docker/tukiyo3/xrdp-x86_64)
    * [aarch64版](https://hub.docker.com/repository/docker/tukiyo3/xrdp-aarch64)

Ubuntu 21.04 (2021.02.14)で作成したが、20.04のほうがイメージが100MBほど小さくなって良いかも。

![core.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/4ee4c022-0e16-2d39-3ac8-00ed8c160309.png)


## TODO

* support pulseaudio

![スクリーンショット_2020-05-18_15-28-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/ec51dbd7-d0a6-481f-8d78-1f538a303638.png)


## 使い方

```sh
# USER と PASSWD を適宜変更してください。

# SYS_ADMIN : chrome 使用時に必要
# DAC_READ_SEARCH : smbmount 使用時に必要

docker run -it -d \
    --cap-add SYS_ADMIN \
    --cap-add DAC_READ_SEARCH \
    --security-opt seccomp=unconfined \
    --name xrdp \
    --restart=always \
    -u $(id -u):$(id -g) \
    -e USER=user1 \
    -e PASSWD=hoge \
    -v /dev/shm:/dev/shm \
    -p 3389:3389 \
  tukiyo3/xrdp-$(uname -m)

```

```sh:接続
rdesktop localhost -u user1 -g 1280x1024
```

* `半角/全角`キーで日本語入力onoffできます。

```sh:firefoxをインストールしたい場合
sudo pkgadd.sh firefox firefox-ja

firefox
```

## Firefoxなどが頻繁にクラッシュする理由

* [Docker上に構築したUbuntuデスクトップ環境でFirefoxがクラッシュする現象の対処 - kuranabeの開発備忘録](https://kuranabe.hatenablog.com/entry/2019/01/26/191441)

`shm-size` の指定が必要。

## chrome の起動

以下が必要

```yml:docker-compose.yml
cap_add:
- SYS_ADMIN
```

## (検証中) xrdp で音を出せるようにする

* alsamixer 用の[モジュール](https://github.com/neutrinolabs/pulseaudio-module-xrdp.git)を[コンパイル](https://c-nergy.be/blog/?p=13655)し `/var/lib/xrdp-pulseaudio-installer` に入れる。

-> dame

## enable encrypt

```sh
usermod -G xrdp,ssl-cert xrdp
```

see: /etc/xrdp/xrdp.ini

## 感謝

@yama07 さんの[Dockerでuid/gid指定可能かつsudo使用可能なデスクトップ環境を構築する(XRDP編)](https://qiita.com/yama07/items/b905ceff0498e52b00cb#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB) を参考に ubuntu 21.04 対応版を作りました。

* ibus-mozc
* xrdpのディレクトリパーミッション
* 起動スクリプト

などとても参考になりました。ありがとうございました。

## 2022/06 追記

ubuntu 21.10 から security-opt の変更をしないとxfce4が起動しなかったので注意

```diff
docker run
- --security-opt apparmor:unconfined \
+ --security-opt seccomp=unconfined \
  ...
```

### brave browserインストール方法

https://brave.com/linux/
【Golang】if文

#【Golang】if文
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main
//if


import "fmt"

func main(){

	a := 1
	//if else if else
    if a == 2{
		fmt.Println("2だ")
	}else if a == 1{
		fmt.Println("1だ")
	}else{
		fmt.Println("それ以外")
	}

	//内包表記
	//1行で書く
	//if 条件の;　結果がTrueなら{
		//これを表示
	//}
	if b := 100; b == 100{
		fmt.Println("100だ")
	}
}
```
Slack API でハイパーリンクを付ける方法

Slack ではマークダウン記法によるハイパーリンクを付けることができないので、ニュースなどを Slack API の chat.postMessage を使って AWS Lambda から定期的に投稿するようにしていても URL が邪魔で文字が非常に読みづらいと常々思っていました。
そこで何か方法があるのではと思い、調べていたら見つけたので備忘録として記事にすることにしました。

# Slack API でのハイパーリンク方法

まず前提として、この方法は Slack API 経由でしかできません。
そのため、テキストで同じように書いてもリンクはできません。
テキストの場合は Slack のテキストエリアのところにハイパーリンクの作成があるので、そちらを利用することになります。

で、 API 経由の場合は以下のような文字列を作成すれば OK です。

```
<https://hogehoge.co.jp|このテキストにリンクがつく>
```

たったこれだけ。
この形式で文字列をたくさん用意して連結しても大丈夫でした。

# 参考

※ 以下のリンク、BASIC認証が追加されて見れなくなったみたいです。

こちらのサイトに記載がありました。
[リンクのスラックマークダウンが解決しない](https://www.it-swarm.dev/ja/markdown/%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%AE%E3%82%B9%E3%83%A9%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%80%E3%82%A6%E3%83%B3%E3%81%8C%E8%A7%A3%E6%B1%BA%E3%81%97%E3%81%AA%E3%81%84/823497018/)

https://www.it-swarm.dev というサイトの存在を知らなかったのですが、誰が運営しているんだろう。
データを他のアプリへ送る(Swift5)

## 概要
めちゃくちゃお久しぶりです。書こう書こうと思ってるとすぐ時間が過ぎる・・・

さて、SNSへ投稿したりするあれです。
SNSだけじゃなくて対応したアプリ(自作含め)は表示されますので好きなアプリに送信すれば良いわけです。
今回はサンプル画像をメモに送って確認したいと思います。
![IMG_1450.TRIM 2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491285/bedc5978-f114-dfe5-fc98-d6fc4caa3e2b.gif)

UIDocumentInteractionControllerを使います。
これを使ったサンプル記事はQiita内外でもあるのでご参照ください。

ところでこれ、ハマりました。
罠がありますがあんまり触れている方が少なかったので記事にしました。
画像（データ）が送れなかったり、コントローラが表示されなかったりしました。

まず、論よりコードです。動くやつ。
storyboardにてボタンの追加とイベント処理を追加してますがそれは省略します。


## サンプルコード
```ViewController.swift
// 
// Copyright (c) 2020年, hats_yaki. All rights reserved.
//
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    // 追加したコード
    @IBAction func touch(_ sender: Any) {        
        let img = UIImage(named: "cat4")!     // cat4.pngという名前でasset登録済とする
        _ = SendDocumentView(image: img, targetView: self.view)
    }
    
}
```

```SendDocumentView.swift
//
// Copyright (c) 2020年, hats_yaki. All rights reserved.
//

import UIKit

class SendDocumentView :NSObject {
    
    var dController :UIDocumentInteractionController!
    var reference :NSObject!
    
    init(image:UIImage, targetView:UIView) {
        super.init()
        self.reference = self       // 自身への参照
        
        guard let data = image.pngData() else { return }
        
        // ファイル一時保存してNSURLを取得
        let url = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("tmp.png")!
        do{
            try data.write(to: url, options: Data.WritingOptions.atomicWrite)
        }catch{
            print("画像データ保存でエラー")
            return
        }

        dController = UIDocumentInteractionController.init(url: url)
        if !(dController.presentOpenInMenu(from: CGRect(x: 0, y: 0, width: 500, height: 300), in: targetView, animated: true)) {
            print("ファイルに対応するアプリがない")
        }
    }
    
}
```



## ちょっとだけ解説
データ送信機能はSendDocumentView(Viewじゃないんですが)として独立させました。
これにUIImageと親となるUIViewを渡すと送信画面が表示されます。
疎結合なのでユーティリティのように使えるのではないでしょうか。

dController.presentOpenInMenuのところはもっと汎用的に書いている他の人のコードを参考にしてください。私はまだよくわかっていません。
あとdControllerの消滅とともにリソースが破棄されることを期待していますがそれもちゃんと動くかは要確認です。


## ハマったとこ
さて、ハマったとこですがSendDocumentViewのinitの2行目に自身への参照を持たせています。
一見これに意味がなさそうですがこれがないと期待する挙動になりませんでした。
iOS12系のiPhoneではコントローラーは表示されるのですが画像が空になり、iOS13系のiPadだとそもそもコントローラーが表示されなかったりしました。
なんで違いが・・・違いが出る理由がわかりませんが参照関係にある（あるべき）オブジェクトの生存期間の違いによるものだと思われます。詳しい方教えてもらえたら嬉しいです・・・
[学習遍歴]

/////  サンプル  /////

### カテゴリ 1
- [リンク名　タイトル](URL)　：　概要

--- 

### カテゴリ 2
- [リンク名](URL)　：　概要
- [リンク名](URL)　：　概要



リンク名 = タイトル＋投稿日
【HTML, CSS基礎】インライン要素、ブロック要素の配置方法

HTMLとCSSの基礎をすぐ忘れてしまうので、メモしたいと思います。




## ブロック要素、インライン要素とは


### ブロック要素

文字通りかたまりを表す要素のことで、箱をイメージするとわかりやすいと思います。
ブロック要素は高さや幅を指定することができます。
このブロック要素の大きさを調整して、ウェブサイトをおおまかな見た目を作っていきます。

例) divタグなど


### インライン要素

文章の一部として扱われる要素で、主にブロック要素の中に入れて使用します。
インライン要素は高さや幅の指定ができないので、そのまま使うと狙い通りの配置にならずダサくなります。
なので、インライン要素は必ずブロック要素の中に入れて使うようにしましょう。

例) iタグ、aタグ、inputタグ、buttonタグ、pタグなど




## なぜ要素を把握することが重要なのか

ブロック要素とインライン要素では大きくコーディングのやり方が変わってくるからです。
具体的にどう違うのかは次で説明します。
必ず、どちらの要素なのかを知った上でタグを使うようにしましょう。


## 要素ごとの配置方法

### インライン要素の左右中央寄せ

インライン要素を親のブロック要素の幅に対して、左右中央寄せしたいときのCSSの記載です。
親ブロックに対してtext-align: centerを適用します。

（補足）
text-align: centerは一つ親のブロックに対して左右中央寄せされ、二つ以上親のブロックは無視されます。


### インライン要素の上下中央寄せ

インライン要素を親のブロック要素の高さに対して、上下中央寄せしたいときのCSSの記載です。
親ブロックに対してline-height: ○○px（親ブロックのheightに合わせる）を適用します。


### ブロック要素の左右中央寄せ

ブロック要素をその親ブロックの幅に対して、左右中央寄せしたいときのCSSの記載です。
こちらは２つ方法があります。

①　動かしたいブロック要素にmargin: 0 autoを適用します。
　　基本的にはこれを使ったほうがいいです。

②　動かしたいブロック要素の親要素にdisplay: flexとjustify-content: centerを適用します。
　　こちらはフレックスボックスと呼ばれる手法になり、
　　中央寄せ以外にも様々な配置を実現することができる便利な手法になります。

しかし、display: flexには要素を横並びするという役割もあるため、結果として意図した配置にならないことがあります。そういう意味では①の方法を使ったほうが事故が起こりにくいです。


### ブロック要素の上下中央寄せ

ブロック要素をその親ブロックの高さに対して、上下中央寄せしたいときのCSSの記載です。
親ブロック要素に対してdisplay: flexとalign-items: centerを適用します。


## まとめ

以上まとめますと、コーディングをする際は要素がブロック要素なのかインライン要素なのか把握しましょう。
その理由は、要素によって配置の仕方が変わってくるからということでした。
具体的には、下のようにCSSを記載しました。

- インライン要素の左右中央寄せ　⇒　親要素にtext-align: center
- インライン要素の上下中央寄せ　⇒　親要素にline-height: ○○px（親ブロックのheightに合わせる）
- ブロック要素の左右中央寄せ　⇒　動かしたい要素にmargin: 0 auto
- ブロック要素の上下中央寄せ　⇒　親要素にdisplay: flexとalign-items: center

もっといい方法はあると思いますが、ひとまずこのやり方で問題なくviewを作れているのでメモしました。
こうした方がいいだったり、アドバイス等ありましたらコメントくださると幸いです。
もっとコーディングに関しての知識が深まればまた更新したいと思います。
以上、ここまで読んでくださり、ありがとうございました。では！
位置引数のタプル化

```python
def say_something(word, word2, word3):
    print(word)
    print(word2)
    print(word3)

say_something('Hi!', 'Mike', 'Nance')



def say_something(*args):
    print(args)
say_something('Hi!', 'Mike', 'Nance')

def say_something(*args):
    for arg in args:
        print(arg)
say_something('Hi!', 'Mike', 'Nance')

def say_something(word, *args):
    print('word=', word)
    for arg in args:
        print(arg)
say_something('Hi!', 'Mike', 'Nance')
```
Hi!
Mike
Nance
('Hi!', 'Mike', 'Nance')
Hi!
Mike
Nance
word= Hi!
Mike
Nance
word= Hi!
Mike
Nacy
css 方針まとめ

## cssの設計について自分なりの方針をもちたい


### 背景

基本的業務でbootstrapをベースにしているので、微修正など
をするときに、どこにcssを追記していいかで時間がかかる。

### 持論


```
## ファイルの構成

assets/配下

# controllerベースでファイルは分割する
todos.scss
users.scess
momos.scss

# commonファイル
※font,色,btnなどのコンポーネントをまとめる


# この中に /* コンポーネント毎などにcssを書いていく */
common.scss

# 悩みどころは色など
```



### OOCSS（オーオーシーエスエス

- 場所に応じたcss設定ではなくパーツに応じたcss設計が必要
- dry

#### 

https://app.codegrid.net/entry/oocss-1


### BEM

https://pikawaka.com/html-css/bem

```html
<div class="search"> <!-- Block -->
  <input class="search__input"> <!-- Element -->
  <input class="search__btn"> <!-- Element -->
</div>
```


### ECSS 

`block__element--modifier`



#### 参考記事

https://qiita.com/manabuyasuda/items/37523e9d0bfbad34211f
Railsで7つの基本アクション以外の定義

#基本アクションのおさらい

以下がRailsの標準アクションです
<img width="655" alt="スクリーンショット 2020-05-16 15.12.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533191/34ecf232-eaba-af9e-4f9b-480a041d1301.png">


#自分でアクションを定義する

上記の基本アクション以外の処理を行いたい場合は自身で定義することができます。

その際のルーティングの定義方法には**collection**と**member**が使えます

```rb

Rails.application.routes.draw do
  resources :hoges do
    collection do
      HTTPメソッド 'オリジナルのメソッド名'
    end
  end
end
```

```rb
Rails.application.routes.draw do
  resources :hoges do
    member do
      HTTPメソッド 'オリジナルのメソッド名'
    end
  end
end
```

違いとしては、生成されるルーティングに**id**が付くか、付か無いかです。

・collection   →   :idなし
・member       →   :idあり

特定のページへ遷移する必要がある場合などは、memberを使うといった感じです。

そして、重要なのは、どこにメソッドの内容を記述するかです。

一般的に、開発現場などでも、テーブル（DB)とのやりとりに関するメソッドはモデルに記載するのが通例らしいです。

例えば、検索機能を実装したい時なんかはその処理を行うメソッドをモデルに書き、コントローラーで呼び出します（viewの検索フォームなどの記述は省略します）

#使用例

```routes.rb
 resources :tweets do
    collection do
      get 'search'
    end
  end
```

```tweet.rb
class Tweet < ApplicationRecord
  #省略

  def self.search(search)
    return Tweet.all unless search
    Tweet.where('text LIKE(?)', "%#{search}%")
  end
end
```

```tweets_controller.rb
class TweetsController < ApplicationController
 
  #省略
  

  def search
    @tweets = Tweet.search(params[:keyword])
  end

end
```

それぞれを説明すると、

まず、searchアクションのルーティングを設定します。検索結果を表示するには、詳細ページに行く必要がなく、そのため、collectionを使っています。

formでユーザーが検索を行うと、controllerでsearchアクションからモデルに記述したsearchメソッドを呼び出します。その際、引数として検索結果を渡しています（params[:keyword]）

検索結果はモデルのsearchメソッドの中で変数searchに代入されメソッド内で使用できるようになります。

処理の内容は、searchの中身が空なら全ての投稿を取得し、値が入っているならwhereメソッドの中身の条件式に一致した投稿を取得します。
関数定義

```python
class Person(object):
    def say something(self)
        print('hello')
print(result)
def say_something():
    s = 'Hi'#sという変数を宣言
    return s#sをsay_somethingという関数に返す
result = say_something()#say_something()という関数を呼び出したときに何かを返して欲しい
def what_is_this(color):#colorは変数（引数）
    if color == 'red':
        return 'tomato'
    elif color == 'green':
        return 'green pepper'
    else:
        return 'I do not know.'

result = what_is_this('red')#what_is_thisという関数（function）にredという文字列を代入する
print(result)
「証明できても真とは限らない」ってマジ？

## 0. はじめに
以下の名著が元ネタで、一部引用等を含みます

- フランセーン『ゲーデルの定理～利用と誤用の不完全ガイド～』

## 1. 衝撃の事実
フランセーンからの引用:

>ある無矛盾な体系が, 例えば, 無限に多くの双子素数の存在を証明するという事実だけでは, 決して双子素数予想が真であることを意味しない(p42)

同様の指摘:

>...例えば双子素数予想に関しては, もし基本的な算術を含んでいる無矛盾な理論において証明可能か不可能かだけがわかったとしても, 予想の真偽については一般に何も結論することはできない (p30)

より一般的な指摘:

>無矛盾な理論のなかには, 偽の数学的言明を証明するものがある(p42)

親しみやすい指摘:

>ZFCの無矛盾性を信じるだけでは, ZFCでの証明可能性から A (引用者注: Aは算術的定理)が真だとすることは, 一般的に正当化できないのである(p29)

## 1.1 何か衝撃か？
僕らは「証明が存在すれば真であるし、反証が存在すれば真でない。」という信念を持っている。だからこそ 証明が重要視されているし、中学生の頃から証明のやりかたを勉強する。

上記の指摘は, この信念に影を落とすように感じられるからだ。証明できても真か偽か分からないとしたら証明に一体どんな意味があるのだろう？と思ってしまっても仕方がない。

## 1.2 少しの安心
上記の指摘が当てはまるのは、少し難しめのクラスの問題である。一方、Π01言明と呼ばれるクラスの算術的言明に関しては、我々の信念「証明されるならば真」ということが言える。なので、特定のディオファントス方程式の非可解性（例：フェルマーの定理）や、ゴールドバッハの予想といった問題は、証明できれば真であるといえる。

一方 双子素数予想や、コラッツ予想は、Π01言明でないので「証明されても真とは限らない」が適用される。

## 2. なんでそうなるの？
ゲーデルの第二不完全性定理によると, ZFCが無矛盾であれば `ZFC+「ZFCは矛盾している」` という理論も無矛盾であるが、この理論は真なるΠ01言明「ZFCは無矛盾である」を自明に反証できる。また、同じことだが、偽なる言明「ZFCは矛盾している」を自明に証明できる。よって

- 無矛盾な理論のなかには, 証明できても偽である算術的言明がある

の一例を簡単に構成できた。このことから以下が直ちに従う

- 無矛盾な理論だからといってその定理が真であるとは限らない

## 2.1 Π01言明はなぜ大丈夫なの？
任意に選んだΠ01言明を A と名前を付ける。「Aが証明可能ならAが真である」を示す。

**補題**: 偽なるΠ01言明は反証可能である。（補題の証明：反例に当たるまで枚挙するという手続きは必ず停止するアルゴリズムである）

Aが偽であると仮定しよう。上記補題より ￢A が証明できる。Sが無矛盾であるなら、A と ￢A の両方は同時に証明できないので、A は証明できない。これは前件に反する。よって帰謬法により A は真である。

# 3. おわりに
フランセーンの本は、ゲーデルの定理や計算可能性に関する各種定理・性質に関する かなりきわどいところを攻めてくるので面白いです。興味あれば購入することをお勧めします。
ブロックチェーンって何？

## ブロックチェーンとは

あらゆる資産を仮想通貨として表現し、第三者不要かつ改ざんできない状態で管理することのできる技術

## ブロックチェーンの特徴

- 資産を仮想通貨として代替表現
    - あらゆる資産を仮想通貨として管理することができる（ex. 土地,家）
- 第三者不要
    - 特定の管理者が不要になる
- 改ざんが極めて困難
    - 全てのノードが完全に同一のデータを保持している

## 参考
[POL]
(https://pol.techtec.world/)
Nuxt.js + FirebaseでDeployできない？

## やりたいこと
1. Nuxt.js でクライアントサイドを開発し、
2. Firebase（Cloud Functions） でサーバーサイドを開発し、
3. Netlify で自動デプロイ & ホスティング

基本的にな設定については他に詳しい記事があるので割愛。
 -> [『Nuxt + Firebase Hosting』で超速deploy - Qiita](https://qiita.com/omochironn/items/27d80d5ef470cdb2baca)

## Deployできない？
こんなエラーがでてDeployに失敗してしまう。

```sh:
10:12:56 AM: ERROR in /opt/build/repo/functions/src/index.ts
10:12:56 AM: ERROR in /opt/build/repo/functions/src/index.ts(1,28):
10:12:56 AM: 1:28 Cannot find module 'firebase-functions'.
10:12:56 AM:   > 1 | import * as functions from 'firebase-functions'
```

## 現状の確認
### ディレクトリ構造

```sh:
.
├── README.md
├── assets
├── components
├── data
├── dist
├── firebase.json
├── firestore.indexes.json
├── firestore.rules
├── functions
├── layouts
├── middleware
├── models
├── node_modules
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
├── plugins
├── server
├── static
├── store
├── stylelint.config.js
└── tsconfig.json
```

これは公式ドキュメントの通りこのコマンドで初期化したままの状態。

```sh:
npx create-nuxt-app <project-name>
```

##### ここで注目すべきは以下
1. TypeScript を採用
2. ESLint を採用
3. Nuxt.jsのリポジトリ内にfunctions/を含めている
4. functions/ 内で利用されるパッケージが、Nuxt.jsでは利用されない

1, 2は初期化時に設定。
3のため、ESLintはfunctions/以下のファイルも静的解析する。
4のため、Nuxt.jsに対して静的解析すると、functions/ 内で利用されるパッケージはインストールされていないことになる。

というわけで、ログからはわかりにくいが、今回のエラーの主はESLint。

## 対処
tsconfig.json で、functions/ 配下を静的解析の対象外とする。

```ts:tsconfig.json
{
  ...

  "exclude": [
    "node_modules",
    ".nuxt",
    "dist",
    "functions" // <- 追加
  ]
}
```

## 以上
今回はプロジェクト規模が小さかったので、リポジトリをまとめることにしましたが、
FirebaseとNuxt.jsを別のリポジトリに分ける方法もありだと思います。