OmniAICreator/Qiita-1.07M huggingface dataset:
[AWS CLI] cofigureを設定せずに一時的にCLIを利用する

# AWS CLIを一時的に使用する
EC2インスタンス上でAWS CLIを利用するには、aws configureを使うことが
一般的かと思います。configureを利用すると、コンフィグファイル( ~/.aws/config)
にID情報を格納します。
しかし、他の人も使用する場合、ID情報を格納しておきたくないです。
※本来、使用者ごとにユーザーを作成すればよいですが、
　ユーザー名：ec2-userを他の人と使いまわすこともあり得るかもしれません。
上記、実現するために、環境変数に一時的にID情報を格納することで、
AWS　CLIコマンドを利用することができます。
なお、環境変数のため他のコンソールからのアクセスでは、
AWS　CLIコマンドは効きません。
備忘録として残しますが、誤りがありましたらご指摘ください。

# 事前準備
・アクセスIDとシークレットIDを取得する
１．AWSサービス一覧から「IAM」を選択。
２．ユーザーより対象のユーザーを選択。
３．認証情報からアクセスキーの欄のアクセスキーの作成をクリック。
⇒アクセスIDとシークレットIDが取得できるので、保持しておきます。

``` sh
# まずは、環境変数の設定をしていない場合
[ec2-user@ip-10-0-0-155 ~]$ aws ec2 describe-vpcs
You must specify a region. You can also configure your region by running "aws configure".
⇒通常、configure設定を要求されます。

# ここでexportを用いて、IAMで取得した各種変数を設定します。
[ec2-user@ip-10-0-0-155 ~]$ export AWS_ACCESS_KEY_ID="*********"
[ec2-user@ip-10-0-0-155 ~]$ export AWS_SECRET_ACCESS_KEY="***********"
# 使用するリージョンを記述します。東京なら下記です。
[ec2-user@ip-10-0-0-155 ~]$ export AWS_DEFAULT_REGION="ap-northeast-1"
# AWS CLIの応答でのフォーマットを選択します。ここではjsonとします。
# JSON (json) / タブ区切りテキスト (text) / ASCII 形式のテーブル (table)から選択できます
[ec2-user@ip-10-0-0-155 ~]$ export AWS_DEFAULT_OUTPUT="json"
# 再度実行します。
[ec2-user@ip-10-0-0-155 ~]$ aws ec2 describe-vpcs
※応答データは記載しておりませんが、json形式でVPCの情報が表示されます。

```

## 下記が設定する環境変数一覧
上記で使用した環境変数は下記となります。コピー用に再記載します。

```sh
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
export AWS_DEFAULT_REGION=""
export AWS_DEFAULT_OUTPUT=""
```
## リージョン一覧
下記にAWS_DEFAULT_REGIONに設定するリージョンが一覧化されています。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html
vim-jpの活動とプラグインとヘルプファイル

# お題
今回の話題は「vimのヘルプの公開」です。

## 序
vim-jpはvim界隈でも活動実績が評価されてるユーザーグループです。(なんとなくはしっこに参加させてもらってます)

ここの成果はいろいろありますが...

- vim本体の不具合の確認やパッチ作成の場(日本語)
- vital.vimという有用ライブラリプラグイン(他のプラグインに取り込んで使う)
- vimのヘルプの日本語訳

などがあります。

ここで今回のに関係するものとして「vimのヘルプの日本語訳」があります。

