OmniAICreator/Qiita-1.07M huggingface dataset:
aceエディター用のシンタックスハイライトファイルを作成する


需要はない?が備忘録用。
##予備知識
- VSCodeなどのシンタックスハイライトはTextMateシンタックスで書かれている。詳細は以下を参照。

https://macromates.com/manual/ja/language_grammars

- TextMateシンタックスはjsonやyamlで書きたりする。勿論変換も可能。

https://marketplace.visualstudio.com/items?itemName=Togusa09.tmlanguage

- そしてtmLanugageファイルはace用のjsファイルに変換できる。

https://ace.c9.io/#nav=higlighter

- またVSCode用のシンタックスハイライト拡張機能は数多く開発されている(むしろない場合のほうが稀に思える)。

つまり**VSCode用の拡張機能からシンタックスハイライト用のファイルだけお借りして変換すればace(ブラウザーエディター)で使える**(かも)。

##実際にやってみる
今回はyaml。まずyamlファイルを取ってきてtmLanguageファイルに変換する。

https://qiita.com/koara-local/items/4a7b832755f0ef475461

### カスタムタグの編集
ただ変換しようにもいくつか問題があった。まずyamlにカスタムタグが設定されている場合、yaml.loadするとエラーになる。
これを回避するには新たなスキーマをjs-yamlに登録する必要がある。

````js
const yaml = require('js-yaml')

let schema = yaml.Schema.create([
    new yaml.Type("<custom tag>", {kind: "<data type>", construct: function (data) {return <process data>}})
])
<...>
let datas = yamlTexts.map((t) => {
    return yaml.load(t, {schema: schema}) // set the schema
})
````

js-yamlのバージョンは3.8.3。4以上だとyaml.Schema.createメソッドが変わってるらしくよくそれにあたるメソッドがわからなかった。

カスタムタグは以下みたいなやつ。

````yaml
key: !hoge value
````
データ型はscalar, sequence, mappingのどれか。返したいデータ型に合わせる。constructで引数に取ったデータを加工して値を返す。
### tmLanugageファイルの編集
tmLanugageを生成したら次は下のリポジトリのtmlanguage.jsでace用のjsに変換する。

https://github.com/ajaxorg/ace/tree/master/tool

tmLanguageはxmlを拡張したやつで主にplistタグの中にdict, array, key, stringタグで構成されている。
こっからもう一加工必要で、まずplistの中のデータが返されるのでこいつがちゃんとtmlanguage.jsの意図したものになっていないといけない。
jsonで表現すると下のようになってる必要がある。

````json
{
  "name": "hoge",
  "patterns": [{}]
}
````
ポイントは一番外がオブジェクト(dict)でその中にnameが必要。私が生成したtmLanugageは下のようになっていた。

````json
[
  {
    "patterns": [{}]
  }
]
````
一番外が配列でその中のオブジェクトにnameがない。ので上のように加工して

````
$ node tmlanguage.js hoge.tmLanguage
````
でaceようのシンタックスハイライトをつくれた。

##ビルド
最後にビルドする。

https://aleksander-mendoza.github.io/syntax_highlighter.html

> - add your language to \$ACE_ROOT/lib/ace/ext/modelist.js. In my case I inserted a new line like Mealy: ["mealy"],.
- (optional) you may now test your Ace editor by running node static.js --allow-save in $ACE_ROOT and going to http://localhost:8888/tool/mode_creator.html and http://localhost:8888/build/kitchen-sink.html.
- run npm install in \$ACE_ROOT
- run node ./Makefile.dryice.js full in \$ACE_ROOT. This should create \$ACE_ROOT/build/src. You should even see there your syntax \$ACE_ROOT/build/src/mode-\$NAME.js.
- Copy \$ACE_ROOT/build/src to your project directory. In my case I added it to code/ace/build/src, which you can even see on GitHub.
- Finally embed ace in your HTML file like in this example. Notice that $ACE_ROOT/build/src contains ace.js.

あとは生成したbuild/src-hogeをコピーして使うだけ。
Android Kotlin オプションメニューを表示させる

#はじめに
今回は画面右上にオプションメニューを表示させていきます。

![スクリーンショット 2021-08-11 22.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704865/7fbe9733-02e2-07ed-c118-54c62f709b11.png)

##オプションメニュー
画像右上がオプションメニューです。
ちなみにこのボタンを押すと、
![スクリーンショット 2021-08-11 22.54.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704865/5c31c9ac-85ab-c87d-89a5-f4aa27b3df77.png)
上記の画像のようにお問い合わせボタンをクリックするとお問い合わせフォームに画面が遷移する様にしていきます

##実装
menuフォルダを作成し、フォルダ内にxmlファイルを作成

```Kotlin:menu_options.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/optionsInquiry"
        app:showAsAction="never"
        android:title="@string/options_inquiry"
        />

</menu>
```
titleについてはstring.xmlで「お問い合わせ」を記述しています

上記の記述だけでは画面上にはオプションメニューが表示されないので
MainActivityの方で表示させる記述とクリックした際に画面が遷移する記述をしていきます。

```Kotlin:MainActivity.kt
 override fun onCreateOptionsMenu(menu: Menu): Boolean {
        //オプションメニュー用xmlファイルをインフレイト
        menuInflater.inflate(R.menu.menu_options , menu)
        return true
    }

    // オプションメニューのボタン選択時のメソッド
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        //戻り値用の変数を初期値trueで用意
        var returnVal = true
        //選択されたメニューのIDのR値による処理の分岐
        when (item.itemId) {
            //お問い合わせが選択された時の処理
            R.id.optionsInquiry -> {
                //インデントオブジェクトを生成
                val intent = Intent(
                    this@MainActivity , OptionsInquiryActivity::class.java
                )
                //第二画面の起動
                startActivity(intent)
            }
            //それ以外
            else ->
                //親クラスの同名メソッドを呼び出し、その戻り値をreturnValとする
                returnVal = super.onOptionsItemSelected(item)
        }

        return returnVal

        return super.onOptionsItemSelected(item)
    }
```

インフレイトしているファイルは先ほど作成したxmlファイルです。
ボタンクリック時のメソッドでインデントオブジェクトを作成時に（遷移前のアクティビティ、遷移先のアクティビティ）を記述しています

startActivityで画面を遷移させます

![スクリーンショット 2021-08-11 23.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704865/437cdda9-436c-afa4-e8db-085d3ee84ec6.png)

MainActivityに表示させるメソッドとボタンクリック時のメソッドを記述する事で、
実際に画面で画面を遷移させることができました！

##さいごに

睡魔が襲ってきて説明を若干ハショリましたが、、かなり簡単に実装出来ますね！
このオプションメニューはどの多くのアプリに取り入れられているので、開発する際には是非取り入れましょう！
ちなみにxmlファイルと選択時のメソッドに複数の項目を記述すれば
![スクリーンショット 2021-08-11 23.22.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704865/57227179-7516-53a2-9a41-04d383316f9e.png)
この様にボタンの選択肢を複数にすることができます！（違うアプリやないか、、）

それではおやすみなさい、、、。
[Rails]予約語一覧[h~m]→指摘を頂いたので修正します

# はじめに
本記事では、Railsの予約語一覧を記述しています。
以下の記事の続きになります。

https://qiita.com/mkato1013/items/07194f6a799fa9acedac

# 予約語一覧(注意すべき単語を記述しています)
|頭文字|単語||||
|-|-|-|-|-|
|h|having|hold|host|hour|
||*「hour~」も多いです||||
|i|if|ignore|ilike|import|
||in|index|indexerror|infile||
||initialize|insert|int|int1|
||int2|int3|int4|int8||
||integer|into|io|is|
||isolation||||
|j|join||||
|k|key|keys|kill|||
|l|lag|language|large|last|
||layout|lead|leading|leave|
||left|less|level|like|
||limit|lines|link|ln|
||load|loaderror|local|lock|
||long|loop|lower||
|m|map|match|matchdata|matchingdata|
||math|max|mediumtext|member|
||merge|method|min|minute|
||mod|modify|module|month|
||mysql|*「mysql~」も多いです|||
|n|nameerror|names|national|natural|
||new|new,|next|nil|
||nilclass|no|nomemoryerror|nomethoderror|
||none|not|notnull|null|
||nullif||||

#　終わりに
話はそれますが、
本日は、頭痛がすごく体調が優れませんでした。

すぐに家に帰り、記事を書き終えたので、
今日はお休みします。

明日も頑張りましょう！！
Fcitx5 mozcで入力ができない問題に対処

Debian/Ubuntu系やArch系のディストロを色々と試す中で毎回基本的にFcitx5を導入しているのですが、Fcitx5とFcitx-mozcが正常にインストールされていて、Fcitxも入っていないのに入力できないことが度々ありました。

これの対処法は単純、Fcitx-mozcの設定画面で「Hanja-Hangul」と表示されているところを探し、全てを「Zenkaku-Hankaku」に変更するだけです。

