OmniAICreator/Qiita-1.07M huggingface dataset:
aws boto3 で describe した結果から欲しい情報だけ取得・表示する

<code>素人が自分のノートとして書いてますが、改善点あれば是非コメントください</code>

###例1：DBインスタンスのインスタンスIDとエンジンバージョンを取得・表示する

- 条件
 - aws lambda
 - python 3.8 
 - boto3

```python:コード
import json
import boto3

def lambda_handler(event, context):

    #rds クライアントを定義
    rdsclient = boto3.client('rds')

    #describe_db_instances で取得した結果(json)をresponseにいったん投入
    response = rdsclient.describe_db_instances()

    #結果確認のために表示
    print("describe_db_instances=", response)

    #response は json形式の配列になっているので、最初の要素：DBinstances の値を抽出し response1 に投入
    #実際のDBインスタンスの情報が要素：DBinstancesの値(=response1)として入っている。
    response1 = response['DBInstances']

    #結果確認のために表示
    print("DBinstances from describe_db_instances=", response1)

    #response1 はDBインスタンス毎のリストになっているので要素数分for分で回す
    #このfor文で記載している”each_instance”は何でもよい。
    #response1 に含まれる要素数分回ると勝手に止まってくれる。
    for each_instance in response1:

        #各要素の['DBInstanceIdentifier']の値を抽出し、dbinstanceid に投入
        dbinstanceid = each_instance['DBInstanceIdentifier']
        #結果確認のために表示
        print("DBinstanceid=", dbinstanceid)

        #各要素の['EngineVersion']の値を抽出し、dbinstanceeversion に投入
        dbinstanceversion = each_instance['EngineVersion']

        #結果確認のために表示
        print("DBversion=", dbinstanceversion)
```

- とにかく print() で取得できている情報を都度確認しつつ、抽出する情報を絞り込んでいくのが重要。
【Laravel】ブレードで@yieldと@sectionを使ってCSSを出し分ける方法

Laravelのブレード（ビューファイル）で、@yieldと@sectionを使ってclass属性を指定することができる。

合わせて@parentも併用すると、ブレードによってCSSを出し分けることができる。

@yield, @section, @parentの基本的な使い方は[こちら](https://qiita.com/yuta-38/items/bea8406d99e699c29900)


##1. @yieldと@sectionのclass属性への適用
`@yield`はクラス属性やhrefなど属性の中でも使うことができる。

```php:base.blade.php
<div class="@yield('contentClass')">
  @yield('content')
</div>
```

class属性にcntentClass、divの中身にcontentというセクションを代入する。

```php:index.blade.php
@extends(base)
   
@section('contentClass', 'yellow')

@section('content')
 文字色をクラス属性で変更する
@stop
```

`class="yellow"`を適用する。

   ↓ コンパイル


```html:.html
<div class="yellow">
  文字色をクラス属性で変更する
</div>
```

例えばスタイルは16pxと黄色を適用。

```css:.css
.yellow{
  font-size: 16px;
  color: yellow;
}
```


<br>
##2. クラス属性の上書き
`@parent`を用いずに、同じセクション名を記載すれば上書きされる。

```php:base.blade.php
<div class="@yield('contentClass')">
  @yield('content')
</div>
```

class属性にcntentClass、divの中身にcontentというセクションを代入する。

```php:index.blade.php
@extends(base)
   
@section('contentClass', 'yellow')

@section('content')
 文字色をクラス属性で変更する
@stop

//上書き
@section('contentClass', 'blue')
```

contentClassのyellowがblueで上書きされるため、`class="blue"`となる。

   ↓ コンパイル


```html:.html
<div class="blue">
  文字色をクラス属性で変更する
</div>
```

以下のようなcssの場合、背景色 白が適用される。font-sizeや文字色の指定はない状態。

```css:.css
.yellow{
  font-size: 16px;
  color: yellow;
}

.blue{
  background: blue;
}
```


<br>
##3. クラス属性の追記
`@parent`を使うことでクラス属性を追記することができる。


```php:base.blade.php
<div class="@yield('contentClass')">
  @yield('content')
</div>
```

class属性にcntentClass、divの中身にcontentというセクションを代入する。

```php:index.blade.php
@extends(base)
   
@section('contentClass', 'yellow')

@section('content')
 文字色をクラス属性で変更する
@stop

//追記
@section('contentClass') @parent blue @stop
```

contentClassに元々の`yellow`と追記した`blue`が適用される。

   ↓ コンパイル


```html:.html
<div class="yellow blue">
  文字色をクラス属性で変更する
</div>
```

以下のようなcssの場合、文字色 黄色、フォント16px, 背景 青色が適用される。

```css:.css
.yellow{
  font-size: 16px;
  color: yellow;
}

.blue{
  color: blue;
}
```

<br>
以上。
BQ sql メモ

--文字列の最大長を取得
```select max(char_length(user_name)) as user_length
from `mh_project.ibushima_dataset.kihiko`
;
```
--パーティション確認
```select _PARTITIONTIME pt
from `mh_project.kinjisi_dataset.rolling_table`
where _PARTITIONTIME > '2021-01-01'
group by _PARTITIONTIME
order by _PARTITIONTIME
;
```

--一部カラムを除外してcreate
```create or replace table `mh_project.furufuru_dataset.puyopuyo_table` as
select *except (camp_send_date) from `mh_project.furufuru_dataset.puyopuyo_table__20210101`
;
```
Java PDFページを回転する

<p><strong>今回はSpire.PDF for Javaという無料のライブラリを利用して、PDFページを回転する方法を紹介していきます。簡単なので、もしお役に立てば嬉しく思います。さあ、行きましょう！</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/pdf-for-java.html">Free Spire.PDF for Java</a>無料版をダウンロードしてください。</strong><strong> </strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210331/20210331103946.png" alt="f:id:lendoris:20210331103946p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong>2.IDEを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire.PDF.jarを参照に追加してください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210331/20210331104004.png" alt="f:id:lendoris:20210331104004p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<h4><strong>回転前</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210407/20210407171223.png" alt="f:id:lendoris:20210407171223p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<h4><strong> </strong><strong>サンプルコード</strong></h4>
```JAVA
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.PdfPageRotateAngle;

import java.io.IOException;

public class RotatePDFPages {
    public static void main(String[] args) throws IOException {
        //PDFファイルをロードします。
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile("Input.pdf");

        //初めのページを取得します。
        PdfPageBase page = pdf.getPages().get(0);

        //ページ現在の回転角度を取得します。
        int rotateAngle = page.getRotation().getValue();

        // 右へ90度回転させます。（0/90/180/270度の範囲で選択可能）

        rotateAngle += PdfPageRotateAngle.Rotate_Angle_90.getValue();
        page.setRotation((PdfPageRotateAngle.fromValue(rotateAngle)));

        //保存します。
        pdf.saveToFile("Rotated.pdf");
    }
}
```
<h4><strong>回転後</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210407/20210407171341.png" alt="f:id:lendoris:20210407171341p:plain" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><br /><br /></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
PythonちゃんでDiscordに投稿されたゲーム系URLを別チャンネルにブチこむよ

あくまで備忘録なので、自分用メモ的に記載。

discord.pyちゃんはPythonのバージョンに注意が必要。
今回は3.6で作成。

`pyenv install 3.6.13`
`pyenv local 3.6.13`

これらをやった上で、`pip install python.py`実行。

CHANNEL_IDはDiscordにて確認。
※要開発者モードへの切り替え

TOKENは[Discordのディベロッパーページ](https://discord.com/developers/applications)のメニュー部分に
Botとあるのでそこをクリックすると表示されるページのCopyボタンをクリックすると取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29160/f36cf330-30a0-7cf9-8aa3-7a2710ce042c.png)


```python:main.py
import discord

client = discord.Client()

@client.event
async def on_ready():
    #一応確認用
    print("実行中")

@client.event
async def on_message(message):
    #ゲーム系のドメイン名
    l = ["steamcommunity","steampowered","4gamer","gamewith","gamespark","humble","automaton","fanatical"] 

    # Botなら粛清
    if message.author.bot:
        return 

    for item in l :
        #URLでゲーム系だったら別チャンネルに飛ばすよ
        if item in message.content and "http" in message.content  :
            channel = client.get_channel(CHANNEL_ID)
            await channel.send(str(message.content))

client.run(TOKEN)
```
あとは、同じくDiscordのディベロッパページのOAuth2を選択し、
ScopesのBotにチェックを入れると、URLが表示されます。
このURLを叩いて、設置したいDiscordのサーバを選択してあげるだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29160/45d34153-0bc7-04ce-6317-703cd2b78954.png)

Herokuちゃんとかで動きっぱなしにするといいですよ
【Javascript】配列、オブジェクトについて

## はじめに
Javascriptでいうオブジェクトと配列がPHPとは少し違っていたので紹介します。

## 配列
配列とは要素を[]で囲んだものです。
これは、PHPなどと同じです。

```js
['apple', 'banana', 'ichigo']
```



## オブジェクト
JavascriptでいうオブジェクトはPHPでいう連想配列のようなものです。
要素は{}でかこみ、keyとvalueをもちます。