本体の日本語化などはKaoriya(香り屋)版vimで有名な @koron さんや @mattn さんらが[始めて](https://www.kaoriya.net/blog/2011/08/20110813/)、ヘルプについても多数の方が継続的に翻訳更新しつづけているものです。現在は @h_east さんらが積極的に活動されてますね。

これはプラグインとしてvimへ導入できるので、その用途での利用が多いかと思います。
ただ、あわせてHTML変換したヘルプを公開しており、

> [help - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/)

として閲覧可能です。

## プラグインのヘルプ

話はかわりまして、各Vimプラグインですが、(英語の)help docが充実しているというのがあります。

これは

- 統合的なパッケージ管理サイトが作られたとはいえなかった(なくはないが更新がおいつかない)、これによって独立独歩な気風がある
- Emacsでもややそうだが、疎結合すぎるor勝手に動くと迷惑になりすぎることもあり、プラグインとして説明が必須なこと
- 併せて、設定のためのUIなどはなく、ヘルプから設定オプションを知る必要がある/知らせる必要があること
- インタフェースが自由(すぎる)ので、ヘルプで利用方法を説明し、そうしているIFは安定IF、逆に説明がないならどんどん変更しても文句はいわせない、という線引きになる(あるプラグイン製作者曰く)

という理由などになります。

## 課題

さて、各プラグインのヘルプなのですが、ただでさえ英語多数なのに加え、プレーンテキストベースの文章です。
読める環境を制限しないかわりに、ミニマークアップ程度なので、読みやすいかというと微妙です。

ですが、そういう状況でも各プラグインのドキュメントはHTML化などはあまりされていません。
(自動生成ドキュメント系はHTMLにしての公開が多いですよね、Python系とか)

これはvimで見るうえ、そのvimではハイパーリンクやシンタックスハイライト+自分の好きなカラースキームで見れるというのがあるためです。

ただ、vim-jpの vim help で分りますが、HTML化+公開すると、

- Webから簡単に見れる/Vimがなくても見れる
- Vimなどにくらべるとフォントとカラーリッチ(やろうと思えば)

などもあり、無駄ということもなさそうです。

## 解決

今回、これを解決するために、簡単にHTMLで公開できるように仕組みを作ってみました。

<a href="https://github.com/tsuyoshicho/action-vimhelp-html-generate"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/tsuyoshicho/action-vimhelp-html-generate.png" width="460px"></a>

GitHub Actionsを有効にし、上記actionを使って次のワークフローを定義することで、自動でgh-pagesへデプロイできます。

```vimhelpdeploy.yml
name: "deploy vim help to gh-pages"
on:
  push:
    branches:
      - master
jobs:
  ghpages:
    name: Convert and deploy vim help
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@master
      - name: generate html
        uses: tsuyoshicho/action-vimhelp-html-generate@master
        env:
          FOLDER: build
      - name: deploy gh-pages
        uses: JamesIves/github-pages-deploy-action@master
        env:
          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
          # alternative GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BASE_BRANCH: master
          BRANCH: gh-pages
          FOLDER: build
```

例
- 自作vimプラグイン [vim-pass](https://github.com/tsuyoshicho/vim-pass) のHTML化 [doc](https://tsuyoshicho.github.io/vim-pass/)

これを各プラグイン製作者が自分のプラグインに組込むことで、自動的(GitHubのリポジトリオプションでgh-pagesを公開する設定は必要)に公開できます。

### 不具合
なお、変換にかかわるコードを vimdoc-jp からもってきて移植したのですが、まだまだ荒削りで以下の不具合があります。

- ターゲットはvim help固定、docフォルダ固定(これはまあ仕様に近いから拡充するモチベーションはないですが)
- ライト固定でbackgroundのダーク化や、カラーテーマの選択はできない(さぼってる)
- なにより自動生成しているindexが `tree` コマンドそのまま

## 結

各vimプラグインの内容をもっと低い敷居で取得、理解できるようになり、vimとプラグインが発展していくと嬉しいですね。

(というか、持ち上げておいてなんですが、ヘルプのないプラグインもそれなりにあるし、日本人作でもグローバル対応としてヘルプが英語だけ/手間から日本語だけ、みたいなことも多いので、HTML公開でのアピール向上がしやすくなることで、それがもうちょっとでも充実させるモチベーションになって、充実してほしいというのもあります)
gitで変更内容を元に戻したい

初心者な私がいろいろローカルで開発中している際、
いろんなファイルをごちゃごちゃ追加してしまって
動かしてみたら予期していないエラーが多発した・・・。

収拾がつかなくなって元に戻したい！って時に使えるコマンドを
備忘録として記事にしました。
（インデックスにあげる前が前提）

#ローカルのファイルの中身を元に戻す
```
$ git checkout .
```
これで既存の変更した全てのファイルの中身は元に戻ります。

一応、ファイル毎に指定する方法も、　

```
$ git checkout (ファイルパス)
```
これで直せます。
ファイルパスは`$ git status`で確認してコピペするのもありかと思います。

#ローカルで変更した内容全てを元に戻す
```
$ git clean -fd
```
gitのローカルで追跡されていない全てのファイルをディレクトリを含めて削除できます。
新規でつくったファイル達はこれで居なくなります。　
　

これでインデックスにあげる前なら元に戻せます。
ffmpeg-pythonで動画ファイルの情報を取得する

ffmpeg-pythonを使って、動画の情報をストリームごとに辞書で取得する方法。あらかじめffmpegとffmpeg-pythonをインストールしておくこと。

```python:get_video_info.py
import sys
from pprint import pprint
import ffmpeg

in_filename = sys.argv[1]
probe = ffmpeg.probe(in_filename)
for stream in probe['streams']:
    print('stream {0}: {1}'.format(stream['index'],stream['codec_type']))
    pprint(stream) #Python3.8からsort_dicts=Falseが使える
    print('')
```

```:実行結果
$ python get_video_info.py "sample.mp4"
 stream 0: video
 {'avg_frame_rate': '30000/1001',
  'chroma_location': 'left',
  'codec_long_name': 'MPEG-2 video',
  …省略…  
  'width': 1440}

 stream 1: audio
 {'avg_frame_rate': '0/0',
  'bit_rate': '255750',
  'bits_per_sample': 0,
  'channel_layout': 'stereo',
  …省略…  
  'time_base': '1/90000'}

 stream 2: subtitle
 {'avg_frame_rate': '0/0',
  'codec_long_name': 'ARIB STD-B24 caption',
  'codec_name': 'arib_caption',
  …省略…  
 'time_base': '1/90000'}
```
qiitaのtagsページのページネーションが微妙と感じたので今後のUIデザインの反面教師とした際のメモ

#概要
普段はReactNativeでiOSアプリを開発、改善を行なっている

今回は、qiitaで記事を書くにあたり自分が持ってる技術について現在何がqiitaで受けてるか事前に該当技術のタグの一覧(例：[Javascript](https://qiita.com/tags/javascript)）を調べてから描き始めるが、この一覧のページ遷移が扱いにくかったので、自分が開発運営しているサービスのUI改善などに活かすべくメモを共有する

#現状
サイトに入った直後
<img width="550" alt="スクリーンショット 2019-11-03 16.21.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99502/4b4b6291-5ec0-ab63-fdbf-57271d3cacff.png">



ページネーションに注目した動作
![cursorqiitapaginationnotgood.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99502/30017273-434d-bb73-4c25-59988e6eb05e.gif)

上記のように、次ページを押すと戻るリンクが出現しそれに押されるようにページネーションエリアが右に移動している
その結果、次ページリンクもズレてしまい戻るリンクが出る2ページ以降同じ位置でクリックすることができずにそのズレに対応する位置にカーソルを動かさざるを追えなくなってしまう

下記に該当HTMLを記述する

```first_page_.html
<ul class="st-Pager">
   
   <li class="st-Pager_count"><span>1 / 2935</span></li>
   <li class="st-Pager_next">
       <a class="st-Pager_link" rel="next"><span class="fa fa-angle-right"></span></a>
   </li>
</ul>

```


```next_page_.html
<ul class="st-Pager">
   <li class="st-Pager_prev">
      <a class="st-Pager_link" rel="prev">
        <span class="fa fa-angle-left"></span>
      </a>
   </li>
   <li class="st-Pager_count"><span>2 / 2935</span></li>
   <li class="st-Pager_next">
       <a class="st-Pager_link" rel="next"><span class="fa fa-angle-right"></span></a>
   </li>
</ul>

```

この二つを見比べるとli.st-Pager_prevが新しく出現していることがわかる

#解決案

解決案としてあらかじめ1ページからでも戻るリンクを出現させることがqiitaのcssを見てすぐ解決できる方法だと感じた

どうやらjustify-content: centerの仕様がそもそもこのcssを設定したタグを中心に置くことに特化した設計なようで、タグが幅が変化した際に同様に中央も変化していくのが原因だった

つまり初めから変化させない前提でデザインしていくことが解決への最短距離ではないかと思っている

```proposal_first.html
<ul class="st-Pager">
   <li class="st-Pager_prev">
      <a class="st-Pager_link disabled" rel="prev">
        <span class="fa fa-angle-left"></span>
      </a>
   </li>
   <li class="st-Pager_count"><span>1 / 2935</span></li>
   <li class="st-Pager_next">
       <a class="st-Pager_link" rel="next"><span class="fa fa-angle-right"></span></a>
   </li>
</ul>

```
上記HTMLはfirst_page_.htmlに戻るリンクを追加させた構成となっている
その戻るリンクのクラスに新しくdisabledを追加した　このクラスに1ページ目だけはクリックさせないように[css](https://oar.st40.xyz/article/365)に記述する

```paginate.css
a.disabled{
   pointer-events: none;
}
```

これで1ページ目に存在する戻るリンクが押されない状態になった
そのため配置バランスは1ページ目と2ページ目以降共に同じになり、ページ送りの煩わしさが減ったと思う

ただこのままではページを送っても戻るリンクを押すことができないのでJavaScriptでaタグのdisabledクラスを消して再度ページを戻れるように細工をしたい


今回のメモでは1ページ目と2ページ目以降のリンクデザイン崩れについて言及したが最終ページとその前のページも上記記述の応用で解決する




#参考文献
[ST40PG: ＜a＞タグのリンクを無効(disabled)にする](https://oar.st40.xyz/article/365)
【Element UI】Component Sample 

# Element UI の Component Sample 
随時更新していきます。
# 目次
- [Button](#Button)

# Button
```button.vue
<template>
  <div>
    <el-button @click="test()">テスト</el-button>
  </div>
</template>

<script>
export default {
  methods: {
    test() {
      console.log("ボタンがクリックされました");
    }
  }
};
</script>
```
スクレイピングした結果を縦書きのCSSで保存する書き方

スクレイピングをした結果、CSVの横軸制限２５５を超えてしまって全部保存できなかったので
なんとか縦書きにCSV出力するために奮闘した結果を備忘録的な意味で残します。

```
CSV.open("categories#{id}.csv", "w") do |csv|
    doc = Nokogiri::HTML.parse(html, nil, charset)
    doc.css('.brand-list-initial-box-brand-name > div > p').each do |node|
      category = []
      category << node.inner_text
      csv << category
    end
  end
```

※※※※※※※※※※※※※※※※注意※※※※※※※※※※※※※※※※※※

```
 doc.css('.brand-list-initial-box-brand-name > div > p').each do |node|
 category = []
```

上記部分を逆順にすると要素１つに対して保存内容が乗数的に増えてしまうのでお気をつけください。
勉強ログ_day6_MySQL入門⑤(条件指定・集計）

# はじめに
非エンジニアの勉強ログ。
**超初心者プレイ**のため、内容は自分の勉強メモです。

### 今日のゴール
- MySQL　条件指定したり集計したり

### 環境
- ホストOS：Windows10 Pro 1903
- [こちら](https://qiita.com/kantan/items/099e2c3ed700f1781df8)で構築した環境を利用する
- MySQL:5.7.27
- SQL開発ツール：A5:SQL Mk-2 2.14.4

### 参考資料・引用元など
- ドットインストール：[MySQL入門](https://dotinstall.com/lessons/basic_mysql_v3 "MySQL入門") ←勉強はこれを基軸に進める
- Qiita：[よく使うMySQLコマンド集](https://qiita.com/CyberMergina/items/f889519e6be19c46f5f4)

# 条件つけたカラムの生成
### if, case 利用してテーブル生成
ifやcaseで条件つけて新たにカラム出せる
頭にcreate table つけると、それをそのままテーブルにもできる

```ruby:mysql
select 
  user_name,
  age,
  if (age > 20, 'Adult', 'Young')
from persons;
```

```ruby:mysql
create table user_ivents as
select 
  user_name,
  age,
  case
    when age = 20 then 'congratulation'
    when age = 30 then 'marverous'
    else null
  end as ivent
from persons;
```

### テーブルコピー
createとas組み合わせでテーブルコピー可能
※as省略可
likeつけると中身からになる

```ruby:mysql
create table info_copy select * from persons;
create table info_empty like pesrons;
```

# グループで集計
group byをつかう
group byしたカラム・数字で条件絞りたかったら、そのあとにwhere
select自体を条件絞って出したかったらgroup by より前にwhere


# あとがき
- ifでカラムだせるのめっちゃたのしい　これほしかったやつ
【BootStrap基礎】中寄せ,背景色の変更

##Bootstrap忘備録

.text-center => 中寄せ

.bg-primary => 背景を青色にする など

```html:html
<h2 class="font-weight-normal display-4">Hello Bootstrap</h2>
<div class="text-center bg-primary">BOX</div>
<div class="text-right bg-success text-warning">BOX</div>
<div class="text-center bg-info font-weight-bold">BOX</div>
<div class="text-center bg-dark text-light">BOX</div>
```

↓
<img width="759" alt="スクリーンショット 2019-11-03 16.45.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/8575b50e-5bc6-e862-1593-4e1c0472fa64.png">
MariaDB を一般ユーザーで起動

MariaDB を一般ユーザーで動かす時は、ポート番号とソケットが他のユーザーと衝突しないように
変更をします。

次の設定ファイルは、
　ポートを　49554
　ソケットを　/tmp/mysql_uchida.sock
に設定します。

```text:/home/uchida/my-opts1.cnf
[mysqld]
datadir = /home/uchida/mydata1
port = 49554
socket=/tmp/mysql_uchida.sock

[client]
socket=/tmp/mysql_uchida.sock
```

起動方法

```bash
mysqld --defaults-file=/home/uchida/my-opts1.cnf
```
Accessで必ず使う VBA Navigation Paneにアクションマクロボタンだけ表示させるか切り替えるVBA

#NavigationはPaneかWindowか
今一つ揺れるんですけど、現在の解説は単にNavigationとしているみたいですね
とりあえずナビゲーションペインと呼んでいます。
VBAではそうなっているので。
#アクションマクロで起動することでメニュー画面にする
アクションマクロボタン自体をメニューにすることも可能ですが、デザインに時間がかかります。
そこで、単純にマクロボタンだけ表示させるようにして、マクロボタンのところをメニュー画面代わりにしようというものです。

##マクロボタンのとても便利な点
###といってもかなりコアですが・・・
CSVファイルを読み込むSelect Into系のクエリは、データベースと同じフォルダにあるファイルをしているすると、なぜか次から表示されなくなります。
たしかにフォルダを移動するからそれもありですが、やはり困ったものです。
ところがマクロボタンにSQLを登録するとフォルダ名が変わりません。
実はアクションクエリ保存ボタンだったのです。

###まずコード
マクロからSubプロシージャを起動する場合、このように起動するユーザー定義関数が必ず必要です。これではちょっと紛らわしいので
mcr_Moduleといった名前のモジュールを作成してユーザー定義関数（User-defined function,UDF)はそこに書くようにしています。っそのかわり別のモジュールから呼び出すために、Publicがついているわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/51f239c1-c424-d6ef-8466-6bcf1a83f9cb.png)
さらにこうしたSwitchNavigationDiscriptionOptionのようなものはどういうAccessのデータベースでも役立ちます。こうしたどのデータベースでも使用するコードはTool_acModuleに入れます。すると、Exportすれば他のデータベースでも使えるため、毎回コードを書かなくて住みます。なおacModuleはAccessのモジュールを表しています。McrはMacroとしたいのですが、Mainの前に来てしまうので、ちょっと省略した形になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/385852e9-014c-169e-b23f-412e8fb74631.png)
実際にMcr_acModuleに入れているところです。Tool用は共用のため、他と分けて書いておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/8253312d-b6b7-bfce-c80f-c4272a76fa53.png)
実際にこういうイメージで、Tool用は下に来るようにします。

####注意
このVBAは起動する前にまずマクロボタンを作ってください。
そうしないと全く表示されなくなります。

```vb
Public Function Macro_SwitchNavigationDiscriptionOption()
Call SwitchNavigationDiscriptionOption
End Function

Public Sub SwitchNavigationDiscriptionOption()
Dim flag As Boolean
flag = Application.GetOption("Show Hidden Objects")
If flag = True Then
DoCmd.NavigateTo "acNavigationCategoryObjectType"
DoCmd.RunCommand acCmdViewMacros
Else
DoCmd.NavigateTo "acNavigationCategoryObjectType"
End If
Application.SetOption "Show System Objects", Not flag
Application.SetOption "Show Hidden Objects", Not flag
Application.SetOption "Show Navigation Pane Search Bar", True
End Sub
```

###アクションマクロのプロシージャの実行はユーザー定義関数がないとできない
VBAとアクションマクロ、連携して使いたいのですが、このような変なルールがあります。

###ユーザー定義関数のテクニック
できればこのマクロ用のユーザー定義関数だけのモジュールがあったほうが良いです。
作り方はまずSubを作ります。
そして名前をコピーします。
Function のあとにMacro_と打ってコピペします。
Call のあとにコピペします
マクロボタンを作成し、プロシージャの実行でMacro_とするとアクションマクロ用の関数だけが出てきます。出てこないときは
Macro_としてコピペし、半角の()をつけます
この（）は大事です。
###マクロボタンは名前で優先順位が付くようにする
次にマクロボタンは手順に沿って使う順番にネーミングします。
01_CSVのインポート
といった感じです
システムのメンテナンスはツールとして
T_Navigation詳細表示とします。
今回のVBAはここに登録します。
するとメンテナンスは後ろ、操作は上にきます。
機種依存文字の使用はできません。
またテーブル、クエリ等を含めて名前は固有でなければならず、重複ができません。
#この他お役立ちMacro
隠し機能のアプリケーションの起動でcalc.exeが起動できます。
【RPA】本当の自動化 vs 趣味の世界

RPAは「1」と「1」を繋ぎ合わせることで自動化をしよう！という技術です。
例えば、Excelからデータを取ってきて、基幹システムに登録する。こういうのはよくあると思います。

そのような自動化をするための「開発」はもっと楽にならなければいけません。なぜなら、RPAは「誰もが開発できるツール」である必要があるからです。

将来は「1人1RPA」の世界になっているのが理想です。

※これはRPA Community主催のRPALT vol14でお話した内容です。

# もっと開発を楽にする - 本当の自動化 -

先程も申し上げましたが、本当に自動化のハードルを下げたいなら、もっともーっとたくさん部品を作って、大きい部品・小さい部品いろいろ作って、それを組み合わせるだけの状態にする必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238739/b7fb692a-cea8-8f6b-1afb-6e05e29ef706.png)


ただ、面白みに欠けるというのが実情...（結構大事）

# もっと開発を楽しくする - 趣味の世界 -

全部繋ぐ合わせるだけなら、開発が退屈になっちゃいます。

誰でもできるものになればなるほど、面白みに欠けてしまいます。


しかし、よくよく考えてみると身近に組み合わせて遊ぶものがありますよね！！

それは**レゴブロック**！

RPAはレゴブロックを目指すのが良いのでは？と思いました。

# RPA!目指すはレゴブロック！

レゴの特徴は

* 組み立てるのが簡単
* カスタマイズ性が高い
* 組み立てれば、基本的になんでも作れる！


つまり、簡単な自動化から高度な自動化までできるんです！！

しかも楽しい！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238739/d80d768f-11fe-c098-d58c-5f4b6e7b5295.png)


# おわりに

RPAはレゴブロックを目指すのがいいのでは!?という結論に至りました。


部品を大量に作れば、簡単な自動化から高度な自動化までスムーズに実現できます。

そしてレゴみたいに、「こんなのも作れたよ!?」って楽しく"遊べる"ようになると思います。
俺用　備忘録　勉強法

#はじめに
新しいことを始めたいので勉強する．
勉強法について，できる人に教わったのでその時のメモ

#方法
##時間配分について
使える時間に対して，時間の割り振り．
自分の場合，基礎：応用：今の仕事＝5：1：4
つまり，8時間つかうとしたら５時間は基礎的なことに費やす．
1時間は基礎を用いた応用について
残りの4時間を今やるべきことに費やす．

##効率化UPのために．
１日８時間もやるのに成果０っておかしすぎる．
絶対に成果が０にならない行動をする．
Evernoteで議事録を書く．→今日の目標，ノルマ，実際に成功したこと，やり遂げたことを書いていく．

書き方．
今日の目標

実際のタスク
□・・・・・
□・・・・・
□・・・・・
□・・・・・

できるようになったこと
・・・

やり遂げたこと
・・・

明日やること．
・・・

その他
・・・


Evernoteのいいところ
検索に優れている．（紙のメモではすぐに埋もれる．）
スマホでも見れる．
チェックボックスにチェック入れるときの達成感．
PDFも見れる．
ペーパーレス化できるのでごちゃごちゃしにくい．素晴らしい．

##問題に対しての解決方法

###集中できない．
長い間集中してやることない．
5分勉強を１日２回やるだけでもいい．
まずは成功体験をつくる→増やす→時間をのばしていく．

スマホは玄関で充電する．
機内モードにする．



###勉強してもすぐ忘れちゃう

勉強をする→忘れる．わかったつもりになる．頭空っぽ人間の出来上がり．

勉強して忘れるのは当たり前．
忘れたころにまた勉強する→繰り返す→忘れない．
忘れても１回見れば思い出せるチートシートを作っておく．
すべて暗記しても意味がない．プロでも「あれ，これなんだったっけ」は存在する．
理解しておけば，わすれてもなんとなく思い出せるもの．
なんとなくこれやったなあという経験も大事．理解せず暗記してすぐ忘れるほうが最悪．

忘れない勉強方法（１時間の場合）
0. 5～10分くらい前回の見直しをする．（やり方は4～5）
1. 勉強する（40～50分くらい）
2. 終わり５分前に，今日やったことを見返す．
3. その日寝る前に見返す．さっとでいい．
4. 次の勉強の前，前に勉強したこと，覚えている範囲でいいので書き出す．→このときノートは見ない
5. 答え合わせをする．
6. 勉強を始める．
7. 2をやる．．繰り返す

ノートはきれいに書かない．
ノートは取らなくていい．教科書写すのは非効率．
なんとなくのメモだけでいい．

私の場合大事なことノートにとっても埋もれてしまう．
なのでノートとったとしても後でEvernoteに書く→読みたいときに読み返す．


###つまらなくなってきたら？
自分事化する
こんなの将来使わないじゃん．．．．という気持ちで勉強しない．
まずは自分とのかかわりを見つける．

応用する
勉強した内容を用いて面白い応用例を考える．
なるべく馬鹿なやつがいい．記憶にも残るし．

発信すること
人に教えられたら自分の身にもなる．人に教えたり，ブログで発進したりしてみる．

##将来にむけて

変わっていっている時代．
動きに合わせて変化させることも必要．
変なノルマは一切必要ない．
なるべく昔からある古臭い検定や資格は取らない．
資格を持っていても，使っていなければ意味がない．（高学歴で使えないやつが多い．）

##tips
数学は夜にやる．→睡眠導入作用がありよく眠れるようになる．
picoCTF 2019 plumbing - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/96f04e79-2386-33d8-07a6-bdbf06730368.png)

#解いてみた

ひとまずアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5348c156-d99a-78cf-4247-3c86cfce36b3.png)

ダメでした。
ncでアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e38a56bb-829c-7fad-deb2-b331b255c08f.png)

大量のデータが表示されました。
grepすればよさそうですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/cbf7de03-f8f2-4852-42da-7115c5d263b5.png)

できました。
【RPA】IT未経験者 vs エンジニア

RPAはよく「誰でもできる！」などと言われていましたが、最近は「そんなことねーよ！」というつっこみが増えて、誰でもできるものじゃないという認識が広まってきたでしょうか。

ただ、IT未経験者の人がRPAツールを使用するというケースは結構多いように感じます。

そこで実際に私が感じた、「IT未経験者」 vs 「エンジニア」についてお話します。

※本記事は、RPA Community主催RPALT vol.14でお話した内容を記事にしたものです。

# 変数名は英語!?日本語!?

私はUiPathユーザーなので、変数名は英語が日本語か論争がたまにおきます。

変数という概念がないツールもありますが、そこは一旦スルーでお願いします。笑


昔ながらのエンジニアは当然、"英語"で変数を宣言していました。その流れでRPAツールで変数を宣言する際は当然"英語"でしょ!?という人も一定数いたかと思われます。

しかし、RPAの究極的な理想はEUCで、IT未経験者でも使えるのが最善策です。事務員の人がパッと見て意味が分かりやすいものはどちらでしょうか？

それは**日本語**じゃないでしょうか？

RPAツールの場合、変数の宣言に日本語が使えるなら、日本語で良いと思うんです。

# エンジニア思考も必要

変数名の場合は、IT未経験者に寄せて「日本語」が良いと申し上げました。

しかし、RPAといえどシステム開発と似て非なるものはたくさんあります。

例えば"ググり力"。（人によるということは百も承知でいいますが）エンジニアはググる天才です。

疑問を持ったらすぐにググる。これはRPAでも必要な思考だと思います。

他のツールのことをあまり知らないのでUiPathの話に偏ってしまいますが、ワークフローの分割をして"関数"っぽい書き方をするのもエンジニア思考です。

このようなところはエンジニアの真似をするのが良いでしょう。

# 終わりに

RPAは世界で初めて生まれた**IT未経験者**と**エンジニア**の中間に位置する技術だと思います。今までのエンジニアの常識が一部崩れてしまい、誰もが混乱していると思います。
（実際にRPA導入がうまくいっている会社は超少ないという印象を受けます。証拠はありません。。。）

RPAの場合は、IT未経験者とエンジニアのいいとこどりをしましょう！

というお話でした！
picoCTF 2019 picobrowser - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/cd5c1de9-be46-3a0b-0ae7-93ad9111d5c1.png)