Hanja-Hangulは韓国語のことのようですので、なんらかの設定ミスなのかも知れません。
Python の列挙型を JSON Serializable にする方法

Python の列挙型はそのままでは JSON Serialize することができない。

``` python
from enum import Enum

class NUMBERS(Enum):
    ONE = "one"
    TWO = "two"
    THREE = "three"
```

``` python
import json

json.dumps(NUMBERS.ONE)  #=> TypeError: Object of type NUMBERS is not JSON serializable
```

この場合、JSON Serializable な型のサブクラスにすると解決する。

``` python
from enum import Enum

class NUMBERS(str, Enum):
    ONE = "one"
    TWO = "two"
    THREE = "three"
```

``` python
import json

json.dumps(NUMBERS.ONE)  #=> "one"
```

この例では値が文字列なので `str` のサブクラスにした。
値が整数の場合は同様に `int` のサブクラスにしてもよいが、代わりに `IntEnum` を使うこともできる。

## 参考
- [enum --- 列挙型のサポート — Python ドキュメント](https://docs.python.org/ja/3/library/enum.html)
Windows server のリモート デスクトップ環境の猶予期間について

# 猶予期間とは

 RDS 環境においては環境を構築してから 120 日間※1はライセンス サーバーが不要な猶予期間が設けられています。
 
 この間は RD ライセンス サーバーが構築されていなかったり、 CAL のインストールが行われていない状況であっても RDS の運用に支障がきたさないようになっています。

その間は下記のような通知が表示されます。

![rdsh1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/471fdf40-c1e9-70c2-dfd9-914c6796bca6.png)


 RD ライセンス サーバーの設定を行ったにもかかわらず上記の通知が出ている場合には
適切に RD ライセンス サーバーが指定されていない可能性が非常に高い状況です。

そのような場合には下記[RD ライセンス サーバーを追加しCALをインストールする方法](https://qiita.com/valpasucucci43/items/735f23a7e24d2440fba1)の
(4) RD ライセンス サーバーの指定を参照してライセンス サーバーの指定を行っていただくと改善すると思います。

※1 今時使われてないと思いますが Windows 2000 では 90 日です。
一部Web情報では Windows Server 2019 や Windows Server 2016 では 180 日とされている情報もありますが私自身が確認した限りでは以前と変わらず 120 日です。

 Windows Server 2008 R2 までしか記載がありませんがMicrosoft公式情報は下記です。
[ Overview of Remote Desktop Licensing | Microsoft Docs](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc725933(v=ws.11)?redirectedfrom=MSDN)



# 猶予期間の終了のタイミング

猶予期間は下記のいずれかで終了します。

* 猶予期間（RDS 構築から 120 日）を超える
* クライアントに対して永続的なライセンスが発行される

2つ目がポイントです。
構築から 120 日経過していなくても RD ライセンス サーバーから接続元クライアントに対してCALが一度でも発行されるとその時点で猶予期間は終了します。

その為
[120 日間猶予期間が設けられている]
ではなく
[最長 120 日 RD ライセンス サーバが構築されていなくても RDS が使用できる]

と認識いただいたおいたほうがいいです。

少々古いですが下記が Microsoft の公開情報です。

[Overview of Remote Desktop Licensing](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc725933(v=ws.11)?redirectedfrom=MSDN)
※ The grace period ends after whichever of the following occurs first:
以下の記載が該当する説明です。

# 猶予期間の確認方法

前述の通知の日数を確認いただくほかに、下記の手順でコマンドレットで確認することが可能です。

1. RD セッション ホスト、または RD 仮想化ホスト サーバーへサインインします。<br>※ RD ライセンス サーバー上ではない点に注意してください。
2. Windows PowerShell を管理者として起動します。
2. 下記コマンドレットを実行します。

    ```
(gwmi -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).GetGracePeriodDays().DaysLeft
    ```

4. 実行結果で表示された数値をを確認します。
下記の画像の場合猶予期間の残り日数は 115 日です。
![RDSH1_001a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/479b915b-09e0-cb4e-e382-da46362df3ea.png)

なおこの値が下記のように [0] である場合、猶予期間は終了しています。
![rdsh2a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/2d3c16a1-664d-5dde-3a38-191087b51d8a.png)

# 猶予期間をリセットできるか？

公式情報を調べる限り正規の手順で猶予期間をリセットする方法はないです。
その為RDS環境を構築する際には計画をしっかりたてて猶予期間が終了する前に RD ライセンス サーバーを適切に構成するようにしましょう。
【スキルの棚卸し】未経験から受託企業に入り2年経ったので、学んだことを書いてみる

##前回の記事

https://qiita.com/m_masashi/items/b79666f12eaf67dc34a4

#はじめに　

2019年7月にキャリアをスタートさせました。
エンジニアとして2年でいろいろなことを学びました。

前回から半年たったので振り返りつつ学んだこと、反省点、次に改善することをまとめてみます。

いろいろなキャリアの積み方があるのでどれほど成長できてるのかは不明ですが、ほんの一例としてご参考ください。

#経歴

- 2018/10〜　某エンジニアスクールで学習開始
- 2019/01〜　卒業
- 2019/07〜　色々あって就職
- 2020/07〜　1年
- 2021/01〜　1年と半年
- 2021/07〜　2年



#半年で学んだこと(できるようになったこと)


##１）技術関連

### Ruby/Rails

社内研修でrailsを教えていました。基本的な知識の復習にはなりましたが実務レベルでつかうコードに触れる機会はありませんでした。

### ステージング/本番環境へのデプロイ

一切なし


### SQL

上記の社内研修でSQLを教える機会があり、SQLを教えていました。
恥ずかしいですが内部結合、外部結合などのSQLを初めて書きました。



###Java

- スレッドの書き方、デザインパターンについての知識が増えました
- paiza, codewarsで問題を解いてJavaコードの書き方について前回より詳しくなりました。

### Spring

社内事業でSpringでアプリを作り,Springの理解が深まりました。

具体的に学習したこと

- 動的なクエリの作成方法（JPA Specificcation, Criteria Builder）
- `@RestController`を使ってapiサーバーとして利用してAngular×Springbootでアプリを作成 


###動画作成

あるPJでpremier proを使って動画を作成しました。

社内での勉強会を動画にし、社内の一体感、知識を共有する雰囲気作りに貢献できたと思います。

##２）顧客対応,スケジュール管理
###タスク/スケジュール管理

WBSを書くことは慣れたのですが初めて触る言語、FWの場合は見積もりが甘くなることが多く、反省しています。
あと一度できた実装に関してはスピードが上がるので作業時間の見積もりの精度を上げていきたいです。


#反省(できなかったこと)

- チームマネジメント

#改善案

### 具体的に

自分は新しいことを学ぶのに時間がかかってしまうタイプ。普段から少しずつ勉強しておくことが必要

## 次の半年で学びたいこと

### インフラ関連

- AWSのSAAに合格します

- Ansibleサーバの構成ツールについての学習



### 検証


※アドバイス等あれば嬉しいです。


社内で書かれてるコードを読むのも勉強になるので、自社のPJのコードを積極的に読んで行きたいと思います。

### JavaScript

Codewarsで引き続き学習する


[開眼！ JavaScript――言語仕様から学ぶJavaScriptの本質](https://www.oreilly.co.jp/books/9784873116211/)

[改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X)
[JavaScript Primer](https://jsprimer.net/)
まずはこの辺りを参考にする予定です。

### IT基礎

slackチャンネルで1日1問形式で問題を解く

### チームリーダー

顧客対応が任せられるようになること
各メンバーのスキルを把握し適切なタスクを振り分けるスキルを身に付けたいです。

### 突破力

ググり力はそのまま、コードを読む力は前よりも上がったと思います。
頭の中でコードをつなげる力がまだまだ弱いです。（脳内メモリ少なさも原因かも）
多くコードを読んで鍛えて行くしかありません。日々精進。


[【スキルの棚卸し】未経験から受託企業に入り1.5年経ったので、学んだことを全部書いてみる](https://qiita.com/m_masashi/items/b79666f12eaf67dc34a4)
ローカル環境とリモート環境のDockerfileを共通化する

# 動機

リモート環境をAmazon ECSにし、ローカル環境もDockerで構築していましたが、このときDockerfileの運用に悩みました。ローカル環境とリモート環境では、コンテナ化したいものが違ったからです。

- ローカル環境
    - 主にランタイムをコンテナ化したい
    - 手元のIDEでコーディングしたいので、コードはミュータブルで良い
- リモート環境
    - アプリケーションも含めてコンテナ化したい
    - コードは書き換えられなくて良い

上記のような欲求のため、Dockerfileを分けていましたが、管理が複雑になってきたため一つにまとめたいと思いました。

# TL;DR

- マルチステージビルドでリモート環境とローカル環境を分ける
    - FROM句を複数書くやり方
    - 共通な部分とローカル環境・リモート環境で分けるものを別々で記載すると良い

# [マルチステージビルド](https://docs.docker.jp/develop/develop-images/multistage-build.html)を使う

## 概要

上記の課題を解決するため、Dockerの[マルチステージビルド]([https://docs.docker.jp/engine/userguide/eng-image/multistage-build.html](https://docs.docker.jp/engine/userguide/eng-image/multistage-build.html))を使いました。
マルチステージビルドは、1つのDockerfileにFROM句を複数記載するやり方です。
これを使って、PHPのDockerfileを記載してみます。

```dockerfile
# ローカル環境とリモート環境で共通なもの
FROM php:8.0-fpm AS base
RUN apt-get update && apt-get install -y zlib1g-dev git zip && \
    docker-php-ext-install opcache && \
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
    php composer-setup.php && \
    php -r "unlink('composer-setup.php');" && \
    mv composer.phar /usr/local/bin/composer

# ローカル環境用。xdebugとかもここ。
FROM base AS local
RUN pecl install xdebug && \
    docker-php-ext-enable xdebug

# リモート環境用。コードもコピーしちゃう。
FROM base AS remote
WORKDIR /var/www/html/
COPY . .
RUN composer install -n --prefer-dist
```

## 各FROM句の説明

### base

baseはローカル環境とリモート環境で変わらない処理を記載します。
MySQLやRedisのライブラリ、Composer等がここになります。

### local

localはローカル環境用でbaseの処理以外でローカル環境で必要なものを記載します。
Xdebugはローカル環境で使いたいだけなので、ここに記載します。

### remote

remoteはリモート環境用で、アプリケーションのコピーや依存関係の解決などを行います。
他にリモート環境で必要なものがあれば、ここに記載します。

## 周辺ツールとの連携

マルチステージビルドを使うことで、Dockerfileを1つにまとめることができましたが、周辺ツールでlocalとremoteを使い分ける必要があります。  
ここでは自分が利用しているDocker-ComposeとAWS Copilotの例を記載します。

### Docker-Compose

yamlファイルのbuildの欄にtargetを追加します。
ローカル環境で使いたいだけなので、ここではlocalを設定します。
これで、base + localのビルドを行ってくれます。

```yaml
services:
	app:
	    build:
	      context: .
	      dockerfile: Dockerfile
	      target: local
```

### AWS Copilot
AWS Copilotのmanifestも、同様にtargetを指定することができます。
ECSはリモート環境で、アプリケーションもコンテナ化したいので、remoteを指定します。
これで、base + remoteのビルドを行ってくれます。

https://aws.github.io/copilot-cli/ja/docs/manifest/lb-web-service/#image-build

```yaml
  build:
    dockerfile: Dockerfile
    context: .
    target: remote
```

# まとめ

マルチステージビルドを使うことで、ローカル環境とリモート環境のDockerfileを共通化することができ、悩みを解決することができました。

以上、最後まで読んでいただきありがとうございました。

# 参考資料

- [マルチステージビルド](https://docs.docker.jp/develop/develop-images/multistage-build.html)
エンジニアがデータサイエンティストになるための経済の勉強

５０代でデータサイエンティストを目指す無謀な男　ごとうです。

データサイエンティストにはビジネス力が必要だそうです。
技術者出身の私は職人肌でお金の話は少々苦手ですが、
データサイエンティストを目指すにせよ目指さないにせよ
令和時代のビジネスパーソンとしては知らないわけには行かないでしょう。

私はYouTubeを見ていくつか本を読んでみたり、日経新聞に真面目に目を通してみたりしています

ということでYouTubeからいくつか紹介します

## 日経テレ東大学【五輪後の日本経済】成長率1位は“茨城県“!?訪日外国人客による地方浮上策!? 冨山和彦、森永卓郎と日本の未来を予測！

https://www.youtube.com/watch?v=4bJz3lDqVgc

### ポイント
#### 五輪による経済への影響
 - 過去のオリンピックでは、開催決定後インバウンド（訪日外人客）が増えるトレンドであった
 - 東京は開催決定後２０１９までは伸びた。２０２０は激減
 - 日本の観光地は人手不足＝来客数が多い。が、増えたのは安いツアー。オペレータも海外の人。地元に金が落ちない
 - 顧客単価の高い外国人に来てもらわないと日本のGDPに貢献しない。量でなく質を挙げないと。
 - 一方でグローバル化そのものがコロナで行き詰った。経済もインバウンドに振り回されてきた。
 - 昔は9割がた日本人の顧客だった。そういう時代に戻すべき。インバウンド至上はやめたほうがいい。
 - いずれにせよ量より質。フランス人とか、教養のある外国人を大事にする。

#### 都道府県別の経済成長率
 - 東京は39位０．８％
 - １位は茨城県６．３％
 - グローバル経済はガンバってもGDPにならない、GDPにはローカル経済のほうが大事
 - 先進国は国内型経済になっている。日本もそう。欧米は基本的にローカル型経済。
 - 東京はめちゃめちゃ人口増えているので、一人あたりGDPは実は減っていると思われる
 - 往復3時間は生産性ゼロ、何も生んでない。
 - 農業県や観光県がGDP増えている。世帯所得1千万超えが増えている。ネットを使ってうまくブランディングしている
 - ローカル型経済は全体の7割。生産性が倍になったらすごい、所得にもろ反映される。
 - 東京一極集中はよくない。政治と経済と文化を１箇所に集中させているのは日本ぐらい。
   - 荒川決壊で東京23区の３分の1が浸水。首都直下地震も。東京が壊滅したときどうするのかを日本は考えてない。
   - 東京集中しなくてもいいのでは。ZOOMでよい。


#### 企業における債務の過剰感
 - １／３以上の中小企業が過剰債務と思っている
 - 過剰債務は問題抱えている企業。借金を減免したところで賃金を下げられない。人手が足りないので給料を払わないと労働力を維持できない。
 - 地方を中心とするビジネスを恒久的に続けていければよい

#### 主要国の最低賃金
 - 日本は最低レベル先進国内９０２円
 - 最低賃金は上げたほうがいい
 - 労働生産性が低い企業は生産性が高いところに移したほうがいい
 - 韓国のほうが高い　日本は先進国の中でぶっちぎりに低賃金。最低賃金を世界を足並みそろえないとだめ

#### 日本経済はオリンピックの後浮上するのか
 - 昭和のおじさんたちはだめだ、平成以降の若者たちが頑張れ、世代交代ができれば日本は伸びる
 - 一方で若者に権限が移ることはすぐにはない。まだそういう国なので、ずるずる落ちるのではないか
 - 近い将来発展途上国になる
 - 五輪は昭和の栄光の始まりと幕引き

#### まとめ
 - オリンピックは経済効果なのか
 - 東京は一極集中は幻想
 - 先進国で賃金が一番低い

### 感想

 - 雑学としての知識は増えたが余り響く内容ではなかったように思う

## 日経テレ東大学【ひろゆき×蛭子能収】なぜお金舞い込む？･･･妻に頭あがらぬ２人【マフィア論的分析】

https://www.youtube.com/watch?v=P8_KeWBhQKU

### ポイント
#### 人類にとってお金とは何か
 - ひろゆき氏と蛭子能収氏が対談する
 - ひろゆき氏と蛭子能収氏も楽な方に、嫌なものから逃げる戦略で生きている。楽な道を覚えてしまったので。
 - なぜ人はお金を大事にしているのか
  * 不安、めんどくさいことを避けたい
  * ご飯食べられなくなるのが怖い　お金がないことで不幸が来ることを避けたい
  * どれくらいあればいいか計算してないだけ。計算しておけばほどほどで生きていけるのでは？
  * 30万円毎月入る状態を作ればゴールではないのか
  * お金が無くなるのは豊かだった経験がふとした瞬間に失われてしまう恐怖
 - 成田氏：お金は世の中のバロメーター
  - 自分の心とお金は結びついてない。お金がなくて困ったら死ねばいい（笑）
 - ローンを返さなかったときにどうなるかわからないから怖い。
  - 実際は払えなくなったら自己破産して終わり。不安要素はない。
  - 存在しない不安を作って不安をあおることで商売する人たちがいる
 - お金は手段であって目的でない。勘違いしている人が多い。

### 感想

 - お金に執着のない人たち（お金に困らない人たち）の対談だったのでこちらも余り響かなかった
 - 家族のことを思うと、なかなか計算どおりには行かないよね〜と思った
NavigationBarにItemが表示されない時に解決した方法

# 今回の内容

* 以前、遭遇した表示ミスについての内容です。

* NavigationBarにItemが表示されない時に解決した方法

# Main.storyboard
こんな感じのアプリを作っている時の出来事です
<img width="400" alt="0828665D-F3A7-43BB-9865-EFCD53B90394_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/ab1459a2-d4f0-242f-15d2-15ca5d1b8e38.jpeg">


# 表示されなかった時の状況

* ViewControllerの `override func viewWillAppear(_ animated: Bool){}`内で下記のコードを書いていました。

```Swift:ViewController
   self.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(showSearchAlert)),
                                              UIBarButtonItem(title: "Today", style: .done, target: self, action: #selector(showTodayList))]

```

* ViewControllerの `override func viewWillAppear(_ animated: Bool){}`外で下記のコードを書いていました。

```Swift:ViewController
    @objc func showSearchAlert(){

       //押された時の処理

    }

    @objc func showTodayList(){

       //押された時の処理

    }
```

# 表示される様になった時の内容

* TabBarControllerを使っているので、`CocoaTouchClass`で`TabBarController`を作成します。

* Main.storyboardのTabBarControllerの`CustomClass`にCocoaTouchClassで作成したTabBarControllerクラスを設定します。

* 作成したTabBarControllerクラスの`override func viewWillAppear(_ animated: Bool){}`内にNavigationBarにItemを追加するコードを書き写します。

```Swift:ViewController
   import UIKit

class TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

       
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(showSearchAlert)),
                                                   UIBarButtonItem(title: "Today", style: .done, target: self, action: #selector(showTodayList))]
        
    }
    
    @objc func showSearchAlert(){

       //押された時の処理

    }

    @objc func showTodayList(){

       //押された時の処理

    }
   
}
```

#終わり
他にも表示されない原因はあると思いますので、対応力を磨き磨きたいですね。
そのためにも、たくさんコードを書きたい!!!
ご指摘、ご質問などありましたら、コメントまでお願い致します。
OpenBSD + xfce で日本語環境を整理(したかった)

#目次
[1. はじめに](#1-はじめに)
[2. xfce_GUIでシャットダウンできない？](#2-xfce_GUIでシャットダウンできない？)
[3. 追加のソフトウェアの設定](#3-追加のソフトウェアの設定)
[4. おわりに](#4-おわりに)

#1. はじめに
前回の記事で、OpenBSDの日本語デスクトップ環境を導入したわけなのですが、何かと普段使いするには物足りないので設定を追加していきます。

#2. xfce_GUIでシャットダウンできない？
デスクトップ画面の右上のところをクリックすると、シャットダウンなどのドロップダウンメニューが出てくる... のですが、なぜか

* ユーザーの切り替え (S)
* サスペンド (P)
* シャットダウン (D)

が暗くなっていてクリックできないんですよね...
![xfce_dropdown.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874028/293f39c7-26ce-8167-d97a-69e1ad1d8963.jpeg)

なんかヒントないかなぁ... と思って色々と調べていたら、こんなものを見つけました。

<TABLE ALIGN=CENTER>
  <TR>
    <TD WIDTH=400px>
      <A HREF="https://litt.hatenadiary.org/entry/20110521/p1?utm_source=pocket_mylist" TARGET="_blank"><p><strong>Xfce4.8で再起動とシャットダウンとかを有効にする</strong></a></p>
      <br>
      <p>
      4.6から4.8にバージョンアップしたら、ログアウトダイアログで再起動とシャットダウンのボタンが押せなくなってた。
      </p>
    </TD>
    <TD WIDTH=150px>
      <IMG STYLE="float:left;margin-right:.5em;" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874028/fcd1d053-04bd-d371-d895-47db40d1fcc8.png"/>
    </TD>
  </TR>
</TABLE>

###残念ながら...
ただ、この操作をしてもやはりこの動作はできませんでした...
何かご存知でしたらコメントお待ちしております。

私はとにかく面倒くさがりで、かつ使い勝手が悪いのは嫌いなので、これだけでもだいぶ心が折れそうです... 

特に日本語環境を完成させる以前の段階で詰まってしまうとかなり萎えるんですよね...

とは言ってもここは乗りかかった船、せっかくだから他の作業を進めてみましょう。


#3. 追加のソフトウェアの設定
以下のコマンドで必要なソフトウェアとパッケージをインストールします。

```bash
doas pkg_add firefox thunderbird libreoffice
```

###3-1. Firefox
firefoxはインストール当初はUIが英語なのでこれを日本語にします。
![スクリーンショット 2021-08-11 21.07.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874028/0e376bd2-34b1-9ce8-20c2-c69f5c36700e.png)
ここの右上にある横三本線みたいなやつをクリックして、
"preferences" (設定) に入って最初の画面をスクロールしていくと言語の設定が出るはずです。そこをクリックして "Search for more languages to add" みたいなことが書いてあるところをクリックすれば以下のようなポップアップが出てくるはずです。
![スクリーンショット 2021-08-11 21.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1874028/2cc2def1-3ac5-37d3-99fb-30e60f9bf415.png)
ここで「追加する言語を選択...」の場所をクリックすれば言語の一覧が出てくるので Japaneseを探して選択し、「add」(追加)というボタンを押して上の言語リストの最上段にJapaneseが来れば、OKを押して終了です。このあとFirefoxを再起動すればFirefoxの日本語化は終了です。

フォントが気に入らなければ同じ設定画面から変更できるのでお好みのものに変更してください。
私のおすすめはIPAフォントです。

###3-2. Thunderbird
こいつは設定がとっても簡単です。ほぼGUIに従えば良いだけですし、OSに依存して操作が変わる部分も特にないのでわからないことがあれば他OS向けの解説を読んでいただければ解決するはずです。

###3-3. LibreOffice
他のUnix系OSで一般的なように、pkg_add で LibreOffice 本体と言語パッケージを両方ダウンロードしようとしたのですが...

残念ながら日本語のパッケージはリポジトリにないようです。
pkg_info -Q で調べても、ar, bg, ca, de, es, fa, fi, fr, hu, it, kk, lt, lv, nl, pl, pt, ru, sl, sv は見つかったのですが肝心の ja がありません。

これはソースからビルドするしかないってことですかね...?
グハッ...

今回は挫折しましたが, また時間のある時にもう少し調べて挑戦しようと思います。
The Document Foundation のwikiに何やら関係ありそうなことが書かれていたのでリンクを貼っておきます。

<a href="https://wiki.documentfoundation.org/Development/BuildingOnLinux/ja">リンク</a>

#4. おわりに
今回こそ日本語環境を綺麗にしてやろうと思ったのですが、やはりBSD系は初心者からすると何かと情報が少なくて苦労しますね。特に最近の日本語での情報がほとんどないのが辛いですね...

ということで、OpenBSDに関しては問題を解決できる目処がたてばまたインストールするということにして、他のLinuxや*BSDを試してみようかと思います。
LANケーブルの色の順番

しばらくLANケーブルを作らないでおくと、色の順番を忘れてしまいますよね？
そんな時は、この記事を参考にしてください。
シンプルに写真だけでわかるようにしました。

# ストレートケーブル

![3D3E62B3-7C86-42B0-BEB0-986B9687E2C4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222607/0b4c4a71-6947-da6c-33e4-f3c6c71edd6f.jpeg)

# クロスケーブル
一方をストレートケーブルにします。
そして逆側を下記の写真の通りにするとクロスケーブルの出来上がりです。

![6A68B4AF-92F7-4909-8A4F-43B964A76647.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222607/8701cff7-c654-fcd1-06c4-ff4c01dc6003.jpeg)

**以上**
環境を揃える為にrubyのインストールで出たエラー(M1Mac)

課題で環境指定があるため
指定された環境構築を行なっていた中でrubyのverをインストールした時に
起きたエラー

>普段の環境：Mac M1  rails6.1.4 ruby3.0.1
>指定環境: rails5.2.5 ruby 2.6.3

```sh
Downloading openssl-1.1.1k.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
Installing openssl-1.1.1k...
Installed openssl-1.1.1k to /Users/uk./.rbenv/versions/2.6.3

Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 11.4 using ruby-build 20210526)

Inspect or clean up the working tree at /var/folders/wg/2z1wcj6x01z_q0lqb4jk_jkw0000gn/T/ruby-build.20210810115410.36976.30c1Jy
Results logged to /var/folders/wg/2z1wcj6x01z_q0lqb4jk_jkw0000gn/T/ruby-build.20210810115410.36976.log

Last 10 log lines:
compiling ellipsize.c
compiling normalize.c
compiling modify.c
linking shared-object -test-/tracepoint.bundle
compiling set_len.c
compiling enc_str_buf_cat.c
compiling new.c
linking shared-object -test-/string.bundle
linking shared-object date_core.bundle
make: *** [build-ext] Error 2
```

***make: *** [build-ext] Error 2***

同じ様にインストール出来ない人のため先人様の情報載せておきます。
[M1 の MacBook で rbenv + Ruby 2.6.6 をビルドする](https://secret-garden.hatenablog.com/entry/2021/01/02/220713)

これでrubyはインストール

```sh
RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC rbenv install (インストールしたいrubyのver)
```
そこからrubyのバージョン変更

[Rubyのバージョン確認方法と変更方法](https://yasagori-programing.hatenablog.jp/entry/2019/03/18/231528)

ver切り替えコマンド

```sh
% rbenv local (切り替えたいrubyのverを入れる)
```
Catalina以降のIllustratorやPhotoshopなどで、ファイル名だけを選択状態にするAppleScript

実行方法はいろいろあるのでお好きに。

Keyboard Maestroで実行する方が素直に動作します。
保存ダイアログ（シート、従来）のファイル名フィールドを選択後、SHIFTキーとカーソルキーを使って拡張子以外を選択させているので、AppleScriptのみで実行すると発火のためのキーにSHIFTが含まれている場合、モデファイキーをすぐ離さないと誤作動します。
Keyboard Maestroで実行すれば、押しているキーを無視してマクロ実行してくれるので、発火キーにSHIFT等含まれていても問題なし。

Keyboard Maestroのマクロは以下。

![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35477/7fcc9747-569a-72f6-3bae-d77a4ff74b76.png)

AppleScript部分のコードは以下。

```applescript
tell application "System Events"
	set a to name of first application process whose frontmost is true
	tell window 1 of process a
		try
			set b to text field 1
		on error
			try
				set b to text field 1 of sheet 1
			on error
				return false
			end try
		end try
		set focused of b to true
		set c to value of b
		set d to offset in (reverse of characters of c as text) of "."
		return d
	end tell
end tell
```
Save to Variableで戻り値を変数に格納し、以降のマクロで使っています。
※捨て変数としてVariableという名前のものを使っているのでややこしいけど…


AppleScriptのみで実行する場合は以下。

```applescript
tell application "System Events"
	set a to name of first application process whose frontmost is true
	tell window 1 of process a
		try
			set b to text field 1
		on error
			try
				set b to text field 1 of sheet 1
			on error
				return false
			end try
		end try
		set focused of b to true
		set c to value of b
		set d to offset in (reverse of characters of c as text) of "."
		key code 125
		repeat d times
			key code 123
		end repeat
		delay 0.1
		key code 126 using {shift down}
		return d
	end tell
end tell
```
Telloドローンからの受信画像をPCでWindow表示されないときは、key = cv2.waitKey(1) & 0xffを忘れていないか要確認



###ハマりどころ

この一行を削除すると、画像が受信できなくなる。

>```Python3:
> key = cv2.waitKey(1) & 0xff
>```

__msg = input("")__で、キーボード入力を受け取る場合も、上記の行は、残さないといけない。


###実行画面

```bash:Terminal
from djitellopy import Tello
import cv2, math, time

tello = Tello()
tello.connect()

tello.streamon()
frame_read = tello.get_frame_read()

#tello.takeoff()

while True:
    # In reality you want to display frames in a seperate thread. Otherwise
    #  they will freeze while the drone moves.
    img = frame_read.frame
    cv2.imshow("drone", img)
    
    #次の行（key = cv2.・・・）を削除すると、画像が受信できなくなる。
    key = cv2.waitKey(1) & 0xff
    msg = ""
    msg = input("Tello1号機に送る指示コマンドを入力してください。：  ")
    print("操作コマンド ：　{0} が入力されました。".format(msg))
    if msg == "i":
        tello.takeoff()
    elif msg == "w":
        tello.move_forward(30)
    elif msg == "s":
        tello.move_back(30)
    elif msg == "a":
        tello.move_left(30)
    elif msg == "d":
        tello.move_right(30)
    elif msg == "e":
        tello.rotate_clockwise(30)
    elif msg == "q":
        tello.rotate_counter_clockwise(30)
    elif msg == "r":
        tello.move_up(30)
    elif msg == "f":
        tello.move_down(30)
    elif msg == "g":
        tello.land()
    

tello.land()

```
【WSL】wslコマンドのバグ


Windows 10のコマンドプロンプトから、WSLの環境で処理を実行できるコマンドがあります。それは`wsl`というコマンドです。

Windows 10のコマンドプロンプトでWSL環境に依存するコマンドを実行できるってすごく便利だなと思っていたのですが、試してみるとバグのような挙動がありました。

## 事前準備

事前準備として、WSL環境で下記コマンドでHomebrewをインストールしました。

```
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

## 実行したコマンド全文

```
C:\Users\boiler>wsl brew
/bin/bash: brew: command not found

C:\Users\boiler>wsl
boiler@boiler-PC:/mnt/c/Users/boiler$ brew
Example usage:
  brew search TEXT|/REGEX/
  brew info [FORMULA|CASK...]
  brew install FORMULA|CASK...
  brew update
  brew upgrade [FORMULA|CASK...]
  brew uninstall FORMULA|CASK...
  brew list [FORMULA|CASK...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA|CASK

Contributing:
  brew create URL [--no-fetch]
  brew edit [FORMULA|CASK...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh
boiler@boiler-PC:/mnt/c/Users/boiler$
```

![2021-08-11 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/79cfc39e-a431-0ce0-cc5e-23bdee406ffc.png)

## 詳説

```
C:\Users\boiler>wsl brew
```

上記のコマンドを打てば、Homebrewのヘルプテキストが表示されるはず。と思って実行するのですが、

```
C:\Users\boiler>wsl brew
/bin/bash: brew: command not found
```

その結果は`command not found`になってしまいます。なぜでしょう。
ちなみに、下記のように一度`wsl`コマンドを単独で打ってから、`brew`すると想定通りにHomebrewのヘルプテキストが表示されます。

```
C:\Users\boiler>wsl
boiler@boiler-PC:/mnt/c/Users/boiler$ brew
Example usage:
  brew search TEXT|/REGEX/
  brew info [FORMULA|CASK...]
  brew install FORMULA|CASK...
  brew update
  brew upgrade [FORMULA|CASK...]
  brew uninstall FORMULA|CASK...
  brew list [FORMULA|CASK...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA|CASK

Contributing:
  brew create URL [--no-fetch]
  brew edit [FORMULA|CASK...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh
```

## 解決策

今のところ解決策はありません。

これ、絶対Windows 10のバグですよね。Microsoftさん早く何とかしてください！
React知識整理(関数コンポーネント)

## はじめに
フロントエンドの技術進歩は凄く、どんどん便利になっていきますよね。
プロジェクトでReactを使っていて当初はClassComponentで作っていましたが、
FunctionalComponentのほうがいいよねってなって変えました。
移植などの制約がない限り最新版を使うと思うので、FunctionalComponentやHooksについて整理したいと思います。

## コンポーネント化手法の違い
ちょっと大げさですが、上述の通り2種類あります。
クラスコンポーネントは従来からの手法です。サポートは継続するそうですが、2018頃から関数コンポーネントの登場と
2019年～のステートフックのサポートで主流になったのではないかと思います。
色々なライブラリやコンポーネントを組み合わせ作りますが、今ではほとんどHooksをサポートしていると思います。

## 何がうれしいか？
開発者としては意識せずどちらも使えますが、ここは押さえておきたい部分です。

* コード量削減、可読性向上、細分化できる

この辺はReactに限らず、クラスと関数で作った場合の違いだったりすると思いますし当然デメリットもあると思います。
細分化に関しては、ロジック部分を切り出したり（カスタムフック）等テクニックが使いやすくなったと思います。
昔はクライアントサイドにロジック実装なんて・・・でしたが今は違いますよね。
デバイス、ブラウザ、ディスプレイ差異はフレームワークやライブラリが吸収してくれるので依存コードになりにくい。

他にもメリットはあると思いますが、これだけで十分採用価値ありだと思います。
学習コストはかかりますが、再利用が進み生産性は上がります。その結果、開発スプリントでこなせるベロシティ向上に寄与できますよね。

[フックの導入](https://ja.reactjs.org/docs/hooks-intro.html#motivation)

## 何が大変か？
あまりReactに触れて歴史が浅いので正確ではないですが、苦労した点。

* ライフサイクルの理解
クラスコンポーネントの場合、[この図](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)の通りライフサイクルメソッドがコールバックされそこに記述すればOKでAPIからデータ取得であればcomponentDidMount()に実装するかと思います。

実装当初は関数コンポーネントで無限ループになるコードをよく書いて？？ってなってました。
「そのコンポーネントもしくはその上位のコンポーネントの state が更新される度に実行される」ため関数コンポーネントの内に、
何も考慮せずstate更新ロジックを書くと、連鎖反応が起き無限ループとなります。

この辺は、[副作用フックの利用法](https://ja.reactjs.org/docs/hooks-effect.html)にメカニズム解説があります。

### カスタムフック
[独自フックの作成](https://ja.reactjs.org/docs/hooks-custom.html)
この辺が一番のメリットで醍醐味ではないでしょうか？
独自フックとしてアプリの共通化が図れハンドリング等もできる。ライブラリコールを局所化できる等使いどころ満載です。
上述の通り色々なライブラリもフック対応を進めていて、クラスコンポーネントはレガシーになるので、
関数コンポーネント作成がモダンかもしれないです。

[react-router-dom HooksAPI](https://reactrouter.com/web/api/Hooks)
[axios-hooks](https://github.com/simoneb/axios-hooks)

axios-hooksは見てもらうとわかるのですが、外部アクセス（API）時にコールバックを返してくれて、
スピナやプログレス表示できるようになっています。これをさらにカスタムフックでラップすれば、APIコールを共通化できます。
そうすることで利用側は個々に例外ハンドリングやローディング制御、プログレス等の実装を考慮しなくていいですし、
モジュール化のメリット（バグが減るとか）を享受できます。
Windows 11でのVirtual Box起動時エラー

#Hyper-VのせいでVirtualBoxが起動できない

Windows InsiderプログラムでWidnows 11(バージョン10.0.22000 ビルド22000)にアップグレードした途端、VirtualBoxで仮想マシンを起動できなくなったため対処法をメモ。
エラーコード:E_FAIL (0x80004005) 

##「Linux用Windowsサブシステム」と「仮想マシンプラットフォーム」を無効化

「Windowsの機能の有効化または無効化」からチェックが入っていれば無効化する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35690/0a6d3ab0-0010-3845-b59f-4488f2bafbe1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35690/252b0ea4-3ae8-b188-ef8d-12914608bcce.png)

公式などに依ればHyper-Vを無効化すればよいとのことだったが、Windows 11からは機能名がHyper-Vとして記載されていないので少し迷った。
WSL2などが利用できなくなるが、共存できないため仕方がない。
C#で再帰メソッドの戻り値を IEnumerable<T>にしたい


再帰メソッドの戻り値を`IEnumerable<T>`型にしたい場合ってありますよね。

この記事はC#で再帰メソッドの戻り値を`IEnumerable<T>`型にする時にどう書くかを簡単に説明したものです。


## 普通の再帰メソッドを書いてみる

まずは、FizzBuzzプログラムの再帰版を書いてみましょう。まあ通常FizzBuzzで再帰メソッド定義することはないと思いますが、ちょうど良い再帰メソッドを思いつかなかったので許してください。

```cs
using System;

FizzBuzz(20);

void FizzBuzz(int n)
{
	_FizzBuzz(1, n);

	void _FizzBuzz(int i, int last)
	{
		if (i > last)
			return;
		string s = null;
		if (i % 3 == 0)
			s += "Fizz";
		if (i % 5 == 0)
			s += "Buzz";
		Console.WriteLine(s ?? i.ToString());
		_FizzBuzz(i + 1, last);
	}
}
```

ローカル関数_FizzBuzzが再帰メソッドです。

このプログラムを実行すると、

```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
(以下省略)
```

と表示されます。

## モデルとビューを分離したい

では、FizzBuzzを求めるロジックと、求めた文字列を出力するロジックを分離したい場合はどうでしょうか。

これを解決する方法のひとつが、イベントやdelegateを使う方法です。
文字列が求まるたびに、イベントを発行すれば、FizzBuzzメソッドの利用者が FizzBuzzメソッドに手を入れることなく、自由に独自の処理を書くことができます。

ただ、この方法にも欠点があります。
例えば、GUIのプログラムで、次へボタンを押すたびに、文字列をひとつずつ表示することを考えて見ましょう。こういった要求には、イベント発行する方法は上手く対応することができません。

## 再帰メソッドの戻り値を`IEnumerable<T>`にする

解決策のひとつが、FizzBuzzメソッドの戻り値を`IEnumerable<T>`にする方法です。

全ての結果を `List<string>`などに溜め込む方法でも、FizzBuzzメソッドの戻り値を`IEnumerable<T>`に出来ますが、 全てを列挙し終わらないと、FizzBuzzメソッドから制御を戻せませんので、与える数値が大きい場合は、最初のひとつを取り出すのにも多くの時間を要してしまい好ましくありません。

そのため、`yield return`使って反復子を定義すれば良いのですが、再帰メソッドの場合はちょっとした工夫が必要です。

以下にそのコードを示します。

```cs
using System;
using System.Collections.Generic;

foreach (var s in FizzBuzz(20))
{
	Console.WriteLine(s);
}

IEnumerable<string> FizzBuzz(int n)
{
	return _FizzBuzz(1, n);

	IEnumerable<string> _FizzBuzz(int i, int n)
	{
		if (i > n)
			yield break;
		string s = null;
		if (i % 3 == 0)
			s += "Fizz";
		if (i % 5 == 0)
			s += "Buzz";
		s = s ?? i.ToString();
		yield return s;
        var results = _FizzBuzz(i + 1, n);  // ★
		foreach (var item in results)
		{
			yield return item;
		}
	}
}
```


注目すべき点は、再帰メソッドを呼び出して返ってきた戻り値の扱いです（★印）。

`return results;` 

とは書けません。foreachで一つ一つ要素を取り出し、`yield return;` しています。こうすることで、再帰メソッドで、戻り値を`IEnumerable<T>`にすることができます。 

## おまけ

> GUIのプログラムで、次へボタンを押すたびに、文字列をひとつずつ表示することを考えて見ましょう。

もしかしたら、本当に戻り値を`IEnumerable<T>`にすることでこの要求に応えられるのか疑問に思っている方がいるかもしれないので、以下のコードも載せておきます。

GUIのコードではないですが、これを理解できればGUIのコードにするのも難しくないはずです。

enterキーを押すたびに、FizzBuzzメソッドから得られる文字列をひとつずつ出力しています。


```cs
var ite = FizzBuzz(20).GetEnumerator();
while (true) 
{
	Console.ReadLine();
	if (!ite.MoveNext())
		break;
	var s = ite.Current;
	Console.WriteLine(s);
}
```
ネクストエンジンAPIにGAS スプレッドシートから接続する

ネクストエンジンAPIを叩くシリーズ第3回です。
前回まではEXCEL-VBAを使っていましたが、最近はパソコンさえあれば、OSやMS OFFICEのインストール関係無しに
使用できるGoogleスプレッドシートが良さげかなと思い、今回作ってみました。

今回は商品マスタを登録更新するAPIを叩きます。
前回と同じく、スプレッドシート上に書かれた複数セルを選択し、ボタンを押すことで
それをそのままCSV化して、商品マスタにアップロードしたものと同じ結果を得ます。


まずはこんなスプレッドシートを用意。
B1とB2に有効なアクセストークンとリフレッシュトークンを入れておきます。
![スクリーンショット 2021-08-09 174605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346867/9672c9f0-26de-c7cf-0f98-fdb9091568a2.png)

Uploadは図形描画でなんでもいいので作成。
スクリプトを割り当て。
![スクリーンショット 2021-08-09 174759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346867/8019ccba-0680-3000-5d53-1ca957728e92.png)

スクリプトの中身です。
メイン処理(neUpload)

```javascript 
function neUpload() {
  let ss = SpreadsheetApp.getActiveSheet()
  //スプレッドシート選択範囲を2次元配列にセット
  let lis = ss.getActiveRange().getDisplayValues();
  //データをCSV型に変換する
  let temp = [];
  for(let i = 0; i < lis.length; i++) {
    temp.push(lis[i].join(','));
  }
  let dt = temp.join('\n');
  let endpoint = 'https://api.next-engine.org/api_v1_master_goods/upload' //エンドポイント
  //データとエンドポイントをAPI実行モジュールに投げる
  let jobj = execApiUpd(dt, endpoint);
  
  let rs = ss.getRange(3,2)
  //戻ってきたJSONオブジェクトからデータを取り出す
  rs.setValue(jobj['result'])
  var date = new Date();
  //実行日時をセット
  rs.offset(0, 1).setValue(Utilities.formatDate(date, 'JST', 'yyyy-MM-dd HH:mm:ss'))
  
  //resultが'success'のときだけアップロードキューIDとトークン関連を取得する
  if (jobj['result'] == 'success') {
    rs.offset(1, 0).setValue(jobj['que_id'])
    rs.offset(-2, 0).setValue(jobj['access_token'])
    rs.offset(-2, 1).setValue(jobj['access_token_end_date'])
    rs.offset(-1, 0).setValue(jobj['refresh_token'])
    rs.offset(-1, 1).setValue(jobj['refresh_token_end_date'])
  }
}
```

API実行モジュール(execApiUpd)
これを切り離したのは、エンドポイントが違う更新系APIでも叩けるようになりそうだなと思ったから。


```javascript
function execApiUpd(data, endpoint) {
  let spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  let ss = spreadsheet.getActiveSheet()
  
  ss.getRange(3,2).clear()
  //スプレッドシートからアクセストークン・リフレッシュトークンを取得
  let acto = ss.getRange(1, 2).getValue() //アクセストークン
  let reto = ss.getRange(2, 2).getValue() //リフレッシュトークン
  
  //HTTPリクエストオプション
  //payloadにパラメータをセットする
  let options = {
    'method' : 'post',
    'contentType': 'application/x-www-form-urlencoded',
    'payload' : 'access_token=' + acto + '&refresh_token=' + reto + '&data_type=csv&data=' + data
  }
  
  //HTTPリクエスト実行
  let response = UrlFetchApp.fetch(endpoint, options)
  //戻り値をJSONパースして呼び出し元に返す
  let jobj = JSON.parse(response.getContentText())
  return jobj;
}
```

有効なトークンが入っているとresultにsuccessが入ります。
ネクストエンジンの商品マスタアップロードにキューが入っています。
※CSVアップロードと同様データチェックはNE側で行われるので、正しくアップロードされたかどうかは
必ずNE側で確認してください。

次回は商品データ取得もやります。
WEBAPI応用できたら楽天市場APIとかも触りたいですね。
HD電源の修理

PC-9801VM2用に買ったICMという昔大阪にあった会社の40Mのハードディスクの電源を再利用してみようと思ったところ、うまくいきません。

負荷無しで電圧を測ったところ4.7Vと12.5Vくらいは出ます。

ところがHDDをつないで負荷をかけると3Vくらいしか出なくなります。

最初分解方法が分からず、いろいろ試しているうちにブラスチックがかけてしまいました。正解は中の四つのネジを外すと中の金属フレームがベッセルごと前に引き抜けます。反対側に電源が入っています。

電源はTDK製でコンデンサーが膨らんだりはしていなくて、見た目では分からなかったのであきらめかけたのですが、もう一度基板を見たところコンデンサーの下の方が黒くなっています。

![IMG_20210811_201340.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/2de9908e-4ccd-b2d5-2c0d-562d6802deeb.jpeg)

1000uF10Vと470uF25Vを他の基板から取った1000uF10Vと470uF50Vに交換してみました。元は105Cでしたが交換した部品は85Cです。

元は90年くらいの製造ですが、交換した部品は97年くらいのものです。

どうもこのコンデンサー（日本ケミコン製 SXF）は悪名高き「四級塩電解液使用電解コンデンサ」のようです。

http://www.nextftp.com/susumu_oiso/repair_tec.htm

このタイプのコンデンサーは上部は膨らまないけど、下に漏れることがあるようです。

やばいコンデンサーのようなので小さいほうの150uF35V(220uF35V)と470uF10V(470uF16V)も交換しました。やはり足のところに小さく漏れが確認できました。

ちゃんと使えるようになって気をよくして電源のLEDを点灯するようにしてみました。電源から5Vを取りLEDの基板につないで、基板のパターンをカットして制限抵抗入れました。三番目の帯が茶色の100Ω台の抵抗を探して400Ω位を部品取りをして入れたらちょうどいい感じになりました。

![IMG_20210812_104514.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/084db0d8-85ab-e3be-308e-ef5557b04fd7.jpeg)

上に載ってるのはSATAの250Gのディスクです。IDE変換してUSB変換してます。元々40Mだったので、6250倍です。

このハードディスクの全領域に/dev/zeroをddして正常に終了していたので、おそらく当面は問題なく使えそうです。

分解して気がついたのですが、青い電源のプッシュスイッチは自社製でした。こだわりがあったのかもしれません。
1分でサーバーを作る方法

#まえがき

8月某日、うちのTV録画用HDDを買い替えた。
当然交換するわけだから、今まで使っていたものが古いHDDとなる。
つまり使われなくなる。

それじゃいかん！せっかくだからPCに移植しよう！
でも2TBだから使いきれるかなぁ・・・
せや！スマホの写真を簡単にPCに移動できるように、サーバーを作ろうじゃないか！

さて、何もわからないので検索開始。
調べたら、全てが24時間稼働させる前提のものばかり。
でもわざわざ24時間つけるわけでもなし。電気代がバカにならなそうだからね。

色々調べまくって試行錯誤した結果、IPの設定もいらなくてめっちゃ簡単だったので、備忘録的に書いておくよ。

#環境
PC：デスクトップPC、Windows10
インターネット環境：WiFi、あのSoftbank Air。

#目的、条件
WiFiが届く範囲内でメインPCの一部フォルダをサーバーとして機能させる。
24時間稼働はいらない、アクセスしたいときだけPCをつけて対処する。

#手順
サーバーにしたいフォルダを右クリックして、プロパティをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1877698/791474b5-f46f-5f07-4f64-cdb18e4202fd.png)

共有タブをクリックして、共有をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1877698/3acf4bca-4e57-39ad-0598-54e545c95491.png)

共有するユーザーを選択して、（一人でも表示されていたらOK）
共有をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1877698/e5e8e938-7116-cc67-c2d4-89481fb5ba42.png)

共有が完了。サーバー名はPCの名前になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1877698/ef3dc667-e917-43ef-b864-773c5b1b277f.png)

あら簡単！
驚き！

入るときは、
パス：\\\\Desktop-kaja（PC名）
ユーザー名：共有するユーザを選択する画面で選択したユーザー名
パスワード：PCのロックパスワード
で入れるぞ！

ちなみにスマホから入るには、CX ファイルエクスプローラーがおすすめ。
それ以外は知らん。

https://play.google.com/store/apps/details?id=com.cxinventor.file.explorer&hl=ja&gl=US
【React】'Hoge' is defined but never used  no-unused-varsの対処法

<h2>症状</h2>
reactアプリをnpm startしたときに以下のような警告が表示されてしまいました。
特に動作に問題ないので放置していたところ、何百行分も出力されるようになってしまったため対処することにしました。

内容を翻訳すると、「「Hoge」は定義されていますが、使用されることはありません」となりました。
どうやら使われない変数だったり、importしたものがあったりすると、親切心からそれを教えてくれるようです。

```terminal:warn
Line 1:16:  'Hoge' is defined but never used  no-unused-vars
```

```react:Fuga.jsx
import React,{useState} from "react";
import Hoge from "../Hoge";

export const Fuga = () => {
  const [count,setCount] = useState(0)

  function addCount() {
    setCount(count + 1);
  }

  return (
    <div>
      <button onClick={() => addCount()}>
      {count}
    </div>
  )
}
```

<h2>解決方法</h2>
使われていないimportを消したら解決しました。

```react:Fuga.jsx
import React,{useState} from "react";

export const Fuga = () => {
  const [count,setCount] = useState(0)

  function addCount() {
    setCount(count + 1);
  }

  return (
    <div>
      <button onClick={() => addCount()}>
      {count}
    </div>
  )
}
```
【Rails】rails aborted! ActiveRecord::RecordNotFound: Couldn't find User with 'id'=0の対処法

<h2>症状</h2>
Railsでテストデータを作成しようとしたとき、下記エラーが発生してうまくデータが作成できませんでした。
どうやら、データベースにゼロ番目のデータが登録されていないにもかかわらず、ゼロ番目を参照しようとしているため、エラーが出ているようです。

```terminal:エラー
rails aborted!
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=0
```

以下がseedのソースになります。

```ruby:seed.rb
3.times do |n|
    user = User.new(
      first_name: "firstname#{n}",
      last_name,"lastname{n}",
    )
    user.save!
end

3.times do |n|
  user = User.find(n)   

  6.times do |m|
    home = user.homes.build(
          name:"name:"honename#{n}",
          address:"address#{n}",
        );
  end
end
```

<h2>解決方法</h2>
2つ目のループが0番目から繰り返していたために、findしたときにエラーが発生していたので、その個所を任意の値からループさせるようにすることで、解決しました。

```ruby:seed.rb
3.times do |n|
    user = User.new(
      first_name: "firstname#{n}",
      last_name,"lastname{n}",
    )
    user.save!
end

3.upto(7){|n|
  user = User.find(n)   

  6.times do |m|
    home = user.homes.build(
          name:"name:"honename#{n}",
          address:"address#{n}",
        );
  end
}
```

<h2>参考</h2>

https://www.javadrive.jp/ruby/for/index6.html
Forrester TEIの調査によると、Dataikuの利用がROIを3年間で423%に

[最新のAIプラットフォームを構築する](https://blog.dataiku.com/building-a-modern-ai-strategy-for-data-platforms)際に、組織はAIのライフサイクル全体にわたってツールを寄せ集め、時間やエネルギー、リソースを費やすべきではないと以前に述べましたが、これでは最終的にデータパイプライン全体の全体像を見失うことになるためです（技術的負債が増えるのは言うまでもありません）。その代わり、エンドツーエンドのAIプラットフォームに投資することで、再利用によるコストの削減、スムーズなガバナンスとモニタリング、インパクトの大きいテクノロジーの導入への集中といったメリットが得られます。
これは常にDataikuの哲学でもあります。Forrester社による調査、*The Total Economic Impact™ Of Dataiku (conducted by Forrester Consulting and commissioned by Dataiku)* にて、お客様が体験しているこれらのベネフィットが数値化され、示されています。


>[![Forrester-TEI-3D-cover.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/f9d93ba1-ced6-194f-7778-94ef37b79605.png)](https://pages.dataiku.com/forrester-tei-report)
><font color="Blue">「再利用可能なデータパイプラインとデータプロダクトを持つことで、開発の運用面での効率化を図ることができました。400万ドル以上のコスト削減が可能になりました」
—某製薬会社のAnalytics Innovationチームのリーダー</font>
><font color="Gray">*→調査レポートの無料ダウンロードはこちら：[The Total Economic Impact™ Of Dataik](https://pages.dataiku.com/forrester-tei-report)*</font>

<br>
[この調査](https://pages.dataiku.com/forrester-tei-report)で示されたベネフィットのハイライトをいくつかご紹介します。
- データエンジニアやデータサイエンティストの生産性が向上し、840万ドル以上の効果が得られた。これは、組織が確認した最大のメリットでした。複合型の組織の場合、データエンジニアとデータサイエンティストは、Dataikuを使うことで、それまでプロジェクトに費やしていた時間を75％短縮しました。
- アナリティクスツールやコンサルタントのコストを削減し、320万ドル以上の節約に成功。調査対象者の組織では、アナリティクスやデータサイエンスに使用するレガシーツールを削減することで、コスト削減を実現。
- 報告書作成の効率が向上し、その額は73万5000ドルを超えました。マニュアル作業で繰り返される作業を自動化することで、調査対象者の組織は業務の効率化を図ることができました。その中でも特に影響が大きかったのが報告書作成の分野です。複合型の組織の場合、Dataikuを使うことで、定期的な報告に関わるマニュアル作業の繰り返し作業の90%を削減することができました。


##DataikuでAIによるビジネス価値を最大化する
Dataikuはテクノロジーを提供していますが、当社のカスタマーチームは、組織があらゆる分野でAIの成熟度を高めることにも注力しています。これらの6つのドライバー（以下のインフォグラフィックを参照）は、AIの導入と成功戦略の基礎であり、長期的にAIから最大限のビジネス価値を得るためには不可欠なものだと考えています。
![The Business Value Guide Infographic for Blog (PNG).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/e979db98-5821-929f-36cd-7f6035d0b5f9.png)


##このレポート”The Total Economic Impact™“を読むには
企業へのインタビューと財務分析によると、複合企業では3年間で1,289万ドルの利益と247万ドルのコストが発生し、正味現在価値（NPV）は1,043万ドル、ROIは423％でした。主な調査結果やベネフィットなどについては、本レポートの全文はこちらよりダウンロードいただけます。
<font color="LightSeaGreen">ダウンロードはこちら</font>




原文：[*Forrester TEI Study Shows How Dataiku Can Drive 423% ROI Over 3 Years*](https://blog.dataiku.com/forrester-tei-study-shows-how-dataiku-can-drive-423-roi-over-3-years)
QiitaのContribution数が仕様変更でインフレ気味に？

記事を書こうとQiitaを覗くとContributionが2倍になってました。

あれ？仕様変更？

# Qiita夏の大型アップデート
![スクリーンショット 2021-08-11 20.19.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614389/33d2c7a9-108b-6ba2-5da2-3b956d809a2f.png)

新Contributionsがあるのは聞いてましたが、段階的にロールアウトされるようで、僕のアカウントでは先ほど有効になってました。いくつか重要と感じた変更点をピックアップします。

# 何が大きく変えたのか？
人にもよると思いますが、ストックされた数が影響して増えたのかな？と仮説を立てて、Qiitaの公式ブログを読んでみると、色々とContributionsの算出方法が変わってました。


https://blog.qiita.com/add-items-for-calculating-contribution/

##[変更]ストック数はLGTMの半分と同程度Contributionsに加算される
これはありがたいですね。これまでストックされても何も貰えなかったので、**「ストックするならLGTMをくれ！」**と心の中で叫んでましたが、これからはそんなことはなさそうですね！

さらに、驚きな仕様変更が！

##[変更]記事の投稿一回が1つのLGTM数と同じだけ寄与する
これは、ある意味ではかなり大きな影響をQiitaコミュニティに与えうると思います。

このせいで記事を量産するということが流行らないといいのですが。。。💦
例えば、一億ページとか記事をGPT-3[^1]みたいな文章自動生成AIの力を借りて量産した場合に、Contribution数がオーバーフローするとか（笑）、そんなことが起きないように、皆さんの善意が必要ですね！


# 学習の動機付けという観点からの報酬はありなのでは？
とはいえ、「記事を書く」、「コメントをする」などの能動的な行動にContributionが与えられるのは、学習の観点からはちょうどいい報酬になると思います。
皆さんも、今回の仕様変更を機に、スキナー箱[^2]に入れられた鳩のように、Contributionを求めてQiitaを盛り上げていきましょう！

ここには書いてませんが、他にも変更点があるので公式ブログを是非みてみてください！あなたは賛成ですか？それとも反対？

お読みいただきありがとうございました！


[^1]: 世界を震撼させている自然言語処理モデルです。 https://openai.com/blog/openai-api/

[^2]: ハトが装置の中で試行錯誤をするうちに、餌がもらえることに気づいて学習するというやつです。程度の差はあれど、人間も似たような感じですよね。強化学習の教科書でよく登場します。
メモ: どのWindowsファイアウォールのルールが接続をブロックしているのか調べる

基本的に[この記事](https://superuser.com/questions/1130078/how-to-tell-which-windows-firewall-rule-is-blocking-traffic)をそのままやるだけ。


# 1.監査ログの有効化

`auditpol /set /subcategory:"フィルタリング プラットフォーム パケットのドロップ" /success:enable /failure:enable`
`auditpol /set /subcategory:"フィルタリング プラットフォームの接続" /success:enable /failure:enable`

* カテゴリー名はロケールにそって設定しないといけない模様。~~マジ糞~~


# 2. 問題を再現する

ファイアウォールによってブロックされている(と思われる)処理を実行する

# 3. ファイアウォールのログをファイルに出力

`netsh wfp show state`

カレントディレクトリーに`wfpstate.xml`が作成される


# 4. イベントビューアーから、失敗イベントの特定

1. イベントビューアーを起動する
2. 左側のツリーから「Windowsログ」「セキュリティ」を選択
3. 原因と思しきログを探す
4. 「フィルターの実行時ID」をメモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231669/c9c56f3b-3aea-fcfe-5ba3-517a687e0776.png)


# 5. ルールの特定

1. 3で作成したファイルを開き、4で特定した「フィルターの実行時ID」で検索をかける
2. ファイアウォールが原因であれば`<item>`要素下の`<filterId>`にマッチするはず
3. 同`<item>`要素の`displayData.name`から、原因のルールがわかる

# 6. ログをオフにする

`auditpol /set /subcategory:"フィルタリング プラットフォーム パケットのドロップ" /success:disable /failure:disable`
`auditpol /set /subcategory:"フィルタリング プラットフォームの接続" /success:disable /failure:disable`


# Tips

* `auditpol /list /category` ` auditpol /list /subcategory:"オブジェクト アクセス"`で監査ポリシーのカテゴリーを調べられる
* `auditpol /backup /file:c:\auditpol.csv`で現状のポリシーを出力できる
EC2ログイン手順

##はじめに

EC2のログインの手順をすぐに忘れてしまうので、自分用に残しておきます。


##ターミナルからEC2ログイン
EC2インスタンスは既に作成されているものとします。

EC2インスタンスの作成の方法はこちらでまとめています。

https://qiita.com/minhee/items/98b7b1a3f016cc617bef


```terminal
cd .ssh/
```

```terminal
% ssh -i ダウンロードした鍵の名前.pem ec2-user@作成したEC2インスタンスに紐付けたElastic IP
```

.sshの中にキーペアがあることを確認しなければなりません。
computed で classを動的に指定


html

```index.html
<div id="app">
  <p :class="textStyle">test text</p>
</div>
```

css

```style.css
.textColor{
  color: blue;
}

.textFont {
  font-size: 30px;
  background: red;
}
```

```Vue.js
new Vue({
  el: "#app",
  data: function(){
      return {
          shouldApply: true
      }
  },
  computed: {
      textStyle: function() {
          return {
              textColor: this.shouldApply,
              textFont: this.shouldApply
          }
      }
  }
})
```

※computed は return と this がいるよ
node.jsのバージョン設定[Homebrew, nodebrew, node.js]

### node.jsのインストールからバージョン設定まで
1. Homebrewを用いたnodebrewをインストール
1. nodebrewを用いて、該当のnode.jsのバージョンをインストール
1. 該当のnode.jsを使用可能にする（パスを通す・バージョンを選択

```bash
- node.jsのパッケージ管理ツール"nodebrew"のインストール
$ brew install nodebrew
$ nodebrew setup
$ nodebrew -v
# nodebrew 1.1.0

- インストールできるnode.jsのバージョンを確認
$ nodebrew ls-remote

- 該当のバージョンのnode.jsをインストール
$ nodebrew install-binary v16.3.0

- 該当のバージョンがインストールされている確認
$ nodebrew list
# v16.3.0
#
# current: none

- 適用したいnode.jsのバージョンを指定
$ nodebrew use v16.3.0
# use v16.3.0

- 設定できたか確認
$ nodebrew list
# v16.3.0
#
# current: v16.3.0

- パスを通す（.zshrcファイルで管理している場合）
$ echo 'export PATH="$HOME/.nodebrew/current/bin:$PATH"' >> ~/.zshrc
$ source  ~/.zshrc

- 該当のバージョンのnode.jsを利用可能な状態になっていることを確認
$ node -v
# v16.3.0
```