```js
{
    'apple': 'red',
    'banana': 'yellow',
    'ichigo': 'red'
}
```

## おまけ

 - 配列の要素として、オブジェクトを使用できる

```js
[
    {
        'apple': 'red',
        'banana': 'yellow',
        'ichigo': 'red'
    },
    {
        'apple': 'red',
        'banana': 'yellow',
        'ichigo': 'red'
    },
]
```
 - PHPでいう添字配列のような形は、Javascriptだとオブジェクトとして扱われる

```js
// これはオブジェクト
{
    0: 'apple',
    1: 'banana',
    2: 'ichigo'
}

// これは配列
['apple', 'banana', 'ichigo']
```

## 最後に
PHPとJavascriptのように、扱う言語の違いによって、値の扱われ方などが異なる場合があります。
特に、Javascriptでは配列とオブジェクトで使える関数が違ってきたりもします。
値の受け渡し方、定義の仕方を気をつけるようにしましょう。
関数

# 関数
関数とは、ある処理をまとめたプログラムの塊で、printも関数の1つです。
本来、コンソールに文字を出力するには色々なコードを書く必要がありますが、printという関数のおかげでprintと書くだけで良いようになっています。
関数は自分で作ることができます。関数は`def 関数名():`と記述することで定義できます。
関数は定義しただけでは実行されないので、呼び出す必要があります。
呼び出し方は`関数名()`と記述することで呼び出せます。
※ただし、関数は定義した後でしか呼び出せないので注意が必要です。

```py:例
def hello():
    print('Hello')

hello()
```

```text:出力結果
Hello
```
と記述することで、まず`def hello():`と関数を定義し、関数の処理の内容はインデントをして書いています。
その後、`hello()`で関数を呼び出すことで、関数が実行されます。

# 引数
関数を呼び出す際に、関数に値を渡すことができます。この値のことを**`引数`**と呼びます。
引数を渡すと関数の中でその値を利用することができます。
関数に引数を渡せることで、その値によって関数の処理の結果を変えることができます。
関数に引数を渡すには、引数を受け取れる関数を定義しなければなりません。
その為に、関数の定義部分で、引数を受け取る変数**`仮引数`**を指定します。
次に関数に引数を渡すには、`関数名(引数)`として関数を呼び出します。渡された引数は、関数の仮引数に代入され、その値を関数の処理の中で用いることができます。

```py:例
def 関数名(仮引数):
    実行する処理

関数名(引数)
     ⬇
def hello(name):
    print('Hello ' + name)

hello('Abe')
```

```text:出力結果
Hello Abe
```
と記述することで引数を渡し、その値を関数の処理の中で用いることができます。
仮に引数を変更した場合、「`hello('Sato')`」であれば出力結果は「`Hello Sato`」となります。
このように関数に引数を渡せることで、その値によって関数の処理の結果を変えることができます。
***
### 複数の引数を持つ関数
引数は複数渡すことができます。複数の引数を受け取るためには仮引数を「,(コンマ)」で区切って定義します。
引数は左から順に「第1引数, 第2引数...」と呼びます。

```py:例
def hello(name, message):
    print(name + 'さん、' + message) # print(f"{name}さん、{message}")と記述しても同様に表示されます

hello('Abe', 'おはよう')
```
```text:出力結果
Abeさん、おはよう
```
と記述することで、複数の引数を渡すことができます。
しかし、引数をの順番は、対応する仮引数の順番と同じにする必要があります。
***
### 引数の初期値
引数には初期値を設定できます。
引数が省略された時、初期値が与えられていれば代わりの値として初期値が使われます。

```py:例
def hello(name, message = 'こんばんは'):
    print(name + 'さん、' + message)

hello('Abe', 'おはよう')
hello('Abe')
```

```text:出力結果
Abeさん、おはよう
Abeさん、こんばんは
```
上記のように、仮引数`message`に初期値`message = 'こんばんは'`と設定することで、第２引数が省略されていても初期値が使われます。
## スコープ
変数には、その変数が使える範囲が存在します。その範囲のことを**`スコープ`**と呼びます。
仮引数や関数の中で定義した変数のスコープは関数の中だけとなります。
よって、その変数を関数の外で使うことはできません。

```py:例
def hello(name):
    print(name) # 変数nameのスコープ(変数nameはこの関数内のみ使える)

hello('Abe')
print(name) # 変数nameのスコープの外(変数nameは関数の外なので使えません。よってエラーが出ます)
```
```text:出力結果
Abe
︙
NameError: name 'name' is not defined
```
上記のように、関数内では変数nameは使用できました。
しかし関数の外でも変数nameを使用しようとしましたが、変数nameのスコープの外であったため、使用できませんでした。エラー文を見ても分かるように、スコープの外で使用しようとしたnameは定義されていませんというエラー文が表示されました。
【unix】よく使うコマンドまとめ【チートシート】

#目次

* 目次
* 改版履歴
* よく使うコマンドたち(本編)
* おわりに

#はじめに
　本記事は筆者の備忘録的な記事です。記載している内容には誤っている点等が含まれる場合があるので注意してください。


#改版履歴

|更新日  |更新内容  |
|---|---|
|2021年04月07日  |初版  |
|・・・  |・・・  |

#よく使うコマンドたち



---
###【ls】　-ディレクトリ内のファイル一覧/詳細情報を表示する
####書式
_ls [オプション] [ファイルまたはディレクトリ]_
_ex) ls -la hogeDir_
####オプション
以下の通り

|オプション|機能|
|---|---|
|-a|隠しファイルを含むすべてのファイルを表示する|
|-d|指定したディレクトリ自身の情報を表示する|
|-l|ファイルの詳細を表示する|
|-o|ファイルタイプに応じて色分けする|
|-r|エントリ名で降順に並び替えて表示する|
|-t|最新更新日時を最新のものから順に表示する|
|-u|「-l」と同時指定で、最終更新日時ではなく最終アクセス日時を表示する|
|-A|「-a」とほぼ同じだが、カレントディレクトリと親ディレクトリは非表示|
|-F|ディレクトリには/、実行ファイルには*、シンボリックリンクには@を付けて出力する|
|-R|サブディレクトリも含めて表示する|
|-X|拡張子でソートして表示する|

####実行結果の見方

```:実行結果
root@testSrv:~# ls -la
total 33
drwx------   3 root     root           7  4月  6日  16:29 .
drwxr-xr-x  25 root     sys           28  4月  6日  19:15 ..
-rw-------   1 root     root        8090  4月  7日  14:53 .bash_history
-rw-r--r--   1 root     root         159 10月  7日 2015年 .bashrc
-rw-r--r--   1 root     root         568 10月  7日 2015年 .profile
-rw-------   1 root     root         223  4月  6日  16:29 .spellhist
```
左から順に、

* ファイルの種類と許可属性
* ハードリンク数
* 所有者とグループ
* ファイルサイズ
* タイムスタンプ
* ファイル名

が表示される。

---
###【chmod】-ファイルやディレクトリの権限を変更する
####書式
_chmod [オプション] [権限値] [ファイル名]_
_ex) chmod -R 755 hogehoge.txt_
####オプション

|オプション|機能|
|---|---|
|-c|実際にアクセス権が変更された場合のみ、処理結果を詳細に出力する|
|-v|全てのファイルに対して処理結果を詳細に出力する|
|-f|ほとんどのエラーメッセージの出力を抑える|
|-R|ディレクトリを変更する際に、中のファイルやサブディレクトリも再帰的に変更する|
|--version|バージョン情報を出力する|
|--help|使用方法を表示する|

####権限書式
|文字|数値|内容|
|---|---|---|
|r|4|読みだし可|
|w|2|書き込み可|
|x|1|実行可能|
|rwx|7 (4+2+1)|読み出し可＋書き込み可＋実行可能|
|rw-|6 (4+2)|読み出し可＋書き込み可|
|r-x|5 (4+1)|読み出し可＋実行可能|
|-wx|3 (2+1)|書き込み可＋実行可能|


---
###【chown】-ファイルやディレクトリの所有者を変更する
####書式
_chmod [オプション] [ユーザ / :グループ / ユーザ:グループ] [ファイル名]_
_ex) chown hogeUser fuga.exe_
####オプション

|オプション|機能|
|---|---|
|-f|権限がなくて変更ができない場合に、エラーを出力しない|
|-h|シンボリックリンク自身の所有者を変更する|
|-R|ディレクトリを変更する際に、中のファイルやサブディレクトリも変更する|

※変更は__ファイルの所有者__か__スーパーユーザ__のみ可能。



---
###【useradd】-ユーザを追加する
####書式
_useradd [オプション] ユーザ名_
_ex) useraddd -g hogeGroup -k /etc/skel -m /fugaDir -d /fugaDir -s /usr/bin/csh_
####オプション