#解いてみた

picobrowserのみ表示できるらしいです。
とりあえず普通にアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/73c975b5-0548-a350-9872-8ee9d6badd1c.png)

Sign InとSign Outはどちらも未実装でした。
Flagボタンを押すとpicobrowserではないよというエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/2b7f02b8-97cb-20ac-e38d-0e7cf4baecf3.png)

UAを編集すれば行けそうですね。
ChromeのDeveloper Toolsを使ってUAを編集します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/47eac264-977d-e115-7350-816504f88d52.png)

この状態でFlagボタンを押してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/52449511-1fce-d5c8-e418-205e37c98815.png)

できました。
picoCTF 2019 la cifra de - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5f96e380-4aeb-2d04-b50b-bcf0ec6ced7b.png)

#解いてみた

ncで接続してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ed37205e-ce8b-6ceb-6e82-c3bcdc84bbff.png)

この暗号文を解読すればよいということでしょう。

```
hgqqpohzCZK{m311a50_0x_a1rn3x3_h1ah3x54ioc1h9}
```

これがpicoCTF{XXXXXXXXXXXXX}ということなんだと思います。
ちょっとpicoCTFより文字数が多い気がしますが。

ROT13などシーザー暗号は見てみましたが、違うようです。

quipqiup - cryptoquip and cryptogram solver
https://quipqiup.com/

