OmniAICreator/Qiita-1.07M huggingface dataset:
Google Calendar APIで祝日判定をする

# サンプルコード

以下のコードを参照。

コメントにも書いたが、Google Calendarでは、全日の予定の日付は内部的にUTCになっているらしい。JSTだと検索条件がずれて一日違いになっている。

Google Calendarの「日本の祝日」は、機械的処理を目的としたものではないため、将来的にこの方法で祝日判定できることは保証されないので注意（たとえば、「この日は祝日ではなくなりました」というイベントが追加されるかもしれない）。あくまで勉強用に。

```js
const { google } = require('googleapis');
const dayjs = require("dayjs");
const utc = require("dayjs/plugin/utc");
dayjs.extend(utc);

const auth = new google.auth.GoogleAuth({
  scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
});
const calendar = google.calendar({version: 'v3', auth: auth});

const isHoliday = async (dateString) => {
    // Google Calendarの日付は内部的にUTCになっている。JSTだと検索条件がずれるので注意
  const date = dayjs.utc(dateString);
  const response = await calendar.events.list({
    calendarId: "japanese__ja@holiday.calendar.google.com",
    timeMin: date.toISOString(),
    timeMax: date.clone().add(1, "hour").toISOString(),
  });
  return response.data.items.length > 0;
};
```
vagrantで仮想マシン作成するときのコマンド【備忘録】

#目的

Vagrantを使用してVirtualBoxに仮想マシンを作成する際のコマンドを忘れてしまいがちなので残します。

#事前設定

