OmniAICreator/Qiita-1.07M huggingface dataset:
django-allauthの認証で、googleからメールアドレスを取得できずにハマった話

django-allauthを利用してソーシャルログイン機能を実装する際に、メール情報が取得できずにハマりました。
せっかくなので、その事象と原因、対応策をこの記事に残しておきます。

## 起きた事象
試していたことは、django-allauthを利用してgoogleソーシャルログインをできるようにするというものです。
公式ドキュメントやqiita記事にある通りに実装することで、ログインできるとこまでは確認したのですが、作成されたアカウント情報を見ると、なぜかメールアドレスが空という事象が発生しました。
![not_email.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763555/da9516f2-9ecd-8054-c1ff-5f47533a5e1d.png)
　図：googleソーシャルログイン後に、作成されたアカウントの中身（管理画面で確認）


## 原因
結論、googleプロバイダのscopeを適切に設定できていなかったことが原因です。
django-allauthが標準で持つgoogleプロバイダは、デフォルトのscopeを`profile`のみに設定しています。
`profile`APIからのレスポンスにはメールアドレス情報は存在しません。よって、そもそも情報をgoogleから得られていなかったので、今回の事象は発生したということになります。

では、どう対処するのかというと、、、
「メールアドレス情報をくれるAPI」をscopeに追加するということが解決策になります。
ちなみにgoogleの場合、そのAPIの名前は`email`です。