ここで解析してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/3279eec3-c30c-40af-dcf7-e22e1239de2d.png)

全然それっぽいのができませんでした。

たぶんビジュネル暗号なんでしょう。
pohzCZKはpicoCTFだろうという予想は立ってるので、それを考えながらCyberChef使ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/272a0546-797c-7737-662e-3b4460ec8404.png)

とりあえず最初は両方ともpなのでaでよいですよね。
残りも同じようにやっていくと「agfl」でpicoCTFになりました。
keyはflagということですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/8ecd458d-fa6c-5de1-0d68-877c2bb3931a.png)

これが答えになります。

#ちなみに

ちなみに答えには関係ありませんが、picoCTFより前の文字はスペースがなくて気になったので調べてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f5189dde-c910-dfa9-f625-0b1c84ee7a93.png)

なんかよくわかりません。

いずれにせよ

```
halfpicoCTF{
```

ならスペース入れて

```
half picoCTF{
```

にしたほうが良いんじゃないかなと思った。
【駆け出しWEBエンジニアのためのメモ】配列の要素の平均値算出（Ruby）

※コメント欄の通り scivola様 よりご指摘/アドバイスを頂いたため、コードを修正させていただきます（integerクラスを1つ、floatクラスを2つで新たに記載させていただきました）^^
正確な記事をかけるよう務めておりますが、駆け出し故に未熟な部分もあるかと思います。差し支えないようでしたら、コメント等頂けると幸いです。
　
　
こんにちは。

Rubyの試験の復習中、配列内の要素の平均値を算出する必要がありました。
色々調べたため、こちらに備忘のためのメモを残させていただきます。

よろしければ参考にしていただければ幸いです。

その他、参照させていただいたサイトのリンクも添付しておきます。
感謝です。

```rb
numbers = [1, 2, 3, 4, 5]

# integer
puts average = numbers.inject(:+) / numbers.length #=>3

# float ( Numeric#fdiv )
puts total.fdiv(numbers.length) #=>3.0

# float ( Numeric#fdiv + Array#sum(Ruby2.4以降) )
puts numbers.sum.fdiv(numbers.length) #=>3.0
```

※「numbers.length」は要素の個数の合計で、ここでは「5」。

※以下の「each」で合計を算出しておりましたが「numbers.inject(:+)」に置き換えました。意味を理解するため、以下にメモとして残させていただきます。

※「total = total + number」は「total += number」でもよい。

```rb
total = 0
numbers.each do |number|
　total = total + number
end
```
　

以上です。
他にも書き方はあるみたいです。
ここでは、私がイメージし易い書き方で記載させていただきました。
参考にさせていただいたサイトも以下に添付させていただきますが、
色々と調べてみてください^^


##参考にさせていただいたサイト
https://techacademy.jp/magazine/19683
Railsチュートリアル12章のRestFulルーティングについて整理

# Railsチュートリアル12章のルーティングは複雑

Railsチュートリアル12章では、パスワードの再設定を行う
1.メールアドレス送信画面(パスワード再設定を行いたいユーザのメールアドレス)を表示する
2.メールアドレス送信画面でメールアドレスを送信する
3.パスワード再設定画面を表示する
4.メールアドレス送信画面で新しいパスワードを送信する

というざっくりと、4つの操作がある

## 4つの操作、4つのURL

| HTTPリクエスト    | URL               |Action 	            |名前付きルート 	            |
|:-----------------|:------------------|:-------------------|:-------------------|
| GET             |/password_resets/new |new|new_password_reset_path|
| POST           |/password_resets |create 	|password_resets_path|
| GET             |/password_resets/\<token>/edit| 	edit| 	edit_password_reset_url(token)|
| PATCH               |/password_resets/\<token>|update|password_reset_url(token)|

上記の1～4の操作に対応して、4つのURLルーティングが用いられる

ここで混乱したのは主に
・11章(ユーザーの有効化)ではAction:editで登録動作を行っていた点
・new create /edit updateがモデルの異なる値を更新する点
であった

## 11章はAction:editで登録を行った理由
これは、11章のユーザーの有効化においてはユーザーが何らかの値を送信する必要がないため(今回でいうところのメールアドレスやパスワード)
Getでの送信で登録を行うセキュリティ上の危険性はトークンとダイジェストによる認証で安全性を担保しているのでeditにてそのままDBの値を書き換えている
裏を返すと、12章での処理はユーザーがメールアドレスを送信する、パスワードを送信するという動作が入るためにcreateとupdateが必要となる

## new create /edit updateがモデルの異なる値を更新する点の整理
#### URLルーティングごとにどういった処理を行うかは設計の問題

URLルーティングが先にあって、それに合わせて処理を行う形ではなく
先にあるのは処理で処理に対してURLルーティングが割り当たる

12章でいえば、上記1-4の処理をしなくてはいけないので
今回は画面の新規表示はnew、表示した画面からのPostはCreateを割り当てただけの話であり
例えば、ユーザーを新規作成する場合はユーザーの新規作成画面がnew、画面からのPostがCreateとなる