|オプション|機能|
|---|---|
|-g|ユーザが所属するグループを指定します。|
|-G|複数のグループに所属する場合に指定します。|
|-k|スケルトンディレクトリを指定する場合に指定します。|
|-c|コメントを設定する場合に指定します。|
|-d|ユーザのホームディレクトリを指定します。|
|-m|ユーザのホームディレクトリを作成します。|
|-e|ログイン可能な期限の日付を指定します。|
|-f|ユーザのパスワードの有効期限が過ぎてからも、ログインを許可する日数を指定します。|
|-D|デフォルトのパラメータを表示します。|
|-o|既にシステムに登録されているUIDを利用することを許可します。|
|-u|ユーザのユーザIDを指定します。|
|-s|ユーザのログインシェルを指定します。|
|-R|カンマで区切られた1つ以上の役割を指定します。|



#おわりに
　サーバこわい
社会人エンジニアになるときに覚えておくと良い9つのこと

社会人エンジニアになってもう13年。
学生から社会人エンジニアになると、同じソフトウェアに関することでも心掛けるべきことがかなり違ってきます。

4月なので、新社会人になるエンジニアの方々のために、少しでもスムーズに入っていけるように、私が社会人エンジニアとして今まで沢山の壁にぶつかって気づいたことを綴っていきたいと思います。

これから新しい一歩を踏み出す社会人エンジニアの参考になれば幸いです。

# 1.最も大切になるのは、人のコードを読む力
学生時代だと、一から組むということが多いかと思いますが、社会人になると、ほとんどのケースで先人が組んだコードを変更していくことになります。
会社に入ると、おそらく最初は構造把握に時間を割くことになります。そしてこの作業は、プロジェクトが変わるたびに訪れます。
このスキルは、社会人エンジニアとして最も重要なものと言っても過言ではありません。

# 2.ハードウェアリソースは有限
私は組み込み系エンジニアなので顕著ですが、学生時代はPCのアプリケーション関係を中心に学んでいたためか、このリソース管理の意識がすっぽりと抜け落ちていました。
具体的にいうと、少しでもコードが少なくROMを節約する方法を考えるとか、無駄に変数を作りすぎてStackを圧迫しないなど。
組み込み系になると、このROM/RAMの消費量はハードウェアのコストにかかってくるので、かなり重要なポイントになってきます。

# 3.後の人のことを考える
チームで開発することになると、独りよがりのコードになってしまってはいけません。
自分もいつまでも同じプロジェクトに居るとは限りませんし、新しいメンバーを迎えることもあるでしょう。チームは必ず入れ替わりが発生するものです。
そのようなことを想定し、コードを組む際には他人が理解しやすいよう、また変更ができるだけ容易になるような構造を考慮しましょう。

# 4.焦った時ほど慎重に
焦って直した時ほどミスが入り込みやすいです。社会人になると開発の日程は順守しなければなりません。
締め切り直前や、緊急対応で変更を入れる際には、普段なら気づくようなミスをうっかり見逃してしまいやすくなります。
自信があっても、ダブルチェックをお願いするぐらいの慎重さを持っておくと安心です。

# 5.良いコードに直すだけが正解ではない
先人のコードを見ていると、もっと良い方法があると気づき、直したくなることがあります。
もし容易に修正できるとしても、ここは慎重になるべきです。なぜなら、そう組まざるを得なかった理由があるかもしれないからです。
今動いているコードは、少なくともリリースされて世に出ているという実績があります。
先ほどの「後の人のことを考える」と少し逆行する面もありますが、良いコードにすることが必ずしも正解とはならないことを覚えておくべきです。
昔のコードほど保証するのもそれなりに工数がかかってきます。その手間は新しい機能の開発に向けた方が賢明です。

# 6.テストの手間を考える
お金を生み出すコードは品質保証が必須です。そのため、ソフトを組んだらテストをパスしないと世に出すことができません。
変更が1行で済んでも、テストに1週間かかるという修正を行ってしまうと、後工程に影響を与えます。
そういった変更はインパクトが大きいので、後工程の担当者と調整が必要になってきます。
自分の手間だけではなく、全体の工数が少ない方法を選択すべき場面があることを念頭に置いてください。

# 7.チームの技術力は一定ではない
会社ではいろいろなバックグラウンドを持った方が集まってチームとなります。
そのため、技術力にはバラつきがあります。
もし、あなたのコードが業界のスタンダードや、ベストプラクティスには沿っていても、高度すぎて他のメンバーが理解できないものであったとしたら。
残念ながら、皆が勉強してついてくるタイプの人間ばかりとは限りません。
そうなると、当然のごとく作った人に質問が飛んでくることになります。メンバーが多ければ多いほど、説明に費やす時間が自分の時間を圧迫します。
また、新しいメンバーが次々入れ替わるプロジェクトになると、より多大な工数を取られてしまうことになります。
そうならないためには、あらかじめ説明のためのドキュメントを用意しておくか、レベルを下げて万人が容易に理解できるコードにとどめておくと良いでしょう。
大抵の場合、エンジニアの給与はいかにハイレベルなコードを組んだかには比例しません。

# 8.学び続ける姿勢を持つ
入社したらまず、仕事で使う言語を学ぶことになるでしょう。
ですが、それを知ったら終わりではなく、常に新しい学びを求めて勉強し続ける姿勢を持つと良いです。
そのような姿勢を持っていると、同じ空気を感じる同僚や上司が自然と集まってきて、一緒に勉強会を開いたり、面白い技術を導入しようと意気込んだり、とても面白いメンバーに恵まれることもあります。
うまくいけば、思わぬプロジェクトに抜擢されることになるかもしれません。
その積み重ねが、自分の将来のキャリアに必ずプラスに働いてきます。

# 9.お手本となるエンジニアの先輩を探す
社内でお手本となるエンジニアとはお近づきになっておきましょう。
その人はその会社の歴史や背景、暗黙の了解などのお作法も含めて知っているので、
自分がこれから組むコードがどうあるべきなのか、その正しい方向性を教えてくれるはずです。
本当にソフトウェアが好きな人なら、ソフトウェアについて勉強したいと思っている人には喜んで接してくれると思います。
自分の好きなことを質問されるほど嬉しいことは無いからです。

# さいごに
これからどんなエンジニアになるのか、期待に胸躍らせていることかと思います。
早く会社に馴染んで、エンジニアとしての素晴らしいキャリアを築いていけるよう、応援しております！
Node.js管理ツールの更新頻度とスター数を比較してみた

# 概要
Node.jsのバージョン管理ツールについて調べたところ、nvm、nodebrewなど色々存在しており、
なにを使えば正解なのかわからなかったので、Gitリポジトリの最終コミット日付とコミット数とスター数で比較してみました。
※2021/10/05更新
# 結論
更新頻度やコミット数、リファレンスの多さを基準としたオススメ順です。

## 1.nvm
最もスター数が多く、今なお開発が続いていることから、**nvm** が一番のオススメです。
スター数も47.6kと、他のNode.js管理ツールと比較してダントツで獲得数が多いです。

## 2.n
スター数は、nvm に及ばないものの、こちらも現在開発が続いております。
nvm はみんな使ってるから、別のツールを使ってみたいという方は、**n**をおすすめします。