* scopeってなんだよ？という方はこちら ➡ [OAuth2 スコープの操作 | Apigee | Google Cloud](https://cloud.google.com/apigee/docs/api-platform/security/oauth/working-scopes?hl=ja)
* googleが提供しているOAuth2.0のAPIはこちら ➡ [OAuth 2.0 Scopes for Google APIs](https://developers.google.com/identity/protocols/oauth2/scopes)


## 対処法
対処法としては、以下の2つのどちらかを行えばOKです。
1. settings.pyにて、`ACCOUNT_EMAIL_REQUIRED=True`と設定する
2. settings.pyにて、`SOCIALACCOUNT_PROVIDERS`でgoogleプロバイダのscope設定をする

### 1. settings.pyにて、`ACCOUNT_EMAIL_REQUIRED=True`と設定する

```python:setting.py
...
ACCOUNT_EMAIL_REQUIRED=True
...
```
この設定をすると、googleに限らず他のプロバイダでもメールアドレス情報が取得できるよう、django-allauthが良しなにやってくれます。
例えばgoogleプロバイダの場合、`profile`APIのほかに`email`APIも、デフォルトのscopeに勝手に追加される形になります。（詳しくは、[githu](https://github.com/pennersr/django-allauth/blob/master/docs/installation.rst)で確認してください）

### 2. settings.pyにて、`SOCIALACCOUNT_PROVIDERS`でgoogleプロバイダのscope設定をする

```python:settings.py
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'SCOPE': [
            'profile',
            'email',
         ],
    },
}
```
この設定では、1の方法とは違って直接利用するAPIを指定しています。


## まとめ
以上、django-allauthにて、プロバイダからメール情報が取得できない事象の原因と対処法でした。


## 参考
* [django-allauth 公式ドキュメント](https://django-allauth.readthedocs.io/en/latest/overview.html)
[K8s] ポッドのトラブルシューティング

## 概要

K8sのデプロイが正常にうまくいかない時は基本的にポッドの起動失敗だと思うので、調査する際のコマンドとその結果についてまとめた個人メモです。

### 実行コマンド

```
$ kubectl get pods
```

### 実行結果の意味と対策

|STATUS|意味と対策
|---|---
|ContainerCreating|イメージのダウンロード中、もしくはコンテナの起動中。<br>また、ConfigMapやSecretを正常にマウントできてない。
|CrashLoopBackOff| ポッド内のコンテナが終了し、次の起動までの待機状態。コンテナが2回以上終了すると、左記ステータスとなる。コンテナのプロセス見直しが必要
|Pending | ポッド生成の要求を受け取ったが、1つ以上のコンテナが作成されていない状態。
|Running | ノードに対応付けられ、全てのコンテナが作成されている。
|Terminating | コンテナへ終了要求シグナルを送信後、コンテナが終了するまでの待機中。時間を待っても終了されない場合は強制終了させる。
| Succeeded | ポッド内のコンテナが正常に終了した。
|Completed | ポッド内のコンテナが正常終了し存在している。ポッドが削除されるまで存在し続ける。
| Error | コンテナが異常終了した・ポッド内にコンテナが複数ある場合、第一コンテナが異常終了するとポッドも異常終了として扱われる。
| Unknown | 何かしらの理由により、ポッドの状態を取得できない。ノード障害によりマスターからノードの状態を取得できない場合も表示される。
2020/10/3 テックキャンプ１３日目　アウトプット

#Railsで投稿アプリつくってみる２　
投稿機能をつける
-
- ストロングパラメーターとは、指定したキーを持つパラメーターのみを受け取るようにするもののこと
- プライベートメソッドとは、クラス外から呼び出すことのできないメソッドのこと
- バリデーションとは、データを登録する時に、一定の成約をかけること

ツイートを削除する
--
・削除機能実装の流れ
１　ツイートを削除するためのルーティングを設定する
2　削除ボタンをビューに追加する
3　destroyアクションをコントローラーに定義する
4　削除後のビューを追加する

- 用語
- destroyアクションとは、ツイート削除を行うときに定義するアクション
- DELETEはdestroyアクションを動かす際に指定するHTTPメソッドのこと
- rails routesは設定されているルーティングを確認するためのコマンド
PowerVS IBM i 日記(13): AMT で WDS に課金せずに PDM を利用する

# AMT で WDS に課金せずに PDM を利用する

IBM i を 5250 で操作する場合、PDM は手放せませんよね。
でも、通常通りに PDM を使えば「[PowerVS IBM i 日記(12): サーバー詳細の編集 - 課金金額の最適化とライセンスの追加購入](https://qiita.com/6onoda/items/6675c86d7d53deb80c41)」の時のように、5770-WDS のライセンス超過が記録され、猶予期間の 70 日を超えると利用できなくなります。

PDM のためだけに WDS を買うのもな...という方に朗報です。WDS を買わなくても PDM を使う方法があります。

## 5770-AMT IBM Rational Application Management Toolset for i を使う

「5770-AMT IBM Rational Application Management Toolset for i」は、5770-WDS の PDM と SEU のみを提供する製品です。

IBM Cloud では「[IBM i ライセンス・プログラム製品 (LPP) およびオペレーティング・システム (OS) のフィーチャーのバンドル](https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-ibmi-lpps&locale=ja)」の記載通り、追加料金を払わなくても利用できます。
(リストには「**5761-AMT**: Rational Application Management Toolset」とありますが、正しくは **5770-AMT** です。)

AMT に関しては「[5770-AMT IBM Rational Application Management Toolset for i v7.2](https://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_sm/t/877/ENUS5770-AMT/index.html&lang=en&request_locale=en)」に情報が見つかりました。

ライブラリは QPDA2 です。
**WRKOBJPDM** で QPDA2 内の \*CMD を確認してみます。WDS の PDM に対応した AMT のコマンドが確認できます。
WDS の WRKLIBPDM が **WRKLIBAMT** とコマンド名が変更されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/67666564-fc08-9dd7-8e5f-ce667da90384.png)!

さっそく **WRKOBJAMT** で QPDA2 内の *CMD を確認してみます。同じ内容の画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/b5acd4bc-62a9-644e-5ce7-0163d6429d52.png)

STRSEU の代わりは **ETDCLU** です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/da2aa110-d5d6-f1e3-b49b-28316a0192ba.png)

編集可能なタイプは CL 系と TXT に限定されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/d788f99a-a3da-7098-e184-fd0ee268a173.png)

5770-AMT は Limit *NOMAX で登録されているので、ユーザー数を気にしなくてく済みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184930/548ec59b-8795-6a3a-e93e-10b10269db8e.png)

完全に WDS のライセンス購入を無くすことは困難だとしても、PDM で操作できないと不便だから人数分 WDS を購入するということは避けられるかもしれません。

---
当日記のIndexは[こちら](https://qiita.com/6onoda/items/f146c78c0c1bbe905a42)です。

---
許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
CSSアニメーションでページをフェードインさせたときに画面がちらつくのを治す方法

最近個人開発アプリにCSSアニメーションでフェードインを導入しました。とりあえず動くことにはうごくのですが、連続してクリックすると普通にページが表示されてから一瞬画面が真っ白になり、そこからフェードインされて表示される現象が発生しました。ちらつく感じなのでいかにも不具合という感じなので何とかしなけばと思いあわてて治しました。。
これを解決するのにすこし詰まってしまったので、ここで共有したいと思います。

【環境】

- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.7
- nginx:1.15.8

##まずは解決策
**まずちらついている要素に```display: none;```を指定します。**
私はアプリケーション全体に適用していたのでbody要素に指定しました。

```scss:custom.css

body {
  display: none;
}
```

その後jQueryで以下のように指定します。(数行でファイルを分けるまでもなかったのでhamlでベタ書きしてます。)
アプリケーション全体に適用させたかったので```application.haml.haml```に私は書きました。

```javascript:application.html.haml

:javascript
  $('body').fadeIn(700);
```

jQueryを導入してない方は、jQueryを導入してください。詳しい方法はさがせば記事がたくさん出てくるので、ここでは割愛します。
```$('要素').fadeIn('時間');```でフェードインさせたいようそと、時間数を指定できます。

ちなみに、```display: none;```をしたのは、fadeIn()は非表示になっているHTML要素に対してのみ機能するためす。

このようにしたらちらつきがなくなりました。

##それでも治らない場合
一度行ったページを再びクリックするとちらつく場合、Railsのturbolinksが悪さをしている可能性があります。
jQueryのコードを読み込む前にturbolinksによりキャッシュがロードされてからjQueryが読み込まれるため、ちらついてしまうようです。（[詳細はこちらをご参考下さい](https://stackoverrun.com/ja/q/10980244)）

その場合headタグ内に次のように記述してturbolinksを無効にします。

```haml:application.html.haml
%meta{:content => "no-cache", :name => "turbolinks-cache-control"}
```

##注意点
この場合、JavaScriptがオフだとページが表示されないので、JavaScriptがonの場合のみCSSアニメーションのクラスを付与するようにできるとなおよいと思います！
また、時間がある時にこちらの追記しようと思います！

##最後まで読んでいただきありがとうございます！
このように、日々学習した内容をアウトプットしております！ご指摘や感想などコメントしていただけると嬉しいです！
renderで与えれんだー

##はじめに
 　JavaScriptでも、Railsでも登場したので、まとめておく。正確にはJSの学習中に、出てきただけで、記述方法や言語はRubyである。

#renderメソッドとは
　renderの訳は「与える」。つまり、何かを与えるときに使うメソッド。では、何を与えるのか。
　
　ここでは３種類の使い方を紹介する。３つに共通しているのは「レスポンスとして返している」ということ。

##<font color=red>部分テンプレート</font>を与える

 railsで、共通するHTMLを一つのファイルにまとめ、必要な箇所に代入のような形で呼び出す。この仕組みを部分テンプレートである。
　部分テンプレートのメリットは、
・同じコードを何度も書かなくて済む。（使いまわせる）
・変更があった場合、修正する箇所が少なくて済む。
・一つのファイルの記述量が減り、読みやすくなる。
などが考えられる。

###部分テンプレートのポイント
呼び出し方法

```Ruby
<% render partial: "test" %>
```

「_test.html.erb」というファイルを呼び出している。（同じ階層にファイルがある場合）
`partial`オプションを使って、呼び出すファイルを指定する。
※ファイル名は「_(アンダースコア)」から始める。
※部分テンプレート内で変数を用いる場合は`local`オプションを用いるが、今回は割愛する。

##<font color=red>レスポンスの形式を指定</font>して与える

　JSを用いてAjax（非同期通信）を行うには、ファイルとしてサーバーをやりとりをするのではなく、データ形式でやりとりを行う。その際、Railsでは、デフォルトでファイル形式でをレスポンスを返すことになっているので、renderメソッドを用いて、形式を変えることができる。

###レスポンス形式の指定のポイント

例えばコントローラーで、

```Ruby
def new
 post = Post.new
 render json: { post: post }
end
```
`{ post: post }`をjson形式でレシポンスしているということになる。Ajaxでは頻出。

##<font color=red>view</font>を与える
　例えば、railsでのコントローラーで、

```Ruby
 render 'ファイル名'
```
とすると、指定した、ファイルを表示させることができる。
よく似た使い方に`redirect_to`メソッドがあるが、こちらは、ルーティングやコントローラーを経由して、ビューを表示させる。`render`メソッドは、経由せず、直接表示するという違いがある。

##ポイント
- [x] 　「与えている」というイメージを大切に。
- [x] 　`redirect_to`メソッドの使い分けに注意。


##最後に
　共通して言えるのは、どれもレスポンスとして返しているということ。他にも、ただ文字列を返すだけ、など様々な使い方がある。
備忘録 vue.js  computed、filters使い方


```
<template>
  <div>
    <p v-for='item in items' :key = 'item.name'>
      {{ item.name }}
      {{ item.price | numberWithDelimiter}}
      {{ item.quantity }}
    </p>
    <p>合計金額(税抜き) {{ totalPrice }} </p>
    <p>合計金額(税込み) {{ totalPriceWithTax }} </p>
  </div>
</template>

<script>
export default { 
  name: 'Section2',
  data: function() {
    return {
      items:[
            {
              name: 'pencil',
              price: 1300,
              quantity: 1,
            },
            {
              name: 'note',
              price: 1400,
              quantity: 2,
            },
            {
              name: 'eraser',
              price: 1300,
              quantity: 3,
            }
      ]
    }
  },
  computed: {
    totalPrice: function() {
      var sum = 0;
      for(var i = 0; i < this.items.length; i++) {
        sum += this.items[i].price * this.items[i].quantity;
      }
      return sum;
    },
    totalPriceWithTax: function() {
      var sum = 0;
      for(var i = 0; i < this.items.length; i++) {
        sum += this.items[i].price * this.items[i].quantity;
      }
      return Math.floor(sum * 1.10);
    }
  },

  filters: {
    numberWithDelimiter: function(value){
      if(!value){
        return 0;
      } else{
        return value.toLocaleString();
      }
    }
  },
}
</script>

<style scoped>
</style>

```
※数字にカンマ付けする場合は、正規表現でも可能だが、toLocaleString()を使用する事で3桁カンマ付けにできる。

※filtersを使用するときはムスタッシュ記号内で{{ ○○ | △△ }}と書くことで文字列を整形してクライアントに表示できる。


参考：Vue.js入門 基礎から実践アプリケーション開発まで　技術評論社　https://gihyo.jp/book/2018/978-4-297-10091-9
【Ruby】論理演算子のリファクタリングの難しさ（正確性と可読性）

Don't Repeat Yourself（同じ記述を繰り返さない）ことを突き詰めようとした結果、本来の目的が達成できないケースがあったため、記事として残しておきます。

###要件定義
例えば、ある特定の文字列のみの入力を求めるとする。（下記の場合は、"0","1","2"のどれか1つの入力を、if文でjudgeしている。）

###論理演算子を用いた記述
```rb
input_number = gets.chomp
sample_number = ["0","1","2"]

if input_number == "0" || input_number == "1" || input_number == "2"
    puts "入力は、0,1,2のうちどれかです。"
 else
    puts "0,1,2以外の文字が入力されましています！"
end
```
論理演算子||（または）の箇所が長ったらしい…。なんとか簡潔にできないかと試行錯誤してみる。

###between?メソッドを使ってみる
```rb:case1　between?メソッド
input_number = gets.chomp
sample_number = ["0","1","2"]

#入力された文字列が"0"から"2"までの間かどうかを、真偽で返す。
t_or_f = input_number.between?("0", "2")

if t_or_f == true
  puts "入力された文字列は、0,1,2のうちどれかです"
else
  puts "それ以外の文字が含まれています！"
end
```
変数定義が１つ増えたが、仮に受け入れる文字列をもっと増やしたい場合には、論理演算子よりも追記・修正が少なくて済む。
リファクタリングはおしまい、と思いきや別の問題が発生することが分かった。
アルファベット等の関係ない文字列を含む場合はfalseとなるが、"0120"や"1.9"といった入力をtrueと返してしまうのだ。
次はどうだろうか。

###any?メソッドとinclude?メソッドを使ってみる
```rb:any?メソッドとinclude?メソッド
input_number = gets.chomp
sample_number = ["0","1","2"]

#any?メソッド・・・どれか1つでも条件を満たすのであればtrue、すべて条件を満たさないのであればfalseを返す
#ブロック{}内の処理・・・sample_numberの配列内の要素をブロック引数nに代入。
#input_numberにブロック引数nが含まれて（includeされて）いるかを判断し、trueかfalseを繰り返し（この場合は3回）返している。
t_or_f = sample_number.any? {|n| input_number.include?(n)}

if t_or_f == true
  puts "入力された文字列は、0,1,2のうちどれかです"
else
  puts "それ以外の文字が含まれています！"
end
```
この場合は、入力された文字列が0,1,2いずれかを含んでいれば、必ずtrueを返してしまう。
（例：1234 => true, abc0120 => true）

###結論
結局は、論理演算子||で入力を厳格に求めることが、一番確度が高い。

###in?メソッド（※Rails限定）
Rubyオリジナルではなく、Rails内の拡張されたRubyには__in?メソッド__というものがある。
この場合、0,1,2のみ受け入れ、01などは通らない。

```rb:in?メソッド
input_number = gets.chomp
if input_number.in?(["0", "1", "2"])
 puts "入力された文字列は、0,1,2のうちどれかです"
else
  puts "それ以外の文字が含まれています！"
end
```
【Java】StackOverflowErrorとOutOfMemoryErrorの違い

Java Silverの勉強をするにあたり調べたことのメモ。

#StackOverflowErrorとOutOfMemoryErrorの違いは何か？

##StackOverflowErrorとは
[クラス StackOverflowError](https://docs.oracle.com/javase/jp/7/api/java/lang/StackOverflowError.html)
**スタック領域**でメモリがなくなることで発生するエラー

【発生する状況例】
メソッド内で**再帰呼び出し**を行う

【スタック領域とは】
**ローカル変数やメソッドの情報**を格納するメモリ領域のこと。
名前の通り、スタック状のデータ構造（後入れ先出し方式）を持つ。

メソッド内で自分自身のメソッドを呼び出し続けてしまうと、スタック領域にメソッドの情報が積み上がっていきパンクしてしまう。そうすると、JVM(Java Virtual Machine)がスタック領域が足りなくなったことを検知して、StackOverflowErrorを発生させる

##OutOfMemoryErrorとは
[クラス OutOfMemoryError](https://docs.oracle.com/javase/jp/7/api/java/lang/OutOfMemoryError.html)

> メモリー不足のために Java Virtual Machine がオブジェクトを割り当てることができず、ガベージコレクタによっても使用可能なメモリーをこれ以上確保できない場合にスローされます

**ヒープ領域**でメモリがなくなることで発生するエラー

【発生する状況例】
**無限ループ**がおこっている
(参考： [OutOfMemoryError例外の理解](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/troubleshoot/memleaks002.html) )

【ヒープ領域とは】
**インスタンス**の情報を置くための領域のこと。


##まとめ
JVMに割り当てられたメモリ（スタック）がいっぱいになるとStackOverflowErrorが発生する。
JVMがメモリ割り当てに失敗すると、OutOfMemoryErrorになる。

##参考文献
・[ヒープ領域とは？スタック領域との違いや具体的な管理方法を解説！](https://it-trend.jp/development_tools/article/32-0041)

・[スタック領域とは](http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000987.html#:~:text=%E3%83%A1%E3%83%A2%E3%83%AA%E4%B8%8A%E3%81%AE%E3%80%81%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E5%A4%89%E6%95%B0,%E6%A0%BC%E7%B4%8D%E3%81%99%E3%82%8B%E9%A0%98%E5%9F%9F%E3%81%AE%E3%81%93%E3%81%A8%E3%80%82&text=JVM%E3%81%8C%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%A1%E3%83%A2%E3%83%AA,%E7%8A%B6%E3%81%AB%E6%A0%BC%E7%B4%8D%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82)
【AWS SOA】EC2インスタンスタイプ変更

#はじめに
AWS SOAの試験でEC2のインスタンスタイプ変更を行なう問題が出題される。今回は改めてインスタンスタイプの変更の方法について押さえたいと思う。

#手順
・EC2インストール(今回はその点は省略する)
・SSH接続
・メモリ容量の確認
・インスタンスの停止
・インスタンスタイプの変更
・インスタンスの起動
・SSH接続
・メモリ容量が増えているか確認

#やってみた
SSH接続は、以下の記事参照。
https://dev.classmethod.jp/articles/aws-beginner-ec2-ssh/

SSH接続できたら以下のコマンドを使って、容量を確認する。
今回の場合(t2.micro)、合計のメモリが983であることが確認できる。

```
$free -m
              total        used        free      shared  buff/cache   available
Mem:            983         101         422           0         458         732
```

インスタンスタイプの変更のため、一旦インスタンスを停止する。
該当のインスタンスを選択して、アクション>インスタンスを停止を選択する。
![スクリーンショット 2020-10-03 12.03.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/46b45bb7-72ad-db8f-be66-e757309578e2.png)
停止できたら、アクション>インスタンスの設定>インスタンスタイプを変更を選択する。
![スクリーンショット 2020-10-03 13.15.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/c7fbead7-b9ae-18ef-428c-c1c91763ac92.png)
インスタンスタイプを変更画面が出てくるので、インスタンスタイプを変更する。変更したら適用を選択する。
![スクリーンショット 2020-10-03 13.18.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/67f46de6-9f18-1690-bbb2-61247031a507.png)

![スクリーンショット 2020-10-03 13.19.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/ce9f416e-4c15-92bd-b3a1-92d674cf715e.png)
変更が完了したら、該当のインスタンスを選択して、アクション>インスタンスを開始する。
![スクリーンショット 2020-10-03 13.22.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/53c8a459-a2e2-2a72-ff40-00d42d5ccda4.png)

インスタンスが立ち上がったらSSH接続する。(Elastic IPを設定してない場合、インスタンスを停止するとパブリック IPv4 アドレスが変わるので注意する。)

先ほどと`free -m`コマンドを叩くと、合計のメモリが変わっていることを確認する。

```
$free -m
              total        used        free      shared  buff/cache   available
Mem:            1993         46         1793           0         154         1707
```

参考
Ultimate AWS Certified SysOps Administrator Associate 2020
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-resize.html
AtCoder Regular Contest 104 参戦記

# AtCoder Regular Contest 104 参戦記

C, D, E を眺めて D が一番簡単かなと思って考え始めて、途中で勘違いに気づいてどれも解けないやんってなった. 速解きチャレンジ失敗していて、1900位くらいになってしまったのでレーティングが下がって悲しい.

## [ARC104A - Plus Minus](https://atcoder.jp/contests/arc104/tasks/arc104_a)

3分で突破. どれくらいの範囲をチェックすればいいんだろうと思いつつ.

```python
A, B = map(int, input().split())

for X in range(-200, 200):
    for Y in range(-200, 200):
        if X + Y == A and X - Y == B:
            print(X, Y)
            exit()
```

今思うと方程式を解いて、(A+B)÷2 と (A-B)÷2 でよかった.

```python
A, B = map(int, input().split())

print((A + B) // 2, (A - B) // 2)
```

## [ARC104B - DNA Sequence](https://atcoder.jp/contests/arc104/tasks/arc104_b)

14分で突破. SegmentTree かなと思ったあとで、累積和だなと思い直したのが無駄に時間がかかった原因かなって. Python だと割と制限時間ギリギリ.

```python
from itertools import accumulate


def main():
    N, S = input().split()
    N = int(N)

    a = [0] * (N + 1)
    g = [0] * (N + 1)
    c = [0] * (N + 1)
    t = [0] * (N + 1)

    for i in range(N):
        x = S[i]
        if x == 'A':
            a[i + 1] = 1
        elif x == 'G':
            g[i + 1] = 1
        elif x == 'C':
            c[i + 1] = 1
        elif x == 'T':
            t[i + 1] = 1

    a = list(accumulate(a))
    g = list(accumulate(g))
    c = list(accumulate(c))
    t = list(accumulate(t))

    result = 0
    for i in range(N):
        for j in range(i + 2, N + 1, 2):
            k = a[j] - a[i]
            l = g[j] - g[i]
            m = c[j] - c[i]
            n = t[j] - t[i]
            if k == n and l == m:
                result += 1
    print(result)


main()
```

累積和なくても解ける.

```python
def main():
    N, S = input().split()
    N = int(N)

    result = 0
    for i in range(N):
        a, b = 0, 0
        for c in S[i:]:
            if c == 'A':
                a += 1
            elif c == 'T':
                a -= 1
            elif c == 'C':
                b += 1
            elif c == 'G':
                b -= 1
            if a == 0 and b == 0:
                result += 1
    print(result)


main()
```

*O*(*N*) でも解ける.

```python
N, S = input().split()
N = int(N)

result = 0
t = {}
t[(0, 0)] = 1
a, b = 0, 0
for c in S:
    if c == 'A':
        a += 1
    elif c == 'T':
        a -= 1
    elif c == 'C':
        b += 1
    elif c == 'G':
        b -= 1
    if (a, b) in t:
        result += t[(a, b)]
        t[(a, b)] += 1
    else:
        t[(a, b)] = 1
print(result)
```
Pythonでソースコードから日本語を含む1行コメントを削除する

この記事ではPython3を使っています。
# コード
```test.py
import re

# 改行コード
EOL = '\n'
# ASCIIパターン
p_ac = '[!-~\\s]'
# 日本語(ASCII以外)パターン
p_jp = '([^!-~\\s]|[　])'

# 1行コメントパターン
p_com = '//'
# p_com = '#'

# pattern 全体
pattern = f'[ ]*{p_com}({p_ac}*{p_jp}+)+{p_ac}*$'

# 置換したい文字列
s = '''1 aaa
2 bbb // あaいiうuえeおo
3  // kaかkiきkuくkeけkoこ
4    // いいい
5 // uuu
6 print (aaa)   // aaaを表示
7 print (ccc)   // print ccc
8
[EOD]'''

# 置換前
print (s)
print ('----------------------')

n = ''
# 一行ごとに分割
ary = s.split(EOL)

# 置換処理
for l in ary:
    # 対象削除
    r = re.sub(pattern, '', l)
    n += r + EOL

# 置換後
print (n)

```

# 出力
```
1 aaa
2 bbb // あaいiうuえeおo
3  // kaかkiきkuくkeけkoこ
4    // いいい
5 // uuu
6 print (aaa)   // aaaを表示
7 print (ccc)   // print ccc
8
[EOD]
----------------------
1 aaa
2 bbb
3
4
5 // uuu
6 print (aaa)
7 print (ccc)   // print ccc
8
[EOD]
```
Java,RubyをFizzBuzzで比較


#【Java,RubyをFizzBuzzで比較】

業務での開発言語は、Javaを使用しています。
業務外では、Rubyでポートフォリオ作成をしています。

##Java,RubyのFizzBuzz

FizzBuzzは、ある数字からある数字までを画面に表示するプログラムを組むもの。
ただし、以下のような条件がある。
・3の倍数のときは数字の代わりにFizzと表示
・5の倍数のときは数字の代わりにBuzzと表示
・15の倍数のときは数字の代わりにFizzBuzzと表示

###Java

```java
class FizzBuzz {
  public static void main(String args[]) {
    for (int i = 1; i <= 15; i++) {
      if (i % 15 == 0) {
        System.out.printIn("FizzBuzz");
      } else if (i % 3 == 0) {
        System.out.printIn("Fizz");
      } else if (i % 5 == 0) {
        System.out.printIn("Buzz");
      } else {
        System.out.printIn(i);
      }
    }
  }
}
```

###Ruby

```ruby
(1..15).each do |i|

  if i % 15 == 0
    puts 'FizzBuzz'
  elsif i % 3 == 0
    puts 'Fizz'
  elsif i % 5 == 0
    puts 'Buzz'
  else
    puts i
  end

end
```
【メモ】BeautifulSoup4の使い方(2) Requestsで記事の見出しを表示

インターネット上のWebサイトのhtmlには様々な情報が含まれており、自力で解析するのは難しい。そこでRequestsというhtmlを取得するライブラリを使う。

今回はMSN Japanの国内欄の記事の見出しの取得を通してRequestsの使い方を学んでいく。

In[1]BeautifulSoupとRequestsとReをimportする

```:In[1]
from bs4 import BeautifulSoup
import requests
import Re
```
In[2]変数urlshutokuにhtmlの情報を格納する

```:In[2]
urlshutoku = requests.get("https://www.msn.com/ja-jp")
```

In[3]ページ全体を表示してみる

```:In[3]
urlshutoku.text
```

In[3]を表示すると不要な情報の方が目立つので、今回必要な情報である見出しのみを表示する。そのために見出しの情報を取得しなければならない。そこで使うのがGoogleChromeのデベロッパーツールだ。

まず、見出しを右クリックし、検証(I)をクリックする。すると以下のような画面が表示される。
![2020-10-03_220938.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672907/546f64a9-8d4e-d0b4-e630-b2abb2a1a756.png)

スクレイピングで用いるのは上記の画面の左側の英数字ばかりの情報だ。先ほど検証をクリックした部分の一番上の見出しの部分が青くなっていることを確認する。次に記事の見出しのurlに相当する\<a href="/ja-jp/news/national/~">を確認する。他の見出しも同様になっているので\<a href="/ja-jp/news/national/~">が手がかりになるようだ。

In[4]BeautifulSoupとhtml.parserで解析

```:In[4]
soup = BeautifulSoup(urlshutoku.text,"html.parser")
```

In[5]find_allを使って国内系の見出しを抽出

```:In[5]
midashi = soup.find_all(href=re.compile("/ja-jp/news/national"))
```
jupyternotebook上でmidashiと打つと見出しの情報が表示されるが、urlの情報も入っている。このままでは見づらいので文字だけ表示できるようにする。

In[6]for文とstringを使って文字のみ表示

```:In[6]
for ichiran in midashi:
    print(ichiran.string)
```

これで見出しのみが表示される。
Azureに静的サイトを構築する

#### １．ストレージアカウントで静的Webサイトの作成

- ストレージ アカウントの作成
- 左メニューから「静的なWebサイト」をクリックし、「静的なWebサイト」を有効にする。
- 「インデックス　ドキュメント名」と「エラードキュメントのパス」を指定
- 左メニューから「概要」をクリックし「Azure Strage Explorer」をダウンロード・インストール
- 「Azure Strage Explorer」でインデックスドキュメントとエラードキュメントをアップロード

#### ２．Azure CDNおよびエンドポイントの作成

- ストレージ アカウントの左メニューから「Azure CDN」をクリックし、CDNを作成する
- 「価格レベル」は「標準Microsoft」、「CDNエンドポイント名」は任意のURL（のちにサイト（静的なWebサイト等）が増えるごとにエンドポイントを追加する）、「配信元のホスト名」に上記手順で作成した「静的Webサイト」を選択する

#### ３．App Service ドメインでカスタムドメインの取得

- 「AppServiceドメイン」を新規作成する
- 「サブスクリプション」「リソースグループ」「ドメイン」は任意の値を入力する

#### ４．DNSゾーンを作成し、カスタムドメインとエンドポイントを紐づけ

- 「DNSゾーン」を新規作成する
- 「レコードセット」をクリックし新規レコードを作成
- 「名前」にホスト名、「種類」は「CNAME」、「エイリアス」に２．で作成したエンドポイントを入力

#### ５．エンドポイントにカスタムドメインを設定、HTTPSを有効化

- 「エンドポイント」に戻り、「カスタムドメイン」の追加
- 「カスタムホスト名」は４．で作成したホスト名を指定
- 「カスタムドメイン」作成後に、「カスタムドメインHTTPS」を有効化

#### ６．サブドメインの追加

- 手順１のストレージアカウント」及び「静的Webサイト」を追加
- 手順２のエンドポイントを追加
- 手順４のCNAMEレコードを追加
- 手順５のエンドポイントと追加したサブドメインを紐づけ


![bfcf0d61-e770-e6f8-eae2-fb06bf08dd32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188834/f5bf7e1d-3b47-a1b4-5d8d-fb7311e8b914.png)
CarrierWaveをつかったRspecテスト実行後にテストイメージを消去する方法


# はじめに
Ruby on Railsでポートフォリオを作成している、Ruby初学者です。
CarrierWaveで画像アップロード機能を実装されている方も多いかと思います。私もその一人です。
ユーザのアバター設定や投稿時の画像添付などでこのgemを使用しており、各種テストにも確認のためCarrierWaveの画像アップロード機能を含めていました。

ポートフォリオ作成中、テストを何回か回したあと、たまたま画像を保存しているフォルダをみてみると、・・・・**フォルダ数600！？**

全然気づいていませんでした。テストを回せばその分テストケースに含まれている画像アップロードも何度も何度も実行されます。いつのまにか、私のフォルダは画像の容量で逼迫していました・・・

手動で消す事もできますが、テストはリファクタリングや機能追加毎に実行しますし、それだとかなり面倒です。
というわけで、**テスト実行後にテスト用に作られたCarrierWaveの画像を消す**ように設定していきます。

# 環境
Docker内にコンテナを作成してrails開発をしています。

```
Docker for mac 2.3.0.4
Ruby on Rails 5.2.2
ruby 2.4.5
CarrierWave 2.1.0
```

# 答えはCarrierWaveのWikiに
参考にしたのは、CarrierWaveのwikiの以下のページ
[How to: Cleanup after your Rspec tests](https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Cleanup-after-your-Rspec-tests)

これを参考にしながら、以下の流れで消去します。
**１. test時のアップロードフォルダを指定する（uploeaderファイル）**
**２. rspecテストの実行後に、指定したパスのフォルダを全て消去するようにする**

**1.テスト時のアップロードフォルダ指定**
 キャッシュファイルもいくつか生成されるため（エラーチェックのテストケース時に）
 キャッシュとストア両方のフォルダを指定します。

```app/uploaders/***_uploader.rb

:
  #キャッシュのフォルダを指定
  def cache_dir
    if Rails.env.test?
      "uploads/#{Rails.env}/tmp/#{mounted_as}/#{model.id}"
    else
      "uploads/tmp/#{mounted_as}/#{model.id}"
    end
  end

　#storeのフォルダを指定
  def store_dir
    if Rails.env.test?
      "uploads/#{Rails.env}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    else
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  end
:

```




**2.rspecテストの実行後に、指定したパスのフォルダを全て消去するようにする**
 上で指定したキャッシュとストアフォルダを一気に削除するようパスを書く。


```spec/spec_helper.rb
:
  config.after(:all) do
    if Rails.env.test?
      FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads/#{Rails.env}/"])
    end
  end
:
```

これでrspecテストを流す毎に自動的にテスト用フォルダを消去してくれます。


# おわりに
テストを何度も回して、フォルダが大量に出来てしまったり、容量を逼迫することはなくなりましたが、
消去というプロセスがテストに入ったことにより、多少rspecの処理スピードが遅くなってしまった印象。
これはどうしようもないのでしょうが、テスト時に本当に画像アップロードが必要かどうかは見分けて、不要であれば画像なしでfactoriesを作ることも検討した方がいいですね。テストケースの見直しも行いたいと思います。
AppEngineの共有メモリキャッシュのフラッシュの仕方が問題

![スクリーンショット 2020-10-03 22.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39852/95d11955-84ba-8efe-d32c-bf849503747e.png)

AppEngineでは、共有メモリキャッシュを無料で利用できるが、
そのキャッシュサイズの遷移はこの図ようになっている。

共有で無料で使えるからといって、なんで一気にフラッシュするの？

GoogleのAppEngineの開発担当者は、
このフラッシュの仕方が本当に問題ないと思っているのだろうか？

思ってないよね。

キャッシュを消し去った瞬間にバックエンドの負荷がスパイクして、
不具合が生じるのは明白。

インスタンスサイズをもっとあげて課金して、ってことですか？

まじでGoogle性根が腐ってる。
sshトンネルを今さらながらやってみた

# はじめに
恥ずかしながら 5 年目になっても sshトンネルをやったことが無かったのでやってみました。

# 環境
* Windows10
* Git Bash

# sshトンネルとは
sshトンネルは sshポートフォワーディングとも言われており、
ポートフォワーディングは主に ssh を使って行われることが多く、
ssh を使ってポートフォワーディングを行うことを
特に sshポートフォワーディング( sshトンネル)と言うらしいです。(伝われ)

# 実際にやってみる
ssh が実際に出来るサーバを用意します。
何でも良かったので今回は AWS の EC2 で安い Amazon Linux サーバを立てました。

```
$ ssh -i id_rsa.pem ec2-user@203.0.113.1
-> ログインできる
```

次にローカル(Git Bash)で実際にポートフォワーディングをやってみます。

```
$ ssh -L 12345:localhost:80 ec2-user@203.0.113.1 -i id_rsa.pem
```

ローカルでアクセスしてみましょう。

```
$ curl http://localhost:12345
-> 203.0.113.1:80 の中身が確認できる。
```

もし確認出来なければリモートに Apache とか入れてみてください。

# 何が良いの？
ここまでだと AWS のセキュリティで 80 番を開けて
203.0.113.1:80 にアクセスすればローカルで確認出来るため、何が良いのか分からないですよね？
sshポートフォワーディングを行うことで以下のメリットがあります。

* ssh プロトコルを使用することで通信を暗号化出来る。(上記では 80 を経由しています)
* ssh ポートがあればローカルで確認することが出来る。
* 踏み台サーバを経由してリモートアクセスが出来る。

踏み台サーバを経由すると例えば以下のようになります。

```
$ ssh -L 12345:localhost:8080 -L 8080:localhost:9080 ec2-user@203.0.113.1
```

# 参考
[IT用語辞典 ポートフォワーディング](http://e-words.jp/w/%E3%83%9D%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0.html#:~:text=%E3%83%9D%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AF%E3%80%81IP,%E6%8C%81%E3%81%A4%E3%81%9D%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E6%A9%9F%E8%83%BD%E3%80%82)
[RFC5737 - ドキュメント例示用 IPアドレス](https://tools.ietf.org/html/rfc5737)
PHP ~web開発編~

はじめに、
一通り基礎的な事を学び終えたので今日からPHPでweb開発に関する学習をしていきます。
復習も含めて初歩的な事も記事にしてアウトプットしていきたいと思う。
 
# PHPの埋め込み
[解説]
16行目
<?php ** ?>
**の部分のPHPの記述をする事で使える様になります。
17行目
echoした結果を埋め込む時は省略ができます。
echoとphpの記述を削除して＝に変える事で出力可能です。
18行目
こちらは定義した変数を埋め込んでいるだけです。
![スクリーンショット 2020-10-03 17.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/35d1b833-38ea-85eb-660a-0c120387e20c.png)
#  htmlspecialchars()
下記のコードを実行すると、javascriptのalertが出てしまいます。
これを防ぐ為に< > 'などをhtmlspecialchars()を使いただの文字列にします。
![スクリーンショット 2020-10-03 17.21.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/c7861be0-40c7-0fb9-8d66-6b48efc274e3.png)
htmlspecialchars(変数、　変換の為のフラグ（今回は ' も変換させています。）、 文字コード)
![スクリーンショット 2020-10-03 17.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/7c586211-bb55-ffba-0570-31621ddaa9df.png)
VScodeで共有ライブラリのデバッグを行う

C++で作成した共有ライブラリ(.so)のデバッグをVScodeでやろううとしたが,
あまり情報がなく苦労したので記事にしておきます。

### 共有ライブラリの作成
まずはライブラリの作成

```shell
g++ -shared -g -fPIC -o libtodebug.so file1.cpp file2.cpp
```

分割コンパイルする場合は

```shell
g++ -g -fPIC -c -o file1.o file1.cpp
g++ -g -fPIC -c -o file2.o file2.cpp
g++ -shared -o libtodebug.so file1.o file2.o
```
でビルドします. -fPICオプションを入れる必要があります.

### VScodeでデバック
VScodeのデバッグでは, 
デバッグ設定ファイルに共有ライブラリを使用する実行ファイルを起動するよう設定する必要があります。

```json:launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Pythonデバッガ",
            "type": "cppdbg",
            "request": "launch",
            "program": "python",
            "args": [
            "${デバッグ用のPythonファイル名, debug.py}"
            ],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
                }
            ]
        }
    ]
}
```
gdbでデバッグをするプログラムにPythonのプログラムを指定し,
Pythonないで共有ライブラリを読み込み, Pythonから共有ライブラリ内の関数をコールすることで,
gdbでデバッグを行うという形になります.

もちろんPythonでもなくていいのですが,
今回は共有ライブラリをロードして実行する関数が書きやすいPythonを選択しました.

### Pythonプログラムの作成
共有ライブラリをロードして関数をコールするPythonプログラムを書きます.

```python:debug.py
import ctypes

def main():
    sharedlib = ctypes.cdll.LoadLibrary("./libtodebug.so")
    func = sharedlib .SampleFunc
    func.argtypes = [ctypes.c_int]
    func.argtypes = [ctypes.c_int]
    res = func(ctypes.c_int(10))
    print(res)

if "__name__" == "__main__":
    main()
```
こんな感じになります。
私の場合はtkinterでGUIを作成して柔軟にデバッグできる環境を作成しました.
シェルスクリプトの基礎#2

シェルスクリプトの基礎#2

#関数の定義書式
3通りの定義がある。

```shell
function <関数名> ()
{
        処理
}

#かっこを省略した関数定義
function <関数名>
{
        処理
}

#functionを省略した関数定義
<関数名> ()
{
        処理
}
```

簡単な例を示す。
関数名をfunction1とし、処理は現在日付を表示するもの。

```shell
[wataru@localhost work]$ cat shellTest.sh
#!/bin/bash

function1 ()
{
	date
}

function1

[wataru@localhost work]$ ./shellTest.sh
Fri Sep 25 16:46:29 PDT 2020
```
uuidを使用したブラウザバックによる連続投稿への対策

## 概要

入力、確認、完了画面と遷移する、よくあるフォームを作っていて、uuidによるブラウザバック対策を試したのでメモ。
ブラウザバックそのものというよりは、完了から確認画面にブラウザバックして何度も投稿させるのを防ぐことを目的にしている。

## 方針

DBのテーブルに、uuidを保存するカラムを追加する。
すると完了画面の時点でuuidも保存されるが、パラメーターの中に残っているuuidがテーブル内に既に存在する場合は、エラー画面にリダイレクトさせる。

## 実装

### 1. カラム追加

uuidを保存するためのカラムを足す。

```ruby:20201003xxxxxx_add_uuid_to_sample.rb
class AddUuidToSamples < ActiveRecord::Migration[5.2]
  def change
    add_column :samples, :uuid, :string
  end
end
```

### 2. コントローラー


newアクションのタイミングで、uuid を発行しておく。confirm では、キャッシュを保存できないよう no-store を設定。
confirm と create で uuid が既に存在していないかを確認し、存在していればエラー画面に遷移させる。

Cache-Controlの参考
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control

```ruby:sample_controller.rb
before_action :verify_validate, only: [:confirm, :create]

def new
  @sample_form.uuid = ::SecureRandom.uuid
end

def confirm
  response.headers['Cache-Control'] = 'no-store'
end

def create
  if sample_form.save
    redirect_to complete_sample_path
  else
    render :error
  end
end

private

  def sample_form
    @sample_form ||= ::SampleForm.new(Sample.new)
  end

  def verify_validate
    render :new sample_form.validate(params[:sample])
    return redirect_to error_sample_path if Sample.exists?(uuid: sample_form.uuid)
  end
```

### 3. ビュー

最後に、new と confirm に対応するビューに、hidden_fieldを仕込んでおく。
uuid の生成は、newアクションだけで行うようにして、以降は hidden_field でバケツリレーさせる。

```ruby:new.slim
= form_for sample_form, url: confirm_samples_path do |f|
  # 省略
  = f.hidden_field :uuid
  = f.button '確認'
```

```ruby:confirm.slim
= form_for sample_form, url: confirm_samples_path do |f|
  # 省略
  = f.hidden_field :uuid
  = f.button '送信'
```
Azure AD Connect の接続削除方法

# Azure AD Connect を解除する方法

公式ガイドは「[Microsoft 365 のディレクトリ同期を無効にする](https://docs.microsoft.com/ja-jp/microsoft-365/enterprise/turn-off-directory-synchronization)」のDocs。
![AD Disconnect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684720/4e0e0ac3-7153-4761-1dd1-d6559ed94747.png)
テスト等で立ち上げたAD DSを削除できるようになり、Azure ADからもユーザーを削除できるようになります。

- PowerShellのモジュールをインストール

```powershell
Install-Module MSOnline
```
- ログイン (資格情報の獲得)

```powershell
Connect-MsolService
``` 

- 同期解除

```powershell
Set-MsolDirSyncEnabled -EnableDirSync $false
```


## 参考
- Azure AD Connect の強制差分同期

```powershell
Start-ADSyncSyncCycle -PolicyType Delta
```
【初心者でもわかる】疑似要素にも下線がついてしまう時に下線を消す2つの方法

# どうも7noteです。疑似要素にも下線（_）がついてしまう時の対処法2選

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

https://naruweb.com/coding/underline-delete/
herokuにてNo application encryption key has been specified.が出た時の対処法

*Laravel環境です。

<h1>原因</h1>
APP_KEYが設定されていないことが原因です。
まずLocalでAPP_KEYを生成、その後herokuにkeyを登録すると動きます。

<h3>1.keyの生成</h3>
下記コマンドを入力
<pre>php artisan key:generate --show</pre>

<h3>2.herokuにkeyを登録</h3>
生成されたkeyを下記コマンドでherokuに登録します。
<pre>heroku config:set APP_KEY=<生成されたkey></pre>

以上です。
AppleScriptを使ってSafariをイジって見よう

#はじめに
最近[ラムダさんの動画]()でAppleScriptの存在を知って少しイジって見たのですが、少し調べるのが大変だったので忘れないように記事にして残します。
※この記事には**半沢直樹要素**が出てきます。

#AppleScriptの始め方
AppleScriptには特に**環境構築**は必要ありません。プログラムの作成と実行は**スクリプトエディタ**を使います。アプリの開き方はcommand + スペースを押してスポット検索を開き"AppleScript"ぐらいまで入力するとアプリが出てくるので開いて下さい。開くとこんな感じのウィンドウが開きます。![スクリーンショット 2020-10-02 17.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/e3257ebf-c2d5-13cf-d138-b07bdc1f8813.png)

#AppleScriptを適当にイジってみる
ディスプレイダイアログを表示される

```applescript
display dialog "Hello World"
```
これを▶️を押すと次の写真の様に表示する事ができます。
![スクリーンショット 2020-10-03 20.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/7058317f-c370-d86e-5dfa-c025b9442894.png)

次はsafariを自動で立ち上げて見ましょう！

```applescript
tell application "Safari"
	activate
	open location "https://qiita.com/"
end tell
```
画像の様にsafariを開き特定のサイトを開かせる事に成功しました。
![スクリーンショット 2020-10-03 20.50.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/1ccdaed6-632a-7eff-b452-06006bee0f43.png)
#AppleScriptで半沢直樹
```applescript
repeat
	
	display dialog "" buttons {"親が自分の部屋に来た", "面倒な事を頼まれた", "閉じる"} default button 3 with icon note
	copy the result as list to {ret}
	
	if the ret is "親が自分の部屋に来た" then
		tell application "Safari"
			
			open location "https://www.youtube.com/watch?v=QTkop65FLYM"
			delay 2.5
			close tab 1 of window 1
			open location "https://www.youtube.com/watch?v=hJBZkO0YFws"
			delay 4.0
			close tab 1 of window 1
			quit
		end tell
	else if the ret is "面倒な事を頼まれた" then
		tell application "Safari"
			open location "https://www.youtube.com/watch?v=IXUGjCl_Xvs"
			delay 5
			quit
		end tell
	else if the ret is "面倒な事を頼まれた" then
		tell application "Safari"
			open location "https://www.youtube.com/watch?v=IXUGjCl_Xvs"
			delay 5
			quit
		end tell
	else if the ret is "閉じる" then
		exit repeat
	end if
	
end repeat
```
![スクリーンショット 2020-10-03 20.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/074d3a07-b566-b709-ccfa-65e5491c15bb.png)

このプログラムを起動すると上のスクショの様なディスプレイダイアログが表示されます。親が自分の部屋に来たや面倒な事を頼まれたなどを押すとYouTubeのリンクに飛んでセリフを再生させたのちに自動でsafariを閉じてくれます。またYouTubeのリンクを変えると違う動画も再生できるので、変えてみると面白いかも知れません。
【3D OD LiDAR編】SECOND : Sparse Convolutionで高速化

<h1>SECOND: Sparsely Embedded Convolutional Detection</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ca557f95-571e-1edc-0353-b70b8d49d8cd.png)


[VoxelNet](https://qiita.com/minh33/items/9f13bb51da4aa8b5a727)とほとんど同じなSECOND。
違う点だけを見ていきたいと思う。
1. Feature Learning Network => Voxel Feature and Coordinate + Voxel Feature Extractor
2. Convolutional Middle Layers => Sparse Conv Layer
3. Region Proposal Network => Region Proposal Network

<h1>新規性</h1>
<h2>Sparse Convolutional Middle Extractor</h2>
VoxelNetではConvolutional Middle Layersと呼ばれていた、3Dを2Dに畳み込む処理。
Sparse Convolutionを採用する事で高速化。

*Sparse Convolutionの詳細は別記事で追記


<h2>Region Proposal Network</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/e6076400-6140-bdf9-41c1-77c647145461.png)

2D Object Detectionの話だから軽く流すが、Multi ResolutionでLocalとGlobalの特徴量を得られる構成にした。


<h1>Sine-Error Loss for Angle Regression</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3ae68c8d-8dfd-4b55-3543-3e4047f866d2.png)
角度のlossを計算する時0とPIで同じ角度を示すのに、値としてジャンプしてしまうのでsinやcosで解決しましょうっていう、よくあるやつ。


<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/8678b078-9470-aa3a-2815-d366973513b0.png)
スピ-ドはSparse Convolutionalを3D=>2Dの畳み込みに採用し向上
精度は角度のlossにsinを使ったことと、2DのDetectionをMulti Resolutionにしたことによって向上
って感じかな〜。

<h1>結論</h1>
・VoxelNetを踏襲しつつ、精度も速度もシンプルな変更で上げていた。

<h1>参考文献</h1>
SECOND: Sparsely Embedded Convolutional Detection
https://pdfs.semanticscholar.org/5125/a16039cabc6320c908a4764f32596e018ad3.pdf
Windows10にWin-Kex(kali-linux)を導入する。

Windows10にWin-Kex(kali-linux)を導入することになったので、
自分がした作業を記す。

環境
Windows10
wslでubuntuをインストール済だった。(これにより、もしwslを使ったことがない人に必要な設定をしていた可能性があるので、手順に抜けがあればすいません。)
wslを使用可能な状態にするのは、他の記事を探してみてください。

流れ
1.kali-linuxをWindows Storeからインストール
2.wslで動作するのでwsl2に変更する
3.win-kexをインストール

となります。

1.kali-linuxをWindows Storeからインストール
Windowsを押して検索にstoreと打ち、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/4a21860f-5809-3aaf-14aa-c1865cc1e0aa.png)

kaliと検索し、画像のものをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/d18de200-1c79-d740-8cc7-0447492f3cf9.png)

インスコがおわると、kali-linuxがアプリに追加されてるので検索して起動（Windowsを押して検索にkaliと打つ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/ebb0de1e-a25d-7e9f-9d9b-21242c4aaaab.png)

クリックして起動。
コンソールが立ち上がると、
ユーザ名とパスワードの設定が求められますので、
各自設定してください。
(これはkali-linuxのユーザとパスワードの設定ですので、
windowsのユーザとは関係ないです。)
これでインストール完了。

2.wslで動作するのでwsl2に変更する。
win-kexを使うためにwsl2に変更が必要なので、やっていきます。
まずwsl2にするために必要なものをmicrosoftからDLします。
やりかたは↓の通りなのですが、説明していきます。
https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-2---update-to-wsl-2

まず、必要な機能で無効になってるものを有効にしていきます。
windowsキーをおして、機能と入力すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/58887209-73b8-a65d-6323-a49a97ca3b2a.png)
これがでてくるので、押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/96f5adaf-477b-922c-47f4-b6eaf242354c.png)
windowsハイパーバイザープラットフォーム
仮想マシンプラットフォームを有効にします。
を有効にします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/d92989e5-da20-3390-7177-d782c68eb691.png)
上の画像にあるリンクをクリックしてインストールします。

次にコマンドでwslをwsl2にします。
windowsキーをおして、cmdと打ちエンターでコマンドプロンプトを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/0d7e9888-4c00-9a85-3a80-a689374af34e.png)

kali-linuxがあることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/520a7324-d6d0-92ca-6c39-771c1dc2ea65.png)
上の画像のようなコマンドをうち、wsl2に変更が終わります。