「ユーザーのメールアドレス再設定」という概念に対して、new /create edit/ updateを割り当てているとも考えられる
new/createにて「ユーザーのメールアドレス再設定」を作成して、edit/ updateにて「ユーザーのメールアドレス再設定」を編集してパスワードを再設定する
と考えられる
XPMCKでVGMを作る備忘録

XPMCKでVGMを作ると、メガドラのサウンドのvgmファイルを作ることができる。

FM音源のパラメータがどうなっているのかよくわからんので調べてみた。

マニュアルはここ
http://jiggawatt.org/muzak/xpmck/manual.html


# FMのアルゴリズムは@で指定

			@0 = Distortion guitar, high hat chopper bass
			@1 = Harp, PSG-like sound
			@2 = Bass, electric guitar, brass, piano, woods
			@3 = Strings, folk guitar, chimes
			@4 = Flute, bells, chorus, bass drum, snare drum, tom-tom
			@5 = Brass, organ
			@6 = Xylophone, tom-tom, organ, vibraphone, snare drum, bass drum
			@7 = Pipe organ

## フィードバック
FB2　

## 　オペレーター指定
OP0
OP1 
OP2
OP3
OP4

## FMレートスケーリング
RS2
ピッチに対してのエンベロープ速度が変わる
 
## デチューン
D-1

## デチューンの何か
MF2 MF3

0-15

## エンベロープ
@ADSR0 = {31 3 4 30 0}

OP0 ADSR(28 29 4 25 19)



@MOD0
なんだろう

・・・
mckとも共通の部分も多い感じがする。
【駆け出しWEBエンジニアのためのメモ】each_with_index（Ruby）

こんにちは。

Rubyの試験の復習中「each_with_index」と出くわしました。

初見ですが、調べてみるとものすごく使える。



こちら備忘のためのメモです。

よろしければ参考にしていただければ幸いです。



その他、参照させていただいたサイトのリンクも添付しておきます。
感謝です。





##eachループで回しつつ、行列内の値に1から番号を振りたい時

with_index doの前に、book内の変数「author,title,price」に値を代入後、行列booksに格納してます（結構端折ってますので、わかりにくい場合は申し訳ないです）

```rb
~

book = { author: author, title: title, price: price }

books << book

~



#ここで「each_with_index」を用いて、行列books内のbookに対し１から順に番号を付加してます

books = [ ]

books.each_with_index do |book, index|

  puts "#{index + 1}: #{book[:title]}"

end

```
　

###また「each.with_index」ですと、eachループで回しつつ、行列内の値に指定した番号から順に番号を振ることができるそうです。

１０から順に番号を振ってます

```rb
books.each.with_index(10) do |book, index|

  puts "#{index + 1}: #{book[:title]}"

end
```
　
　
#参考にさせていただいたサイト

https://udemy.benesse.co.jp/development/web/ruby-each-with-index.html
CodeCommitのトリガーからCodeBuildを起動

CodePipelineを使えばいいのでは？となりそうですが、CodePipelineの月額1ドルも節約したい時の話です。

# 前提
| サービス   | 項目                 | 設定値       |
| ---------- | -------------------- | ------------ |
| CodeCommit | リポジトリ名         | sample_repo  |
| CodeBuild  | ビルドプロジェクト名 | sample_build |

# IAMの作成

Lambdaでの実行ロールを作成します。次のポリシーをアタッチした、IAMを作成します。

- AWSCodeBuildDeveloperAccess
- AWSLambdaBasicExecutionRole


# Lambdaの作成

作成したIAMを指定してLambdaを作成します。


![create_lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/94be501e-d6b5-c1cd-5eb9-66af91b36566.png)

Lambdaのトリガーを作成します。今回はブランチをプッシュした際に起動するようにしておきます。

![add_trigger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/7e99b264-a050-fdb8-51c3-8feee001f15d.png)


```python:lambda_function.py
import boto3

def lambda_handler(event, context):
    print("start build")
    client = boto3.client('codebuild')
    client.start_build(projectName='sample_build')
    return 0
```


# まとめ

lambdaが動かせるので、単にAWS SDKを使って起動しました。
firebaseのPromise内でthisを参照する方法


# 何に困っているか

下記のようにある Vue.js の component 内で firebase のクエリを処理してその結果を自分の data 内に格納しようとしたとき、
then の中で this を参照して marker プロパティに代入したいが、実行すると this は undef だと怒られる。

``` javascript
export default {
  data () {
    return {
      markers: [],
    }
  },

  methods:{
    updateMarkers() {
      var db = firebase.firestore()
      var query = db.collection('markers')

      query.get()
        .then(function(snapshot){
          var markers = []
          snapshot.forEach(function(doc) {
            var marker = { position: doc.data().latLng }
            markers.push(marker)
          })
          this.markers = markers
        })
    },
  }
}

```

# どうすれば良いか

this を一旦ローカル変数に格納し、Promise 内でそれを参照させるようにする。

``` diff
export default {
  data () {
    return {
      markers: [],
    }
  },

  methods:{
    updateMarkers() {
      var db = firebase.firestore()
      var query = db.collection('markers')

-
+		var self = this

      query.get()
        .then(function(snapshot){
          var markers = []
          snapshot.forEach(function(doc) {
            var marker = { position: doc.data().latLng }
            markers.push(marker)
          })
-          this.markers = markers
+          self.markers = markers 
        })
    },
  }
}
【GAS】GASで値を保存して次の実行時でも利用する

#概要
値を保存する手段としてSpreadsheet, Propertie, Cache などの方法がありますが、今回はCacheについてです。
以下ぞれぞれの特徴です。

- **Spreadsheet Service** 
    - https://developers.google.com/apps-script/reference/spreadsheet
    - 沢山のデータを永続的に保存できる
    - アクセスは遅い
    - GoogleDriveから閲覧編集できる
    - 基本配列
    - ちょっとした保存とかには面倒
- **PropertiesService** 
    - https://developers.google.com/apps-script/reference/properties/properties-service
    - 小さなデータを永続的に保存できる
    - アクセスは早い
    - GASのメニューから値がKey,Valueで見れる
    - 保存時に文字列に変換される
    - 永続的で便利だが大きなデータは保存できない
- **Cache Service** 
    - https://developers.google.com/apps-script/reference/cache
    - 比較的大きなデータ（100KB）を一時的に保存（最長6時間）できる
    - アクセスは早い
    - keyとvalue.値はGUIから多分見れない（多分）
    - 保存時に文字列に変換される

CacheはリファレンスにもありますがRSSの更新確認のためなどに使うには便利そうです。
前回の実行時間の確認やデータの引き継ぎなどの一時的なデータは文字通りキャッシュを利用したほうが良さそうです。

#Cache Serviceサンプルプログラム
データは保存時に文字列に変換されてしまいます。ラップしてJSONで変換するほうが使いやすそうです。

```javascript
function makeCache() {
  const cache = CacheService.getScriptCache();
  return {
    get: function(key) {
      return JSON.parse(cache.get(key));
    },
    put: function(key, value, sec) {
      //リファレンスよりcache.putの3つ目の引数は省略可。
      //デフォルトでは10分間（600秒）保存される。最大値は6時間（21600秒）
      cache.put(key, JSON.stringify(value), (sec === undefined) ? 600 : sec);
      return value;
    }
  };
}
 
function test3() {
  const cache = makeCache();
  
  Logger.log(cache.put('array',[1,2]))
  Logger.log(typeof cache.get('array'))
  
  Logger.log(cache.put('number',256))
  Logger.log(typeof cache.get('number'))
  
  Logger.log(cache.put('string','test'))
  Logger.log(typeof cache.get('string'))
  
  Logger.log(cache.put('date', new Date()))
  Logger.log(typeof cache.get('date'))
  
  Logger.log(cache.put('object',{a:[1,2], b:1, c:'test'}))
  Logger.log(typeof cache.get('object'))
}