**n** に関しては、参考記事が見つからなかったので実際にインストールして試してみました。
[n (Node.js管理) のインストール手順](https://qiita.com/tora_oba/items/2761452fe8c2b0035ba0)

## 3.volta
Rust製の比較的新しい Node.js 管理ツールです。
M1MacOSに対応しており、高速にバージョンの切り替えが可能です。

# Node.js管理ツールまとめ
※以下に列挙した以外にもあるかもしれません。
※最終コミットの最新順でソートしています。

| Node.js管理 | コミット数 | 最終コミット | スター数 |
|:-----------|------------:|------------:|:------------:|
| volta     | 2136      | 2021年10月4日       |4.2k|
| nvm       | 2024        | 2021年9月29日        |51.8k|
| n     | 730      | 2021年9月26日       |15.1k|
| nodenv       | 943        | 2020年7月22日         |1.5k|
| nave         | 228          | 2020年5月30日           |1.5K|
| nodebrew       | 219       | 2019年1月7日       |961|
| nodist    | 441     | 2019年3月30日      |1.3k|
| ndenv    | 13     | 2018年12月27日      |313|

## volta
コミット数:2136
最終コミット:2021年10月4日
スター数：4.2k

https://github.com/volta-cli/volta

## nvm
コミット数:1980
最終コミット:2021年3月30日
スター数：48k

https://github.com/nvm-sh/nvm

## n
コミット数：730
最終コミット:2021年9月26日
スター数：15.1k

https://github.com/tj/n

## nodenv
コミット数:943
最終コミット:2020年7月22日
スター数：1.5k

https://github.com/nodenv/nodenv

## nave
コミット数：228
最終コミット:2020年5月30日
スター数：1.5k

https://github.com/isaacs/nave 

## nodebrew
コミット数：219
最終コミット:2019年1月7日
スター数：961

https://github.com/hokaccha/nodebrew

## nodist
コミット数：411
最終コミット:2019年3月30日
スター数：1.3k

https://github.com/nullivex/nodist

## ndenv
コミット数:13
最終コミット:2018年12月27日
スター数：313

https://github.com/riywo/ndenv
VMware PowerCLI & GitHub を利用したLabスクリプトの保存について

vSphereを使ったLab環境の構築について、<font color="red">**VMware PowerCLIにてスクリプト化し、GitHubにあげる手順**</font> を記載します。

# VMware PowerCLIのインストール
前提）Windows PowerShell 5.1以降の環境でないと、VMware PowerCLIのオンラインインストールが失敗する為、<font color="deepskyblue">必要に応じてPowerShellをUpgrade</font>する　[※参考手順](http://woshub.com/install-update-powershell-windows/)

* PowerCLIのインストール
：[こちらの手順](https://mt9276.hatenablog.com/entry/2019/05/13/063128)を参照してインストール

```
Install-Module -Name VMware.PowerCLI
```
※下記エラーが表示された場合は、[こちら](https://cloudsteady.jp/post/30310/)を実行　（<font color="gray">インストールスクリプトのTLS1.2対応の必要性</font>）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/52a78f5c-50e5-6119-77fc-6536973bf563.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/a9f95502-b1a9-a53d-f9d1-9a5063ec00e1.png)
#PowerCLIの動作確認
* セキュリティポリシーの確認＆変更 (Unrestricted 又はRemoteSignedであることを確認　[参照](https://www.atmarkit.co.jp/ait/articles/0805/16/news139.html))

```
PS C:\Users\Administrator> Get-ExecutionPolicy
Unrestricted
```
```
PS C:\Users\Administrator> Get-PowerCLIVersion
PowerCLI Version
----------------
   VMware PowerCLI 12.2.0 build 17538434
---------------
```
#PowerCLIスクリプトの作成＆GitHubリポジトリに保存
* 簡易なPowerCLIサンプルスクリプトを作成（Nest ESXi 6.7ホスト3台のデプロイ）
　　<font color="gray">ESXiのインストールは仮想アプライアンスを使用</font>　[※参照](https://www.virtuallyghetto.com/nested-virtualization/nested-esxi-virtual-appliance)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/eb4c7330-718b-225e-c4d6-10fb0ebc2674.png)

* [こちら](https://www.modis.jp/staffing/insight/column_30/)を参照して、GitHubにアカウントおよびリポジトリを作成

* 作成したリポジトリに、PowerCLIスクリプトをアップロードする  　
[※参照：Git for Windowsの使用](https://prog-8.com/docs/git-env-win)

```
$ git push origin master
warning: ----------------- SECURITY WARNING ----------------
warning: | TLS certificate verification has been disabled! |
warning: ---------------------------------------------------
warning: HTTPS connections may not be secure. See https://aka.ms/gcmcore-tlsverify for more information.

```
* スクリプトのUpload先のリポジトリはこちら：

https://github.com/m-eno/nested-esxi6.7-3host-cluster-deployment/tree/master



# 参考リンク
https://thinkit.co.jp/story/2011/02/24/2008
Laravel 5.8以降でどうやって一時にenv()の値を変更？

#Laravel 5.7以前でenv()の値の変更方法

👉 `env('AAA') = getenv('AAA')`
→　だから、`putenv('AAA', 'true');` にすると、 `env('AAA') = true` になる

###Laravelのフレームワークのソースを参考：

```src/Illuminate/Support/helpers.php
    if (! function_exists('env')) {
        /**
         * Gets the value of an environment variable.
         *
         * @param  string  $key
         * @param  mixed   $default
         * @return mixed
         */
        function env($key, $default = null)
        {
            $value = getenv($key);
    
            if ($value === false) {
                return value($default);
            }
    
            switch (strtolower($value)) {
                case 'true':
                case '(true)':
                    return true;
                case 'false':
                case '(false)':
                    return false;
                case 'empty':
                case '(empty)':
                    return '';
                case 'null':
                case '(null)':
                    return;
            }
    
            if (($valueLength = strlen($value)) > 1 && $value[0] === '"' && $value[$valueLength - 1] === '"') {
                return substr($value, 1, -1);
            }
    
            return $value;
        }
    }
```

#Laravel 5.8以降でenv()の動作は変更された！

👉 `env('AAA') != getenv('AAA')`
→　だから、`putenv('AAA', 'true');` にしても**env('AAA') の値は変わらない**！！！

このようになる：
`env('AAA') = Env::getRepository()->get('AAA');`

###Laravelのフレームワークのソースを参考：

```src/Illuminate/Support/helpers.php
    if (! function_exists('env')) {
        /**
         * Gets the value of an environment variable.
         *
         * @param  string  $key
         * @param  mixed  $default
         * @return mixed
         */
        function env($key, $default = null)
        {
            return Env::get($key, $default);
        }
    }
```

```src/Illuminate/Support/Env.php

    public static function get($key, $default = null)
    {
        return Option::fromValue(static::getRepository()->get($key))
            ->map(function ($value) {
                switch (strtolower($value)) {
                    case 'true':
                    case '(true)':
                        return true;
                    case 'false':
                    case '(false)':
                        return false;
                    case 'empty':
                    case '(empty)':
                        return '';
                    case 'null':
                    case '(null)':
                        return;
                }

                if (preg_match('/\A([\'"])(.*)\1\z/', $value, $matches)) {
                    return $matches[2];
                }

                return $value;
            })
            ->getOrCall(function () use ($default) {
                return value($default);
            });
    }
```

#Laravel 5.8以降でenv()の値の変更方法

 **`Env::getRepository()->set('AAA','true')`** にすると、 `env('AAA') = true` になる

###Laravelのフレームワークのソース
[Laravel Githubのソース](https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/helpers.php)
asyncDataについて

Nuxt.jsでの開発にあたって、ページ遷移時にapiを叩いてデータ取得したいときに利用するasyncDataの利用にあたっての注意

```users/_id/index.vue
<script>
export default {
  async asyncData(context) {
    let result = await context.$axios.get(`/users/${context.route.params.id}`)
    return { user: result.data }
  },
}
</script>
```
asyncData内ではthisが利用不可であるため引数としてcontextを利用する。
contextに格納されているパラメータについては以下を参照。
***

###参考
[データの取得- Nuxt.js](https://ja.nuxtjs.org/docs/2.x/features/data-fetching/)
[コンテキスト- Nuxt.js](https://ja.nuxtjs.org/docs/2.x/internals-glossary/context/)
gcloud compute ssh でサーバに接続できなくなった（Permission denied (publickey,gssapi-keyex,gssapi-with-mic)）原因と解決策

# はじめに
原因調査にかなり苦戦したので、備忘録も兼ねて記事として公開します。
同様の事象に悩まされている方の参考になれば幸いです。

# 起きた問題
- 一部のメンバーが、特定のサーバにSSHで接続できない
  - 接続できないのは、新規参入メンバーや直近でPCを新しい端末に交換したメンバーのみ
  - 問題なく接続できるサーバもある
- 認証鍵ファイル(`google_compute_engine`, `google_compute_engine.pub`)を作り直しても直らない

## 環境
- 接続先サーバ： CentOS7
- 接続元PC： macOS Big Sur

## 接続しようとした際のエラーメッセージ
```sh
# SSH接続しようとすると、
gcloud compute ssh --zone "asia-northeast1-b" "VM_NAME" --project "PROJECT_NAME"

# 以下のようなエラーが出力され、接続できない
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].
```

# 解決策
SSH接続する際のユーザー名を指定することで解決しました。

```sh
gcloud compute ssh --zone "asia-northeast1-b" "USERNAME@VM_NAME" --project "PROJECT_NAME"
```

参考：https://cloud.google.com/compute/docs/instances/ssh#metadata-managed_ssh_connections

# 原因
接続先サーバ側で、ユーザーの作成に失敗していたのが原因でした。

- 接続できないユーザーのローカルマシン（Mac）のユーザー名は数字のみ（例： 1234）<br>※端末の管理上、管理番号や社員番号等でユーザー作成されている場合など
- gcloudコマンドでは特にユーザー名を指定しない場合、デフォルトでローカルのユーザー名が使われる
- gcloudコマンドで初めてSSH接続する際、接続先サーバ側でユーザー作成が行われる
- Linuxではユーザー名の先頭に数字を指定することはできない

以上のことから、数字から始まるユーザー名でユーザー作成に失敗し、結果的に権限がない旨のエラーを返していたのが原因と思われます。

補足：一部問題なく接続できていたサーバはOSのバージョンが少し古かったので、数字のみのユーザー名でもユーザー作成できていたようです。
atnos-effを使ってRead/Writeを合成可能なトランザクションEffを作る 

#はじめに
DB操作を行う際、ReadのみかWriteを伴うかに応じて処理を分けたい場合があります。これらをコンパイル時に判定できれば、Masterに問い合わせるべきクエリをSlaveに発行してしまうような事故を未然に防ぐことができます。

具体的には、以下の機能が欲しいです。

- Read/Writeを型で表現する
- ReadとWriteを合成するとWriteになる


このような合成可能トランザクションモナドとしてはFujitaskが有名ですが、本記事では[atnos-eff](https://github.com/atnos-org/eff)を使ったトランザクションEffを考案します。

#作用の変換
ReadとWriteを区別するため、次のように型を定義します。

```scala
// 使っているライブラリのものに置き換える
type DBIO[A] = MyDBIO[A]

case class DBIORead[A](value: DBIO[A])
case class DBIOWrite[A](value: DBIO[A])

type _dbior[R] = DBIORead |= R
type _dbiow[R] = DBIOWrite |= R
```

Effを利用する側のコードは以下のようになると思います。

```scala
def runReadWriteSample: Option[User] = ({
  type R = Fx.fx2[DBIORead, DBIOWrite]
  for {
    _ <- fromDBIOWrite(AddUser(User("hoge", "hoge fuga", 20)))
    userOption <- fromDBIORead(FindUserById("hoge"))
  } yield userOption
}).runDBIO.runTransactionDBIO.run
```

しかしながら、このようなコードではReadトランザクションとWriteトランザクションをばらばらに実行することになり、期待した挙動にはなりません。

そこで、作用DBIOReadを作用DBIOWriteに変換することを考えます。atnos-effでは、次のように記述することで作用を変換できます。

```scala
implicit def fromDBIOReadToWrite: DBIORead ~> DBIOWrite =
  new (DBIORead ~> DBIOWrite) {
    override def apply[X](x: DBIORead[X]): DBIOWrite[X] =
      DBIOWrite(x.value)
  }

implicit def deriveDBIOMember[R](
  implicit member: MemberIn[DBIOWrite, R]
): MemberIn[DBIORead, R] = member.transform[DBIORead]
```

こうした変換コードを記述することで、ReadとWriteを合成して1つの作用として振る舞います。

```scala
def runReadWriteSample: Option[User] = ({
  type R = Fx.fx1[DBIOWrite]
  for {
    _ <- fromDBIOWrite[R, Unit](AddUser(User("hoge", "hoge fuga", 20)))
    userOption <- fromDBIORead[R, Option[User]](FindUserById("hoge")) // 同じfor内でread/writeを合成してwriteになっている
  } yield userOption
}).runTransactionDBIO.run
```

ここで仮に`type R = Fx.fx1[DBIORead]`と書くとコンパイルエラーになります。また、この場合はfromDBIOWrite等の型引数を省略して自動的にDBIOWriteに推論することもできます。ただし、ReadOnlyな場合に`type R = Fx.fx1[DBIOWrite]`と書いてしまうと予期せずDBIOWriteに変換されるので注意が必要です。

#その他の応用
作用の変換はとても強力な機能で、他にも様々な応用が考えられます。例えば、`Aの権限が必要が必要な操作 + Bの権限が必要な操作 = A+Bの権限が必要な操作`のようなルールの権限Effは、HListと組み合わせることで次のような変換コードにより実現できます。

```scala
implicit def fromAuthZHNil: AuthZ[HNil, *] ~> AuthZ[P, *] =
  new (AuthZ[HNil, *] ~> AuthZ[P, *]) {
    override def apply[X](fa: AuthZ[HNil, X]): AuthZ[P, X] = fa match {
      case Authorize(userId, scope) =>
        Authorize[P](userId, scope)
    }
  }

implicit def fromAuthZHCons[H, T <: HList](
  implicit selector: Selector[P, H],
  tail: AuthZ[T, *] ~> AuthZ[P, *]
): AuthZ[H :: T, *] ~> AuthZ[P, *] = new (AuthZ[H :: T, *] ~> AuthZ[P, *]) {
  override def apply[X](fa: AuthZ[H :: T, X]): AuthZ[P, X] = fa match {
    case a: Authorize[H :: T] =>
      Authorize[P](a.userId, a.scope)
  }
}

implicit def deriveAuthZMember[T[_], R](
  implicit member: MemberIn[AuthZ[P, *], R],
  t: T ~> AuthZ[P, *]
): MemberIn[T, R] = member.transform[T]
```

#サンプルコード
[transaction-eff-sample](https://github.com/ippei-takahashi/transaction-eff-sample)
OpenJDK時代のJDKの配布先(ダウンロード先)メモ

# これは何？

- ずっと昔は、JDKの入手先はOracleが1択でした。
- 今はいくつかOpenJDKのディストリビューションが出現したので、まとめたメモです。
 - 手元で実行環境が欲しかったりするので、サッとダウンロード先が欲しいときがあります。
- 基本的には、LTS(Long Term Support)を目当てにしたもの。

# Eclipse Adoptium（旧AdoptOpenJDK）

* https://adoptopenjdk.net/
 * HotSpot と OpenJ9 のJVMが選択可能

# Amazon Corretto

* https://aws.amazon.com/jp/corretto/

# Microsoft Build of OpenJDK

* https://www.microsoft.com/openjdk
* 2021年4月頃追加

# まとめ

- 今のところ上3つ。OracleはLTSを配布していないので、実質選択肢なしか。
 - ページの使いやすさは、AdoptOpenJDK が一番。
 - https://openjdk.java.net/ ← OpenJDKの公式はこちらだがページが使いにくい。
ROS2 on Windows インストールメモ

WindowsにROS2(foxy)をインストールしたときのメモ。
[こちら](http://docs.ros.org/en/foxy/Installation/Windows-Install-Binary.html)をもとにインストールしたが、つまづいたことや、悩んだことを中心にまとめておく。
ただしインストールしただけで、本格的に使っていないので都度修正が必要かもしれない。

#インスト－ル方針
下記の方針でいくことにした。

- 現時点(2021.4)のLTSであるFoxyにする。ラズパイ4と連携させるつもりでそちらは Ubuntu20.04だから問題なさそう。
- 極力chocolatelyを使わない（必要性を感じなかったし、コマンド引数のオプションがいっぱいありすぎて確認するのがめんどくさそう）
- Python3はユーザ環境でインストールする。(ドキュメントはAdmin権限で C:\Python38 にインストールするが、普段づかいするとき pip --user がめんどくさいので）

#chocolatelyのインストール
ドキュメントのリンク先にいき、右上のInstall Nowからたどる。Step1のメールアドレスの登録するようになっているが、無視してもStep2のインストールはできる。
個人利用なのでIndividualのタブの手順を実行する。

- 管理者モードでPowerShellを起動する。
- インストールディレクトリをデフォルトから変えたい場合は、事前に環境変数 ChocolatelyInstall を指定しておく。`setx -m ChocolatelyInstall C:\Dev\インストールしたいディレクトリ>` 自動的にディレクトリが作られないようなので事前につくっておかないといけないらしい。
- 四角に囲まれたコマンドを管理者権限のPowershellで実行

#Python 3.8のインストール
方針に示したように、ユーザ環境にインストールしたい。

- choco でインストールする場合は管理者権限（全ユーザむけ）のインストールになるから使わない。ちなみにchocoでインストールするときはドキュメントにあるように --version 指定をしないと最新(3.9.2など)がインストールされるので必ず指定すること。C:\Python38にインストールされる。
- ユーザ環境(C:\Users\<yourname>\Python)にインストールは本家python.orgからダウンロードすればよい。3.8系の最新(3.8.9)をインストールしてみたが今のところ問題なさそう。
- Ros2のバイナリパッケージに含まれるすべてのPythonスクリプトには`c:\Python38`がハードコーディングされている。今回はユーザ環境にインストールしているのでリンクをはって対処する。管理者じゃないコマンドプロンプトで`mklink /D C:\Python38 C:\Users\<username>\AppData\Local\Programs\Python\Python38`を実行しシンボリックリンクをはる。LinuxやMacと違って、`mklink /D リンク先 リンク元`なのが注意点。

あとは"Enviroment Setup"までドキュメント通り実施する。
chocoをつかうと便利だった点は"Install dependencies"のところ。1行で終わり。
もちろんすべてnupkgなので実はVisualStudioがあるから重要でもないのかもしれないけど。PATHをchocoが追加してくれるのがありがたいということで。

#環境変数の設定
`call <インストールディレクトリ>\local_setup.bat`で終わりかと思いきやそうでもない。環境変数2つを手動で設定してやる必要があった。
## QT_QPA_PLATFORM_PLUGIN_PATH
チュートリアルのturtlesim_nodeを起動しようとすると下記エラーがでて、そもそもwindowが開かない。

```
qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "C:\Qt\5.15.0\msvc2019_64\plugins\platforms"
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
```

これの対処として環境変数`QT_QPA_PLATFORM_PLUGIN_PATH`をros_foxy\bin\platformsに指定してやる必要がある。

```
C:\Users\username> set QT_QPA_PLATFORM_PLUGIN_PATH=<インストールディレクトリ>\ros2-foxy\bin\platforms
C:\Users\username> setx QT_QPA_PLATFORM_PLUGIN_PATH <インストールディレクトリ>\ros2-foxy\bin\platforms
```
これで亀がでてくる。

#ROS_DOMAIN_ID
ROS1から2への変更点で大きなものはmaster-slaveでなくなったこと。つまり母艦PCでmasterを起動したり、スレーブのロボットでslaveを起動しなくても node同士で通信できるということ。
母艦とロボット間を連携させるためには、ROSのドメインROS_DOMAIN_IDを合わせてやる必要がある。

```
set ROS_DOMAIN_ID=1
```
一セットしかROS2を使わないならsetxしてやるといい。

#まとめ
とりあえずラズパイ、VMware上のUbuntuのROS2の間でturtulesimで相互にメッセージを交換できた。
これからあそんでいこう。
プロフィール詐欺をしていたので、いい加減そろそろ作品をQiitaで共有する(VRゲーム制作話)

#東京ゲームショウに出展した話(過去形)
去年(2020年)の東京ゲームショウでゲームを出展していた話をします。
当時はまだQiitaを始めていなかったので、作品を共有することができませんでした。
![スクリーンショット (230).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1207332/2a751a14-3f55-2a3d-1b2a-034181f77a51.png)
そのくせプロフィールにこんなことを書いていたのでいい加減共有しようと思います。

#そもそもどうやって出展したの
プロフィールを見て頂ければ分かりますが、自分は北海道情報専門学校の学生です。この学校では、毎年東京ゲームショウに出展するのが恒例？になっており自分のやる気と実力次第で出展の権利を得ることができます。(学内コンペとかで決める)
この学校に入学する際、この東京ゲームショウ出展を目標にして入学したので、とても嬉しい経験でした。
ほかの学校に行ったことがないので分かりませんが、出展することが恒例化してない学校でも頼んだりしたらいけるのかな？もしそのような経験が教えてください。

#何はともあれ作品をどうぞ
こちらのリンクで遊べるので遊んでみてください。と、言いたいところですが、今回出展した作品は、VRゲームなので実行環境がないと遊べないです。ごめんなさい。
なので出展した際に使用した動画を共有します。
***
https://www.youtube.com/watch?v=moKyaBr0YY8
***
こちらのゲームで、詳しくは動画で確認してほしいのですが、簡単に概要を説明すると、VR空間で何個かミニゲームをプレイしてたらあなたの能力を測定してくれますよーといったものになっています。

ボイスガイドがどんなことをすればいいのかを教えてくれるので、初めてVRゲームをする方でも気軽にできます。

#開発で意識したこと
まず一番最初に意識したのはVR酔いの対策です。
そもそもVRに触れる機会がほとんどなく、開発メンバーで一度もVRゲームをやったことのない人もいたのでまず色々なVRゲーム(公式のものとか、先輩方が作ったものとか)をプレイしたのですが、一番最初に酔いがきついなと感じました。
自分たちが作るものも同じ問題にぶつかることが予想されたので、まずはこの部分を意識して開発することになりました。

#酔い対策①プレイヤーの移動
そもそもなんで人は酔うのかというと、
***
https://yomidr.yomiuri.co.jp/article/20160719-OYTET50046/#:~:text=%E4%BA%BA%E3%81%AF%E3%81%A9%E3%81%86%E3%81%97%E3%81%A6%E4%B9%97%E3%82%8A%E7%89%A9%E3%81%A7,%E3%81%97%E3%81%A6%E7%9C%BC%E7%90%83%E3%81%8C%E5%8B%95%E3%81%8F%E3%80%82
***

この記事のタイトルに書いているように、揺れ、耳の感知に目が不適応。つまり、**聞こえたり、肌で感じている感覚と目で見ているものに「ずれ」が生じる**ことで人は酔ってしまう...らしいです(詳しいことは専門外なのでわからない)。
と、いうことは、VR空間内でプレイヤーキャラが歩いた場合、VR空間内ではそのキャラに合わせて景色が流れますが、現実世界では全く動かないのでこの「ずれ」が起こります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1207332/36f9a536-ae68-926e-5edc-b84fd56cfe1c.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1207332/5580c7b1-8826-a196-433a-0dbede62424c.png" width=50%>
　　　　　　　　↑現実   　　　　　　　　　　　　　　↑VR空間内

これがVR酔いの一番大きな原因となります。
一番簡単に解決する方法はそもそもゲーム内で歩く機能を用意しないことです。この作品は、**ミニゲームを選んだらそのミニゲームをプレイするための場所にワープする**といった形でそれを実現しました。

#酔い対策②高いfpsの確保
先ほど話した「ずれ」の原因ですが、プレイヤーの移動だけでなくfpsが安定しないことによる画面のブレなども挙げられます。
普通のゲームの場合でもカクカクしたらイライラするのに、それプラス酔いまで来るとなるとゲームどころではなくなります。
実際、デバッグをしているときはfpsが足りなく、デバッグをしている人が酔ってダウンすることが多々ありました。
Unityには標準でfpsを表示する機能があるので、それを利用しながらオブジェクトの数を調整したり、レンダリングの設定を見直すことで、70fps以上を維持できるようになりました。(40fps下回るとカクついて酔う)

#ボイスガイド
この作品は、UIを撤廃し、ボイスガイドでユーザーへ指示出すという形になっています。この仕組みにした理由として
**・UIによるゲームへの没入阻害の排除**
**・更に、ボイスガイドによる世界観構築の補助**
の2点が挙げられます。
前者は**ボイスガイドをつける前からぶつかっていた問題**であり、様々な方法で問題解決を図ろうとしていましたが、最終的このような形になりました。
後者ですが、動画内にもある世界生成も合わせることでSFチックな世界観で、能力を測るテストを受けているという感覚をプレイヤーに植え付けることを意識しています。
**没入することは、ユーザーの酔いの対策にもつながる**ので、ボイスガイドを導入したのは正解だったと思います。

#最後に
他にも色々な障害がありましたが、最終的に作品を出展出来て良かったと思います。
コロナウイルスの影響で現地に行けなかったのは残念ですが、初めてのVR開発という点も含めてとてもいい経験になりました。

~~という半年前に書くべき記事でした~~
AWS EC2 macからSSH接続 方法 ポイントのみ

AWS EC2 macからSSH接続 方法 ポイントのみのこします

次回つまずきそうなので黙示録

動作確認環境
macOS mojave
AWS EC2


方法
1.pemファイルダウンロード※しっかり管理しないと積みます


2.パス移動(ここからmacのターミナル)
cd ~/.ssh/keys ※なければ作成

3.ここに XXX.pem を配置

4.
ssh EC2アカウント名@IP -i ダウンロードした鍵.pem

5.yes入力 ※そのまま Enter すると エラーでます｡


リソース
https://gloria.cool/blog/20200528-aws-ssh/
【jQuery】年齢・学年自動更新

##はじめに
ポートフォリオ製作中に、年齢と学年を毎年変更したくないよー、と思い、盟友JavaScript君と一緒に自動更新してくれる機能を作ってみました！
ただし、大学生のみに対応しております。いずれ小中高にも対応できたらと、思ってはいます。対応コード書いてくだされば、すぐにでも反映いたします。

##コード

```javascript:jQuery
  /**
   * 年齢・学年自動計算
   *
   * YYYY/mm/ddの形式で指定
   * data-birth -> 誕生日
   * data-graduate -> 卒業日（学年の切り替わるYYYY/03/31を想定）
   * 
   * https://qiita.com/yuuumbk/items/5e750e18ab6370cef9fc
   */

  var today = new Date();

  $('.birth').each(function () {
    //年齢
    var birth = $(this).data('birth');
    var birthDate = new Date(birth);

    var age = today.getFullYear() - birthDate.getFullYear();
    var month = today.getMonth() - birthDate.getMonth();

    if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) {
      age--;
    }

    age = Math.max(age, 0);
    var value = age + '歳';

    //学年
    var graduate = $(this).data('graduate');
    var graduateDate = new Date(graduate);

    if ((graduate.getFullYear() - today.getFullYear()) >= 0){
      var grade = 4 - (graduate.getFullYear() - today.getFullYear());
      var month = (graduate.getMonth()) - (today.getMonth());

      if (month < 0 || (month === 0 && graduate.getDate() < birthDate.getDate())) {
        grade++;
      }

      if (grade < 5) {
        value += ' - 大学' + grade + '年生';
      }
    }

    $(this).append(value);
  });
```
大学5年生になると自動的に大学生の表示は消えるようになっています。
また、`value`の部分は自由に変えてくださって結構です。

使用例はこんな感じです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <span class="birth" data-birth="2003/03/27" data-graduate="2025/03/31"></span>
</body>
</html>
```

![サンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1142160/c29c079a-3c3c-f071-a7ad-5aa14e3d150c.png)

##おわりに
社会人になってもいつまでも大学生のまま、なんてことになりませんように！

##参考
https://www.gamehuntblog.com/entry/auto-calculate-age-script
(初心者の考察)bootstrapのgemの使い方について

こんにちは
プログラミング初学者のkoheiです。

今回はrailsにbootstrapのgemの認識について書き残したいと思います。
bootstrapをインストールしたものの、使いこなすにはどうすればいいんだろうか、、？
そう思い色々とbootstrapの中身をみていました。

もし、
もっとこんなことが出来る！
間違っているよ！
という方がいらっしゃったら、アドバイスしていただけたら幸いです。

## 現在の自身の解釈

「予め多くの要素に対しレイアウトが決められているため、
HTML側に対応したクラスをつけることで、scssファイル内の記述を減らすことが出来る。」



、、、どうでしょうか。
そう感じた経緯は以下の通りです。

1. ビューがなかったため、bootstrapのHPのサンプルのHTMLを拝借 ( https://getbootstrap.jp/docs/4.3/examples/ )
1. 上記HTMLにはweb上のレイアウトファイルへのリンクが含まれていたためコメントアウト
1. レイアウトが崩れたことを確認
1. bootstrap gemのインストール
1. 3でレイアウトが崩れたビューが元通りに

ここでインストールした際にassetディレクトリ上にscssファイルが生成されたから、と予想したのですが存在しないことに驚きました。
また、元のHTMLファイルにpy-5など見慣れないクラス名が指定されており、それをVSCode内で検索しても該当するファイルは出てきませんでした。

その後、ブラウザで検証ツールを使用し確認したところ
application.self内に以下の記述があったこと

```css
省略
/* line 50, ../../.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootstrap-5.0.0.beta2/assets/stylesheets/bootstrap/mixins/_utilities.scss */
.py-5 {
  padding-top: 3rem !important;
  padding-bottom: 3rem !important;
}

/* line 50, ../../.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bootstrap-5.0.0.beta2/assets/stylesheets/bootstrap/mixins/_utilities.scss */
.pt-0 {
  padding-top: 0 !important;
}

省略
```
またmacbookのfinderで"bootstrap"と検索すればインストール時に生成されたファイルが多数あったこと

以上から、
フォントや細かな設定はbootstrapのデフォルトの物を使用し
必要最低限のscss記述のみでビューを完成させることが出来る。

といった解釈に至りました。

といっても、まだまだ使い勝手が解らないことが多いため、今後も色々調べていきたいと思います！
UnityでOculus用のVRアプリを作るときはVR用の設定を最初にしよう

# はじめに
割とやらかして後で面倒になりがちなので、次こそは忘れないようにメモを残します。
UnityでOculus用のVRアプリを作成する際、
1. プロジェクトを作成する
2. OculusでのVR用の設定をする
3. 中身を作る
4. 実行ファイル（.apk）作成
の順番でやろうねという話です。

2021/04/08
コメントをいただき、「VR用の設定」の実行順を修正しました。
@shiena様ありがとうございます。

# 環境
OS：Windows10
Unity：2018.4.10f

# 詳細
以下にやらかしてしまった時どう対処しているか（対処したか）を書きます。
## やらかし
VR用の設定が割と時間がかかるのでついつい後回しにしてしまい、
1. プロジェクトを作成する
2. 中身を作る
3. 動くことを確認したので満足する
4. OculusでのVR用に設定する
5. apkファイル作ろうとすると謎のエラーが！
という状況になりがち。

## 直近出たエラー
直近で発生したエラーは
`Unity Package Name has not been set up correctly oculus`のエラーが表示され、「Player Seetings」の各種名称で半角英数字だけ使って修正するように促される。しかし全ての名前で半角英数字しか使っていないので名前をどう変更しても解決しない…！
ちなみにコンソールには`UnityEditor.BuildPlayerWindow+BuildMethodException: 2 errors at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x00242]`みたいな内容が表示されており、解決策をググるが検索で出てくる諸々が多岐にわたっており面倒…といった状況でした。

## 解決：作り直し
ということなので作り直しです。
新規プロジェクトを作成したら、以下の手順で作り直します。

### VR用の設定
プロジェクトを新規作成したら、まずVR用に色々やります。

- Build Settingsで「Android」にSwitch
- Player Settingsで以下設定
 - 「Other Settings」で「Minimum API Level」をKitKat以上に設定
 - 「XR Settings」のVRサポートにチェックを入れ、ListにOculusを追加
- Asset StoreからOculus IntegratorをImport

作り直しの場合は不安になっているのでこの時点で「▶」で実行できるか？Buildでapkファイルが作られるか？といったところを確認してもいいと思います。

### 元のプロジェクトから作成物をImport 
ここでもまた横着して元のプロジェクトからPrefabやScriptをコピペで済ませようとしてエラーを起こす場合があります。
きちんとImportしましょう。

- Assets内で右クリック
- 「Import New Asset」を選択
- 持ってきたいScript, Prefab, その他データを選択
    - Script付きのPrefabの場合、関連付けが切れている場合があるため、面倒ですが手動でやり直しましょう

全て作り直せたらBuild出来るかを確認。

# おわりに
Unityは手軽にいろいろできて簡単なようでいて難しいです。
ちゃんとした解決方法があるよという場合はコメントいただけると幸いです。
SynologyでFilezillaを使う

## はじめに

Synology便利ですよね。非常に使いやすいNASだと思います。Synologyでは、Dockerアプリが提供されています。これを使うことで、パッケージセンターで提供されていない多くのソフトウェアが利用可能になります。今回は、Filezillaを起動したので記録に残します。

## Dockerのインストール

アプリセンターを起動し、Docikerをインストールします。

## Filezillaのインストール

　Dockerを起動します。レジストリから`Filezilla`を検索します。いくつかヒットしますが、とりあえず公式である、スター数が多い、更新の頻度が高い、等の指標で選んでおけば大きな間違いはないかと思います。
　イメージのダウンロードは意外と時間がかかります。管理画面の表示だとあまり進んでいないように見えるときがありますが、しばらく待つとダウンロードが完了します。

## イメージの起動

　ダウンロードしたらイメージを起動します。CPUの優先度やメモリの使用範囲の設定などができます。

## ボリュームの追加

　コンテナ→編集で、ボリュームを追加できます。任意のホストのディレクトリを追加しておきます。

　さて、Dockerを起動しても、管理画面上でFilezillaの画面がされるわけじゃありません。概要からポート設定を開きます。ポート設定で、ローカルポートとコンテナのポートという画面があります。ここでポート番号を確認します。
Synologyのアドレスが`http://88.888.888.888` ローカルポートが `54321` の場合は、

`http://88.888.888.888:54321/`

に接続します。これでFileZillaのGUIが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/54205ba2-1a6c-d486-3e3e-98b84be9d3dc.png)

## いざとなったらssh

Synologyはコントロールパネルから、sshに接続できる設定があります。これを利用してsshで接続すれば、いざとなったらコマンドラインからdockerを操作することが可能です。

この記事は以上です。
XCrySDenをWindows (WSL, Ubuntu) で使う

# やりたいこと
WIEN2kの入力(出力)ファイルの可視化のため、Xcrysdenのインストール
環境: WSL (Windows Subsystem for Linux)
- Windows 10 Pro
- Ubuntu 18.04

# インストール
Ubuntuで次のように実行する。

```
sudo apt-get update
sudo apt-get -y install tk tcl tclx
sudo apt install xcrysden
```
これで/usr/share/xcrysden/にxcrysdenがインストールされる。
起動は

```
xcrysden
```

でできるが、GUIを使える環境になっていないので次のようなエラーが出る。

```
application-specific initialization failed: no display name and no $DISPLAY environment variable
Error in startup script: can't read "xcrys(platform)": no such variable
```
# GUI環境の構築
GUIを使うため、次のサイトに従いVcXsrvを導入。
参考サイト:
https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html

UbuntuからVcXsrvを立ち上げるため、次のサイトに従って環境変数の設定を行う。
https://qiita.com/ryoi084/items/0dff11134592d0bb895c#wsl%E4%B8%8A%E3%81%AE%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%81%AE%E8%A8%AD%E5%AE%9A
### 注意
上記参考サイトにある

```
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
```
のコマンドだとIPv4が正しく読み込まれなかったので、PowerShellで確認＆自分で入力の方法を採用。
1. PowerShellにて`ipconfig`と入力
2. IPv4 アドレスの値をコピー (aaa.bbb.ccc.dddとする)
3. Ubuntuにて`vi ~/.bashrc`で~/.bashrcを開く
4. `i` で挿入モード
5. `export DISPLAY=aaa.bbb.ccc.ddd:0`を最終行に追記
6. `:wq!`で保存して終了
7. Ubuntuを一旦終了し、再度立ち上げる

### 環境変数の設定確認
Ubuntuにて

```
echo $DISPLAY
```
とした際、aaa.bbb.ccc.ddd:0と表示され、その'aaa.bbb.ccc.ddd'が正しいIPv4であれば正しく設定できている。

#実行
XLaunchが立ち上がった状況で、Ubuntuにて`xcrysden`と入力すればソフトが立ち上がる。


参考サイト:
インストールに関して
http://www2.yukawa.kyoto-u.ac.jp/~koudai.sugimoto/dokuwiki/doku.php?id=xcrysden
https://www5.hp-ez.com/hp/calculations/page211
【RPGⅣ】仕様書の種類と意味合いを記載してみる。


# 背景
RPGⅣの勉強を始めたので、大事だと思ったことをメモ的に記載していきたいと思います。

※まずは仕様書の種類から、書籍を読んで、こんな感じかな、レベルでなので、
今後実務などを通じて理解が進んだら修正する可能性はあります。

# 仕様書の種類

### Ｈ仕様書（制御仕様書） 
プログラムの制御情報を設定する仕様書、「日付設定」などを記述する。

### Ｆ仕様書（ファイル仕様書）
プログラムで使用するファイル（データベースファイル・印刷装置ファイルなど）を記述する。

### Ｅ仕様書（補足E仕様書）→ＲＰＧⅣではＤ仕様書（定義仕様書）
配列、テーブル、データ構造などを記述する。

### Ⅰ仕様書（入力仕様書）
入力ファイルのレコード及びフィールドを記述する。

### Ｃ仕様書（演算仕様書）
プログラムを記述（どんな条件でどんな演算を行なうかなどを記述する。）

### Ｏ仕様書（出力仕様書）
どのような条件で用紙のどの位置に印刷するかなどの記述をする。

# 参考URL
[メイン・ソース・セクション仕様書](https://www.ibm.com/docs/ja/i/7.2?topic=types-main-source-section-specifications)
[SQL]数字の集合を生成するSQLクエリー

```sql:test.sql
;WITH
--数字集合生成
	L1 AS(SELECT 1 AS n UNION ALL SELECT 1)		--2
,	L2 AS(SELECT 1 AS n FROM L1 a ,L1 b)		--4=2^2	
,	L3 AS(SELECT 1 AS n FROM L2 a ,L2 b)		--16=4^4
,	L4 AS(SELECT 1 AS n FROM L3 a ,L3 b)		--256=16^16
,	L5 AS(SELECT 1 AS n FROM L4 a ,L4 b)		--65536=256^256
,	mn AS(SELECT ROW_NUMBER() OVER(ORDER BY n) AS n FROM L4)
SELECT n FROM mn
```

「2のN乗」のイメージで最初の２レコードの集合群[L1]をCROSS JOINで掛け合わせを続けていき、最後にROW_NUMBER()でナンバリングする

たまに使うので忘れずにメモ。
Plotlyの紹介

Plotlyは、拡大縮小したり、ぐりぐり動かせるグラフを、手軽に描画させることができるJavaScriptのライブラリです。
https://plotly.com/

（注：Plotly は KNIMEとは無関係の独立したライブラリです。ただKNIMEの中ではよく使われていて、カスタマイズできるグラフ用のノードとしては、デフォルトの存在になっている模様です。）

（自分はJavaScriptからしか使ってませんでしたが）JavaScript からだけではなく、PythonやRからも扱えます。以下のように各言語別のURLがあります。

* https://plotly.com/javascript/
* https://plotly.com/python/
* https://plotly.com/r/

Plotlyのグラフは、以下の内容を設定、カスタマイズできます。

+ タイトルラベル、軸ラベル、
* タイトル、目盛り、軸ラベルの各フォントサイズ
* 線やプロットの色
* 凡例の表示・非表示

また、グラフはインタラクティブに動かせます。

* 拡大縮小
* 軸を動かせる
* 範囲指定して拡大

## 軸を動かす

以下の図のようなグラフが表示されている時に、
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/aefba018-ddc9-c07c-4d24-b31f4112d904.png)

グラフのY軸をドラックして上方に動かしたときの様子が以下の図。

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/d118268b-21c0-e36a-bbcd-8535127eddd7.png)

X軸をドラックして左に動かしたときの様子が以下の図。

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/8d0d464c-18d5-6d59-30b0-d3538e3e2c54.png)

## 範囲選択して拡大

D&Dで選択した範囲を拡大できます。
１）ドラッグして範囲選択し、
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/d5359ff9-e95d-2eaa-77f5-77aba7675140.png)

２）ドロップすると、選択範囲が拡大されます。
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/a63bdc2d-9cf2-5917-11df-6dd0a1f77d66.png)

## 拡大縮小のリセット

拡大縮小したりすると、グラフが表示直後の状態からずれてしまいますが、表示を元に戻したいときは、上部メニューの**Autoscale**や、**Reset Axes**を押すと元に戻ります。
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/03836f6c-6e5b-bcd5-2f71-02968f0b51da.png)
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/1caa9eb5-2415-0ac2-672f-53b2c89667d1.png)
AWSでWebアプリをデプロイする方法(Java)⑥

#Apacheのインストール
ApacheをインストールすることでWebアプリケーションとして動かせる環境を整えます

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

###前提条件
SSHでの接続ができる状態
まだ、SSHでの接続ができない方は[こちら]
(https://qiita.com/kunrenyouAcount/items/2a24c5789264904418db)

##Apacheをインストールする

###接続する
下記のsshコマンドを入力して接続します
※キーペアのファイルのパスと、ec2-user@以降は、変更して使用してください

```
ssh -i "/Users/koyamatakumi/Documents/Development/practice/aws/myserverkey.pem" ec2-user@13.115.141.44
```

###接続確認
下記のように表示されていれば、接続完了です
![スクリーンショット 2021-04-07 0.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/f1c21fd0-8be0-ab0e-ebdf-c9592fa0a8d7.png)

##SSHでの操作とrootユーザーへの切り替え
###rootユーザーのサインイン
ソフトウェアのインストールはrootユーザーで行います
下記コマンドを入力し、rootユーザーへサインインします

```
sudo -i
```

![スクリーンショット 2021-04-07 0.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/f9b00b1e-975d-f282-6cbe-6088f256bf3e.png)


>##ユーザーの見分け方
####ルートユーザー
```
#
```
####一般ユーザー
```
$
```

###Apacheをインストールする
```
yum install httpd
```

インストールするかどうか聞かれるので[**y**]を入力し、**Enter**
![スクリーンショット 2021-04-07 0.39.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/3c5df3b5-420e-1ae3-290d-101d5699104e.png)

下記の画面になればインストール完了
![スクリーンショット 2021-04-07 0.39.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/c8a396b1-7f8d-3e68-9c9d-70f2c2495949.png)

##Apacheの起動
###起動
インストールしたら、起動して動作を確認します

```
systemctl start httpd
```


###コンソールから状態確認

```
systemctl status httpd
```

以下のように「**Active: active(running)**」となっていれば成功です
![スクリーンショット 2021-04-07 0.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/31cfe076-1799-0bbd-cc8e-4072e0704579.png)


###ブラウザから確認
ブラウザからパブリックIPアドレス(13.115.141.44)を入力して、テストページを表示できるか確認します
![スクリーンショット 2021-04-07 0.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/a04e9bc4-c47c-3baf-4bb7-dc991d7c00a0.png)

##Apacheの停止
###停止
インストールしたら、起動して動作を確認します

```
systemctl stop httpd
```


###コンソールから状態確認

```
systemctl status httpd
```

以下のように「**Active: inactive(dead)**」となっていれば成功です
![スクリーンショット 2021-04-07 0.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/c0310bf5-30ad-8523-b396-239f27b00960.png)

###ブラウザから確認
ブラウザからパブリックIPアドレス(13.115.141.44)を入力して、テストページが表示できないか確認します
![スクリーンショット 2021-04-07 0.56.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/0ea9f85b-a2ba-c91e-e491-ff821209cef1.png)

##自動起動設定
###設定
EC2インスタンスが起動した際に自動でApacheサービスも起動するよう設定

```
systemctl enable httpd.service
```

###確認
Loadedの(/usr/lib/systemd/system/httpd.service;の後がenabledであれば自動起動が有効

```
systemctl status httpd.service
```


#AWSでWebアプリをデプロイする方法⑦
[MariaDBのインストール](https://qiita.com/kunrenyouAcount/items/eb1f211daebdc19933cd)
【CSS】特定のブラウザに反映させる


特定のブラウザのみにスタイルシートを適用したい時に使用します。
`@mixin`でまとめて、このコードを呼び出したい時は`@include`で書きます。

#IE

```style.scss
@mixin IE11 {
  @media all and (-ms-high-contrast: none) {
    @content;
  }
}
```

↓

```style.css
@include IE11 {
ここIEに反映させたいcssコードを書きます。
}
```
以下も`@include`の書き方は同じ。


#Firefox
```style.scss
@mixin firefox {
  @-moz-document url-prefix() {
    @content;
 }
}
```

#Chrome

```style.scss
@mixin chrome {
  @media screen and (-webkit-min-device-pixel-ratio:0) {
    @content;
  }
}
```
pip がエラー吐く！　SSL が何とか言ってるけど... (windows環境)

```
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/tf-nightly-gpu/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/tf-nightly-gpu/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/tf-nightly-gpu/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/tf-nightly-gpu/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/tf-nightly-gpu/
Could not fetch URL https://pypi.org/simple/tf-nightly-gpu/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/tf-nightly-gpu/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
```

同じエラーにあってる方がいるようで、私はこれで解決しました、というのをいくつか試しました。

- python を入れなおす
- pip を入れなおす
- libsslのなんかのdllをpathの上位のほうに持ってくる

私が解消したのは、「OpenSSL 単体を入れなおす」でした。
本家、https://slproweb.com/products/Win32OpenSSL.html からとってきました。lite版とfullがありますが、うちは、liteで行けました。

python 入れ直しとかよりも簡単と思いますのでお試しあれ...