OmniAICreator/Qiita-1.07M huggingface dataset:
駆け出しエンジニアのポートフォリオに役立つ！ Railsプロジェクト6選

#はじめに
はじめましての方ははじめまして、そうでない方もはじめまして。

数ヶ月前にエンジニア転職に成功したTyo_Doと申します。

私のこれまでのストーリーについては
[【完全保存版】5万円でエンジニア転職してみた。未経験から自社開発エンジニアに転職するまでのロードマップ。](https://qiita.com/Tyo_Do/items/72778ef60103a5c05d51)という記事を読んでいただければと思います。
ありがたいことに多くの方から反応をいただきました。

今回は、エンジニアとして転職・就職するのに
とても重要な**『ポートフォリオ』に役立つRailsプロジェクト**を6つ紹介します！

料理人を目指す人が包丁を握って料理しまくるのと同じで、とにかく手を動かしてコードを書きまくりましょう。

これから紹介するプロジェクトを使い倒して、実際のアプリケーション、ゲーム、サイトなどを作りながら学んで、
実践的なスキルを磨いていきましょう！

# これから紹介するプロジェクトに必要な知識

- HTML/CSS/Javascriptの基礎
- Rubyの基礎文法

これらの知識については入門書を読むのも良いと思いますが、 定番の『Progate』でささっと学習するのもオススメです。
1ヶ月で税込¥1078円。破格です。

https://prog-8.com/

# 1.ドラクエ風コマンドラインアプリを作る
https://www.techpit.jp/courses/6
####作るもの
コマンドライン上で動くシンプルなプログラムを作ります。攻撃したり、経験値をためたりすることができます。
####感想
ドラクエを再現してるので、楽しく作れます（完成物はシンプルですが）。
価格は現在¥1,280です。

# 2.メモアプリを作る
https://www.udemy.com/course/rails-hack/
####作るもの
ブラウザ上で動くシンプルなメモアプリを作ります。
####感想
私自身、元々は動画よりテキスト派だったのですが、最近は動画の良さにも気づき始めました。
HTML/CSSの講座も含まれているので、基礎が身についている方は飛ばしてしまっても良いと思います。
丁寧に解説してくれているので挫折せずに作れると思います。これで作り上げることの達成感を味わいましょう。
価格は¥24,000です。セールを狙いましょう。

# 3.社会の窓が空いていることを匿名で通知するメールサービスを作る
https://www.techpit.jp/courses/17
####作るもの
メールアドレスを打ち込むと匿名でメールが送信されるサービスを作ります。
####感想
タイトルに惹かれました。シンプルで学習量も多くないのでささっと作れると思います。
価格は¥980です。

# 4.ミニQ&Aサービスを作る
https://www.udemy.com/course/the-ultimate-ruby-on-rails-bootcamp/
####作るもの
Q&A投稿サービスをRuby on Rails 5で作ります。 質問や回答の投稿、編集、削除から一覧ページまで一通り作ります。
####感想
動画見ながら作りたい！という人にはうってつけです。 講師の声もはっきりしていて理解しやすいです。
価格は¥16,800です。これもまた、セールを狙っていきましょう。

# 5.掲示板を作る
https://www.udemy.com/course/rails-kj/
####作るもの
削除機能、タグ機能など一通りの機能を備えた掲示板を作ります。
ログイン、ログアウトなどユーザー認証機能まで実装できます。
####感想
基本的なデータベース、SQLの知識があるとよりスムーズに作れると感じました。
こちらも、動画見ながら作りたいという方にオススメです。
価格は¥10,800です。
# 6.Instagramを作る
https://www.techpit.jp/courses/2
####作るもの
Instagramの一通りの機能（プロフィール、画像アップ、いいね、コメントなど）を備えたものを作ります。
####感想
結構、量が多いのでやりごたえがあります。
その分、本格的なものを作れるのでインパクトも大きいと思います。

#さいごに
最後まで読んでいただきありがとうございました。

今回は、UdemyとTechpitからポートフォリオの成果物として役立ちそうなプロジェクトをピックアップしてみました。
他にもオススメなプロジェクトがあれば、ぜひ教えてください！
(Youtubeに英語だけど色々ありそうです)

これらのプロジェクトをこなすのは一見時間がかかりそうですが、環境構築の説明など重複している部分もあるので、
意外とスムーズに作りまくれると思います。

最初はほぼ写経みたいな感じになってしまうかもしれませんが、 何度も繰り返しているうちにだんだん書けるようになります。
作ったプロジェクトを自分なりに改善してみることで付加価値を付けられれば、最強です。


私もまだまだ未熟ですが、この記事を読んでエンジニア転職に成功する人が一人でもいてくれると嬉しいです。もしよろしければ**LGTM**してくれると喜びます。

それでは早速、ガンガン手を動かしていきましょう！

####今回紹介させていただいたサービス

- [Progate](https://prog-8.com/)
- [Udemy](https://www.udemy.com/ja/)
- [Techpit](https://www.techpit.jp/)
Azure仮想マシン作成時にOSディスクのサイズを小さくする方法

# 結論

Windows Server 2019 の場合、仮想マシン作成時に[smalldisk]付のOSイメージを選択すると上手くいきます。

# 背景

AzureでWindows Server 2019 の仮想マシンを作成する際、OSディスクは12か月間無料で使えるP6のサイズにしようと考えました。

しかし、通常のステップで仮想マシンを作成すると、OSディスクのサイズを選択するステップが現れず、作成完了した仮想マシンのOSディスクを確認するとサイズがP10になっています。

後からサイズを変更しようとしても、「ディスクのサイズは拡張はできても縮小はできない」と言われてしまいます。

# 対処

調べてみると、Windows Server 2019 のOSイメージには[smalldisk]という接頭辞が付いたものがあり、これを使って新規作成すれば良いという情報がありました。

実際にやってみると、OSディスクのサイズがP4になっています。これで後からP6に変更できる状態になり、無事解決しました。

# 付記

Windows 10 の場合は[smalldisk]のOSイメージが無く、試しに作ってみたらOSディスクのサイズがP10になっていました。
Windows 10 でOSディスクのサイズをP6にする方法は調べていません。
【Swift】なんで流行っていないんだ？？便利ライブラリ Instantiate

# どういうことか

とても汎用性があって便利なのになぜかあまり使っている記事を見ない。

**Instantiate**
<https://github.com/tarunon/Instantiate>

## なにが便利か

例えばNavigation遷移する際に書くこんなコードが

```swift
let storyboard = UIStoryboard(name: "NextViewController", bundle: nil)
let vc = storyboard.instantiateViewController(identifier: "NextViewController")

self.navigationController?.pushViewController(vc, animated: true)
```

こう書ける

```swift
let vc = NextViewController.instantiate()

self.navigationController?.pushViewController(vc, animated: true)
```

## どう使うのか

まずライブラリをインストールする。
それから、ここで言う `NextViewController` の場合

```swift:NextViewController.swift
import UIKit
import Instantiate
import InstantiateStandard

class NextViewController: UIViewController, StoryboardInstantiatable {
    // 略
}
```

あとは

- ViewControllerの名前とStoryboardの名前を**同じ名前にする**必要がある
- Storyboardの `Is Initial View Controller` に忘れずチェックをする

**【Swift】ライブラリ Instantiate を使用した際のエラー "Fatal error: Unexpectedly found nil while unwrapping an Optional value"**
<https://qiita.com/antk/items/24dc77347e12f2b63bac>

詳しくはドキュメントを見てください（ドキュメントに載っていないこともあるんですが）。

おわり(´・ω・｀)
Railsチュートリアル第8章　〜基本的なログイン機構まとめ(後半)〜

# はじめに
この記事は[Railsチュートリアル第8章 〜基本的なログイン機構まとめ(前半)〜](https://qiita.com/Atie/items/7fa51ffb3344c4f3af8c)の後半の記事です。まだ見ていない方はそちらをご覧ください。
また今回はレイアウトに関してはまとめていません。

[Ruby on Railsチュートリアル第8章](https://railstutorial.jp/chapters/basic_login?version=6.0#cha-basic_login)
[Ruby on Railsチュートリアル](https://railstutorial.jp/)
# ログイン
無効な値の送信をログインフォームで正しく処理ができるようになったので実際にログイン中の状態で有効な値の送信をフォームで正しく扱えるようにします。

**ポイント**

- ここではセッションを実装するためにモジュール機能を読み込ませる

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper #インクルード(読み込み)をする
end
```

これで前回生成されたSessionsコントローラーのモジュールをRailsの全コントローラーの親クラスに入れることができたので、
どこでも使えるようになった

## log_inメソッド
``session``メソッドはハッシュのように扱えるので以下のように代入する。

```ruby
session[:user_id] = user.id
```

**ポイント**
この特殊な代入方法を覚えておく

##現在のユーザー
ユーザーIDを一時セッションの中に安全におけるようになったので、今度はそのユーザーIDを別のページで取り出すことにする。
そのために``current_user``メソッドを定義する。
このメソッドの目的は埋め込みruby(erb)で次のようなコードを書くため。

```erb
<%= current=user.name %>
```
また次のようなコードでプロフに簡単にリダイレクトできるようにする。

```ruby
redirect_to current_user
```

``current_user``を次のように定義します。

```ruby
def current_user
  if session[:user_id]
    User.find_by(id: session[:user_id])
  end
end
```
このコードは更に簡潔にして多少重複が生まれますが結果的に以下のようなコードにします。

```ruby:app/helpers/session_helper.rb
module SessionsHelper

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end

  # 現在ログイン中のユーザーを返す（いる場合）
  def current_user
    if session[:user_id]
      @current_user ||= User.find_by(id: session[:user_id])
    end
  end
end
```

# さいごに
今回は重要であると思われるところに限ってまとめてみました。

## 参考文献
[Ruby on Railsチュートリアル](https://railstutorial.jp/)
New Relicを用いてバッチ処理をモニタリングできるようにする

# 背景

私は普段、New Relic APMを利用してアプリケーションの監視をしています。WEBアプリケーション側についてはAPMを有効にすることですぐに監視することができます。ちょっと工夫した取り組みとしては[APMのカスタム属性にアカウント情報を付与](https://qiita.com/dododo8m/items/33c680ce953c0ca59ff8)してアカウント単位でのApex算出などもやったりしました。
一方でバッチ処理などWEBトランザクションから切り離されているものについてはAPMを用いた監視が出来ていませんでした。

# バッチ処理のモニタリング方法

[New Relic APMの整理の仕方](https://docs.newrelic.com/jp/docs/apm/transactions/intro-transactions/monitor-background-processes-other-non-web-transactions/)としてバッチ処理などは `非ウェブトランザクション` という名目で取り扱います。非ウェブトランザクションの説明としては以下のとおりです。

```
非ウェブトランザクションは、ウェブトランザクションではないトランザクションです。当社では、トランザクションがウェブリクエストによって開始したかどうかは検知しません。メッセージの手続きやバックグラウンドタスクなど、ウェブリクエストを扱わないプロセスやジョブも、非ウェブトランザクションに含まれます。
```

非ウェブトランザクションをnew Relic APMでモニタリングするためにはcustom instrumentationの設定を行う必要があります。各言語ごとにそれぞれやり方があります。私の運用しているサービスはRubyで書かれているので、ここで紹介するのはRubyでの設定方法になります。

以下は[公式のサンプル](https://docs.newrelic.com/jp/docs/agents/ruby-agent/background-jobs/monitor-ruby-background-processes/)です

`SalesOrganization#find_new_leads` がコールされたときに非ウェブトランザクションとしてモニタリングするように設定されています。重要な点としては以下の3点です。

1. `ControllerInstrumentation` モジュールをincludeします
2. `add_transaction_tracer` にてfind_new_leadsをモニタリング対象とします。
3. `:category => :task ` とすることで非ウェブトランザクションとして指定します

```ruby
require 'newrelic_rpm' 

class SalesOrganization
  include 
::NewRelic::Agent::Instrumentation::ControllerInstrumentation 
  def find_new_leads 
    ... 
  end 
  add_transaction_tracer :find_new_leads, :category => :task 
end
```

# カスタム属性としてアカウント情報を付与

[こちら](https://qiita.com/dododo8m/items/33c680ce953c0ca59ff8)の資料でも紹介しているようにWEBトランザクションのモニタリングについてはアカウント情報を付与して、アカウント単位での分析ができるようにしています。今回のケースも同様にカスタム属性としてアカウント情報を付与するようにしました。

やり方はWEBトランザクションと同様で `add_custom_attributes` にアカウント情報を追加することで実現可能です。

```ruby
require 'newrelic_rpm' 

class SalesOrganization
  include 
::NewRelic::Agent::Instrumentation::ControllerInstrumentation 
  def find_new_leads 
    ...
    attributes = {
      user_id: job.job_definition.user.id,
      account_id: job.job_definition.user.account.id,
    }

    ::NewRelic::Agent.add_custom_attributes(attributes)
    ...
  end 
  add_transaction_tracer :find_new_leads, :category => :task 
end
```

# New Relic APM側から確認

New Relic APMのダッシュボードから `APM > Transactions`と遷移し、Typeを「Non-Web」に設定することで非ウェブトランザクションがモニタリング出来ていることを確認できます。

![スクリーンショット_2021-04-02_6_26_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215051/f7c73a2d-ce5f-8c42-2c94-7a013be5a1f6.png)

また、カスタム属性として追加したアカウント情報もこちらより確認が出来ます。

![スクリーンショット_2021-04-02_6_27_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215051/9704b056-637f-45ee-e34b-893427a3ace2.png)

現在はバッチ処理においてもWEBトランザクション同様に、アカウント単位で分析するようにダッシュボードに追加しております。

# まとめ

今回はNew Relic APMを用いたバッチ処理のモニタリング方法をまとめました。以上！！！
@IBAction から発火する、function() の 連結Swift編 Timer event 時計の作成

#Button  action による function 任意の文字列(){}からイベントの発生
まずボタンをアクション接続します。接続は、ストーリーボード上で、右上の+ボタンを、オブジェクト選択中に叩きます。※Swiftシートを選択中は、オブジェクトツールは出ません。式の補完候補が出るだけです。

```swift

import UIKit
class ViewController: UIViewController {
   var label1 = UILabel()
   var label2 = UILabel()
   var timer = Timer()
   @IBAction weak button1: UIButton{
       label1.text = “New Label”
       label1.frame = CGRect(x: 40, y: 280, width: self.view.frame.size.width, height: 31)
       label.textColor = .gray
       label.backgroundColor = .black
       self.view.addSubView(label1)
       label2.isHidden = true
       Timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timeUpDate(timer:)) userInfo: nil, repeat: true)
       /* 
         この後がファンクション
　　    */
　　    buttonAction()
    }
    //ここに飛ぶ
    func buttonAction(){
        label2.text = “Move Label”
        label2.textColor = .brown
        let timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(interval(setTimeout:)), userInfo: nil, repeat: false)
        label2.backgroundColor = .blue
    }
    @objc func intervalz(setTimeout: Timer){
        timer2 = Timer2.scheduledTimer(timerInterval: 0.1, target: self, selector: #selector(timeUpDate:)), userInfo: nil, repeat: true)
    }
    @objc func timeUpDate(timer: Timer){
        let nowTime = DateFormatter()
        let nows = DateFormatter()
        let now = Date()
        nowTime.dateFormat = “hh:mm:ss”
        nows.dateFormat = “yyyy/MM/dd”
        label1.text = nows.stringFromDate(now)
        label2.text = nowTime.stringFromDate(now)
    }
    override viewDidLoad(){

    }
}
```

この式の中の、timer の後の Selector任意の文字列が
@objc 任意の文字列{
に繋がっていて、タイムインターバルの5、0.1秒ごとに発生するイベント接続するファンクションをセットし、リピートがあっるものは、インターバル、ないものはタイムアウトイベントとすると定義している。
Flutter 枠で囲んだ文字

Flutterを最近始めたので、なんというかテスト投稿

![Screen Shot 2021-04-01 at 9.05.01 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145550/a8f7a7ea-e644-3c9c-a8ce-f7f2e51f9a37.png)


Dart Padのデモはこちらをどうぞ

https://dartpad.dev/6ef547a692c0af483a16c1f7ba2e3a28?null_safety=true

Wrapウィジェットを使って、文字を二行に分けて表示しているだけのデモです。

拡大してみると多少白い塗りつぶし忘れがあります。各borderRadiusをいじってやると修正できます。
Githubにpushしたら容量オーバーでエラーが出た

#背景
個人のHPをgitで管理しようと思い、commitしてgithubにpushしたらファイルのサイズが重くてエラーが出ました。そこで原因となったファイルを削除して再度pushしたところ同じようなエラーが出てしまいました。しかも原因のファイルはそもそも不要なファイル。このような問題が起きた場合の対処法について記事にしました。

#状況
1. Homepage用のソースファイルを「git init」コマンドを入力し、gitの管理下に置く
2. 「git add .」で全てのファイルやフォルダーをステージングする。
3. 「git commit」で初コミットをする。
4. github上にリポジトリーを作成する。
5. 「git remote add origin {githubのリポジトリーURL}」を打ち、originという名前でgithubの
　 ブランチを追加する。
6. 「git push origin master」でgithubのmasterブランチにpushする。
7. 以下のようなエラーが発生

```
Enumerating objects: 98, done.
Counting objects: 100% (98/98), done.
Delta compression using up to 4 threads
Compressing objects: 100% (91/91), done.
Writing objects: 100% (98/98), 558.84 MiB | 1.04 MiB/s, done.
Total 98 (delta 9), reused 0 (delta 0)
remote: Resolving deltas: 100% (9/9), done.
remote: warning: File xxxxxxx.pdf is 90.41 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: 5b95e6f45d3f8fba822fa66d345dae6ad53f56c312c8480a08044e2ec87d866e
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File xxxxx.pdf is 114.80 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File xxxxx.pdf is 108.29 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File xxxxx.pdf is 109.45 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/xxxxxxx/homepage.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/xxxxxx/homepage.git'
```
#原因
githubにpushする時、ファイルが重かった。
--> this is larger than GitHub's recommended maximum file size of 50.00 MB
訳すとgithubにアップロードできる最大のサイズは50.00MBであるということ。
実はgithubって一度にpushできるサイズの上限があったらしい。

#解決策について

①履歴を確認し過去に戻してみる

1.「git log」で履歴を確認する。
2.「git reset --hard 履歴のid番号」を打ち、pushする前の履歴に戻す
3.原因となる不要なpdfファイルを削除 ->「remote: error: File xxxxx.pdf…」
4.git add & commit
5.再度「git push origin master」でgithubにpushする
6.結果、同じようなエラーが出る。

②履歴を戻しても一度commitしてしまったので、ステージングしたファイルは残っていると思い、revertコマンドで打ち消してみる

1.まずは元のフォルダーのコピーを作成
2.「git revert HEAD」と入力し、コミットを打ち消す。
3.ファイルがきれいに削除されていることを確認。
4.元のフォルダーのコピーから問題の「pdfファイル」と「.gitフォルダー」を除いたものをcopyし、きれいになった元のファイルにpasteする。
5.git add & commit
6.再度「git push origin master」でgithubにpushする
7.またして同じようなエラーが出る。

③元のフォルダーにある「.git」と原因の「pdfファイル」を削除
どうやら元のフォルダーにpdfファイルを削除する前の履歴が残っているのが原因だと思ったので、「.git」を削除。原因のpdfファイルも削除した上でgitの初期設定を行う。

1.「.git」フォルダーを削除。
2.原因のpdfファイルを削除。
3.「git init」で「.git」を新規作成。
4.「git remote add origin {githubのリポジトリーURL}」を打ち、originという名前でgithubの
　 ブランチを追加。
5.「git add.」でステージング、「git commit」でコミットする。
6.「git push origin master」でgithubにpushする
7.容量オーバーのエラーが出ず、意図通りにpush成功！

#終わりに
1.サイズオーバーしたファイルがcommitされた場合、resetやrevertをしても原因のファイルがpushされてしまったので、他の解決策を探してみますがアドバイスいただけるとうれしいです。

2.今回の場合、サイズオーバーしたファイルをgithubにpushするわけではなく、取り除いた状態でpushしgithubのリポジトリーに反映したかったという…　容量オーバーでもpushに失敗しない方法については以下の記事通り。

https://qiita.com/kanaya/items/ad52f25da32cb5aa19e6
Ajax(非同期通信)の基礎知識

# Ajaxとは

Ajax（エイジャックス）とは、JavaScriptを使用して非同期通信を行う処理です。
基本中の基本ですが、仕組みを理解していれば後々の学習に役に立つと信じてまとめます。

# 非同期通信の仕組み

非同期通信とは、リクエスト後に、ブラウザが再読み込みされることなく、ブラウザの一部分のみが更新される通信方法のことです。

有名なものだと既読機能、GoogleMapなどもカーソルを移動するだけでブラウザの再読み込みなしで、地図の情報が更新されていきます。


以下は、クリックした時にメッセージがグレーに変わる既読機能の非同期通信処理の流れです。

①HTMLで既読にしたい要素をクリック
②JavaScriptのイベントバンドラーが動き、コントローラーへデータを渡す
③データベースの内容を既読に書き換え、そのデータを取得し、Java Scriptに返却する
④返却されたデータを元にHTMLの情報を書き換える
⑤書き換えられた情報を元にCSSが適用されてメッセージがグレーに変わる


コントローラーのアクションで返却するレスポンスはデータです。
その為、データが返却されるためのURLが必要となります。

## エンドポイント

エンドポイントとは、Ajaxでやりとりする時の、データ返却のアクションをするためのURLです。
Ajaxを実現するためには、コントローラーでのレスポンスを、HTMLではなくjsonなどのデータ形式で返却する必要があります。そのデータを取得する時にアクセスするためのURLを、エンドポイントといいます。

また既読機能では、どのメッセージを既読にするかを判別するため、
既読とするメッセージ内容のidというパラメータを渡す必要があります。

非同期通信では、URLパラメーターというものを使用して、サーバーへデータを送ります。

## URLパラメーター

URLパラメーターとは、サーバーに情報を送るために記載するURL末尾の文字列のことです。
URLパラメーターは、主に２種類があります。
・queryパラメーター
・pathパラメーター

渡す情報が今回想定しているメッセージのように一意の情報であればpathパラメーターの方が適しているそうです。


## データ形式
データ形式とは、コンピューター上でデータをやり取りする際の形式のことです。
先ほどのエンドポイントの説明の中でjson形式でデータを返却する必要があるとしました。

JSON（ジェイソン）とは、データを扱う場合のフォーマットのことで、
他にもフォーマットはありますが、JavaScriptとの相性がよく、JSON人気が高いそうです。


# まとめ

本当に基本的なことしか書いていませんが、曖昧な理解になっていた部分もあったので、
実装中に理解が不十分なものはこうしてアウトプットする癖をつけたいと思います。
vscodeで合字(ligature)を有効にする方法

# 合字(ligature)とは
プログラミング言語でよく使用する記号(不等号, 矢印, 論理演算子など)をいい感じに見やすく表示してくれます
![スクリーンショット 2021-04-02 1.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950445/b3ca746d-b714-7da0-e871-6f855a048560.png)

### メリット
- テンションが上がる
- 不等号を書くときに <= なのか =< なのか迷わなくて済む



# Fira Codeのインストール
vscodeのデフォルトのフォントではligatureを有効にすることができないので
ligature対応のフォント(今回はFira Code)をインストールします

https://github.com/tonsky/FiraCode

上のリンクからフォントのzipファイルをダウンロードします
![スクリーンショット 2021-04-02 1.04.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950445/24244652-d4fa-eb81-0591-2b8b588336df.png)


zipファイルのttfフォルダ配下にある全てのファイルを選択して「開く」を選択してフォントのインストールを完成させます

![スクリーンショット 2021-04-02 1.06.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950445/cfeeafdb-6b5d-544a-56b5-b958b87c3c0f.png)


# vscodeでの設定

Font Familyに'Fira Code'を追加します(左側にあるフォントが優先されるので一番左に追記する)
![スクリーンショット 2021-04-02 1.11.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950445/eb62695f-2791-b97f-0a91-37a4dca741ba.png)


settings.jsonにて以下を設定する

```settings.json
"editor.fontLigatures": true,
```


Done！！
![ligature.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950445/4d13fcbf-ebdf-e2fd-f838-a28201d493ba.gif)
Python3一行書きの手法まとめ

# なにこれ
自分が Python のワンライン書きにハマって数年が経ったのでこれを機に使ってた手法を軽く纏めてみました。

# 代入1

```python:Before
line = input()
print(line)
```

```python:After
print(input())
```

読めばわかるかもしれないですが、変数に代入する必要がなかったらそのまま突っ込んじゃえばいいって意味ですね。

# 代入2

```python:Before
x = int(input())
print(f'x={x},Y={2*x+1}')
```

```python:After
(lambda x:print(f'x={x},Y={2*x+1}'))(int(input()))
```

変数が必要なら lambda で突っ込んじゃえって意味ですね。
lambda は関数なので、左側に関数、右側に引数という形にするとちゃんと動きます。
要は関数作ってそのまま使ってる感じです。

### 別の手法
```python:another
print(f"x={locals().setdefault('x',int(input()))},Y={2*x+1}")
```

名前空間に直接ぶち込んじゃえって意味ですね。
python は名前空間を辞書型[^1]で管理しており、名前空間のグローバルスコープの内容は`globals()`、ローカルスコープは`locals()`で取得できます。
なので、それで呼び出した dict に直接追加しています。
`setdefault()`は戻り値があるので使っています。

一時期使っていましたが、lambda の方を知ってからはそっちを使ってますね。これ長いので。

[^1]: 将来変わるかもしれないです。

# 条件分岐(三項演算子的な)

```python:Before
if age >= 18:
    print("成年")
else:
    print("未成年")
```

```python:After
print(["未成年","成年"][age>=18])
```
Python の暗黙の型変換を利用した if 文です。if 文は使ってません。
これは、`True,False`がそれぞれ`1,0`になるのを利用しました。

```python
> int(True)
1
> int(False)
0
```

体感ですが三項演算子より読みやすいですね。

#### 応用(文字列のスライス)
```python
print("未成成年年"[age>17::2])
```
「読みやすいですね」:eyes:

# import
```python:Before
import math
print(math.sqrt(4))
# => 2.0
```
```python:After
print(__import__("math").sqrt(4))
# => 2.0
```
python の組み込み関数に`__import__()`というものがあります。
import が必要な関数やメソッドを速攻で使えます。それだけです。

ちなみに**強く**推奨されていないので注意が必要です。[^2]

[^2]: https://docs.python.org/ja/3/library/functions.html#__import__

# 型変換
## map
```python:Before
line = input()                 # 入力
array = line.split()           # 分割
for i in range(len(array)):
    array[i] = int(array[i])   # 型変換
```

```python:After
array = list(map(int, input().split()))
```

`map()`は第2引数のイテレータになれるオブジェクトに入っているすべての値に第1引数の呼び出し可能なオブジェクトを適応させることができる関数です。
イテレータになれるオブジェクトは list や dict 等、呼び出し可能なオブジェクトは関数やメソッド等のことです。
戻り値は map オブジェクトなので list に型変換する必要があります。

## range
連続した数値は`range()`が作り出してくれるので、それを list に変換すれば一瞬で済みます。

```python:Before
array = []
for i in range(5):
    array.append(i)
# array = [0, 1, 2, 3, 4]
```
```python:After
array = list(range(5))
# array = [0, 1, 2, 3, 4]
```

## strの乗算
```python:Before
print("Hello", end="")
if flag:
    print(" World", end="")
print("!!")
```
```python:After
print("Hello" + " World"*flag + "!!")
```

str と int を乗算すると int の分だけ文字列が増えます。
int が 0 の場合、文字列が消えます。

```python
> 'a'*4
'aaaa'
> 'hoge'*2
'hogehoge'
> 'ten-gallon hat'*False
''
```

## 悪いこと

型変換を悪用すると fizzbuzz を if, for 文なしで書けます。

```python:fizzbuzz.py
print(*map(lambda x:x%3//2*'Fizz'+x%5//4*'Buzz'or f'{x+1}',range(int(input()))),sep='\n')
```

可読性は皆無ですね。

# あとがき
コードゴルフには使用できないようなものもたくさんありますね。
ぶっちゃけて言うと可読性が悪くなるのでワンライナーはお勧めしません。
逆に可読性悪いのが書きたくなった場合はワンライナーをお勧めします。

他にもありましたら是非コメントにお願いします。
それと読みにくい場所がありましたら遠慮なく言ってください。訂正します。

## 参考文献
https://docs.python.org/ja/3/reference/executionmodel.html#resolution-of-names

https://docs.python.org/ja/3/library/functions.html#__import__

https://qiita.com/conf8o/items/0cb02bc504b51af09099

https://qiita.com/KTakahiro1729/items/b2b1a9b82fc6e6d8c158

https://qiita.com/ymg_aq/items/b8e5d26035180bc8797e
AWSでWebアプリをデプロイする方法(Java)①

#AWSアカウントの作成

###利用環境
OS:MacOS
ブラウザ:Chrome

##AWSにアクセスする
[awsの公式サイト](https://aws.amazon.com/jp/)にアクセスする
画面右上の「今すぐサインアップ」から登録画面を表示
![スクリーンショット 2021-04-02 1.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/69ba4e03-96fa-056a-ac52-45554da8a690.png)

##登録の際の注意事項

- 名前と住所の情報は英語で入力する
- クレジットカード情報が必要になる(デビットカードでも可)
- 電話番号認証が必要になる
- サポートプランは「ベーシックサポート」を選択

##AWSアカウントでサインインする
サインアップ完了後に案内に従いコンソール画面を表示
![スクリーンショット 2021-04-02 1.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/852bed83-ef5a-cd85-049c-de6ae81af114.png)

ルートユーザーとして、先ほど設定した情報でログインする
下記画面が表示できれば登録完了
![スクリーンショット 2021-04-02 1.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/6389def4-f948-23f1-a749-8d2a74117510.png)

#AWSでWebアプリをデプロイする方法②
[ユーザーを追加する](https://qiita.com/kunrenyouAcount/items/0279d7f6136eb29ef436)
【Vue.js】v-modelとオブジェクト〜親子1対1のデータフローでオブジェクトを扱う〜

## 事前条件
- 子コンポーネントに抽出したいオブジェクトやオブジェクトのリストがある。

## 処理
- 子コンポーネント内でプロパティを変更してオブジェクト全体のコピーを親に送り返す。

## 事後条件
- 変更されたオブジェクトが親コンポーネントに渡される。

## ポイント
- JavaScriptのオブジェクトは参照渡し。
- オブジェクトを直接変更するとVueの親子イベントが回避されてしまう。
    - アプリケーションのトラブルシューティングが難しくなるので、これは避ける。
- emit部分でobject spread syntax,computed property nameを使用する。
    - 前出の問題を避け、親子1対1のデータフローに出来る

## コード例

```vuejs:App.vue
<template>
  <section class="section">
    <div class="container">
      <h1 class="title is-size-2">Using Vue's v-model with complex objects</h1>
      <div v-for="(item, i) in holidays" :key="i">
        <h2 class="is-size-4">{{item.name}}</h2>
        <Child v-model="holidays[i]"/>
      </div>
      {{JSON.stringify(holidays)}}
    </div>
  </section>
</template>

<script>
import Child from "./components/Child";

export default {
  name: "App",
  components: {
    Child
  },
  data() {
    return {
      holidays: [
        {
          name: "Fourth Of July",
          date: null,
          description: ""
        },
        {
          name: "Thanksgiving",
          date: null,
          description: ""
        }
      ]
    };
  }
};
</script>
```

```vuejs:Child.vue
<template>
  <div>
    <div class="field">
      <div class="control">
        <label for="name" class="label">Name</label>
        <input class="input" :value="value.name" @input="updateValue('name', $event.target.value)">
      </div>
    </div>
    <div class="field">
      <div class="control">
        <label for="date" class="label">Date</label>
        <input
          class="input"
          type="date"
          :value="value.date"
          @input="updateValue('date', $event.target.value)"
        >
      </div>
    </div>
    <div class="field">
      <div class="control">
        <label for="textarea" class="label">Textarea</label>
        <textarea
          class="textarea"
          :value="value.description"
          @input="updateValue('description', $event.target.value)"
        />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: Object,
      required: true
    }
  },
  methods: {
    updateValue(key, value) {
      this.$emit("input", { ...this.value, [key]: value });
    }
  }
};
</script>

```

最も重要な部分は emit イベントの処理です。標準的なinputイベントをemitしたいのですが、今回のvalueは特別なもの(＝オブジェクト)になります。

UpdateValueメソッドは、このコード `{ ...this.value, [key]: value }` によって、新しいオブジェクトの値をemitします。ここでは、コードを非常にきれいに保つために、2つのJavaScriptの機能を使用します。
1つ目は、propを介して渡されたオブジェクトをコピーし、更新されたキー/値をオブジェクトにマージする、**[object spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals)**です。

2つ目は、**[computed property name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015)** を使用することで、変数keyをオブジェクト内のキーの名前として使用することができます。これにより、パラメータとしてキーと値を受け取る汎用のupdateValueメソッドを持つことができ、入力を使ってオブジェクトの正しいキーを更新し、それを親に返すことができます。

## 参考・引用
https://www.drewtown.dev/post/using-vues-v-model-with-objects/
【Androidを使い熟す！】Android Frameworkについて

#####※Android技術者認定にも役に立ちます！
#Android Framework!
![Qiita](https://msp.c.yimg.jp/images/v2/FUTi93tXq405grZVGgDqG-NYjmggvksWB_EqCzT6dboshI5Tfo0ak4CLMAQaIC7_HiYaqIuCR_aySatPiV24qYjANCrtMjzdRrlX_-AEAfAggfheT3VZvQQXUlSp7XonUiRzPVMR2VeCefg7VfI7V54iMHre462Zz0fN8B2Ghd-a9qZGQ_m39hsP0rFD9Xz7h4sf1GATNxwY3LqEY1vVgw==/architecture.jpg?errorImage=false"Qiita")

#各構成要素について
<dl>
  <dt>■アプリケーション</dt>
  <dd> 
ユーザにもっとも近い最上層。 
  </dd>
<dt>■アプリケーションフレームワーク</dt>
  <dd> 
ざまざまな機能やライブラリを使うためのコンポーネントやAPIが提供する
<details><summary>※重要</summary><div>

①Activity Manager<br>
→Activityの管理
(アプリケーションのライフサイクルを管理)<br>
②Window Manager<br>
→ウィンドウの管理
(画面の状態を制御する機能を提供)<br>
③Content Providers<br>
→データ共有の管理
(アプリケーション間で共有するデータを管理)<br>
④View System<br>
→ユーザインタフェースの管理
(ボタンやテキストボックスなど、アプリケーション
構築に使用できるウィジェットのセット)<br>
⑤Package manager<br>
→インストールの管理
(端末内のアプリケーションを管理する機能を提供)<br>
⑥Telephony Manager<br>
→電話機能の管理
(電話機能へのアクセス)<br>
⑦Resource Manager<br>
→リソースの管理
(文字列、グラフィックス、レイアウトファイルなどのリソースへのアクセス)<br>
⑧Location Manager<br>
→位置情報の管理
(GPSが取得する位置情報へのアクセス)<br>
⑨Notification Manager<br>
→アラートの管理
(イベントの発生を知らせるアラート機能など)<br>

</div></details>
  </dd>
<dt>■ライブラリ</dt>
  <dd> 
C/C++などで作成されたライブラリ
  </dd>
<dt>■Androidランタイム</dt>
  <dd> 
アプリケーション実行環境
マシン(Dalvik・Google独自Java)のコアライブラリ
  </dd>
<dt>■Linuxカーネル</dt>
  <dd> 
Linux2.6のカーネルをベースとしている
  </dd>
</dl>
AWSでWebアプリをデプロイする方法(Java)目次

#Webアプリをデプロイするまでの備忘録(目次)

>参考書籍:Amazon Web Services 超入門
![スクリーンショット 2021-04-03 23.49.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/c6af2075-d5eb-91fa-c04e-a92bf4570fba.png)
※上記の書籍は、PHPでWordPress環境の作成を作るものとなります。目次でいうとMariaDBのインストールまでが書籍の内容となります。

##目次

###[AWSアカウントの作成](https://qiita.com/kunrenyouAcount/items/97e0008942aea4e191b4)
![スクリーンショット 2021-04-02 1.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/24b9955d-b77e-aba1-e78d-7fb7c0a3a9d2.png)

###[ユーザーを追加する](https://qiita.com/kunrenyouAcount/items/0279d7f6136eb29ef436)
![スクリーンショット 2021-04-03 17.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/41e342ed-50e5-c410-5d70-2ccf21b6c77c.png)

###[請求情報を管理する](https://qiita.com/kunrenyouAcount/items/68f8fde1c96dc139f434)
![スクリーンショット 2021-04-04 1.09.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/fc16264b-68e8-64d5-b518-aff89df0bbc3.png)

###[EC2インスタンスを作成する](https://qiita.com/kunrenyouAcount/items/9537ecc45d34349e9759)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/3f3ff511-30ef-c3f1-6834-ae26fdafaf45.png)

###[SSHで接続する](https://qiita.com/kunrenyouAcount/items/2a24c5789264904418db)
![スクリーンショット 2021-04-06 2.01.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/371d9e18-a38b-2e6d-3223-dbf0f306b69c.png)

###[Apacheのインストール](https://qiita.com/kunrenyouAcount/items/d10fb9a73e911d7f4937)
![Something went wrong]()


###[MariaDBのインストール](https://qiita.com/kunrenyouAcount/items/eb1f211daebdc19933cd)
![Something went wrong]()
----ここまでが書籍の内容----
###[Javaのインストール](https://qiita.com/kunrenyouAcount/items/4ca08c9ac3e2e262e7b1)
![Something went wrong]()
###[Tomcatのインストール](https://qiita.com/kunrenyouAcount/items/3b17275e9b1f9de8d990)
![Something went wrong]()
###[制作物のデプロイ](https://qiita.com/kunrenyouAcount/items/9c701c82915807c9b196)
![Something went wrong]()
- RDSのDBインスタンスを作成する

**デプロイをして終わり、ではなくAWSについての理解も深めるために段階を踏んで実装をする**
KtorのOAuth2のNonceManagerについて

KtorのOAuth2の基本は知っている人向け。

## 結論

無防備すぎるも嫌だが手間もかけたくないなら、StatelessHmacNonceManagerを使うのがおすすめ。

## 発端

KtorでOAuth2のClientを動かすのは難しくない。[公式のサンプルコード](https://ktor.io/docs/oauth.html#example)もあり、InteliJのプロジェクト作成時にコード生成もしてくれる。

ただ、サンプルコードではNonceManagerを設定しておらず、NonceManagerについてのドキュメントがわかりやすい場所にない。セキュリティに関わる部分なので重要な話なのだが。
ということで、NonceManagerについて記す。

## nonce/NonceManagerとは?

nonceとは、OAuth2の言葉でいえば"state"のこと。CSRFという攻撃を防ぐために使うランダム値。
以下の記事が詳しい。
https://qiita.com/naoya_matsuda/items/67a5a0fb4f50ac1e30c1

NonceManagerはnonceを生成したり検証したりするクラス。
Ktorのinterfaceとして定義されており、OAuth2ServerSettingsに実装クラスを渡すことでNonceManagerを指定できる。

## NonceManagerの設定コード例

OAuth2ServerSettingsのコンスタラクタの引数nonceManagerにNonceManagerを指定する。以下、StatelessHmacNonceManagerを設定する場合のコードサンプル。

```kotlin
val encodedKey = System.getenv("NONCE_SIGN_KEY") ?: throw IllegalStateException()
nonceKey = Base64.getDecoder().decode(encodedKey)
...
val loginProviders = listOf(
    OAuthServerSettings.OAuth2ServerSettings(
        name = "github",
        authorizeUrl = "https://github.com/login/oauth/authorize",
        accessTokenUrl = "https://github.com/login/oauth/access_token",
        clientId = System.getenv("CLIENT_ID") ?: throw IllegalStateException(),
        clientSecret = System.getenv("CLIENT_SECRET") ?: throw IllegalStateException(),
        nonceManager = StatelessHmacNonceManager(key = nonceKey),
    )
).associateBy { it.name }
```

## NonceManagerの候補
### GenerateOnlyNonceManager(Ktorのビルトイン)
nonceManagerを指定しない場合のデフォルト。
実運用で使うのはいまいち。nonceを生成するだけで検証はしないから。

### StatelessHmacNonceManager(Ktorのビルトイン)
"ランダム値+期限+署名"という形式のnonceを生成する。検証のときは、改ざんがされておらず、期限が切れていなければOKとする。期限はデフォルト60秒。

期限内ならCSRFが可能だが、すぐに期限切れするのでCSRFするのは難しい。何もしないよりはセキュア。

### セッション変数にnonceを保存するNonceManagerを自作する
nonceをセッション変数に保存する方式は一般的な模様。利用を1回だけにできるので、StatelessHmacNonceManagerよりもセキュアにできる。

ただ、NonceManagerのメソッドにApplicationCallが渡されないので、セッション変数を扱えるのか謎。ApplicationCallを渡しているコードも見かけたが、本当にそれで動作するのかは微妙に思えた。
(なんで、ApplicationCall渡す仕様にしなかったのだろう?)

セッション変数にこだわるなら、Ktorの出来合いのOAuth2の機能を使わないで、自分である程度実装したほうが楽かも。

### Redisなどを使うNonceManagerを自作する
生成したnonceをredisに覚えさせ、検証時はredisにnonceが保存されていればOKとする。1度検証したら、nonceは消す。覚えさせる際に期限を付けるとより良いと思う。

StatelessHmacNonceManagerよりはセキュアと思うが、このためだけにredis入れるのが億劫。

## NonceManagerの選び方

セキュリティを追求する -> セッション変数にnonceを保存するNonceManagerを自作する。
実用上は問題なさそうなレベルで妥協する -> StatelessHmacNonceManagerを使う。

コスパを考えて後者が良いと思う。仕事でのソフト開発だったら前者にしそうだけど。
AWS SSO とは

## 勉強前イメージ

AWSでSSOできるサービス？
AWS Organizationsと一緒に設定するかも

## 調査

### AWS SSO とは

SSOとは `Single Sign-On` の略で、
複数のAWSアカウントとアプリケーションへのSingle Sign-Onアクセスの一元管理を行うサービスになります。

### SSO(Single Sign-On)とは？

1組のID・パスワードによる認証を1度行うだけで複数のサービスにログインできるようにする仕組み
利用者側は複数のサービスを利用しているとID・パスワードの組み合わせも増え、各サービスごとにログインが必要になったり
管理者側はID・パスワードの組み合わせが増えると管理も大変になるので、利便性が向上し
セキュリティリスクも減少させることが出来ます。

### AWS SSO の機能

- AWS Organizations との統合

[AWS Organizations](https://qiita.com/miyuki_samitani/items/c34185fe04f6c4f35449) と連携して組織内のAWSアカウントを管理できる機能です。
マスターアカウントでAWS SSOを有効にすることでAWSコンソールへのSSOアクセスを行うことが出来ます。

- Active Directory との連携

AWS Directory Serviceを使用してしてActive Directoryと連携取ることが出来ます。
Active Directoryの認証を利用してAWSにログインすることが可能になります。

### AWS SSO を利用する前提

SSOを利用するには以下の条件があります。

- AWS Organizations のマスターアカウントの権限をもっていること
- AWS Organizations の ALL FEATURESが有効になっていること

## 勉強後イメージ

AWS SSOはAWS Organizationsと共存出来るというかしないといけないのか。
SSOのはActive Directoryにすると管理者の方とかは二重で管理しなくても良いからよいね。
設定ってどうするんだろうって思うけどそこまで踏み込めてない

## 参考

- [シングルサインオン（SSO）とは？メリットと仕組みを解説](https://www.kagoya.jp/howto/network/single-sign-on/)
- [AWS Single Sign Onについて](https://www.acrovision.jp/service/aws/?p=1383)
- [AWS Single Sign-On（SSO）でAWSアカウントへシングルサインオン](https://blog.serverworks.co.jp/tech/2020/03/06/sso/)
EC2インスタンスにVScodeのRemote SSHで接続するまで（普段WSL利用者向け）

# 前提条件
* 自分で作成した秘密鍵でSSHログインしたい。
* WSLでいつもSSHを利用していて、秘密鍵の場所もWSLのhome以下の.sshで管理している。（秘密鍵の編集権限の設定に関わる。）
* cloud9でもいいけど、結局VScodeが見やすく使いやすいのでVScodeで開発したい人向け。

# 流れ
* EC2インスタンスに公開鍵をEC2インスタンスに登録。
* VScodeでの設定。VScodeでRemote SSHをインストール。設定ファイルの場所を変更。
* 秘密鍵の権限を設定。
* configファイルを設定。

# EC2インスタンスに公開鍵をEC2インスタンスに登録。
EC2インスタンスを起動。
`vim ~/.ssh/authorized_keys`に公開鍵を追記する（既存の公開鍵は削除してしまわないように）。
インスタンスがパブリックネットワークに置かれていること（参照先のルートテーブルにインターネットゲートウェイがあること）を確認する。
また、インスタンスのセキュリティグループの設定でSSHアクセスが許可されていることを確認する。


# VScodeでの設定。
Remote SSHの設定で、設定ファイルの場所を以下（普段WSLでSSHで利用しているconfigファイルの場所）に変更。
秘密鍵もこちらに置いてある。
`C:\Users\${Username}\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\home\${Username}\.ssh\config`
新しくどこかにつくってもよいが、SSH系は一か所で管理した方が楽なので。
ただし、このようにすると秘密鍵の権限設定が少し必要になる。

# 秘密鍵の権限を設定。
WSKで作成した鍵は、Windows（VScode）側からはフルオープンになってしまっている。
確認方法は、エクスプローラーでファイルを右クリック
`プロパティ⇒セキュリティ⇒詳細設定`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/9c662419-7a79-5a50-c9a6-eb8bf9f19fd9.png)
こちらの権限を適切にしないと、VScodeからRemote sshで接続しようとすると`permission too open`エラーが出てしまう。

以下、設定方法。
1. まず秘密鍵をコピー（失敗しても戻れるように）。失敗すると戻れなくなってしまう可能性あり。
1. コピー後のファイルで、権限変更をする。まず継承の無効化をする。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/fde15930-317a-1abc-e0af-c90ebf41f157.png)
1. 無効化すると、ようやくユーザー以外のアクセスを削除できるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/7f38d745-f80c-321c-6a69-99eb1319c118.png)



上記設定は、WSLのターミナルからであれば`sudo chmod 400 ./秘密鍵 `で済むが、Windows側から権限設定となると少し面倒。

注意点：毎回IPアドレスが変わるので、チェックする必要がある。もしくは、こちらの記事でドメイン名を取得し、インスタンス起動時に毎回IPアドレスをドメイン名と紐づけるように設定するとラク。

# configファイルを設定。
ターミナル上で`vim ~/.ssh/config`でconfigファイルを編集。VScodeからもできる。
`C:\Users\${Username}\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\home\${Username}\.ssh\config`こちらでも良いし、WSL上での`~/.ssh/config`どちらでも同じファイルを編集することになる。

```:config
Host cloud9VScode
        HostName ${ip_address} or ${example.com}
        user ec2-user
        identityfile C:\Users\${username}\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\home\${username}\.ssh/秘密鍵
```

これで繋がります。
サイト高速化のためにやること

サイト高速化のために普段していることをまとめます。
しっかり対策することにより、PageSpeed InsightsやLighthouseでの得点も高得点を狙えると思います。

#preconnect dns-prefetch属性
まずpreconnect dns-prefetch属性で該当するものをhead内に指定します。

###考えられる使用例
・Webフォント　(googleフォント､Adobeフォント　等)
・SNS　(Twitter､Facebook　等)
・解析　(googleアナリティクス　等)
・広告　(Googleアドセンス　等)

```html
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="preconnect dns-prefetch" href="//www.google-analytics.com">
<link rel="preconnect dns-prefetch" href="//www.google.com">
<link rel="preconnect dns-prefetch" href="//www.google.co.jp">
<link rel="preconnect dns-prefetch" href="//www.googleadservices.com">
<link rel="preconnect dns-prefetch" href="//googleads.g.doubleclick.net">
<link rel="preconnect dns-prefetch" href="//bid.g.doubleclick.net">
<link rel="preconnect dns-prefetch" href="//stats.g.doubleclick.net">
<link rel="preconnect dns-prefetch" href="//www.googletagmanager.com">
<link rel="preconnect dns-prefetch" href="//code.jquery.com">
<link rel="preconnect dns-prefetch" href="//fonts.googleapis.com">
<link rel="preconnect dns-prefetch" href="//www.googletagmanager.com">
``

#preload属性
次にpreload属性をhead内に指定します。

###考えられる使用例
・css
・js
・font
・image

```html
<link rel="preload" href="/assets/css/style.css" as="style">
<link rel="preload" href="/assets/fonts/icomoon/icomoon.ttf?etnesh" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="/assets/js/vendor.bundle.js" as="script">
<link rel="preload" href="/assets/js/app.bundle.js" as="script">
<link rel="preload" href="/assets/img/top/mainv_pc.png" as="image">
```

ファーストビューや大きな画像があればそれもpreloadで指定しておいた方がいいでしょう。

#各指定について

jsの指定は以下のようにしています。
defer属性を追加することにより、非同期処理となります。ただ読み込み順によってはうまく動作しないこともありますので、要注意です。

```html
<script src="/assets/js/vendor.bundle.js" defer></script>
<script src="/assets/js/app.bundle.js" defer></script>
```

imgの指定は以下のようにしています。

```html
<img src="" width="980" height="300" alt="" loading="lazy">
```
loading="lazy"を書いておくと、ブラウザによって適切なタイミングでロードされます。
ページの読み込み中にレイアウトがシフトしないように、widthとheight属性を記述しましょう。

PCとSPで画像を出し分ける場合はpictureタグを使用します。

```html
<picture>
 <source srcset="/assets/img/top/section_ttl_sp.png" media="(max-width:750px)" width="750" height="310">
 <img loading="lazy" width="980" height="300" src="/assets/img/top/section_ttl_pc.png" alt="">
</picture>
```
SPのみ画像を表示させたい場合はダミーの画像を読み込ませます。

```html
<picture>
 <source srcset="/assets/img/top/section_ttl_sp.png" media="(max-width:750px)" width="750" height="310">
 <img loading="lazy" src="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7" alt="">
</picture>
```

ファーストビューで見える画像はloading="lazy"を指定しても意味がないので、
decoding="async"を指定します。

```html
<picture>
 <source srcset="/assets/img/top/section_ttl_sp.png" media="(max-width:750px)" width="750" height="310">
 <img decoding="async" width="980" height="300" src="/assets/img/top/section_ttl_pc.png" alt="">
</picture>
```


画像の容量が重いと読み込み速度に大きく影響するので、軽量化しましょう。
【Androidを使い熟す！】Android特徴？

#####※Android技術者認定にも役に立ちます！
#Android特徴！
<details><summary>説明</summary><div>
・コンポーネントの再利用と置換(ちかん)が可能なアプリケーションFramework
・携帯に最適化したDalvik仮想(かそう)マシン
・OpenSource【Webkit】エンジンをベースにした総合ブラウザ
・カスタム2DかつOpenGL Es 1.0仕様に基づいた3Dグラフィックが提供され、最適化したグラフィックス
・SQLiteによる構造(こうぞう)化したデータストレージ
・音声、映像、静止画(せいしが)の一般的なフォーマットに対するメディアをサポート
・Bluetooth、EDGE、３G、Wifi、カメラ、GPSなどの機能
・デバイスエミュレータ、デバック用ツール、メモリとパフォーマンスの分析、豊富(ほうふ)な開発環境
</div></details>
Jenkinsスレーブ群のラベルとIPアドレスを一覧取得する

## 背景

Jenkinsをmaster/slave構成にした際に、masterノードからはslaveノードのIPアドレスを知ることができません。
slaveノードをメンテナンスしたい場合などに、IPアドレスが即座にわからないのは不便です。

(「Jenkinsの管理」 > 「ノードの管理」 のノードの一覧に、IPアドレスが表示されていても良さそうですが)


## 方法1 特定のノードのIPアドレスを調べる

1. 「Jenkinsの管理」 > 「ノードの管理」 からIPアドレスを知りたいノードを選択する。
1. 「ログ」を選択する。
1. ログの先頭の方にIPアドレスが表示されているはずです。

表示形式はノードの接続方法によって異なります。

- Jnlp(Java Web Start)接続のノードでは、 `Inbound agent connected from xxx.xxx.xxx.xxx ...`
- SSH接続のノードでは、 `SSHLauncher{host='xxx.xxx.xxx.xx' ...`


## 方法2 全ノードのIPアドレスを一覧出力する

「Jenkinsの管理」 > 「スクリプトコンソール」 (masterノードのスクリプトコンソール) から、次のスクリプトを実行します。
※結果はJenkinsコンソール上に表示されます。コンソールがごちゃごちゃするのを避けるため `return null` としています。

```
jenkins.model.Jenkins.get()?.getNodes().each { node ->
  println "${node.getNodeName()} => ${node.getChannel()?.call(new hudson.model.Computer.ListPossibleNames())}"
}
return null
```

`ノード名 => [xxx.xxx.xxx.xxx]` 形式で出力されます。

※Slaveが複数のIPアドレスを持つ場合は、全てのIPアドレスが表示されます。

### 同じようにラベルを得ることもできます

```
// ノードのラベルを取得する
jenkins.model.Jenkins.get().getNodes().each { node ->
  println "${node.getNodeName()} => ${node.getAssignedLabels() - node.getSelfLabel()}"
}
return null
```

```
// ノードのラベルとIPアドレスを合わせて取得する
jenkins.model.Jenkins.get().getNodes().each { node ->
  println "${node.getNodeName()} => label:${node.getAssignedLabels() - node.getSelfLabel()}, IP:${node.getChannel()?.call(new hudson.model.Computer.ListPossibleNames())}"
}
return null
```


## 参考

こちらの記事を参考にしました。
https://stackoverflow.com/questions/14930329/finding-ip-of-a-jenkins-node

## 環境

Jenkins 2.282 で確認しています。
【SikuliX】スマホゲームの自動化（環境構築）

# はじめに
最近のスマホゲームでよくあるのが何度も周回を繰り返すゲームです。
しかし、ポチポチやるのも時間が勿体ないし、キリがない。
単純作業は自動化する習慣がついているので、自動化するための環境構築を備忘録として残します。

#使用するもの
* PC（Windows10 64bit）
* Java 64bit
* SikuliX（http://sikulix.com/）
* androidエミュレータ（Nox, BlueStacks等）
 
#手順
①Java 64bitをインストール
　SikuliXを動作させるためには、Java 64bit版が必要になるため、Windows オフライン (64ビット)を以下のページよりダウンロードし、インストールする。
 　https://java.com/ja/download/manual.jsp
　
②SikuliXをインストール
　https://raiman.github.io/SikuliX1/downloads.html
　から以下ファイルをダウンロードし、任意の保存場所に配置する。
　・sikulixapi.jar
　・jython-standalone-2.7.1.jar
　・sikulix.jar

　格納したら「sikulix.jar」をダブルクリックする、
　またはコマンドラインから以下のコマンドを実行するとSikuliXがインストールされ起動される。

 ```
java -jar ＜パス＞/sikulix.jar
 ```

　※インストールがうまくいかない場合、他の方が説明されている記事があるのでそちらも参考にしてください。
　[SikuliXを使って無料でRPAをする方法](https://qiita.com/sktw/items/a2e43e4554b779a7079c)
　[[RPA]SikuliXの導入（メモのみ）](https://qiita.com/sktw/items/a2e43e4554b779a7079c)　

③androidエミュレータをインストール
　自動化したいアプリが動くものをインストールする。

④androidエミュレータを起動する
　起動後、自動化したいアプリをインストールする。

⑤SikuliXで自動操作を記述する
　SikuliXに自動操作のスクリプトを書き込めば自動化ができる。

#まとめ
以上がスマホゲームの自動化環境構築の流れです。
SikuliXに記述するスクリプトについては別記事にまとめます。
【Kotlin】リフレクションで、kotlin-reflect無しでデフォルト引数を用いて関数を呼び出す

# TL;DR
- `Kotlin`のデフォルト引数付き関数は`Java`のリフレクションからも呼び出せる = `kotlin-reflect`無しでも呼び出せる
- ただし、`kotlin-reflect`無しで呼び出しのための情報を集めることは困難が伴うため、依然として`kotlin-reflect`の削除は難しい

# 本文
## デフォルト引数付き関数がどうコンパイルされるか
まず、デフォルト引数付き関数がどうコンパイルされるかを見ていきます。
例として、以下のようなデフォルト引数付きコンストラクタを取り上げます。

```kotlin
data class Clazz(val foo: String = "Hello World.")
```

このコンストラクタは以下のようにコンパイルされます。

```java:デコンパイル結果からコンストラクタ部分の抜粋
   public Clazz(@NotNull String foo) {
      Intrinsics.checkNotNullParameter(foo, "foo");
      super();
      this.foo = foo;
   }

   // $FF: synthetic method
   public Clazz(String var1, int var2, DefaultConstructorMarker var3) {
      if ((var2 & 1) != 0) {
         var1 = "Hello World.";
      }

      this(var1);
   }
```

2番目に出ているコンストラクタでは、条件分岐でデフォルト引数が設定されていることが分かります。
ここで、引数は以下のような意味を持っています。

1. コード上で設定した引数
2. 引数が設定されていれば0、設定されていなければ1となるビットマスク
3. デフォルト引数を利用することを示すマーカー（基本的に`null`を渡せばOK）

## 実際に呼び出してみる
このデフォルト引数付きコンストラクタは、コード上からは呼び出せませんが、`Java`のリフレクションからは呼び出すことができます。
実際に呼び出してみたコードが以下です。

```kotlin
import java.lang.reflect.Constructor

data class Clazz(val foo: String = "Hello World.")

fun main() {
    val clazz: Class<Clazz> = Clazz::class.java
    val constructor: Constructor<Clazz> = clazz.constructors.first { constructor ->
        // デフォルトコンストラクタの引数末尾のクラス名は必ずDefaultConstructorMarker
        val isDefaultConstructor = constructor.parameters.lastOrNull()
            ?.let { it.type.name == "kotlin.jvm.internal.DefaultConstructorMarker" }
            ?: false
        // 今回の引数サイズは1、マスクとDefaultConstructorMarkerで2引数、合計3引数になる
        val isCollectArgumentSize = constructor.parameters.size == 3

        isDefaultConstructor && isCollectArgumentSize
    } as Constructor<Clazz>

    println(constructor.newInstance("こんにちは。", 0, null))
    println(constructor.newInstance("こんにちは。", 1, null))
    println(constructor.newInstance("こんにちは。", 2, null))
}
```

このコードを呼び出すと以下のような実行結果となります。
適切なビットマスクを設定した場合、渡した引数は無視され、デフォルト引数が用いられていることが分かります。

```:呼び出し結果
Clazz(foo=こんにちは。)
Clazz(foo=Hello World.)
Clazz(foo=こんにちは。)
```

## これがどう役立つか
`Kotlin`のリフレクションでデフォルト引数を用いた関数呼び出しを行う場合、`kotlin-reflect`モジュールを使って`callBy`するのがほぼ唯一の方法です。
一方、`kotlin-reflect`モジュールは容量が重く、環境によっては扱いにくさが有ります。

今回紹介した方法を上手く使うことができれば、リフレクションを用いて関数呼び出しするツールから`kotlin-reflect`を削除することができるかもしれません。

ただし、実際にこれをやる場合、`kotlin-reflect`無しの`KFunction`からはパラメータ情報が取得できない、`Java`のリフレクション上の`Constructor`/`Method`を取得できないといった事情が有るため、単純に`kotlin-reflect`を削除できるとはなりません。
まだ詰め切れていませんが、自分が分かっている限りでは`kapt` + `KotlinPoet`みたいな感じで事前に処理できる場合には役に立つかもという程度です。

## 参考にさせて頂いた内容
下記コードの中で登場する`TestClass`に対して生成される`TestClassJsonAdapter`の`fromJson`関数にて、実際にこれを用いてデフォルト値を含む関数呼び出しを実装している様子が見られます。

https://github.com/square/moshi/blob/230c3d801fe8c0296986c09d27e7f32a41ec933e/kotlin/tests/src/test/kotlin/com/squareup/moshi/kotlin/DefaultConstructorTest.kt
Macターミナル備忘録(Tab　予測変換)

基本的に今までPCはWindowsしか触って来なかったので、個人的なMac関連の備忘録を残していきます。

職場のWindows PC でコマンドプロントを使用して、簡単なことですが一括でファイルの名前の変更、フォルダーの作成など作業の簡略化を行っていました。


その際に、winではTabキーを押すことで自動で予測変換を行ってくれるので、Macでももちろん出来るだろうと思っていましたが何も起こらなかったので検索・設定してみました。





<h2>作業内容</h2>
<ol>
  <li>homebrew install</li>
  <li>homebreを使ってbash-completionパッケージをインストール</li>
  <li>.bash_profileを書き換える</li>
  <li>source .bash_profile　で更新</li>
  <li>ターミナル再起動、確認</li>

</ol>

<h2>homebrewのインストール</h2>
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f35353138382f38346639326634662d633565622d343263642d333632302d6534383337396132313163652e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1257819/4714af13-4f7e-d8f2-4ced-7e399da22ac8.png)


<a href="https://brew.sh/index_ja" rel="nofollow noopener" target="_blank">Homebrew</a>のサイトトップに表示されているインストールコマンドをコピー、ターミナルに貼り付けて、Enterを押すとインストールが開始されます。

<h2>bash-completionパッケージをインストール</h2>
homebrewインストール後下記コマンドをターミナルに貼り付け＋Enter（実行）

<pre>brew install bash-completion</Pre>

<h2>.bash_profileを書き換える</h2>
.bash_profileはおそらくホームディレクトリにあると思われるので、
ターミナルを開いてすぐの状態で　ls -a などのコマンドで確認してみるといいかもしれません。

<h3>.bash_profileがない場合</h3>
.bash_profileがない場合はターミナルをホームディレクトリの状態で
下記コマンドを入力してファイルを作成します。
<pre> touch ~/.bash_profile</pre>

<h3>.bash_profileがすでにある場合</h3>
.bash_profileがすでにある方は下記コマンドをターミナルで入力、エディタ画面を起動します。
<pre>vi ~/.bash_profile</pre>

エディタを起動したら、下記コードを記入します。
<pre> if [ -f $(brew --prefix)/etc/bash_completion ]; then
  . $(brew --prefix)/etc/bash_completion
fi
</pre>

<h2>source .bash_profile　で更新</h2>
編集が完了したら、下記コマンドを入力して内容を更新します。
<pre>source ~/.bash_profile</pre>

<h2>ターミナル再起動、確認</h2>
source〜を実行した後には何も表示されてないかと思いますが、
そのままのターミナルの状態ではTabキーを押しても予測変換されないので、
ターミナルを１度終了して立ち上げ直して動作確認。


<h2>参考サイト</h2>
https://qiita.com/greenteabiscuit/items/5048457163ab68a6e091

https://qiita.com/zaburo/items/29fe23c1ceb6056109fd
【ESP32・M5Stack】ペアリング済みBluetoothデバイスの取得とペアリング解除

# この記事の目的
ESP32やM5Stack系のデバイスで、一度ペアリングしたBluetoothデバイスの一覧を取得する。またそのデバイスのペアリングを解除する。

# ペアリングしたデバイスの一覧取得
事前にBluetoothの初期化が必要です。例えば`BluetoothSerial`を使用する場合は`BluetoothSerial`内の`Begin()`を呼び出した段階で初期化が完了しています。

```C:bt_list.ino
#include "esp_gap_bt_api.h"
#include "esp_bt_main.h"

  int paired_count = esp_bt_gap_get_bond_device_num(); //ペアリングしたデバイス数を取得
  esp_bd_addr_t dev_list[100];
  esp_err_t result =  esp_bt_gap_get_bond_device_list(&paired_count, dev_list); //ペアリングしたデバイスのアドレス一覧を取得
  Serial.printf("BT paired count=%d\n", paired_count);
  if (result == ESP_OK)
  {
    for (int i = 0 ; i < paired_count; i++) {
      Serial.printf("[Device%d]%d\n", i, dev_list[i]); //アドレスを表示
    }
  } else {
    Serial.println("esp_bt_gap_get_bond_device_list failed");
    return;
  }
```
コードの中ではdev_listの配列要素数を`100`としていますが、実際にはそのデバイスで同時にペアリングできる最大数を指定してください。

# ペアリングの解除
先に示したコードのアドレス(`dev_list[i]`)を指定して、以下のような関数を呼び出すことでペアリングを解除できます。

```C:bt_list.ino
 esp_bt_gap_remove_bond_device(dev_list[i]);
```

# ペアリングしたデバイスの一覧取得を行う全体コード
Serialにペアリングしたアドレス一覧を1秒ごとに出力するコードです。
[bluetoothserial.cpp](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/src/BluetoothSerial.cpp)を参考に、Bluetoothの初期化を行うコードも含ませています。
`M5StickC Plus`で動作することを確認しています。

```C:bt_list.ino
#include "esp_gap_bt_api.h"
#include "esp_bt_main.h"
#include <esp_log.h>
void setup() {
  Serial.begin(115200);
  init_BT(); //Bluetooth初期化
}

void init_BT() {
  if (!btStarted() && !btStart()) {
    log_e("initialize controller failed");
    return;
  }

  esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
  if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
    if (esp_bluedroid_init()) {
      log_e("initialize bluedroid failed");
      return;
    }
  }

  if (bt_state != ESP_BLUEDROID_STATUS_ENABLED) {
    if (esp_bluedroid_enable()) {
      log_e("enable bluedroid failed");
      return;
    }
  }
}
void loop() {
  int paired_count = esp_bt_gap_get_bond_device_num(); //ペアリングしたデバイス数を取得
  esp_bd_addr_t dev_list[100];
  esp_err_t result =  esp_bt_gap_get_bond_device_list(&paired_count, dev_list); //ペアリングしたデバイスのアドレス一覧を取得
  Serial.printf("BT paired count=%d\n", paired_count);
  if (result == ESP_OK)
  {
    for (int i = 0 ; i < paired_count; i++) {
      Serial.printf("[Device%d]%d\n", i, dev_list[i]); //アドレスを表示
      //esp_bt_gap_remove_bond_device(dev_list[i]); //削除
    }
  } else {
    Serial.println("esp_bt_gap_get_bond_device_list failed");
    return;
  }
  delay(1000);
}
```

## 参考文献
以下のページを参考にして本記事を執筆しています。

CLASSIC BLUETOOTH GAP API - ESP32 -  &mdash; ESP-IDF Programming Guide latest documentation
[https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_bt.html](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_bt.html)

BluetoothSerial.cpp
[https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/src/BluetoothSerial.cpp](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/src/BluetoothSerial.cpp)
ラズパイでHPをつくって全世界に公開まで

本記事では、以下の流れでHPを作ります。


1. ラズパイでApacheサーバーを立ち上げる。
1. Freenomで適当な名前でドメインを取得する。
1. MyDNSで動的IPとドメイン名を紐づける。ほとんどの自宅の場合動的IPが割り当てられているので、MyDNSを使用してIPとドメインの紐づけを変更されるたびに行わなくてもいいようにする。
1. google検索等ではHTTPSでないとはじかれてしまうので、Let's encryptを用いて通信をSSL化する。
1. 
![ドメイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/8c53d59d-c4ab-2b05-0b57-3a9ebace027b.png)

#　ラズパイでApacheサーバーを立ち上げる。
`sudo apt-get install apache2`
でラズパイにapacheをインストールする。

`cd /var/www/html`
デフォルトでは`/var/www/html`がApacheサーバーのホームディレクトリになっているのでここへ移動する。

`sudo vim index.html`
index.htmlを作成する。index.htmlがドメインにアクセスした際に飛ばされるHPのトップページになる。

`sudo systemctl start httpd`
このままだとただラズパイが起動しているだけでapache2サーバーとして動いていないので、デーモン化してアクセスを待機する。

`sudo systemctl enable httpd`
このままだと起動の度に↑のスクリプトを実行しなければ、デーモンが立ち上がらないので、自動で立ち上がるように設定する。



# Freenomで適当な名前でドメインを取得する。

[Freenom](https://www.freenom.com/ja/index.html?lang=ja)とは、無料でドメインを取得できるサービス。
.ml（マリ）や.tk（トケラウ - オーストラレシアにある自治領）など、マイナーなドメインになるが、十分。

90日間の中で25回以上のアクセスがなかった場合はドメインがはがされてしまうので注意が必要。
なので、対策をする。対策内容は、MyDNSの設定のセクションで説明。


# MyDNSで動的IPとドメイン名を紐づける。

ラズパイから[MyDNS](https://www.mydns.jp/)に定期的にIPをお知らせすることで、IPが変わってしまうことへの対策とする。

MyDNSではドメインごとにアカウントを登録しなければいけないので新しく登録。
DOMAIN INFOセクションで、ドメイン名を設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/33433b18-a26b-3bba-f010-13e73141cede.png)
また、同ページにあるName Server Listをメモしておく。Freenomにおいて、ドメイン名を探しにいくネームサーバーを登録する必要があるため。

Freenomにて、MyDNSのネームサーバーを名前解決のネームサーバーとして登録する。
Freenomにログインしたら、Services⇒My Domains⇒該当するドメインの"Manage Domain"にて設定画面を開く。
Management tools⇒name serversでネームサーバーを登録する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418672/667f43ac-16ac-a0d5-c57e-e9c025902b93.png)


# google検索等ではHTTPSでないとはじかれてしまうので、Let's encryptを用いて通信をSSL化する。
[こちら](https://qiita.com/ariaki/items/5680cb6da6223844af4e)の記事を参考にLet's encryptを利用する。