/*以下 ログ
[19-11-03 14:41:56:238 JST] [1.0, 2.0]
[19-11-03 14:41:56:278 JST] object
[19-11-03 14:41:56:340 JST] 256.0
[19-11-03 14:41:56:381 JST] number
[19-11-03 14:41:56:428 JST] test
[19-11-03 14:41:56:456 JST] string
[19-11-03 14:41:56:511 JST] Sun Nov 03 14:41:56 GMT+09:00 2019
[19-11-03 14:41:56:560 JST] string
[19-11-03 14:41:56:623 JST] {a=[1.0, 2.0], b=1.0, c=test}
[19-11-03 14:41:56:637 JST] object
*/
```
CodeCommitのLambdaトリガーを作るときはパーミッションをお忘れなく


CodeCommitのコンソールからLambdaトリガーを作るのと、LambdaのコンソールからCodeCommitのトリガーを作るのは結果が違いますよ、という話です。

# Lambdaが実行されない？

Lambdaをあらかじめ作成しておいて、CodeCommitのコンソールからトリガーを作成。Lambdaのコンソールからトリガーを作るのと結果は一緒でしょーと思っていたが、Lambdaが実行されず。

CodeCommitのコンソールに下記の記載があるので、これだよなーとコンソール上を探し回っても設定できそうなところは見つからず。

![caution_lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123946/9360dbde-5863-f90e-4434-5d8a8da79afd.png)


# パーミッションを手動で追加する

AWS CLIを使ってパーミッションを追加する必要があります。
パーミッション用のjsonファイルを作成します。

```permission.json
{
    "FunctionName": "SampleLambda",
    "StatementId": "1",
    "Action": "lambda:InvokeFunction",
    "Principal": "codecommit.amazonaws.com",
    "SourceArn": "arn:aws:codecommit:ap-northeast-1:xxxxxxxx:sample_repo",
    "SourceAccount": "xxxxxxxx"
}
```

次を実行すると、Lambdaのコンソール上のトリガーにCodeCommitが表示されます。

```shell
$ aws lambda add-permission --cli-input-json file://xxx/xxx/permission.json
```

追加したパーミッションを確認するには

```shell
$ aws lambda get-policy --function-name SampleLambda
```

追加したパーミッションを削除するには

```shell
$ aws lambda remove-permission --function-name SampleLambda --statement-id 1
```

# まとめ

AWS CLIを使ったりして作成する場合にはパーミッションの追加が必要です。Lambdaのコンソールから追加する場合は気にする必要はないです。


# 参考
- https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-notify-lambda-cc.html
バイユーのタペストリーの画像が横長すぎるので、縦１８段に再配置した画像を作る


wikipediaの
バイユーのタペストリーの画像が横長すぎる（幅39866 x 高さ360 pixel）
ので、縦１８段に再配置するc#プログラム。

元ページ：
https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%A6%E3%83%BC%E3%81%AE%E3%82%BF%E3%83%9A%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC

画像：
https://upload.wikimedia.org/wikipedia/commons/1/10/Teppich_von_Bayeux.jpg


```csharp:tape1page.cs
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:winexe tape1page.cs