[VirtualBox](https://www.virtualbox.org/)インストール済み
[Vagrant](https://www.vagrantup.com/)インストール済み

#作成時のコマンド

Vagrantの[Getting Started](https://learn.hashicorp.com/collections/vagrant/getting-started)を参照。

ボックスは[Vagrant Cloud](https://app.vagrantup.com/boxes/search)から検索。

<details><summary>ボックスとは？</summary>Vagrant環境がパッケージ化されたもの。CentOSのボックスだと、CentOS環境が自動で構築できるように準備されている。詳細は[Vagrant公式ドキュメント](https://www.vagrantup.com/docs/boxes)をどうぞ。</details>

```

# 作成する仮想マシン用にディレクトリを作成し、それに移動する。
mkdir vagrant_hoge
cd vagrant_hoge

# ディレクトリを初期化してVagrantfileを作成する。
# 引数のhashi~は自分が使用したいボックス名を指定。
# なくても初期化自体はできる。
vagrant init hashicorp/bionic64

# 以下の内容になっていればよい。ボックス名が違っていたら書き換える。
cat Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
end

# 仮想マシン起動。このときにボックスが追加されている。
vagrant up

# ssh接続
vagrant ssh

```

#その他の使用頻度が高いコマンド

```
# ボックス追加
vagrant box add hoge

# 追加したボックスリスト
vagrant box list

# ボックス削除
vagrant box remove hoge

# 仮想マシンシャットダウン
vagrant halt

# 仮想マシン削除
vagrant destroy

# 仮想マシン状態確認
vagrant status

```

#ファイルの同期

ちなみにゲストマシンの`~/vagrant/以下`とホストマシンの`vagrant_hoge/以下`は同期されている。
Cloud functions から Google APIsを使う

# 結論

1
コンソールからサービスアカウントに該当するAPIの権限を付ける

2
認証情報なしでデフォルトのまま、googleapisのGoogleAuthを呼び出す。

サンプルコード（カレンダーにアクセスする場合）

```js
const { google } = require('googleapis');
const auth = new google.auth.GoogleAuth({
  scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
});
const calendar = google.calendar({version: 'v3', auth: auth});
```

終わり。

Cloud Functionsのドキュメントを見てもどこにも書いてなくて困った。

# 参考資料

https://github.com/googleapis/google-api-nodejs-client#application-default-credentials
機械学習ライブラリJAXのインストールで詰まった話

JAXという機械学習ライブラリがpythonから使えると聞いたのでインストールしました
インストール時に詰まったところのメモです

pipを使ってJAXをインストールしようとしました

```sh
pip install jax jaxlib
```

最初にではエラーはこちら：

```sh
ValueError: jaxlib is version 0.1.23, but this version of jax requires version 0.1.37.
```

これはエラーメッセージの下の方に解決方法が書いてあるので，素直に実行します

```sh
pip install --upgrade pip
pip install --upgrade jax jaxlib
```

次に出たエラーはこちら：

```sh
AttributeError: module 'numpy' has no attribute 'histogram_bin_edges'
```

エラーメッセージからnumpyのエラーらしいので，numpyのupgradeをします

```sh
pip install --upgrade numpy
```

最後に出たエラーはこちら：

```sh
ModuleNotFoundError: No module named 'numpy.testing.decorators'
```

エラーメッセージの上の方を見るとnumpyではなくscipyのエラーらしいので，scipyのupgradeをします

```sh
pip install --upgrade scipy
```

これで動きました
関数型プログラミング入門（Java, Javascript）

関数型プログラミングの勉強で役に立った資料一覧

#Java

[関数型プログラミングはまず考え方から理解しよう
](https://qiita.com/stkdev/items/5c021d4e5d54d56b927c)

[今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~
](https://casualdevelopers.com/tech-tips/lets-get-started-with-functional-programming-with-java/)


[Java8のラムダ式を理解する
](https://qiita.com/sano1202/items/64593e8e981e8d6439d3)

[Java 8 のイディオム関数型インターフェース](https://www.ibm.com/developerworks/jp/java/library/j-java8idioms7/index.html)

[【Java】ラムダ式の省略方法まとめ
](https://qiita.com/sano1202/items/40cc8a0e29def0c76fa8)

[【Java 8】5分でわかる関数型プログラミング
](https://lab.m-field.co.jp/2019/09/13/java8-functional-programming/)

[Java8から始める関数型プログラミング
](https://www.slideshare.net/stylefreeslide/java8-64750755)


#JavaScript

[JavaScriptで関数型プログラミングの入門
](https://qiita.com/takeharu/items/cf98d352ff574c5ac536#1-3)

[JavaScriptと関数型プログラミング
](https://note.com/monomemo/n/ne81630812e0d)

Oreilly
[JavaScriptで学ぶ関数型プログラミング
](https://www.oreilly.co.jp/books/9784873116600/)

[JavaScript関数型プログラミング 複雑性を抑える発想と実践法を学ぶ impress top gearシリーズ Kindle版
](https://www.amazon.co.jp/dp/B072JVPFL4/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

[React学習を楽にしてくれるJavaScriptでの関数型プログラミングの基礎知識
](https://qiita.com/terry_6518/items/4b39826d9ee76076a0a7)


##他

[関数型言語のウソとホント
](https://qiita.com/hiruberuto/items/26a813ab2b188ca39019)

[関数型プログラミング入門
](https://postd.cc/an-introduction-to-functional-programming/)
[Rails] redirect_toとrenderメソッドの違いとrenderメソッドの出力方法について色々

この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。

# redirect_toメソッド
- __redirect_to →　ルーティング　→　コントローラー　→　ビュー__の順番で動きます。
- 新しいリクエストが送信された時と同じ経路ですね。
- 元のインスタンス変数の値が__上書き__されます。

```ruby
redirect_to リダイレクト先のパス
```

# renderメソッド
- __render →　ビュー__の順番で動きます。
- 新しいリクエストはなく、__そのままビューファイルに直行__です。
- コントローラーのアクションを通らないのでインスタンス変数は上書きされません。
- フォームに__入力した情報を保持したまま__ビューファイルに戻ってくれます。

```ruby
render :アクション名
```

# redirect_toとrenderの違い
__ルーティングとコントローラーを通って情報が更新されるかどうか__です。



#renderメソッドの使い方色々
上記の使い方意外にも`render`ではい様々なビューを出力できます。

###別のコントローラのアクションテンプレートを出力する
- `render`メソッドで行うことができます。
- 以下のように`app/views`を起点とするパスを指定するとビューファイルを出力できます。

```ruby
render "items/show"
```

###任意のファイルを出力する
- 絶対パスを用いることでアプリケーションディレクトリ外のファイルを出力できます。

```ruby
render "/Users/k/projects/test/app/views/books/index.html.erb"
```

###テキストを出力
- `:plain`オプションでテキストをそのまま出力します。
- `:html`オプションでHTML文字列を出力します。

```ruby
render plain: "text"
render html: helpers.tag('Hello')
```

#参考サイト
https://railsguides.jp/layouts_and_rendering.html
【Git】git stash の使い所

昔の自分の書いた記事って恥ずかしいですよね。
数年前自分が書いたqiit（[勘違いしていたGit stash](https://qiita.com/tundes/items/90e69f4b9ef064d09391)）を読み返してものすごく恥ずかしくなりました。

あの頃の自分とは違い `git stash` を上手に使えるようになったのでまとめてみました。今回はgit stashの使い方というより、使い所についての記事になっています。

基本コマンドは以下のコマンドしか使いません。使い分けとかは面倒なので、

```
git st 'hogehoge'
```
とうてば

```:terminal
git stash save -u 'hogehoge'
```
と同じようになるようにエリアス化しています。

上記コマンドを知らない人ように少し説明すると、

`-u`オプションをつけることで、`untracked`なファイルも一緒にstashできます。
saveをつけることで、コメントを残すこともできます。

本題。

## その１　いきなり緊急タスクが降ってきた
これは多くのかたが使うやり方だと思います。
issuesAを実装しているときに、バグ見つかったからこっち先やってくんね？と言われたら迷わず
`git stash save -u 'hogehoge'`をうって、ブランチを移動します。タスクが終わったらブランチに戻ってきて、
`git stash pop`をすればOKです。

## その２　この実装は別ブランチでやりたいな
ブランチ運用の話を少しします。

`振る舞いに(behavior)`よってbranch分けをします。
例えば、「ある外部APIからデータを取得し、アプリケーション側でデータを修正・保持しておいて、そのデータを取得できるAPI実装」というタスクを実装する際に
以下のようにブランチ分けをします。

実装に必要なものをセッティングするためのbranch
**`feature/initialize`**　branch

外部APIからデータを取得できるようにするbranch
**`feature/get-data`**　branch

取得したデータを修正・保存できるようにするbranch
**`feature/update-data`**　branch

保持してあるデータを取得できるようにするbranch
**`feature/get-hoge`**　branch


イメージはこんな感じです。

で、例えば`保持してあるデータを取得できるようにする`を実装している際に、
`取得したデータを修正・保存できるようにする`の実装でバグや改善点を見つけて修正・追加したときに`stash`を使って一時避難しておきます。
**`feature/update-data`**　branchで修正したら、元いたブランチに戻ってきて、**`feature/update-data`**　branchをマージしてもいいんですが、僕は元いたブランチを一旦削除して、再度**`feature/update-data`**　branchから分岐させます。（commitを綺麗に保ちたい。。。）作り直したブランチで`stash pop`を実行すれば、元どおりになります。

## その３　この実装別ブランチの方が良かったじゃんね？
こんなときないですか？僕は結構あります。
その２の時みたいにブランチを細かく分けていて、すでに実装の終盤で別ブランチの方が良かったと気付いた際に今いるブランチで、PR出したいものだけを`add&commit`しておいて、別ブランチからRPをあげたいものをstashして、該当ブランチに移動、`stash pop`してから`add&commit`するなんてことも最近はやっています。

## まとめ
以上で、最近僕がstashを使う時はこんな時！！というのをまとめました。
上記の運用だと多少面倒ではありますが、レビューワーのことを考えると、なるべく細かい振る舞いごとにPRを作ることでレビューもしやくなると思うので、stashを活用してブランチ分けを気にかけてみてください。

他にもこんなときにstashを使う！！などありましたら是非コメントしてください。
最近知ったメソッド、忘備録①

#はじめに
Rubyを学習していて、最近知ったメソッドを忘れないために、記録しておく。

##最近使ったメソッド
###sliceメソッド

配列や文字列から制定した要素を取り出すことができる。

```ruby
string = "abcde"
str = string.slice(4)
puts str
#=> "d"

puts string
#=> "abcde"
```

元の文字列は変わらない。

###slice!メソッド

```ruby
string = "abcde"
str = string.slice!(4)
puts str
#=> "d"

puts string
#=> "abce"
```

（！）のつくメソッドを破壊的メソッドという。その名の通り、破壊する。slice!メソッドは元の配列や文字列から、指定した要素を削除する。

###scanメソッド

対象の要素から引数で指定した文字列を数え、配列として返す。

```ruby
str = "abcdabcdabcd"
str.scan("ab")
#=> ["ab", "ab", "ab"]
```

###even?メソッド
対象の数値が偶数かどうかを判別し、真偽値を返す。

```ruby
12.even?
#=> true
```

###include?メソッド
指定した要素が配列ないに含まれているか判断し、真偽値を返す。

```ruby
array = ["ab", "cd"]
array.include?("ab")
#=> true
array.include?("ef")
#=> false
```
[ざっくり]AWSの概要

はじめに
---
備忘録です

AWSなどのクラウドサービスについてまとめています

徐々に更新します

AWSとは
---
- アマゾンが提供する`クラウドサービス`

クラウドサービスとは、オンプレミスと対になるものです。

オンプレミスとは、データセンターにインフラを自前で用意する運用方法です。

対してクラウドサービスは、`仮想的なインフラを使いたい分だけ使用`することができます。

クラウドサービスを利用するメリットは、

- `サーバーの増減がしやすい`
- `保守管理の手間が省ける`

デメリットとしては、

- 使った分だけ料金が発生する従量課金型なので、`コストを試算しづらい`
- サービスの数が多い上、頻繁に新しい機能が追加されるので、`ベストプラクティス選定のコスト`がかかる

 　
AWSには200近くのサービスがあります。
また、2019年にAWSから発表された新機能追加情報は1700件以上あるそうです。
参考 : [【2020年】AWS全サービスまとめ | Developers.IO](https://dev.classmethod.jp/articles/aws-summary-2020/) 

AWSの全てのサービスを網羅するより、要件に合うサービスを選定することが大事かと思われます。

ベストプラクティスとは、求める要件を満たした上で最も効率が良い方法のことです。
ゲームで例えるなら、現環境のtier1構築といったところ。
ゲームと同じく、目的や環境によってベストプラクティスは変動します。

　
AWSには、`SaaS`, `PaaS`, `IaaS`何でもあります。
ざっくり解説します。

| サービス分類  | 説明   | 例|提供されるもの|コスト|自由度|
| --- | ------- | ---| ---| ---| ---|
| SaaS (Software as a Service)| クラウドで提供されるソフトウェア |  S3, Gmail  |  インフラ,OS、ミドルウェア、アプリ |高|低  
|PaaS (Platform as a Service)  | アプリケーションソフトが可動するためのデータベースやプログラム実行環境などのプラットフォーム  |Lambda|インフラ、OS、ミドルウェア|⇅|⇅|
| IaaS (Infrastructure as a Service) | 仮想サーバーやハードディスクなどのインフラ  | EC2|インフラ|低|高|


ここでいうインフラは、`サーバー・ストレージ・ネットワーク`の総じて指しています。

---

(ここからはエアプの戯言)

クラウドサービスにはAWS以外に、`GCP`(Google)、`Azure`(Microsoft)などがあり、
それぞれ固有の強みを持ちます。
例えば、GCPは、Google App Engine(PaaS), Google compute Engine(IaaS)などのサービスがあります。
GCPの特徴として、`急激なトラフィック増加に強い`、`機械学習サービスが充実`など、大量のデータを適切に捌くのが得意というものがあります。
デメリットとしては、AWSと比べて`リージョンが少ない`こと、東京リージョンが追加されたのが2016年10月と比較的新しいため`日本語の文献が少ない`ことが挙げられます。

私見として、GCPのリージョンが少ないのはGoogleの怠慢ではなく、Amazonが世界中に物流拠点を置いている地の利によるものかなと思いました。
仮に物流サービスを始めたときから、クラウドサービスの覇権も狙ってたとしたら千里眼やばいですね。


クラウドサービス毎に強みがある為、AWSとGCPを併用することもあるそうです。
そうなると管理コストが増えてしまいますが、実際に併用してみたら結構良かったみたいな話もあるそうです。

複数のクラウドサービスを併用する話に関連して、
マイクロソフトはAzureというクラウドサービスを展開していますが、
`Azure Arc`で、マルチクラウドプラットフォームを、2020年始め頃から普及させているそうです。

(以上エアプの戯言でした)
[Rails] 投稿できない原因がform_withにあった件

#はじめに

以前、twitter的なものを作成している受講生さんから「ボタン押してるのに投稿できない！エラー文も何も出ない！（涙）」っていう質問があり、僕自身もその原因をすぐに突き止めることができなく苦労したので同じような悩みを持つ人のために投稿します。

#バージョン
```
ruby 2.5.7
Rails 5.2.4.3
```

#原因と解決法
```ruby:books_controller.rb
def create
   @book = Book.new(book_params)
   @book.user_id = current_user.id
   if @book.save
      redirect_to book_path(@book)
   else
      @books = Book.all
      render 'index'
end
```
...と、コントローラーにはsaveできたらbook_path(@book)のページに行け！できない時はindexのページに行け！と指定してるのに

```ruby:_list.html.erb
<%= form_with model:book, url:root_path do |f| %>
   
<% end %>
```
...と、ビューにはボタン押されたらroot_pathのページに行け！という謎の別の指定がされていました。

なので、

```ruby:_list.html.erb
<%= form_with model:book do |f| %>
   
<% end %>
```
...のようにビューのurlの部分を全て削除してあげたら問題なく投稿できるようになりました。めでたし。

#最後に
form_withのurlの部分の記述がおかしいとrouting errorの原因にもなってしまうので気をつけましょう。

form_withの使い方について詳しく知りたい方は[こちら](https://pikawaka.com/rails/form_with)の資料がおすすめです。
自己結合

テーブル情報
![スクリーンショット 2020-10-29 23.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/f8b7c298-5b80-524e-e154-83fd3262f39a.png)

カテゴリIDの違う商品をセット商品として商品名、金額をだす。

````sql
select
p1.name as 商品名1
,p2.name as 商品名2
,p1.price + p2.price as セット価格
from
products as p1
inner join
products as p2
on p1.id < p2.id 
and p1.category_id <> p2.category_id
order by p1.name
````

![スクリーンショット 2020-10-29 23.34.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/335f2aa5-a405-1115-63ae-4632988476f2.png)

on p1.id < p2.idとすることで1ど出現したレコードを出さないようにしている。(ぶどうみかんの組み合わせは表示されているがみかんぶどうの組み合わせは表示されていない)
Cannot destructure property 'dialog' of 'require(...).remote' as it is undefined.

```javascript
new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true, // ←を追加する。
    },
    width: 800, height: 600,
});
```

> ![BrowserWindow___Electron.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/02436c76-0805-9f6c-5157-e6c534ff0b80.png)
> enableRemoteModule Boolean (optional) - Whether to enable the remote module. Default is false.
> [【ドキュメント】BrowserWindow | Electron]
(https://www.electronjs.org/docs/api/browser-window#new-browserwindowoptions)

　
> ![ 2020-10-29 23.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/55df6713-6172-4d7f-f939-add8f8248895.png)
>[javascript - Electron JS - Cannot destructure property 'BrowserWindow' of 'require(...).remote' as it is undefined - Stack Overflow](https://stackoverflow.com/questions/63901266/electron-js-cannot-destructure-property-browserwindow-of-require-remot)
【Auth0】openid-configurationの場所と内容

# はじめに
Auth0は[OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)という仕様に定義されている構成情報（`openid-configuration`）を公開しています。
今回はこの構成情報の内容を見てみました。

# openid-configurationの場所
[OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)の「4.1. OpenID Provider Configuration Request」に記載されているパスでAuth0も`openid-configuration`を公開しています。

```
/.well-known/openid-configuration
```

以下のようなパスにアクセスすると、Auth0のテナント毎に置かれている`openid-configuration`を参照することができます。

```
https://{Auth0テナントのドメイン}/.well-known/openid-configuration
```

# openid-configurationの内容

実際にアクセスすると以下のようなjsonが取得できます。

```json
{
  "issuer": "https://{Auth0テナントのドメイン}/",
  "authorization_endpoint": "https://{Auth0テナントのドメイン}/authorize",
  "token_endpoint": "https://{Auth0テナントのドメイン}/oauth/token",
  "device_authorization_endpoint": "https://{Auth0テナントのドメイン}/oauth/device/code",
  "userinfo_endpoint": "https://{Auth0テナントのドメイン}/userinfo",
  "mfa_challenge_endpoint": "https://{Auth0テナントのドメイン}/mfa/challenge",
  "jwks_uri": "https://{Auth0テナントのドメイン}/.well-known/jwks.json",
  "registration_endpoint": "https://{Auth0テナントのドメイン}/oidc/register",
  "revocation_endpoint": "https://{Auth0テナントのドメイン}/oauth/revoke",
  "scopes_supported": [
    "openid",
    "profile",
    "offline_access",
    "name",
    "given_name",
    "family_name",
    "nickname",
    "email",
    "email_verified",
    "picture",
    "created_at",
    "identities",
    "phone",
    "address"
  ],
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token"
  ],
  "code_challenge_methods_supported": ["S256", "plain"],
  "response_modes_supported": ["query", "fragment", "form_post"],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["HS256", "RS256"],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post"
  ],
  "claims_supported": [
    "aud",
    "auth_time",
    "created_at",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "identities",
    "iss",
    "name",
    "nickname",
    "phone_number",
    "picture",
    "sub"
  ],
  "request_uri_parameter_supported": false
}

```

これを見ると、認可エンドポイントなどの各種エンドポイントのURLの他、Auth0が大まかにどういった仕様をサポートしているかがわかります。
主だったところだと、`scopes_supported`にはAuth0が標準でサポートする認可リクエストの`scope`パラメーターの値が列挙されていたり、`claims_supported`にAuth0が提供し得る登録ユーザーの属性の一覧が列挙されていたりします。

各項目がなにを表しているかは、[OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)の「3. OpenID Provider Metadata」に記載されている内容に準拠していると思いますので、詳細はそちらを参照するのがいいと思います。

# おわりに
Auth0固有の仕様は公式ドキュメントを見るしかないと思いますが、OpenID Connectなどの標準仕様をどこまでサポートしているかサッと確認するときなんかは`openid-configuratio`を見ると手っ取り早いかと思います。

また、OpenID Connectで連携をする他システムが対応している場合は、この`openid-configuration`のURLを読み込ませるだけで基本的な設定が完了することもあります。
活用できるとこでは積極的に活用していってみてください。
debianディストリビューションでgem install時にGem::Ext::BuildError: ERROR: Failed to build gem native extension.が出る

#背景
docker-composeでbundleインストール時に、sasscをインストールしてくれと怒られ実行したところOSが起動しなくなったので共有します。


#実行環境
debian 10.6
rails 5.2.4.3

#事象
下記エラーで5分ほどたったあと、サーバーが壊れる

```bash:
# gem install sassc -v '2.4.0' --source 'https://rubygems.org/'
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    current directory: /usr/local/bundle/gems/sassc-2.4.0/ext
/usr/local/bin/ruby -I /usr/local/lib/ruby/site_ruby/2.4.0 -r
./siteconf20201026-6-pwczrb.rb extconf.rb
extconf failedCannot allocate memory - /usr/local/bin/ruby
Gem files will remain installed in /usr/local/bundle/gems/sassc-2.4.0 for
inspection.
Results logged to
/usr/local/bundle/extensions/x86_64-linux/2.4.0/sassc-2.4.0/gem_make.out
An error occurred while installing sassc (2.4.0), and Bundler cannot continue.
Make sure that `g @'`
succeeds before bundling.
In Gemfile:
  bootstrap was resolved to 4.5.2, which depends on
    sassc-rails was resolved to 2.1.2, which depends on
      sassc
```
#原因
メモリが足りない
AWS無料枠でのインスタンスタイプを契約していて、メモリを1G→2Gに変更したところすんなり通った。

#メモリの増設方法
私はインスタンスタイプを変更することで、メモリを増設しました。（新しくOSを構築しました）
AWSインスタンスを起動→Amazonマシンイメージを選択（私の場合はRed Hat）→メモリ2GBを選択....（以下省略）
HTML/CSS:右サイドにメニューバーを表示する方法

#【概要】

<b>[1.結論](#1結論)</b>

<b>[2.どのようにコーディングするか](#2どのようにコーディングするか)</b>

<b>[3.開発環境](#3開発環境)</b>

<b>[補足](#補足)</b>



#1.結論
<b>HTML：ulタグ、liタグ
CSS：display: flex、writing-mode: vertical-rl、right:、padding:プロパティ</b>
を使用する！
<br>

#2.どのようにコーディングするか

```html:❶
<ul class="list">
  <li class="item">GALLERY</li>
  <li class="item">RECOMMEND</li>
  <li class="item">CHARACTER</li>
  <li class="item">SKILLS</li>
  <li class="item">CONTACT</li>
</ul>
```

```css:❷
.ul{
 list-style: none;
}

.list{
right: 0px;
display: flex;
writing-mode: vertical-rl;
}

.item{
padding:20px 0;
}
```

❶で、ulタグとliタグでリスト化しています。これだけでは、縦に並んでしまいますが箇条書きのようなリストになります。

❷で、右サイドにメニューバーを表示するメインのコーディングになります。 list-style: none;はliタグをつけると"・"が付くので余計なため消しています。肝心なのはwriting-mode: vertical-rl;でこれがサイドに文字が横の状態で表示するプロパティになります。display: flex;でブロック横並び整列させ、rightは単に右サイドに追いやっています。padding:20px 0;は文字がきつきつになり見にくいためです。

結果下記の画像のようになります！

![スクリーンショット 2020-10-29 22.30.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686400/07799f24-af07-4407-28ff-fa569e5f0703.png)


<br>


#3.開発環境
HTML5
CSS3
<br>

#補足
flex-wrap: wrapで、文字がまとまり表示が縮小しても文字がばらけない、
justify-content: centerだと画面に対して中央に寄るように、
position: fixedするとスクロールしても固定でメニューバーがでてくるようにしました！またdivタグで被っても上下にビューがずれることはないです。
<br>
コマンドプロンプトを捨ててPowerShellへ強制移行するための第一歩

## みなさんはPowerShell使ってますか？

前回は[WindowsTerminalの利用を前提とした記事](https://qiita.com/hikaruright/items/b415d569b5bbeaf967bd)を書きましたが、
宗教上の理由などでインストールできない現場の方も数多くいらっしゃると思います。


## PowerShellの問題点

PowerShellを使っていて一番面倒なのが

**コマンドが長い。**

ということだと思います。

``PowerShell`` と ``cmd1``、どちらが短いかと言われたらcmdですよね。

そして何よりも辛いのがこれ。

「Powerからのエンターっ、と」

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/6dbccc01-2e15-cf10-ecb3-26ed16dbda23.png" width="60%;">

PowerPoint「おはようニキーwww」

なんでPowerって打ったら先にパワポが来るんじゃボケーーー！


その結果、面倒でついつい``cmd``と打ってしまうあなた。

今回は、そんな方への荒療治です。

## とある日の会話

後輩「あーーーもう」

先輩「どうした？」

後輩「PowerShell起動しようとしてまたパワポ起動させてもうた」

先輩「同じPowerから始まるからしゃーないわな」

後輩「面倒やからcmd使うわ」

先輩「あー、そんなことしはったら・・・」

後輩「ああああ！ls使えん！！！」

先輩「ほーら。」

後輩「これだからWindowsはクソ・・・全部Ubuntuでええやん。」

後輩「憂さ晴らしに``alias vi=emacs``って仕込んだろ」

先輩「おっ、戦争かな？」

先輩「ん？待てよ？ Windowsもエイリアス貼ったらよくね？」

## というわけでエイリアス貼る

実際にaliasを作成できるのはPowerShellの範疇のみなので、``set-alias``は使用不可。

そのため、ショートカットを弄ることにする。


### PowerShellを起動するバッチを作成

ユーザーディレクトリの直下にバッチファイルを作成

```%USERPROFILE%\alias-ps.bat
start powershell.exe &
exit
```

### コマンドプロンプトのショートカットを修正

スタートメニューからコマンドプロンプトを検索し、
「右クリック」 > 「ファイルの場所を開く」を選択

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/e70b9863-355b-88a7-5b46-1fecdb1ffabe.png" width="400" />

ショートカットが見れるので、そのショートカットのプロパティを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/68f2f720-c807-c2ad-ccd9-9119d30c4996.png)

リンク先の欄に注目します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/64a22399-086f-89c6-531d-2a1ed3f02a66.png" width="500" />
cmd.exeの後ろに以下を追加します。

```
/k "%USERPROFILE%\alias-ps.bat"
```

以下の感じにします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97156/4b1a05d4-79b2-98a4-19ae-db5a953284cd.png" width="500" />


この状態で``cmd``でコマンドプロンプトを起動します。

これでPowerShellが起動されたら作業完了です。


## さいごに

後輩「普通にショートカット書き換えた方が良かったのでは」

先輩「あっ」

先輩「・・・まあcmdの本物が迷子になったら困るし・・・いいんじゃね？」

後輩「・・・(若干の沈黙)　あ、ところでここ聞きたいんですけど」

先輩「（あっ、流した）」
Vueで 動的に生成されるコンテンツにスタイルを当てる

# 問題
**Vueで動的に生成されるコンテンツにスタイルが効かない**

フォームの送信画面で　動的に生成されるコンテンツのエラーメッセージ　の色と位置の微調整をしたいときにハマったので備忘録と記憶の定着のためにアウトプットしていきます。
（送信を押さないとその要素はDOM上に存在しない　v-html によって作成された DOM コンテンツ）

# 結論　::v-deepで解決
**ディープセレクタ**
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html

```html:sample.vue
<template>

　<span>名前(必須)</span>
　<input class="DOM上に元から存在するクラス">
　<span>お取り寄せ内容（必須）</span>
　<input class="DOM上に元から存在するクラス">
 　<!-- inputが空の場合DOM上に.q-bottom-errorが動的に追加される -->
　　<span class="q-bottom-error">お取り寄せ内容を入力してください</span>

</template>

<style lang="scss" scoped>　
/* 例　inputタグが空の時に出るエラーメッセージの色を青にしたい */
　.DOM上に元から存在するクラス ::deep .動的に生成されるコンテンツのクラス(.q-bottom-error) {
　　　color: blue;
　}
</style>
```

# Scoped CSSとは
Vue.jsでCSSを利用する際にScoped CSSやCSS Modules、CSS-in-JSなどの手法がある。
Scoped CSSとはある特定の範囲にのみCSSを適用できる機能
scoped 属性をもつ style タグを利用するとき、その CSS は現在のコンポーネントの要素にのみ適用される。


```html:sample.vue
<template>
　<div class="hage">フサフサ</div>
</template>

<style scoped>
/*　sample.vueのhageクラスのみに適用されるcss他ファイルには適用されない */
　.hage {
　　　color: red;
　}
</style>
```

## なぜこのファイルにしか効かないようになるのか
```<style scoped>```にすることによって
Vue.jsでは、HTML側に**コンポーネント毎にカスタムデータ属性を付与し、CSS側にも対応するデータ属性を付与する。**

```html:sample1.vue
<template>
　<div class="hage" [data-v-f3f3eg9]>ふさふさ</div>
</template>

<style scoped>
　.hage[data-v-f3f3eg9] {
　　　color:red
　}
</style>
```
となるので
```html:sample2.vue
<template>
<!-- こちらのhageは赤にならない -->
　<div class="hage">ふさふさ</div>
</template>
```
## 参考にしたページ
Scoped CSSにおけるCSS設計手法
https://ics.media/entry/200515/
スコープ付き CSS
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html
ZennのMarkdown記法
https://zenn.dev/zenn/articles/markdown-guide
Ruby条件分岐処理

#条件分岐処理
##比較演算子(>, >=, <, <=, ==)

比較演算子	使い方	説明
>	A > B	AはBより大きいか
>=	A >= B	AはB以上か
<	A < B	AはBより小さいか
<=	A <= B	AはB以下か
==	A == B	AとBは等しいか

##true, false
```java:
# 1は20より小さいか？
irb(main):001:0> 1 < 20
=> true

# 5は5以下か？
irb(main):002:0> 5 <= 5
=> true

# 1は20より大きいか？
irb(main):003:0> 1 > 20
=> false

# 5は5以上か？
irb(main):004:0> 5 >= 5
=> true

# 2 × 5は10と等しいか？
irb(main):005:0> 2 * 5 == 10
=> true

# 10は20と等しいか？
irb(main):006:0> 10 == 20
=> false
```
##論理演算子(!)
###式の真偽の確認や、真偽値に対しての演算を行うことができる演算子を論理演算子と呼ぶ。!(エクスクラメーションマーク)は not演算子 と呼ばれ、否定の意味で使われる。!と=を合わせた!=は、==と反対の意味で 値同士が等しくない 場合にtrueを返す
```java:
# 2 × 3 は6ではないか？
irb(main):001:0> 2 * 3 != 6
=> false
# 2 × 3 は10ではないか？
irb(main):002:0> 2 * 3 != 10
=> true
```
##if文
###if文は、条件式が正しいか正しくないか、つまりtrueかfalseかで実行する処理を分岐させることができる
```java:
if 条件式
  処理
end
```
##else(if文)
###if文で条件式が偽のときに処理を行うには、elseを使う。条件を満たさなかったときの処理をelse~endの間に記述する
```java:
if 条件式
  # 条件式が真(true)のときに実行する処理
else
  # 条件式が偽(false)のときに実行する処理
end
```
##elsif(if文)
###elsifは、elseのように条件式がfalseだったときの処理を記述するものだが、条件を満たさなかった場合に対して、ifのように条件式を追加できる
```java:
if 条件式1
  # 条件式1が真(true)のときに実行する処理
elsif 条件式2
  # 条件式1が偽(false)のとき、かつ
  # 条件式2が真(true)のときに実行する処理
else
  # 条件式1と条件式2がどちらとも偽(false)のときに実行する処理
end
```
##すなわち正か負か0かの条件分岐は以下のようになる
#現場からは以上です！
DeepChemのGraphConvModelを可視化してみる

#はじめに
化合物でDeepLearningを始めようと思い、手始めに前回DeepChemのGraphConvModelをハックし、summaryメソッドによりテキストで出力した。

今回はplot_modelで可視化してみた。

# 環境
- DeepChem 2.3 
- pydot

#方法

GraphConvModelのクラス定義がされているファイルの624行目に以下のコードを入れ、適当なデータで予測モデルを作成すると、model.pngというファイルが生成される。

```<anaconda3>/envs/deepchem/lib/python3.7/site-packages/deepchem/models/graph_conv.py
    from tensorflow.keras.utils import plot_model
    plot_model(
            model,
            show_shapes=True,
        )
```

#結果
こんな感じ。
Inputの順番が入れ替わっており見づらいが、テキストベースのものよりはイメージしやすいかも。Weaveだともっと複雑になりそうだ。

![model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/41f5cc9e-4f0f-0b8b-0c3e-123b984787b6.png)
Visual Studio Code 日本語化（2020/10/29時点）

#はじめに
初投稿です。
仕事で使うことになったので備忘録として。
OS: Windows10
VSCode version: 1.50.1

###参考記事
以下の記事を参考にさせていただきました。
（社内で新規要員に説明するためにスクショ付きのドキュメントを作っておきたかった。。。）
[Visual Studio Codeで日本語化する方法[Windows]](https://qiita.com/nanamesincos/items/5c48ff88a4eeef0a8631)

#日本語化手順
1. Visual Studio Codeを開く
1. メニューバー → 「View」 → 「Command Palette」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/835444/94beb661-2e17-7135-72d5-10e6d7d2e757.png)

1. 「Configure Display Language」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/835444/9c7e46a1-0ba4-afcb-4da1-a2e7576eb752.png)

1. 「Install additional languages」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/835444/08a307b5-cadf-1bb2-a61f-8453347e703d.png)

1. カテゴリが「language pack」の拡張機能がリストアップされるので、日本語の言語パックを探して「Install」ボタンを押下する。（今回は「Japanese Language Pack for Visual Studio Code」を選択）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/835444/5c3a472c-21e6-142c-b155-d241bfb13df8.png)

1. VSCodeの再起動を促すメッセージが右下に出るので、「Restart Now」を押下して再起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/835444/ac3b0b2c-fb72-ce5a-a3af-427d2ab918b7.png)

### 備考
言語パックの説明に以下の文言がありますが、今回は不要でした。
`使用法
インストールが完了したら、Japanese Language Pack を読み込むために locale.json 内で "locale": "ja" を設定します。locale.json を編集するには Ctrl+Shift+P を押してコマンド パレットを表示させ、"config" と入力し、利用できるコマンドのリストをフィルター処理してから Configure Language コマンドを選択します。詳細については Docs を参照してください。`
Style GANの理解と実装

GANを学ぶ機会があり、どうせなら新しい技術まで知りたいと思ったのでStyle GANについて実装レベルで理解しようと考えました。
TensorFlowとCUDAのバージョン問題でイライラしていたこともあり、PyTorchで実装しているコードがないかと調査したところ、下記の記事があったため、ここのコードを読み込むことにしました。

[PyTorchでStyleGAN](https://qiita.com/t-ae/items/afc969c48450507dc421)

コードは理解しやすかったのですが、

- Trainer部分が入り組んでいた
- Shape(テンソルの形状)を追いかけたかった
- Style GANに使われている個別技術(PixelNormalizationなど)の仕組みを理解したかった

ということで、一部クラスを組み換えつつdocstringコメントを追加するなどして遊びました。

# 実装

- 動作環境
 - GPU: GTX750Ti
 - OS: Windows10
 - Python: 3.7.9
 - PyTorch: 1.5.0
 - CUDA: 10.1

CUDAのについては[自分が書いたこの記事を参考](https://qiita.com/BARANCE_TW/items/30abf85c55070a2bdc9d)に、「グラフィックドライバのアップデート」と「CUDA Toolkitのインストール」を実行しておく必要があります。
なお、NVIDIA製グラフィックボードがない場合はGPU演算できません。
GPU演算ができなくても実行できますが、1バッチ通すのに数秒かかるので大人しくGPU環境を導入した方がよいでしょう。

ソースコードはこちらです↓
[GitHub: StyleGanPytorch](https://github.com/BARANCE/StyleGanPytorch)

設定はsetting.jsonから変更できます。
デフォルトの設定では第7層のバッチサイズを2まで落としているのでまともに学習が進みません。
GPUに余裕がある場合はこの値を大きくしましょう。
GPUスペック以上に大きくすると、メモリが確保できずエラー落ちします。

# 今後の展望

クラスの組み換えとコメント部分以外は前述記事のコードほぼそのままなので恐縮ですが、大変よい勉強にはなりました。
ちなみに機械学習自体の動作に関しては、私のPCのGPUがGTX750Tiということもあり、大幅にバッチサイズを落とさざるを得ませんでした…
このため、記事通りのモデルでは間違いなく学習が終わりません(笑)

後ほど、新しいPCを購入するまでのつなぎとして、モデルのパラメータを減らすなどの作業にチャレンジしてみようと思います。
イラスト生成などできるといいよなあ…

なお、Style GANの原論文で用いられているモデルをそのまま用いる場合、クラウドに湯水の如く金を落とさないと再現実験もできないと思いますので最初から諦めています。
(リアルな画像生成系はスペックとの戦いですよね…)
正多面体の展開図を折りたたんで正多面体を描画してみた

思い立ったらやってみていた。
角度は制限してないので、めり込んでいくスタイル。

マウスでドラッグすると視点を動かせます。

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="QWEaPVm" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="polyhedral net - three js">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/QWEaPVm">
  polyhedral net - three js</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# はまったこと

- `DoubleSide`を指定しないと裏面が描画されない。
- クォータニオンとマトリクスは併用できないっぽい。（結果的にマトリクスに集約した。）
- `THREE.Shape`の`lineTo`での点の登録順序と、`ShapeGeometry`の`geometry`の頂点`vertex`の順序が逆順になる？？

# 説明兼備忘録

## （回転させる前の）展開図の座標を作る

面と辺を選んで、その辺に隣接する正多角形を追加していく。

```js

const polyGenF = [-1,0,0,1,3,3,3,3,2,2,2,2]; // refering Face index
const polyGenI = [-1,0,2,1,0,1,2,3,0,1,2,3]; // refering edge Index
const polyGenN = [ 5,5,5,5,5,5,5,5,5,5,5,5]; // N-polygon
const edgeLen = 150;
const N = polyGenF.length;

中略

  iniFaces = [newFaceTouchEdgeByP(new Point(0, 0), new Point(0, edgeLen), polyGenN[0])];
  for ( let i=1; i<N; i++ ) {
    iniFaces.push(newFaceTouchEdgeByI(iniFaces, polyGenF[i], polyGenI[i], polyGenN[i]));
  }

中略

// 指定した多角形(initialFacesPoints[faceI])の
// edgeI+1番目の辺に隣接する正polyN角形の座標ポイントを生成して返す。
// 辺の座標の順番はラジアンの方向まわりで合わせる。
function newFaceTouchEdgeByI(facesPoints,faceI,edgeI,polyN) {
  const p0 = facesPoints[faceI][edgeI];
  const p1 = facesPoints[faceI][(edgeI+1)%(facesPoints[faceI].length)];
  return newFaceTouchEdgeByP(p0,p1,polyN);
}

function newFaceTouchEdgeByP(p0,p1,polyN) {
  //const edgeLen = calcDistance(p0,p1);
  let theta = calcAngle(p0,p1) - (Math.PI*(1-2/polyN));
  let x = p0.x;
  let y = p0.y;
  let a = [new Point(x,y)];
  
  for ( let i=1; i<polyN; i++ ) {
    x += edgeLen*Math.cos(theta);
    y += edgeLen*Math.sin(theta);
    a.push(new Point(x, y));
    theta += 2*Math.PI/polyN;
  }
  return a;
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/7738b000-b512-a062-242b-b95a7f3102b2.png)

## 面（複数）を選んで辺を軸として回転させる

配列`polyGenF`等のindex 0の面をルート（親）ノードとして、直下の子ノードにあたる隣接面を選択し、各ノードの親との共有辺を回転軸として、つながっている面（＝子孫となるノード）をすべて一律回転させる。これを再帰的にやっている。（語彙力・・）

# 参考サイト

 - [正十二面体 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%AD%A3%E5%8D%81%E4%BA%8C%E9%9D%A2%E4%BD%93)
TeX記法 数学Ⅱ

### 概要
数学Ⅱで使用する公式のTex記法を下記に示す。

### TeX記法 数学Ⅱ


#### 微分と積分

**微分係数**
`\lim_{h \to 0}\frac{f(a + h) - f(a)}{h} = f'(a)`

```math
\lim_{h \to 0}\frac{f(a + h) - f(a)}{h} = f'(a)
```

**微分**
nは自然数、cは定数とする
`(x^n)' = n x^{n-1}`
`(c)' = 0`
`\{c f(x)\}' = cf'(x)`
`\{c f(x) + g(x)\}' = cf'(x) + g'(x)`

```math
(x^n)' = n x^{n-1} \\
(c)' = 0 \\
\{c f(x)\}' = cf'(x) \\
\{c f(x) + g(x)\}' = cf'(x) + g'(x)
```

**接線の方程式**
`y = f(x)`上の点`A(a, f(a))`を通る接線の式は
`y - f(a) = f'(a)(x - a)`

```math
y - f(a) = f'(a)(x - a)
```

**法線の方程式**
`y = f(x)`上の点`A(a, f(a))`を通る法線の式は
`y = -\frac{1}{f'(a)}(x - a) + f(a)`

```math
y = -\frac{1}{f'(a)}(x - a) + f(a)
```

**不定積分**
`\int F'(x)dx = F(x) + C`
`\int x^{n}dx = \frac{x^{n + 1}}{n + 1} + C`

```math
\int F'(x)dx = F(x) + C \\
\int x^{n}dx = \frac{x^{n + 1}}{n + 1} + C
```

**定積分**
`\int_{a}^{b} F'(x)dx = [F(x)]_{a}^{b} = F(b) - F(a)`
`\int_{a}^{b} k f(x)dx = k\int_{a}^{b} f(x)dx`
`\int_{a}^{b} \{f(x) + g(x)\}dx = \int_{a}^{b} f(x)dx + \int_{a}^{b} g(x)dx`
`\int_{a}^{b} f(x)dx = -\int_{b}^{a} f(x)dx`


```math
\int_{a}^{b} F'(x)dx = [F(x)]_{a}^{b} = F(b) - F(a) \\
\int_{a}^{b} k f(x)dx = k\int_{a}^{b} f(x)dx \\
\int_{a}^{b} \{f(x) + g(x)\}dx = \int_{a}^{b} f(x)dx + \int_{a}^{b} g(x)dx\\
\int_{a}^{b} f(x)dx = -\int_{b}^{a} f(x)dx
```

**1/6の公式**
`\int_{\alpha}^{\beta} (x - \alpha)(x - \beta)dx = -\frac{1}{6}(\beta - \alpha)^3`

```math
\int_{\alpha}^{\beta} (x - \alpha)(x - \beta)dx = -\frac{1}{6}(\beta - \alpha)^3
```
npm scripts内の`echo`でダブルクォートを出力させたい

# TL;DR


こんなことを

```sh
echo \"
```

npm scriptsで再現したければ、こう書きます。

```json:package.json
  "scripts": {
    "double-quote": "echo \\\""
  }
```

# 目的

こんなシェルコマンドを叩いて、

```sh
echo { \"home\": \"$HOME\" } > home.json
```

変数を展開したJSONファイルを作りたかったんですね。

```json:home.json
{ "home": "/home/myname" }
```

しかもnpm scriptsに書きたかったんです。

# npm scriptsでは挙動が違う

シェルで実行するときのままこう書くと、

```json:package.json
  "scripts": {
    "create-json": "echo { \"home\": \"$HOME\" } > home.json"
  }
```

`npm run`は正常終了するものの、出来上がるファイルはこんな感じ。
ダブルクォートが消えちゃってInvalid JSONです。

```json:home.json
{ home: /home/the-red }
```

上記のscriptは、シェルでこう打ち込むのと一緒なんですね。

```sh
echo { "home": "$HOME" } > home.json
```

`\"`で「ダブルクォート1文字」扱いになってしまう。

# どうするか？

こうするのです！

```json:package.json
  "scripts": {
    "create-json": "echo { \\\"home\\\": \\\"$HOME\\\" } > home.json"
  }
```

`\\`で`\`そのものを出力、
`\"`で`"`そのものを出力、
合わせて`\"`そのものを出力、という感じ。ややこしや。


この程度なら良いけど、あんまり複雑なJSONファイルを作りたいときは、
scriptsに直接書くのはやめたほうが良さそうですねー。

# 余談
## シングルクォート使えばいいんじゃね？


```json:package.json
  "scripts": {
    "create-json": "echo '{ \"home\": \"$HOME\" }' > home.json"
  }
```

ダメなのです。

```json:home.json
{ "home": "$HOME" }
```

シングルクォートだとシェル変数が展開されないのである。

変数使わないJSONを出力したいなら、まぁシングルクォートで良いけど、
それならscriptで出力させる必要なんかそもそも無いわけで。

## クォートしなければいいんじゃね？

```json:package.json
  "scripts": {
    "create-json": "echo { home: $HOME } > home.json"
  }
```

だからInvalid JSONになるんだってば！

```json:home.json
{ home: /home/the-red }
```

## JSONじゃなくてJSを出力させればいいんじゃね？

```json:package.json
  "scripts": {
    "create-js": "echo module.exports = { home: \\'$HOME\\' } > home.js"
  }
```

```js:home.js
module.exports = { home: '/home/the-red' }
```

うん、、、そうね。趣旨が全然変わってしまったね。
この辺にしときます～。
[day:11]あれ？Font Awesomeが表示されない

# あれ？Font Awesomeが表示されない

## はじめに
現在HTML/CSSを使用した開発タスクを行っているのですが、理解不足な点がいくつかありましたので補強していきます。

## Font Awesomeの導入
[Font Awesome](https://fontawesome.com/?from=io)すごく便利ですよね。
使いたいアイコンを選んでhtmlに記述すれば使いたいアイコンがすぐに表示される！
と意気揚々にhtmlに記述した私ですが、どういうことでしょうアイコンが表示されません...
タグはしっかりと閉じていますし、何も問題はなさそう？
ところが表示されないのはそのはずで、Font AwesomeをCDNとして利用したいのにheadタグにその記述がなかったのです。

普段のタスクでは既存のページの改修が多く、一からページを作成する経験が浅くすぐに気づくことができませんでした。
Font Awesomeを使用する際には以下のようにhtmlのheadタグに記述をしなければなりません。
このように、このサイトからアイコンを使いますよと明示的に記述しないとアイコンのタグが何を示しているか分からずに表示できないというわけです。

```html
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css"rel="stylesheet">
```

一からページを作成するタスクでは意外とハマりがち？私だけ？
皆さんも気をつけましょう！
【pythonで自動化！】前編：設定ファイル編

# 始めに
こんにちは、美味しいしです。
この記事は、[「私、デスクトップが汚い人とはお付き合いしたくないの」と言われないために](https://qiita.com/pn8128/items/58533224bb8c6d7ceea0)の実装解説記事の1つ目となります。
実装について知りたい方は記事をご覧ください！


## 設定ファイルの作成編集部分
今回は設定ファイルにyamlとcsvを使いました。

### 困った点1:設定ファイル何処におこう
設定をユーザーが変更しやすくなるように、外に出そうと言うところまではよかったのだが、いざcli化しようと思うと置き場所に困った。
結局、home dir下に.myscreenshot と言うフォルダを作ることで解決した。
やや力技かも。

### 困った点2:path中に含まれる"~"がhomedirをさしてくれない
設定ファイルを書いてみて、嬉々として動かしてみたら動かない。
なんでかなぁと思ったら、pathの中に含まれる"~"がただのニョロとしてしか解釈されていなかった。

```ptyhon
dirname="~/.myscreenshot"
```
解決方法は以下のとおり

```python
from os.path import expanduser
home=expanduser("~")
dirname=dirname.replace("~",home)
```
### 工夫した点1:勝手にmacの設定とってこれたらかっこいいんじゃね？？？
subprocessを使ってコマンドを叩くことで実装しました。

```python
import subprocess
res = subprocess.run(
        "defaults read com.apple.screencapture location",
        shell=True,
        capture_output=True)
if res.returncode == 0:
    dirname = res.stdout[:-1].decode()
else:
    dirname = "~/Desktop"

res = subprocess.run(
    "defaults read com.apple.screencapture name",
    shell=True,
    capture_output=True)
if res.returncode == 0:
    prefix = res.stdout[:-1].decode()
else:
    prefix = "スクリーンショット"
```
返り値には改行も含まれているのでそれを消しています。また、byte型なので、decodeしてあげています。


これはpython-daemonというライブラリを使うと比較的容易に実装できます。

後編は[こちら](https://qiita.com/pn8128/items/cee612387723377b8827)！
【pythonで自動化！】後編：ファイル操作編

# 始めに
こんにちは、美味しいしです。
この記事は、[「私、デスクトップが汚い人とはお付き合いしたくないの」と言われないために](https://qiita.com/pn8128/items/58533224bb8c6d7ceea0)の実装解説記事の2つ目となります。
今回はやや短めかもです。
実装について知りたい方は記事をご覧ください！

## ファイル操作部分
ここで用いたのは正規表現とshutilです。

### 工夫した点1:ファイル名からキャプチャ時間を抽出しよう！
macのスクショって天才なことに、ファイル名にキャプチャ時間が入るんですね！
これのおかげで、exiftoolのようなものをインストールしてくる必要がなくなりました。prefixにはスクショ時に頭につく接頭辞が入っています。詳しくは[こちら](https://qiita.com/pn8128/items/34f30868e8dddea0c7a1)！

```python
path="スクリーンショット 2020-10-22 10.28.04.png"
cvtpath = re.compile(
        prefix + r"[\s\S]*?(\d{4}).(\d\d).(\d\d)[\s\D]*?(\d\d?).(\d\d).(\d\d)")
flag = re.search(cvtpath, path)
if flag is not None and len(flag.groups()) == 6:
    date = flag.groups()
    date = list(map(lambda x: int(x), date))
```


### 困った点1:曜日ってどうやってとろう
よくよく考えたら、ある曜日のある時間帯にいるってどう判断しよう

解決方法：datetimeで曜日は取れる。後はUNIX時間っぽいものを作ればOK!

```python
day = dtdt(*date).strftime("%a") # 曜日を取得できる
# print(day)
# > Thu
dateemb = date[3] * 60 + date[4] # これで一つの値になったので比較できる
# print(dateemb)
# 628
```

### 困った点2:os.mvがない！
解決方法:osがなければshutilに頼ればいい！

```python
import shutil
shutil.move(oldpath, newdir)
```
# 終わりに
読んでいただきありがとうございました。
前回の記事は[こちら](https://qiita.com/pn8128/items/34f30868e8dddea0c7a1)
Git BashとMSYS2をWindows Terminalに設定する。

Windows Terminalのsettigs.jsonの`profiles.list`に追加します。

```JSON
[
	{
		"guid" : "{【一意なGUID】}",
		"commandline" : "\"%PROGRAMFILES%\\Git\\git-cmd.exe\" --cd-to-home --command=usr/bin/bash.exe -l -i",
		"icon" : "%PROGRAMFILES%\\Git\\mingw64\\share\\git\\git-for-windows.ico",
		"name" : "Git Bash"
	},
	{
		"guid" : "{【一意なGUID】}",
		"commandline" : "C:\\tools\\msys64\\msys2_shell.cmd -msys2 -defterm -no-start",
		"icon" : "C:\\tools\\msys64\\msys2.ico",
		"name" : "MSYS2"
	},
	{
		"guid" : "{【一意なGUID】}",
		"commandline" : "C:\\tools\\msys64\\msys2_shell.cmd -mingw32 -defterm -no-start",
		"icon" : "C:\\tools\\msys64\\mingw32.ico",
		"name" : "MSYS2 MINGW32"
	},
	{
		"guid" : "{【一意なGUID】}",
		"commandline" : "C:\\tools\\msys64\\msys2_shell.cmd -mingw64 -defterm -no-start",
		"icon" : "C:\\tools\\msys64\\mingw64.ico",
		"name" : "MSYS2 MINGW64"
	}
]
```

【一意なGUID】はPowerShellで`New-Guid`と実行して生成してください。上のMSYS2はChocolateyで入れているので、パスが"C:\tools\msys64"に入っています。別の所にインストールした場合は、パスを変えて下さい。

各コマンドはcmderの設定を参考にしました。
【docker】yml ⇆ json を変換する

以下のコマンドを実行

```
$ docker run -it -v $PWD:/mnt/ --rm python:3.7-alpine sh 
```

必要なライブラリなどをインストール

```
/ # cd mnt; apk add jq; pip install yq
```
ymlからjson,jsonからymlに変換する

```
$ yq "." [変換したいymlファイル] > [変換後のjsonファイル]
```
「私、デスクトップが汚い人とはお付き合いしたくないの」と言われないために

# デスクトップの整理、できてますか？
![S__43335687.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545134/ebe211a7-55ef-fdb0-0619-8d9b860e5b24.jpeg)
MacbookProやMacbookAirでスクショを取ると、何故かデスクトップに保存される。
とくに大学生諸賢は授業のオンライン化にともない、スクショをとる場面も格段に増えたのではないだろうか？
期末試験の直前の忙しいときにデスクトップを埋め尽くす大量のスクショをひたすら仕分けるはめになったのは、少なくとも私だけではないはずだ。

こんなお粗末な現状、デジタルネイティブと巷でもてはやされる我々らしくない。
きっと奴がなんとかしてくれるはずだ。
そう、我らがPythonなら！

# tl;dr
- Pythonでスクショを授業に合わせて自動振り分けできるMac向けツールを作ったよ！
- daemon化してあるから、一回起動すれば電源を落とさない限り働いてくれるよ！
- pipでインストールできるし、操作も簡単だからみんないれような！

# はじめに
改めまして、こんにちは。美味しいしです。
python advent calendarということで、今年の11月に作ったツールについて、[加筆](https://qiita.com/pn8128/items/d973cdc637fa67b50009)してみました。
Pythonを使ってスクショの自動整理ツールです。
元々自分のパソコン用に作ったものなのでmacにしか対応しておりません。ご了承ください。

できるだけ多くの人に使って欲しいとおもっているので、記事の前半で使い方、後半で実装に関して述べたいと思います。
お忙しい方やとりあえず使えればいい、という方は[github](https://github.com/pn8128/scr_utils)に簡潔な説明を載せているのでそちらをご覧ください。


## インストール方法  
```sh  
pip3 install Sukusho  
```  
で入ります。  
バグが見つかり次第修正版を上げていくので、たまに  

```sh  
pip3 install Sukusho -U  
``` 
してくれると嬉しいです。  
  
## 使い方  
まず、ターミナルを開いて、
  
```sh  
sukushoinit  
```  
してください。  
するとまず、

>[now:~/Desktop]:press enter or input savedir path 

と言うようにファイルをどこに保存したいかを聞かれます。デフォルトではデスクトップに保存されるようになっています。
このままで良ければ、enterを、変更したい場合はそのフォルダまでの絶対パスを打ち込んでください。  


次に、こんなふうにエクセルがでてくるはずです。  
![SCR 2020-10-29 at 21.31.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545134/11580916-e39b-9da8-7f26-c1c1cc9c4b28.png)

ここに履修している授業をこんな風に打ち込みましょう。  
![SCR 2020-10-29 at 21.35.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545134/597fc7e0-ec71-6554-73a0-9b74ce0a2495.png)

空きコマは空白にしてください。  
jigenの中の時間も、
01:23~04:56
の書式さえ合わせれば変更可能です！

さて、次はテストを走らせてみましょう。  

```sh  
sukusho -t  
```  

ここで、  
> Your sukusho is ready!  

と出てきたらOKです！  
いよいよ稼働させます。  
1回だけ動かしたい場合は、

```sh  
sukusho -e
```  
デーモン化したい時は

```sh  
sukusho -start  
```  
と打ち込めば、システムが走り始めます！  
デーモン化したシステムを止めたい場合には、  

```sh  
sukusho -kill  
```  
と打ち込みましょう。  
保存先を変えたい場合は  

```sh  
sukusho -es  
```  
時間割を変えたい場合は、  

```sh  
sukusho -ej  
```  
で行うことができます。  


# 実装
今回の実装は大きく分けて、

- [設定ファイルの作成編集部分](https://qiita.com/pn8128/items/34f30868e8dddea0c7a1)
- [ファイル操作部分](https://qiita.com/pn8128/items/cee612387723377b8827)
- [デーモン化部分](https://qiita.com/pn8128/items/d973cdc637fa67b50009)

の3つの部分からなります。
デーモン化の部分は[@KosukeJin様の記事](https://qiita.com/KosukeJin/items/e626ddda850aa8407cee)を大変参考にさせていただきました。


# 終わりに
最後まで読んでくださりありがとうございました！
エラーやバグ等の報告がありましたら、githubのissueまたは[twitter](https://twitter.com/pn8128)までお願いします！
プロゲート【JQuery上級-#2フォームの操作-】text,attr,val,submit,selectタグ

#  prorate:JQuery上級コース その２
## フォームの操作
### textメソッド
textメソッドは引数を指定せずに用いることで、要素内の文字列を「ゲット（取得）」することもできる

```javascript
var text = $(‘p’).text();
// textを取得

var html = $(‘main’).html();
// mainの中のhtmlを取得

var fontSize = $(‘h1’).css(‘font-size’);
// h1のcssを取得
```

書き換える場合

```javascript
$(‘h1’).text(‘こんばんは’);
// h1のテキストをこんばんはに書き換える
```

## attrメソッド
HTMLの属性はattrメソッドを用いて「ゲット」と「セット」ができます。例えば、attr(‘id’, ‘title’)のように第一引数に属性名、第二引数にその属性値を指定することで属性をセットすることができます。そして、第二引数を指定しない場合は、その属性の値を取得できます。[progate](https://prog-8.com)

```javascript
$(‘h1’).attr(‘id’,’title’);
//  h1要素にtitleというidをセット

var url = $(‘a’).attr(‘href’);
// a要素のhref属性の値を取得
```

## inputタグの入力値
### valメソッド
inputタグに入力されている値は、valメソッドで取得できる

```javascript
var name = $(‘#name’).val();
```

### submitイベント
submitイベントを用いると、送信ボタンがクリックされたときだけでなく、「Enter」キーでフォームが送信された場合もイベントが発生する

```javascript
$(‘form’).submit(function(){

});
```

```javascript
$('#form').submit(function(){ // submitイベント
    
    var textValue = $('#text-form').val();　// textValue定義
    $('#output-text').text(textValue);　
		// output-textフォームを書き換える
    return false;
    
  });
```

## セレクトボックスの入力値
### selectタグ

> selectタグを用いると選択肢式のセレクトボックスを作ることができます。selectタグとoptionタグからなり、各optionタグが選択肢になります。下図のように、selectタグはvalメソッドによって、選択中の値（optionタグのvalue属性の値）を取得できます。[progate](https://prog-8.com)

```html
<form>
	<select id=“gender”>
		<option value=“male”>男</option>
		<option value=“female”>女</option>
	</select>
</form>
```

## フォームの入力チェック
```javascript
if($(‘text-form’).val() == ‘空文字’){
 //テキストフォームの値がから文字だった場合の処理
}else{

}
```

```javascript
 if (textValue == '') {
      $('#error-message').text('理由を記入してください');
      // エラーメッセージ
    }else{
      $('#error-message').text('');
      // エラーメッセージ非表示
    }
```

## 入力欄への自動入力
valメソッドは値を取得することもできますが、反対に引数に値を指定することで、フォームに値をセットすることもできる。

```javascript

$('.option-btn').click(function(){ // クリックイベント
  var optionText= $(this).text();　
  $('#text-form').val(optionText +'が好きな理由は、');
});
```

## セレクトボックスの自動入力
> selectタグもvalメソッドを用いて自動で選択させることができます。先ほどのinputタグとの違いは、selectタグの場合選択肢が限定されているということです。optionタグのvalue属性に合致する値をvalメソッドの引数に指定しましょう。[progate](https://prog-8.com)

```javascript

$('#gender').val('female);
// value属性がfemaleのものを選択させる
```

## カスタムデータ属性
属性は自分でつくることもできます。これをカスタムデータ属性といい、「data-」から始まる属性名を自由に設定できる。

```html
<div deta-option=“wanko”>…</div>
```
【Chrome】Chromeで警告が出ないようにする

Chromeで以下のようなWarningが出ることがある



![スクリーンショット 2020-10-27 15.26.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377231/65fa8d79-b9d9-f613-d1eb-db437ce5b5a5.png)


https以外のリクエストを叩いた結果SSL認証が一致しないため，セキュリティの観点でWarningが表示されるのが理由である．


テスト等で表示されるたびに毎回「承知で閲覧する」ボタンをクリックするのは面倒なので，リクエスト先が安全で信頼できることを前提にこの警告が出ないようにしたい．

ChromeをSSL認証OFFで起動することでこのWarningが表示されなくなる

Chromeを終了して以下コマンドをコマンドラインから叩くだけです．

```
open -a Google\ Chrome --args --ignore-certificate-errors --ignore-urlfetcher-cert-requests
```
ChromeがSSL認証OFF設定で起動します．
【Julia】キーワード引数(x=x)は(;x)と省略できる

**注意：この機能はJulia1.5以降でのみ使えます。あと、2020/10/29現在ではたぶんVS Codeのプラグインが対応していません。**

# キーワード引数という機能
Juliaには [Keyword Argumants（キーワード引数）](https://docs.julialang.org/en/v1/manual/functions/#Keyword-Arguments) という機能があります。

```julia
function speed(; kyori, jikan) #時間と距離から平均速さを求める関数
  return kyori / jikan 
end
kyori = 0 # ここに長い式があるとする
jikan = 1 # ここにも長い式があるとする
v = speed(; jikan=jikan, kyori=kyori)      #関数normの利用
```
この場合では、Keyword Argumentsを使わないと、逆の順番で引数を渡してもエラーが起こってくれないので慎重になる必要があります。
関数を呼び出すときにキーワードを付ける代わりに`jikan`と`kyori`の引数の順番を気にしなくても良くなります。
数値解析の場では、多数の物理量が登場するし、プログラミングが得意でない人でもメンテナンスできるようことが要求されるので、この機能が役に立つのでは無いでしょうか。

**ただし、この機能には一つだけ欠点があります。**
記述が冗長になってしまうことです。変数の名前とキーワードが一致しているのにそれを、

```julia 
speed(; jikan=jikan, kyori=kyori)
```
わざわざ並べて書くのは煩わしいですよね？

# キーワード引数の短縮記法

上で紹介したドキュメントでも見落としやすいほどサラッと書かれていますが、Julia1.5からはこれを短くできる文法が追加されています。

```julia
speed(; jikan, kyori)
```
ね？簡単でしょう？
カッコの中、キーワード引数を使いたい場所の直前で`;`(セミコロン)を打つと、このように書いても元のコードと同じ意味になるんです。
ちなみに、

```julia
struct Kukan
  kyori::Float64
end
jikan = 54 / 3600 # 54秒
senbayashi_takii = Kukan(0.4) #京阪本線 千林-滝井 駅間の距離は0.4km
v = speed(; jikan, senbayashi_takii.kyori)
```
でもOKです。`senbayashi_takii`の`kyori`プロパティを使うと、キーワードの`kyori`が勝手に補完されてくれます。

この機能はNamed Tuple（名前付きタプル）のフィールドでも使えるようで、
[リリースノート](https://docs.julialang.org/en/v1/NEWS/)では、
> implicitly using the name of the variable as the keyword or named tuple field name

とあるので、**Implicit Keyward / Tuple Field Name (暗黙のキーワード / タプルフィールド名)** とでも仮に呼んでおきましょう。
こういうのは名前がないとノウハウの共有が出来ないので。（ジョシュア・ツリー効果です）

ちなみに、Javascriptでは、Shorthand property namesと言うようです。

# 参考文献
- [Functions - The Julia Language(公式ドキュメント)](https://docs.julialang.org/en/v1/manual/functions/#Keyword-Arguments)
    - [少し古いですが有志の方の日本語版もあります](https://mnru.github.io/julia-doc-ja-v1.0/manual/functions.html)
- [Julia v1.5 Release Notes](https://docs.julialang.org/en/v1/NEWS/)
pythonでSFTP通信したら地味にハマった話

#概要
海外のライブラリはエンコーディングの考えが適当なものがあるから注意って話。

#トラブル内容
業務上、pythonでsftpを触る必要が出たからparamikoを使用し、ファイルをFTPサーバから直接ダウンロードして中身のテキストファイルを統計処理にかけようとした。
[APIのドキュメント](http://docs.paramiko.org/en/stable/api/sftp.html)では「file()関数はpythonのfileと同じ用に使えるようにしてあるよ」ってあったので適当にパスなどを指定したら下記のエラーが出た。

> UnicodeDecodeError: 'utf-8' codec can't decode byte ～～ in position ～～: invalid start byte

コードは下記のような感じ。

```python

client = paramiko.SSHClient()
client.connect(適当な接続情報)
sftp_connection = client.open_sftp()

with sftp_connection.open(ファイルパス) as f
    for line in f:
        print(line)

```

これを行うとfor文の付近でUnicodeDecodeErrorが出た。

##原因
一言で言ってしまえば、「ファイルの中身を取得するときにエンコードを指定できないから」であった。ANSIでエンコーディングされたテキストファイルをUTF-8で読もうとしてしまっていてエラーが起きている。
ソースを見てみたが、現時点ではopen時にエンコーディングを指定することができない。標準の入力では出来てるんだけど。

##回避策

ファイルの中身を英語に書き換えることも、utfで作り直させることもできなさそうなため、今回はバイナリで開いてANSIで別途エンコーディングして読ませることにした。
具体的には、上記のコードのwith文以下を次のようなイメージで書き直した。
(ある程度標準入力に似せているのはsftpじゃなくてローカルでデバッグできるようにしたかったため。当然通信が無いほうがデバッグにかかる手間は少なくて済む。)

```python
import codecs

for line in readlines():
    print(line)

def readlines():
    file f = sftp_connection.open(ファイルパス, "rb")
    return codecs.encode(f.read(), "ANSI").split("\r\n")

```

openの2つ目の変数に"rb"を指定することで、バイナリとしてファイルを読み込む。
それを読み込みたいエンコードで読み直してから、行を返すようにしている。

あまりにもファイルが巨大だった場合は問題が出そうだが、実用上問題なさそうだったので今回はこれでOKとした。


###根本原因
今回の問題の根本原因はparamikoのBufferedFileにエンコードを指定させることだと思う。

しっかり読み込むことができたらいい機会だしparamikoのgithubの方にpull request飛ばしたいなぁ
async, await のシンプルな書き方メモ


以前 [Promiseのシンプルな書き方メモ](https://qiita.com/papettoTV/items/5d860eda0cfe1badca3d) というのを書きましたが、それのasync, await版です。

```javascript

// 非同期処理taskA
const taskA = async (v) => {
  console.log('taskA', v);
  return await mainProc(v);
};

// 非同期処理taskB
const taskB = async (v) => {
  console.log('taskB', v);
  // return await mainProc(v);
  return await mainProcError();
};

// 非同期処理taskC
const taskC = async (v) => {
  console.log('taskC', v);
  return await mainProc(v);
}

// メイン処理
const mainProc = (v) => v + 1;

// メインエラー処理
const mainProcError = () => {
  throw new Error('error');
}

// エラーキャッチ時の処理
const onCatch = (e) => {
  console.log("catch", e);
  return "hoge";
};

// -----------
// メイン処理
// -----------
const main = async () => {
  let res = 1;
  res = await taskA(res);
  res = await taskB(res).catch(onCatch);
  res = await taskC(res);
  console.log("main", res);
};

main();

```

実行結果

```
taslA 1
taskB 2
catch Error: error
    at mainProcError (・・・略)
taskC hoge
main hoge1
```

# 動きをみて分かったこと

* `promise.then().then(). ・・・`は `async内 await,await・・・`で置き換えれる
* await 内のエラーは `.catch()` で拾える
	* その際、catch内の関数 `onCatch` で return した値が awaitの返り値になる
my vimrc

# はじめに

42tokyoのexamでは、まっさらなvimで受けないといけないので、毎回vimrcを書く必要がある。
一番ミニマムなお気に入りvimrcの設定です！

## syntax enable

構文に色をつけてくれるので必須

```
syntax enable
```

## set nu

行数表示。行数がわかると `[行数]+G`でその行に飛べたりするので便利。
でもこのせいでコピペする時に行数までコピーしちゃう時がある。
その時は`:set nonu` で一時的に行数を消せばOK！！！

```
set nu
```

## set paste

貼り付けたい時、デフォルトの設定だと、インデントが変になってしまうのでこれは必須！

```
set paste
```

## set autoindent

デフォルトの設置だと、カーソルがいい感じになってくれないので、インデントを合わせてくれるこれも必須！

```C
int main()
{
    int a;
    int b;
    if (a == b)
|  <ーここにカーソルがきてしまう

}
```

```
set autoindent
```

## set tabstop

タブがスペース何個分かの設定。デフォルトだとなんと８でめちゃ大きいので、半分の４にしてます。
vscodeも4にしてます。

```
set tabstop=4
```

examで必要なのは以上です！

補完機能とかは個人的には必要ないです。