ここで、この変更には1時間から2時間かかりますｗｗｗ
しかも、何％との表示はなく、ただしたの2行が出るだけなので、
とても不安になります。気長に別のことしながら待ちましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/be04d9ed-b95f-fd5b-7f44-d8ad1fce70ee.png)
変換が完了しましたがでれば一安心です。


ようやくWin-Kexのインストールです。

やりかたは下のリンクのとおりです.
https://www.kali.org/news/win-kex-version-2-0/

kali linuxで
sudo apt upgradeして
sudo apt install -y kali-win-kex
でインストール完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/73aa1117-e28e-d35d-92d3-37a8aff05ea6.png)

あとは
kali linuxで
kex
とうてばウインドウが起動します。
エラーが出たりするときは
kex killや
kex stop
してまた、
kexすればだいたいなんとかなります。

Win-Kexから帰ってくるには
F8を押して一番上のメニューを押せば帰ってこれます
焦らないように
SCIM(System for Cross-domain Identity Management) 概要

SCIMの概要をまとめる。

## SCIMとは

* **S**ystem for **C**ross-domain **I**dentity **M**anagementの略称。
* IDプロビジョニング(複数システム/サービス間でIDの整合性を保てるように管理する)のためのスキーマとプロトコルを定義した仕様。
  * スキーマ：リソース(ユーザーやグループなど)のJSON表現。拡張可能。
    ![SCIM_resource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/a5adc388-b8b7-2bd0-783f-f2e67e65c8d0.png)

  * プロトコル：RESTful API、CRUDなど 
  ![SCIM_concept.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/e2a1977c-ec45-5ee8-9cb0-55c08468918a.png)