using System.Drawing;
public class tape1page
{
	public static void Main(string[] args)
	{
		/// https://upload.wikimedia.org/wikipedia/commons/1/10/Teppich_von_Bayeux.jpg
		Bitmap bmpBase = new Bitmap(@".\Teppich_von_Bayeux.jpg", true);
		Rectangle rect; 
		int yi =0;
		int xi;	
		Bitmap canvas = new Bitmap((int)2400, (int)(360 * 18));
		Graphics g = Graphics.FromImage(canvas);
	
		for(xi=0;xi<=(int)bmpBase.Width;xi+=2300){
			rect = new Rectangle(xi, 00, (int)2400, (int)bmpBase.Height);
			/// Teppich_von_Bayeux.jpg  size:39866x360
			if(xi==39100){
				rect = new Rectangle(xi, 00, (int)766, (int)bmpBase.Height);
			}
	
			Bitmap bmpNew = bmpBase.Clone(rect, bmpBase.PixelFormat);
			g.DrawImage(bmpNew, 0, yi, (int)bmpNew.Width, (int)bmpNew.Height);
			yi +=360;
			bmpNew.Dispose();
		}
		canvas.Save(@".\tape1page.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
		bmpBase.Dispose();
	}

}
```

結果はこちら

幅2400 x 高さ6480

![tape1page.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/869ae1d4-717f-0966-718a-2d6c7cf1dfc3.jpeg)
Cloud TPUをtf-nightlyで作成

# Cloud TPUをtf-nightlyで作成

tf-nightly 2.xが使いたい！でもTPUは対応していないそんなとき、解説がなく困ったのでメモ

まずは Google Cloud Shell が使えるところまでセットアップ。
そしたら以下のコマンドを入力。

    ctpu tf-versions

    Cloud TPU TensorFlow Versions:
    	1.15	(default version)
    	1.15.dev20190909
    	1.15.dev20190821
    	1.14
    	1.14.1.dev20190518
    	1.14.1.dev20190508
    	1.13
    	1.12
    	1.11
    	nightly
    	nightly-2.x
    	pytorch-0.1
    	pytorch-0.5
    	pytorch-nightly

使いたいバージョンを選びましょう。

    ctpu up -tf-version nightly-2.x

tf2.0のnightlyを選ぶには上のようにします。確認が出るのでyを入力しましょう。

    ctpu will use the following configuration:
    
      Name:                 your name
      Zone:                 us-central1-b
      GCP Project:          your_project
      TensorFlow Version:   nightly-2.x
      VM:
          Machine Type:     n1-standard-2
          Disk Size:        250 GB
          Preemptible:      false
      Cloud TPU:
          Size:             v2-8
          Preemptible:      false
          Reserved:         false
    
    OK to create your Cloud TPU resources with the above configuration? [Yn]:

以下のコマンドでTPUの確認ができます。

    gcloud compute tpus list

    NAME             ZONE           ACCELERATOR_TYPE  NETWORK_ENDPOINTS  NETWORK  RANGE          STATUS
    your_name        us-central1-b  v2-8              10.240.x.x:8470    default  10.240.x.x/29  READY

以下のようにリソルバに指定して学習できます。

    resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='grpc://10.240.x.x:8470')

## 備考

ちなみに以下のようにstrategy.scopeの中で/job:workerを指定して、データセットなりモデルなりを作らないと動かないので注意。

    with strategy.scope():
        with tf.device("/job:worker"):
    			...
[Catalyst]ストア申請の流れ

# Catalystを有効にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/a40e2137-860d-b97f-15e9-fa3888f474aa.png)

XcodeのDeployment InfoからMacのチェックボックスにいれる。

# AppIDでもCatalystを有効にする

これ大事。maccatalyst.*.*.*というBundle IDでMacビルドが生成されるが、maccatalystというprefixのbundleIDは自分で作ることが出来ない。
Developer portalからCertificates, IdentifiersでiOSアプリのAppIDを探してMacを有効にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/1809f166-092f-f0f7-82c0-83369ebac6e4.png)

# 別アプリとしてAppStoreConnectに登録する

tvOSはiOSと同じアプリに追加できるが、Macの場合は新規アプリとして登録する。
↑でMacを有効にしていると、maccatalyst.*.*.*のAppIDが選択できるのでそれを選ぶ
Angularにおける状態管理

Angularにおける状態管理の方法について検討したので、雑にまとめます。

## 状態管理とは

まず状態管理とは、***画面表示やデータ同期のために必要な情報を管理すること*** かなと思います。
具体的な例をあげると、下記のようなものがあるかと思います。

- Todoアプリケーションで、Todoリストのデータを保持し、追加・削除・編集が行われた時に、Todoリストのデータを更新する
- データの読み込み中にはローディングを表示したいため、読み込み中かどうかの状態を管理する

## 状態管理方法

Angularで状態管理を行おうとした場合、アプリケーションの規模に応じて適した状態管理方法が変わってくる。

- 小規模：Serviceを使って、独自で状態管理を実装する
- 大規模：Flux、Reduxアーキテクチャを利用し、状態管理を実装する

### Serviceを使って、独自で状態管理を実装する

AngularのServiceを使い、自分で状態管理を実装する方法。
Todoアプリケーションであれば、Todoリストの保持やTodoの更新を行う処理をTodoServiceに実装し、コンポーネントでTodoリストを扱いたい場合にはこのTodoServiceを利用する(一例)。
RxJSを利用することで、状態の変更をトリガーに処理をかけたりするので、より宣言的な実装になる。

ただ、この独自で状態管理を実装した場合、下記のような課題感があると思う。

- 実装方針をチーム内で決めないと、オレオレな実装になり保守性が下がる。
- アプリケーションの規模が大きくなると、状態管理が煩雑になる。どこになんのデータがあるのか、データ更新時にはどこのデータをどういうふうに更新すればいいのかなど、複雑性がましていく。
- 関心ごとにServiceを切り出していったときに、コンポーネントが依存するServiceが多くなったりする。再利用性の低下やテスタビリティの低下など

なので、アプリケーションの規模が大きくなってきた場合は、FluxやReduxアーキテクチャを利用する。

### Flux、Reduxアーキテクチャを利用し、状態管理を実装する

Fluxは、単一方向のデータフローを実現するアーキテクチャ。
複雑になりがちなデータフローを単一方向にすることで、開発者が状態の流れを把握しやすくなる。

Reduxは、Fluxの単一方向のデータフローと、Elmの純粋関数による副作用の排除や、イミュータブルな状態表現の制約を踏襲し、より状態変化を予測可能にしようとしている。
状態変化を予測可能にするためのReduxの3原則↓。

- 信頼できる一意となる状態を唯一とする(Single source of truth)
    - それぞれのコンポーネントが同じ状態を参照することで整合性の取れた画面表示になる
- 状態はイミュータブルで表現する(State is read-only)
    - Storeで管理しているStateオブジェクトをイミュータブルにすることで、状態が変更されることを防ぐ。
    - 状態更新する時には、既存のStateオブジェクトから新しいStateオブジェクトを生成し、それをStoreに登録することで状態の更新を行う。
    - そうすることで、状態を変更する箇所が明確になり、より状態の変化を把握しやすくなる。
- 状態の変更は純粋関数で記述する(Changes are made with pure functions)
    - 状態更新を行うReducerが純粋関数であることで、既存のStateオブジェクトとActionから新しいStateオブジェクトを生成すること以外に副作用が生まれないことを保証する。

[ngrx](https://ngrx.io)や、[ngxs](https://www.ngxs.io)といったライブラリを利用することで、手軽にAngularでReduxを実装することができる。

## まとめ

- 小さいアプリケーションであれば、Serviceで状態管理を実装するでこと足りそう
    - または、シンプルな状態管理ライブラリを使う(akitaとか)
- 大規模なアプリケーションや将来的にスケールしそうなアプリケーションであれば、最初からReduxアーキテクチャを利用して状態管理していると保守性が上がりそう。
- アプリケーションやその時の状況に応じて適切な状態管理方法を選択できるようにしていきたい。
MBOXをPSTに手動で変換する方法

ここには、MBOXをPSTに手動で変換する方法を説明するトピックがあります。 組織で最も受け入れられ、高く評価されている2つのファイル形式は、MBOXとPSTです。 ただし、特定の状況により、多くのユーザーはMBOXからPSTファイル形式に切り替える必要があります。 それでは、MS OutlookでMBOXメールにアクセスする必要性と方法について見ていきましょう。
MBOXは、Thunderbird、Apple Mail、Entourage、Claws Mail、Netscape、Mozilla Mail、Eudora、Evolution、Opera Mail、Mulberryなどの多くの電子メールクライアントからアクセスできるため、最高のファイル形式の1つと見なされました。
しかし、今では、PSTファイルにデータを保存し、広範な機能と利点を提供するMicrosoft Outlookの人気が高まっているため、 MBOXからPSTファイルへの変換は、SMBおよび企業で一般的になっています。
## 見出し＃1手動による方法
MBOXをPSTに手動で変換する手順
1. Microsoft Outlookを開き、ファイルに移動します。

2. [インポートとエクスポート]をクリックして、インポート/エクスポートウィザードを開きます。

3. [別のプログラムまたはファイルからインポート]をクリックし、[次へ]をクリックします。

4. [個人用フォルダーファイル（.pst）]-> [次へ]をクリックします。

5. [参照]オプションをクリックして、変換されたPSTファイルを検索または保存します。

6. [次へ]-> [完了]をクリックします。

制限事項：

このプロセスは非常に時間がかかります。
大量のデータがある場合は、手動プロセスに問題がある可能性があります。
基本的または技術的な知識がないユーザーは、MBOXをPSTファイルに正常に変換できない場合があります。

## 見出し＃2。 プロフェッショナルな方法
**Advik [MBOXからPSTへのコンバーター](https://www.adviksoft.com/ja/mbox/pst.html)**はそれらのツールの1つです。 このソフトウェアを使用すると、3つの小さな手順で、メールボックスを既存のプロファイルまたは好みと要件に従って新しく作成されたPSTに移動できます。 これは、データを失うことなく変換の最良の結果を提供する自動ツールです。 このソフトウェアは、Gmail Takeout、Opera Mail、Mozilla Thunderbird、Entourage、Spicebird、および他の多くのメールクライアントによって作成されたMBOXファイルをサポートしています。


プロフェッショナルなアプローチを使用してMBOXをPSTに変換する手順
手順1. Windows PC で Advik [MBOXコンバーター](https://www.adviksoft.com/ja/mbox/コンバータ.html) を実行します。
![mbox1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/6838e163-9e5c-f94a-42a3-a239e45433ad.png)



ステップ2. [ファイルの選択]をクリックして、MBOXファイルをソフトウェアに追加します
![mbox2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/86b245a5-f648-fcc0-2d0a-c8ad498ee32d.png)



ステップ3.メールフォルダを選択し、[次へ]をクリックします
![mbox3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/20a682f5-0657-0aa6-73b0-ac715f717325.png)

ステップ4. 保存オプションとしてPSTを選択します。

![mbox4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/1a9531ee-32bd-2854-0810-b4be6fa790fa.png)

ステップ5. [変換]ボタンをクリックして、.mboxから.pstへの変換を開始します。

![mbox5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526912/ac5586e6-7a6d-3a53-b493-494dbe71a173.png)




これで、MBOXをPSTファイル形式に変換する手順が完了しました。 これで、MS Outlookアプリケーションでインポートされたフォルダーにアクセスできます。

無料ダウンロード : https://www.adviksoft.com/dl/advik-mbox-converter.exe

結論：

より良いオプションは、時間の浪費と長い構成を避けるために専門的なソフトウェアを使用することです。 したがって、このソフトウェアは、メールフォルダーをMBOXからPSTファイル形式にエラーなしで直接転送する最終ソリューションです。
MacでZathuraをインストール・設定する

Zathura を使うと，Vimのようなキーバインドを使って PDF を閲覧することができる．

# Zathura のインストール

ターミナルを開いて，以下を打ち込む．

```
brew tap zegervdv/zathura
brew install zathura
brew install zathura-pdf-poppler
```

`zathura-pdf-poppler` のインストール忘れると pdf ファイルを開こうとした時にエラーが出るから注意．
`brew cask install xquartz` する必要あるかも．

次に，

```
$ mkdir -p $(brew --prefix zathura)/lib/zathura
$ ln -s $(brew --prefix zathura-pdf-poppler)/libpdf-poppler.dylib $(brew --prefix zathura)/lib/zathura/libpdf-poppler.dylib
```

以上のことは https://github.com/zegervdv/homebrew-zathura に書いてある．


# 使ってみる
pdf を見たい時は，ターミナルで

```
zathura [OPTION…]  [file1] [file2] [...]
```
とする．例えば hoge.pdf を見たければ，

```
zathura hoge.pdf
```

使い方わからなくなったら，とりあえず

```
zathura --help
```

でヘルプを見ればおk．


# カスタマイズする

zathura を快適にするには，

```
vim ~/.config/zathura/zathurarc
```

で，zathurarc を書き換える．
zathura というディレクトリは自分で作る．


```
# zoom and scroll step size
set zoom-step 20
set scroll-step 80

# enable incremental search
set incremental-search true

# zoom
map <C-i> zoom in
map <C-o> zoom out

# adjust window size
set window-height 3000
set window-width 3000
```

rcファイルの中は，こんな感じに好きなように書けば良い．
最後の `set window-height` と `set window-width` は，zathura の起動時のウィンドウのサイズを最大の状態(画面いっぱい)にしておくために書いてある．

`set` とか `map` で，何をどう設定できるのかは，

```
man zathurarc
```

で見れる．

# キーバインド
使いそうなやつはここに載せておく．
詳しくは:
https://man.cx/zathura(1)

|キー|動作|
|:-------------:|:------------------:|
| J, PgDn　| 次のページへ |
| K, PgUp | 前のページへ |
| h, k, j, l | 左，下，上，右に移動 |
| Left, Down, Up, Right | 上と同じ |
| ^t, ^d, ^u, ^y | それぞれ左下上右に半ページ移動 |
| t, ^f, ^b, space, <S-space>, y | それzろえ左下上右に 1 ページ移動 |
| gg, G, nG | 最初のページ，最後のページ，nページ目に移動 |
| H, L | 今のページの上or下に移動 |
| ^o, ^i | 前or後のジャンプリストに移動 |
| ^c, Escape | 取り消し |
| a, s | ウィンドウの縦幅or横幅に合わせる |
| /, ? | 検索 |
| n, N | 検索でヒットした，次or前の項目へ |
| o, O | ドキュメントを開く |
| : | コマンド入力開始 |
| r | 90度回転 |
| ^r | グレースケール，色反転 |
| R | リロード |
| Tab | 目次へ |
| d | 見開きモードの開始と終了 |
| F5 | プレゼンテーションモードへ． |
| F11 | フルスクリーンモードへ． |
| ^n | ステータスバー表示 |
| +, -, = | ズームイン，ズームアウト，元のサイズへ |
| zI, zO, z0 | 上と同じ |
| n= | サイズnにズーム |
| q | 閉じる |
Ubuntu18 eth1で固定IPの設定方法

ref: https://qiita.com/devzooiiooz/items/4e2e1c5264d8960eb412

```bash
$ sudo vim /etc/netplan/11-localnetwork.yaml
```
```/etc/netplan/11-localnetwork.yaml
network:
    ethernets:
        eth1:
            addresses: [192.168.0.88/24]
            dhcp4: false
    version: 2
```

```bash
$ sudo netplan apply
```
Android Studio 3.5.1でSync Project with Gradle Filesが見つからない件

# 結論
ありました。
File -> Sync Project with Gradle Files
![sync.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85631/73acb547-850e-6d69-280b-eb8818b6ad92.png)

# ヘルプなどが改善されてなかった

[Android Gradle プラグインのリリースノート｜Android Gradle プラグインのアップデート](https://developer.android.com/studio/releases/gradle-plugin?hl=ja#updating-plugin)

>Android Studio のメニューバーから [Tools] > [Android] > [Sync Project with Gradle Files] をクリックします。

ないし
![sync2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85631/d92d5501-617b-7284-1245-d056e5b3a0c9.png)
【rails】twitter認証からアイコン画像を取得する

##はじめに
アイコン画像を表示するのに苦労したのでメモを残します。

##開発環境
Ruby on Rails 5.2

##手順

###取得方法

以下の様に記入して、twitter認証時にアイコン画像を取得します。

```user.rb
def self.find_or_create_from_auth(auth)
    provider = auth[:provider]
    uid = auth[:uid]
    name = auth[:info][:name]
    image = auth[:info][:image]#これがアイコン画像
    introduction = auth[:info][:description]

    find_or_create_by(provider: provider, uid: uid) do |user|
      user.name = name
      user.image_url = image  #image_urlにアイコンのURLが入る
      user.introduction = introduction
    end
  end
```

###表示方法

ビューにログインユーザー画像を表示させます。
twitterユーザーとそれ以外のユーザーで区別します。

```erb:index.html.erb
  <% if user.uid != nil %>
    <img src="<%= user[:image_url] %>" >
  <% else %>
    <%= image_tag user.image.to_s %>
  <% end %>
```

**これでアイコン画像を表示できました！**

##最後に
uidがあるかないかでifの条件を作りましたが
他にもいい方法があるかもしれません。
Railsのautoloadについて(初心者向け）

# Railsのautoloadについて(初心者向け）
通常のRubyでは自分で作成したRubyプログラム（クラスの定義など）を読み込む場合もrequireを使います。

例）

``` ruby:dog_class 
class Dog
  class << self
    def bark
      p 'Wan'
    end
  end
  def run
    p 'buuun'
  end
end
```

``` ruby:main

# requireが必要。理由はDogClassとmain文が別になっている為。
require './dog_class ' # 追加

Dog.bark -> 'Wan'

dog = Dog.new()
dog.run -> 'buuun'
```


## Railsの場合は
しかしRailsの場合はrequireを書く必要がない時があります。

例） Railsのコントローラクラス

``` ruby
class HogeController < ApplicationController
  def index
    @hoges = Hoge.all
  end
end
```
この場合、ApplicationControllerクラスやhogeクラスを利用しているので本来であれば以下のように記載する必要がありませんか？

``` ruby
# 継承元のapplication_controller
require "application_controller"
# Hogeモデルクラス
require "hoge"

class HogeController < ApplicationController
  def index
    @hoges = Hoge.all
  end
end
```

でもRailsではrequireをわざわざ書く必要はありません。**...... なんで？？？？**
理由はRailsのautoload機能を利用しているからです。

## Railsのautoload
Railsのautoloadとは**「命名規則に則ったファイルを自動でrequireしてくれる機能」のことです。**


> クラス名をキャメルケース(userItemのように2語目の先頭が大文字)で記述したり、
ファイル名をスネークケース(user_itemsのように単語と単語をアンダーバーで繋ぐ)で記述する等の規則に
準じて命名されたファイルをautoでrequireしてくれるというわけです。

[Railsでlibディレクトリをautoload対象に含める方法](https://kossy-web-engineer.hatenablog.com/entry/2019/03/20/231938)

標準でautoload_pathsに含まれるのは以下の6ディレクトリになります。

```
app/controllers
app/models
app/helpers
app/mailers
app/controllers/concerns
app/models/concerns
```

上記で例としてあげたHogeクラスの場合は`ApplicationControl` は`app/controllers`に含まれており、 `hogeクラス`は`app/models`に含まれています。

よって、事前にクラスをautoloadしてくれおりHogeクラスにはrequire文が必要ありません。

**このautoloadに含まれていないクラスを読み込み場合はrequireが必要になります。**


## まとめ
前からRailsのrequireする時としない時の使い分けがわからなかったので調べてみました。
間違いがあれば、訂正をしていただけると幸いです。

## 参考
https://railsguides.jp/autoloading_and_reloading_constants.html
Rubyの開発環境を構築する際、様々なエラーが起こったので解消法をまとめてみた

#環境

Macbook Air(2016年モデル)
macOS Mojave
Homebrewインストール済み

#状況

Homebrewを使って、rbenvをインストールしようと試みたところエラーが発生し、

```
$ brew doctor
```

で確認したところ以下のようなWarningが出現した。

```
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: The following directories do not exist:
/usr/local/opt
/usr/local/sbin
/usr/local/Cellar

You should create these directories and change their ownership to your account.
  sudo mkdir -p /usr/local/opt /usr/local/sbin /usr/local/Cellar
  sudo chown -R $(whoami) /usr/local/opt /usr/local/sbin /usr/local/Cellar

Warning: Broken symlinks were found. Remove them with `brew cleanup`:
  /usr/local/bin/apm
  /usr/local/bin/atom
  /usr/local/bin/firebase
  /usr/local/bin/npm
  /usr/local/bin/npx


```

#解決法

##一つ目のWarningについて

 ```
You should create these directories and change their ownership to your account.
  sudo mkdir -p /usr/local/opt /usr/local/sbin /usr/local/Cellar
  sudo chown -R $(whoami) /usr/local/opt /usr/local/sbin /usr/local/Cellar
```
と書いてあるため、その通りに

```
sudo mkdir -p /usr/local/opt /usr/local/sbin /usr/local/Cellar
```

```
sudo chown -R $(whoami) /usr/local/opt /usr/local/sbin /usr/local/Cellar
```
とコマンドをコピペする。

何も反応はないが、とりあえずそのままでOK。



##二つ目のWarningについて

```
Warning: Broken symlinks were found. Remove them with `brew cleanup`:
  /usr/local/bin/apm
  /usr/local/bin/atom
  /usr/local/bin/firebase
  /usr/local/bin/npm
  /usr/local/bin/npx

```
と書いてあるため、その通りに

```
$ brew cleanup
```

とコマンドをコピペすると、

```
Pruned 5 symbolic links from /usr/local
```
と出てくる。

確認のために、もう一度

```
$ brew doctor
```

と打つと

```
Your system is ready to brew.
```
といってくれたのでエラーは解消できた。

```$ brew install rbenv ruby-build
```でインストールし```$ rbenv -v```で確認すると

```
rbenv 1.1.2
```
となり、インストールが完了。

#まとめ

Homebrewを使っているなら、```$ brew doctor```を使えば大体のことはわかる。
Thinkpad E580 + Ubuntu 18.04 環境でwifiを使えるようにする ( RTL8821CE )

# TL;DR
Thinkpad E580 に Ubuntu 18.04 をインストールしたところ、デフォルトのwifiドライバは対応していないらしく、新しく入れ直す必要があった。
# インストール
以下に手順を記す。
### ネットワークアダプタの確認
``` shell:shell
$ lspci | grep Network
05:00.0 Network controller: Realtek Semiconductor Co., Ltd. \ 
RTL8821CE 802.11ac PCIe Wireless Network Adapter
```
RTL8821CEが wifi ドライバ名であることがわかる。
### ドライバのダウンロード
``` shell:shell
$ cd (適当なディレクトリ)
$ git clone https://github.com/tomaspinho/rtl8821ce.git

// gitをインストールしていない場合
$ sudo apt install git
```
### 導入環境構築
``` shell:shell
$ sudo apt install bc module-assistant build-essential dkms
$ sudo m-a prepare
```
### ドライバインストール
``` shell:shell
$ cd rtl8821ce
$ sudo ./dkms-install.sh
```
この時点で Setting 内で wifi の項目が追加される。しかし、ネットワークアダプタが認識されていないので、再起動が必要。なので、

``` shell:shell
$ reboot
```
終わり。
MacOSにrvmで最新のrubyをインストールする

#rvmを最新版にする

```
rvm get latest
```

#インストール可能なRubyを確認
```
rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.7[-head] # security released on head
[ruby-]1.9.1[-p431]
[ruby-]1.9.2[-p330]
[ruby-]1.9.3[-p551]
[ruby-]2.0.0[-p648]
[ruby-]2.1[.10]
[ruby-]2.2[.10]
[ruby-]2.3[.8]
[ruby-]2.4[.6]
[ruby-]2.5[.5]
[ruby-]2.6[.3]
[ruby-]2.7[.0-preview1]
ruby-head
```
ruby 2.7をインストールします。

```
ruby install ruby-2.7
```

#インストール時にエラーが発生
```
Checking requirements for osx.
Installing requirements for osx.
Updating system...........................................................................................................................................Failed to update Homebrew, follow instructions at

    https://docs.brew.sh/Common-Issues

and make sure `brew update` works before continuing.

Error running 'requirements_osx_brew_update_system ruby-2.7'
Requirements installation failed with status: 1.
```
どうやらhomebrewが古かった様なのでアップデートします。

```
brew update

fatal: could not read Username for 'https://github.com': terminal prompts disabled
Error: homebrew/homebrew-dupes does not exist! Run 'brew untap homebrew/homebrew-dupes'
```
存在しないリポジトリをtapしてるからuntapしてくださいと
親切に教えてくださっているので、untapします。

```
brew untap homebrew/homebrew-dupes
Untapping homebrew/dupes...
Untapped (111 files, 253.6KB).
```
問題が解決したので再度ruby-2.7をインストールします。

```
rvm install ruby-2.7
.
.
.
Install of ruby-2.7.0-preview1 - #complete 
```

rvm listでインストールされていることを確認して完了です。