### SalesForce ユーザー情報取得例

* リクエスト

```http
curl -i -X GET \
   -H "Authorization:Bearer {access_token}" \
'https://{salesforce_org_url}/services/scim/v2/Users/{user_id}'
```

※アクセストークンはOAuth 2.0 JWT ベアラーフローなどで事前取得すること。

* レスポンス

```json
{
    "schemas": [
    	"urn:ietf:params:scim:schemas:core:2.0:User", // 属性定義
        "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
    ],     
    "id": "0123456789xxxxxxxx",
    "userName": "tanaka.taro@freedom-man.com",
    "externalId": "SSO12345",
    "name": {
        "formatted": "TANAKA TARO",
        "familyName": "TANAKA",
        "givenName": "TARO"
    },...
}
```

## SCIM 標準スキーマ

| 属性       | 説明                                                         |
| :--------- | :----------------------------------------------------------- |
| id         | サービスプロバイダが定義するSCIMリソース識別子               |
| externalId | プロビジョニングシステムが定義するリソース識別子 |
| meta       | リソースのメタ属性。リソースタイプ、リソース作成日時など。                                           |

## SCIM 対応HTTPメソッド

| メソッド | 説明                                                 |
| :------- | :--------------------------------------------------- |
| GET      | SCIMリソースを取得・検索する。 |
| POST     | SCIMリソースを登録する。                                 |
| PUT      | SCIMリソースを更新する。全属性更新。                     |
| PATCH    | SCIMリソースを部分的に更新する。                         |
| DELETE   | SCIMリソースを削除する。                                   |



## 認証・認可

* OAuth2.0 Bearerトークンの使用を推奨

  

## 参考情報

* [SCIM 2.0 の仕様](http://www.simplecloud.info/#Specification.html)
* [SAML / OpenID Connect / OAuth / SCIM 技術解説 - ID&IT 2014 #idit2014](https://www.slideshare.net/matake/idit-2014/47)
* [System for Cross-Domain Identity Management (SCIM) の使用](https://help.salesforce.com/articleView?id=identity_scim_overview.htm&type=5)
* [OpenID ConnectとSCIMの標準化動向](https://www.slideshare.net/tkudo/openid-connect-and-scim-overview)
* [SCIM スキーマ定義](https://tools.ietf.org/html/rfc7643)
世界中のコロナのデータをグラフで見れるWebアプリを作成し、それによりAPIの見え方が変わったときの話

#初めに
皆さんはプログラミングの学習や個人開発をどのように楽しんでいるでしょうか？
この記事では、自分があるAPIを使って作ったWebアプリの紹介とそこで使用したAPIを通して自分が感じたことについて扱っていきます。

#自分が作成したWebアプリ
[Corona Report Made by a Failure](http://crmf.s3-website-ap-northeast-1.amazonaws.com/)
トップ画面はこんな感じです。
![CRMF.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478883/501827d8-df73-032a-a877-eaed99ab99e7.jpeg)
ちなみにこのWebアプリのGithubのリポジトリはこちらです。もしこのWebアプリの機能について気になるのであれば、見てみて下さい。
[https://github.com/santooooooo/CRMF](https://github.com/santooooooo/CRMF)

##作成に用いたツールたち
- プログラム言語
    - TypeScript(3.9.3)　⇒Javascriptより後から見返した時の理解が楽そうだから
- フレームワーク
    - Vue.js(2.6.11)　⇒今学んでいるから。
- API
    - [covid19api](https://covid19api.com/) ⇒導入理由は無料で簡単に利用できるから。内容は後に記載。
- その他
 - Chart.js(2.9.3) ⇒簡単に棒グラフや折れ線グラフなどのグラフがアニメーション付きで作成できるから。
 
##機能

- 世界全体のコロナの一日の新規感染者数、新規死者数、新規回復者数とこれまでの感染者数、死者数、回復者数がわかる。
- 一日の新規感染者数、新規死者数、新規回復者数とこれまでの感染者数、死者数、回復者数のそれぞれの分野ごとでの上位10か国の名前とその数がわかる。
- 世界各国の一日の新規感染者数、新規死者数、新規回復者数とこれまでの感染者数、死者数、回復者数がわかる。
- ユーザーが設定した期間の間の世界各国の一日ごとの新規感染者数、死者数、回復者数、コロナにかかっている状態が続いている人の数を折れ線グラフで見ることができる。
![CRMF-chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478883/7a80c380-8ddb-680d-65fc-8da07b2c924e.png)


##こだわり
ユーザーが好きに期間を設定し、その期間のデータをグラフで表示できるように実装しました。また、今回使用したAPIはコロナについてのいろいろな側面のデータを提供してくれていたので、それらを余すことなくユーザーへ伝えられるようなデータの表示を心掛けました。

#使用したAPIについて
##APIの概要
今回使用したAPIは[COVID19 API](https://covid19api.com/)というもので、Kyle Redelinghuysさんという方が今年の3月（本人のTwitterより）に作られたもので、現在もその方が運営しているAPIです。このAPIでできることは、主に`世界各国の感染者数、死者数、回復者数の一日当たりの数又はそれらの現在まで累計値を取得すること`ですが、料金プランによっては一つの国の100万人当たりの感染者数や10万人あたりの感染者率なんかも取得することができます。
このAPIは無料で使用できますが、それだとたびたびデータが送られてこない場合があるので、お試しで触る場合は無料のバージョンを使い、本格的に使用する場合は有料の物を使うことを個人的にはお勧めします。（料金プランは月`$10`、`$30`、`$100`から選べます。）
月`$10`を使っての感想なのですが、このAPIのデータの正確性はあまり高くないと思っています。運営側もデータの誤りやコード上のバグを頑張って修正しているようですが、データの中には値があまりにもおかしいものもあったりするので、他のデータと見比べながら使用することをお勧めします。

##このAPIに触れる中で感じたこと
このAPIの質問、バグの修正等のリクエストはslackのチャンネルを通して行っているのですが、（いろいろな事情があり、Githubでこれらのことは行っていないそうです。）それらの中に`showcase`というチャンネルがあります。そのチャンネルでは、みんながこのAPIを使ったアプリケーションを発表しあい、また他の人からの反応をもらうことができます。

**自分が実際にこのチャンネルで自分のWebアプリを発表しているところ**
![CRMFQiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478883/69ef1953-e8de-6e96-c7ee-cabc5d9bae10.png)
(自分が発表したWebアプリに対してGoodをもらった。たかだか一つであるが、自分が作成したものに対して人から反応をもらえる機会の少ない自分にとっては貴重なもの。)

このAPIに触れて良かったと感じていることは、ただバックエンドの作成をせず手軽にWebアプリが作成できただけではなく、このチャンネルのように自分が作成したものに対し他の人から反応をもらえる場所と機会を得ることができたということです。日々の学習では他人からの反応をなかなか得にくいので、他の方から反応がもらえた時はうれしく感じると共に今後の学習に向けての意欲が湧きました。


#終わりに
今まで自分はAPIに対してただ便利な機能を提供してくれるものとしか見ていませんでしたが、このAPIを通して、APIは便利な機能を提供してくれるだけではなく自分のプログラミングに対するモチベーションを大いに上げてくれるものでもあるということを体感することができました。
今後も様々な人が提供してくれているAPIを使ってどんどん個人開発をしていこうと思います。
LaTeXでゴシック体を指定してもアルファベットや数字がゴシック体にならない

# 問題
LaTeXで`\gtfamily`や`\gt`を用いて文章をゴシック体にすると数字とアルファベットがなぜかゴシック体にならない．

# 環境
e-pTeX, Version 3.14159265-p3.8.1-180518-2.6 (utf8.sjis) (TeX Live 2018/W32TeX) 

# 解決
`\textsf{}`を用いる．
【GAS】「for文」いろいろ①for, for...of, for...in

##概要
for文と言えば `for(i=1; i<=10; i++){` みたいなのだと思っていたけど、何やら種類があるらしい・・・。

「for文」「for...of文」「for...in文」「forEach文」とまとめたところ、長くなったので①②に分割。

##ただのfor文
いつもの見慣れたやつから。

```javascript
function minaretaYatsu() { 
   
  for(var i=1; i<=5; i++){ 
    Logger.log(i); 
  } 
   
  for(var j=1; j<=5; j++){ 
    i = j * 5; 
    Logger.log(i); 
  } 
   
}
```
`for(var i=1; i<=5; i++){`すなわち、i=1 から i が 5 以下の間 i に 1 ずつ足しながら繰り返す。結果はこの通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/32e42511-2fe9-eccf-4429-5fda82df938c.png)
１つ目の繰り返しで、1～5までを出力。２つ目では、それぞれを５倍して出力している。

後に出てくるfor文と違い、繰り返しの中で条件に干渉できる。
例えば、２つ目の繰り返しで、`i=j*5` を `j=j*5` にすると、１周目で j が 5 になるので２周目に突入できない。他にも、breakやcontinue、returnなどとても便利。

**※この後に出てくる他のfor文は中断できない。**
やっぱりfor文、そこにシビれる！あこがれるゥ！
##for...of文
例として１～５が入った配列を用意。

```javascript
function forOf() { 
   
  var array = [1, 2, 3, 4, 5]; 
   
  for(var i of array){     
    Logger.log(i);     
  } 
   
  for(var j of array){     
    j = j * 5;     
    Logger.log(j);     
  } 
   
}
```
配列の要素を順番に、任意の変数へ与えてくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/0d88db2c-62fb-e2a4-43d6-ee78b1f14b4c.png)
この場合、結果だけ見ればただのfor文と一緒だけど、要素の数だけ繰り返すため終了条件を気にしなくて良いのが素敵。
##for...in文
for...of文の時と同じ配列に使ってみると・・・

```javascript
function forIn() { 
   
  var array = [1, 2, 3, 4, 5]; 
   
  for(var i in array){ 
    Logger.log(i); 
  } 
   
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/5414b2f3-0973-db20-0436-0ec69205d203.png)
各要素のインデックスが・・・何か使い道があるんだろうか？良く分からん。

そうではなくて、連想配列に使ってこそのfor...in文！

```javascript
function forIn() { 
   
  var obj = {first : 1, 
             second: 2, 
             third : 3, 
             forth : 4, 
             fifth : 5} 
   
  for(var key in obj){ 
    Logger.log(key); 
    Logger.log(obj[key]); 
  } 
   
  for(var i in obj){   
    i = obj[i] * 5; 
    Logger.log(i)    
  } 
     
}
```
なんと、連想配列の中身が得られる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/7f125479-8704-c6bb-f880-48f144b29111.png)
任意の変数に「キー名称」、`配列名[変数]`で「値」が、それぞれ与えられる。
２つ目の繰り返しは、得られた値を５倍している。
##つづく
[**「for文」いろいろ②forEach～３つの引数～**](https://qiita.com/YasumiYasumi/items/22919507dc440572806a) へ続く...
【意外とハマる！】Rubyの過去バージョンをインストールする際の注意点

こんばんは
アロハな男、やすのりです！

アプリケーション作成をする上で、『どうしても過去バージョンのRubyでの作業が必要だ！』っていう時がきてしまうのではないかなと思います。
(実際自分もチーム開発をやるかもっていう段階になった時に過去バージョンのRubyが必要になりました...:sweat_smile:)

しかし、実際に過去バージョンをインストールしようとしたらうまくいかずに意外と時間がかかってしまったので、同じ様な状況になった人用と未来の自分用に書いておこうと思います！！

# 欲しい過去バージョンが出てこない！？
現状 2.6.5 のバージョンが入っているため、 2.5.1 をインストールするために

```
rbenv install --list
```
を実行したところ、

![スクリーンショット_2020-10-03_19_37_52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/3929906d-6eef-f72c-6517-1af8cda5ab3e.jpeg)

あれ...なんで 2.5.1 のバージョン出てこないの！？
と、混乱してRubyのホームページ行ったりといろいろしてみた結果...答えはすぐそこに転がっていた！！
![スクリーンショット_2020-10-03_19_37_52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/f22800c0-a2c3-f2c7-4dec-5fe32ae0e8d7.jpeg)
はい、見てもらうとわかるんですが...
『全てのバージョンを見るなら --list-allオプション使ってね。』
と...書いてました...親切にも:joy:

混乱したら一旦落ち着く、これがとても大事だということを身をもって体感しました。

# 改めて過去バージョンを表示する
さて、気を取り直して過去のバージョンを表示させましょう！！
さっき確認したオプションをつけて

```
rbenv install --list-all
```
を実行すると...
![スクリーンショット_2020-10-03_19_39_00-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/90640572-b3b0-39db-a3ff-9e130c1666bf.jpeg)
出ました！！
一時はどうなるかと思いましたが、なんとか欲しかった 2.5.1 のバージョンも見つかって一安心です。

そして最後に

```
rbenv install 2.5.1
```
を実行すれば、
![スクリーンショット_2020-10-03_19_39_25-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699622/ee53ef74-94d5-d18a-09dd-6a320e5b2d54.jpeg)
はい！！
正常にインストールされました！！
これにて一件落着ですね:laughing:

# 結論
ハプニングが起きても焦らず状況確認をしっかりしましょう！！
[Java]Object型のnullをString型に変換

##[Java]Object型のnullをString型に変換

Object型で取得した値をString型に変換する必要があって
toString()、String.valueOf()、キャスト変換などなど
変換する方法はいくつかあるけど違いあるのかな？となり、
そして一番気になったのは取得したObject型の値がnullの場合、
エラー起きちゃったりしないかなーって思って調べてみた。
先に結果を先に載せると…

#####【Object型のnullをtoString(),String.valueOf(),キャスト変換で変換】
|toString()|String.valueOf()|キャスト変換|
|:-----:|:-----:|:-----:|
|NullPointerException|文字列"null"|null|
<br>
下記プログラムで確認してみると、

```java:test.java
public static void main(String[] args) {
	Object testNull = null; // Object型null作成
	String testNullString1 = testNull.toString(); // toString()による変換
	String testNullString2 = String.valueOf(testNull); // String.valueOf()による変換
	String testNullString3 = (String) testNull; // キャスト変換

	// 各変換した値をMapに格納
	LinkedHashMap<String,String> map= new LinkedHashMap<>();
	map.put("toString()",testNullString1);
	map.put("String.valueOf()",testNullString2);
	map.put("キャスト変換",testNullString3);

	// 各変換結果を出力
	for(Map.Entry<String, String> mapString : map.entrySet() ) {
		if(mapString.getValue() == null) {
			System.out.println(mapString.getKey() +" で変換すると null になる。");
		}else if(mapString.getValue().equals("null")) {
			System.out.println(mapString.getKey() +" で変換すると 文字列の\"null\" になる。");
		}else {
			System.out.println(mapString.getKey() +" で変換すると その他の何か になる。");
		}
	}
}
```

```:実行結果1
Exception in thread "main" java.lang.NullPointerException
	at Test_CastNull.main(Test_CastNull.java:11)
```

toString()変換で"NullPointerException"発生。toString()は使わないのが無難のよう。
そして、上記テストコードのtoString()のとこをコメントアウトして改めて実行。

```:実行結果2
String.valueOf() で変換すると 文字列の"null" になる。
キャスト変換 で変換すると null になる。
```

となり、当たり前ながらnull(になりえるやつ)の扱いには注意が必要ですね。