OmniAICreator/Qiita-1.07M huggingface dataset:
【Mac】キーボード不具合への対処「SMCリセット」【応急処置】

#結論
から言うと、**以下の記事**
***[Macに原因不明の不具合が起きたら「SMCリセット」のやり方（２） -- あわてないよう「SMCリセット」について知っておこう（2020年05月18日／ASCII）](https://ascii.jp/elem/000/004/012/4012839/2/)***
の、**「レベル１」**の作業で改善しました。（追記をご覧ください）

##追記 - 2020年12月27日
上記を実行後、一時的に改善したものの、１時間ほど使用して再発しました。
（多少マシになったので、試す価値はあります）
すぐに次の手段、**「レベル２」**を試しました。
**厳密には、以下の Apple 公式サポート記事「Mac の SMC をリセットする方法」が正しいです。**
***[Mac の SMC をリセットする方法](https://support.apple.com/ja-jp/HT201295)***
また改めて、後日、状況を追記します。

##追記 - 2021年1月17日

上記「レベル２」のSMCリセットを定期的（毎週末など）に行うことで、**多少、不具合が残るものの、対処できる事が分かりました。**

※一定期間（２〜３週間ほど）経過すると、元の酷い状態まで戻ります。

#経緯
使用している Mac の**「N」キーに不具合**があり、使用率が高く、修理に数日〜１週間かかるようなので、困っていました。
**※MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)を使用しています。**

調べると、**　Apple 公式サポートが修正プログラムが用意している *[不具合の対象モデル](https://support.apple.com/ja-jp/keyboard-service-program-for-mac-notebooks)* のリストに、当てはまっていました。**

**僕と同様にお困りの方も、まずは上記の方法を試してみて下さい。**

#SMCとは
>『「System Management Controller」の頭文字をとった略語だ。（中略）Intel製のプロセッサーを搭載したMacが装備するもので、Macのハードウェアの中でも、主に電源周りを管理する役割を担っている。』

※参考記事***[「Macに原因不明の不具合が起きたら「SMCリセット」のやり方（２） -- あわてないよう「SMCリセット」について知っておこう（2020年05月18日／ASCII）」](https://ascii.jp/elem/000/004/012/4012839/2/)***より引用）


#今後の対策
原因については、正確にはわからないのですが、僕の例で考えられるのは、**OSのアップデート**、ソフト（Docker?）のインストール辺りです。一度、Docker for Mac を使用した影響？と思われるエラーが kernel で起きたのを覚えていて、その辺りを少し疑っています。

いずれにしても、**一番可能性が高いのは、OSのアップデート（Big Sur version 11.0.1）ですね。**

色々なツールを試すことが多いのですが、ほとんど記録を取っていなかったので、**今後は、しっかり作業記録を取ろうと思います。**
【Ruby】便利なやつだよ〜before_action編〜

コントローラー内の記述でかぶっているものについてまとめてくれる、そんな素晴らしいコマンド「before_action」編です。


```
class ItemsController < ApplicationController

  def index
    @items = Item.order('created_at DESC')
  end

  def new
    @item = Item.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      render :new
    end
  end

  def show
    @item = Item.find(params[:id])
  end

  def edit
    @item = Item.find(params[:id])
    redirect_to root_path unless current_user.id == @item.user_id
  end

  def update
    @item = Item.find(params[:id])
    @item.update(item_params)
    if @item.save
      redirect_to root_path
    else
      render :edit
    end
  end

end

```

アクション内でかぶっている記述がありますね。
上から順番に<h3>show<br>edit<br>update</h3>
以上3つの「**@item = Item.new(item_params)**」という記述です。

これをbefore_actionを使ってまとめてみます。

```
class ItemsController < ApplicationController
before_action :find_item　⬅️❶まずこれを記述して

〜略〜

  def show
    @item = Item.find(params[:id])　　　　　⬅️❷これを消してく
  end

  def edit
    @item = Item.find(params[:id])　　　　　⬅️❷これを消してく
    redirect_to root_path unless current_user.id == @item.user_id
  end

  def update
    @item = Item.find(params[:id])　　　　　　⬅️❷これを消してく
    @item.update(item_params)
    if @item.save
      redirect_to root_path
    else
      render :edit
    end
  end

  private　　　　　　　　　　　　　　　　　　　　　⬅️❸privateメソッドにして

 
  def find_item　　　　　　　　　　　　　　　　　⬅️❹find_itemという名前のメソッドを定義して、中身はかぶっている記述をIN
    @item = Item.find(params[:id])
  end


```

そしてページ更新！



はい！エラーになりました！笑
定義したfind_itemメソッドは、かぶっていて記述を削ったアクションにだけ必要になっている。
つまり**show**、**edit**、**update**の3つにだけ適用したい。
そんな時はonlyアクションでしたね。しぼっちゃいましょう。


```
class ItemsController < ApplicationController
before_action :find_item, only: [:show, :edit, :update]　⬅️❶ここに追加
〜略〜

  def show
  end

  def edit
    redirect_to root_path unless current_user.id == @item.user_id
  end

  def update
    @item.update(item_params)
    if @item.save
      redirect_to root_path
    else
      render :edit
    end
  end

  private
 
  def find_ite
    @item = Item.find(params[:id])
  end

```

だいぶスッキリしました。
ずっと同じファイルで記述しているとこういうことが起きやすいのかなと思いました。
コードが増えてきたら一度整理＆確認してみることが大事ですね。
今日も良い経験になりました。
[scss]scssのフォーマットとプロパティのソートの自動化[VScode,csscomb]

## 混沌としてくるcssプロパティ
![スクリーンショット 2020-12-27 220531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180938/ff10b849-358a-8498-3581-0fa88b56c3d4.png)

cssを書き込んでいくとプロパティ順序が混沌としてく...
可読性のためにも記述の順序を統一したいけど手動でやるのはめんどくさいので自動化できないかなーと思っていたらVScodeの丁度いい拡張機能があったので導入してみた。

## インストールと設定
csscombというアドオンがあったので導入。

csscombとはフォーマッター機能にプラスしてcssプロパティのソート機能のオプションがある。便利。

設定はこんな感じ
![スクリーンショット 2020-12-27 221323.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180938/f524432b-7807-8747-862d-86f3e7605cbf.png)


```
 "csscomb.formatOnSave": true,
    "csscomb.ignoreFilesOnSave": [
    
    ],
    "csscomb.syntaxAssociations": {
    "postcss": "scss"
    },
    "csscomb.preset":"./.vscode/mycsscomb.json"
、
```
scssでも使いたいので"postcss"でscssを指定し"csscomb.preset"にcsscombの設定を記述したファイルを指定する。
mycsscomb.jsonの名前や場所はどこでもいい。適当にファイルを作成し以下の設定をする。
![スクリーンショット 2020-12-27 222123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180938/9cd90af3-ba37-fd26-4475-8ac0f275d211.png)


```./.vscode/mycsscomb.json
{
    "exclude": [
        ".git/**",
        "node_modules/**",
        "bower_components/**"
    ],
    "always-semicolon": true,
    "block-indent": "  ",
    "color-case": "lower",
    "color-shorthand": false,
    "element-case": "lower",
    "eof-newline": false,
    "leading-zero": false,
    "quotes": "double",
    "remove-empty-rulesets": true,
    "space-after-colon": " ",
    "space-after-combinator": " ",
    "space-after-opening-brace": "\n",
    "space-after-selector-delimiter": "\n",
    "space-before-closing-brace": "\n",
    "space-before-colon": "",
    "space-before-combinator": " ",
    "space-before-opening-brace": "\n",
    "space-before-selector-delimiter": "",
    "strip-spaces": true,
    "unitless-zero": true,
    "vendor-prefix-align": false,
    "space-between-declarations": "\n",
    "sort-order": [
        [
            "background",
            "background-image",
            "background-size",
            "background-repeat",
            "content",
            "display",
            "position",
            "width",
            "height",
            "margin",
            "padding",
            "top",
            "botttom",
            "left",
            "right",
            "border",
            "color",
            "font",
            "font-size",
            "text-decoration",
            "text-align",
            "vertical-align",
            "writing-mode",
            "other text",
            "content"
        ]
    ]
}
```

sort-orderの部分がcssプロパティがソートする順序。backgroundのつぎにContentやdisplayが来るように設定した。
この辺はお好みで。

![スクリーンショット 2020-12-27 222403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180938/babf2c47-4f7d-f748-8ae3-0cb8baf65926.png)

Ctr + s で自動整形してくれる。便利:tada:


##　参考
- [CSSの記述順で迷わない！汚いコードをキレイにしてコーディング速度をあげよう！VSCode拡張機能【CSScomb】](https://onedarling.site/programming/csscomb/)
- [【Grunt】csscombでソートだけでなくインデントなどのフォーマットも整形する-](http://bashalog.c-brains.jp/14/12/01-202258.php)
Laravel のwhereHasをwhereInに置き換える



# 難しいクエリを作りたくない
whereHasは遅い。激遅い。
left joinや、whereInすれば良いらしいと推測。
でもleft joinはコーディングがしんどいのよな……。

## 結論：whereInで頑張れば簡単だし改善はできるよ
[時間が無い人はここ](#最適解)

### modelの関係性
usersはcommentsと「1対多」の関係。

### whereHasを用いた場合
#### 前提
* リレーション先のカラムでwhereしたい。

###### Commentsを基本とした場合
```php5:UsersController.php
// nameで検索したい
Comments::whereHas('Users', function($query) use ($name){
$query = $query->where('name', $name);
});
```
### whereInに置き換え
###### Commentsを基本とした場合
```php5:UsersController.php
// nameで検索したい
$comments = Comments::whereIn('user_id', function($query) use($name)
{
    $query->from('users')
    ->select('users.id')
    ->where('users.name', $name);
});
```
なんだか冗長で見辛い。どうせサブクエリだし２回叩けばいいんじゃね？

## 最適解
### whereInに置き換えつつ、クエリを２回叩く

###### Commentsを基本とした場合
```php5:UsersController.php
// nameで検索したい
// users単体で、クエリをたたく
$users = User::select('id')
        ->where('name', $name);
// その結果を、当モデルに組み込む。
Comments::whereIn('user_id',$users);
```
###### Usersを基本とした場合
```php5:UsersController.php
// comment_titleで検索したい
$comments = Comments::select('user_id')
        ->where('comment_title', $title);
// その結果を、当モデルに組み込む。
Comments::whereIn('id',$comments);
```
この方法がよさそう。
whereInのみの場合と比較しても大して変わらない。

ちゃんと計測はしていないけど、体感で明らかに早くなったのでよしとする。（whereHasだと1.5倍以上時間かかる）
生クエリや、left joinする方より美しく書ける。

以上。

## 追記
下記の方が、便利なライブラリを作成してくれています。
古のphpバージョンだと対応していない(未確認)ので、以降の記事は備忘録的な意味で残します。
https://qiita.com/mpyw/items/0761a5e44836c9bebcd5
prettierが効かない時の対処法

①prettierをインストールし、vscodeの設定でEditor: Format On Saveにチェックをつけると反映されるという記事が多かったが。自分のvscodeはいうこと聞かず、、、

②しかしその後、設定のEditor:Default Formatterのnullをesbnp.prettier-vscodeに変更したら、反映された。


settings.json
{
  "editor.formatOnSave": true,　　　　<===①
  "editor.defaultFormatter": "esbenp.prettier-vscode" <===②
}

このファイルは、設置を変えると自動で作られるファイル。設定のワークスペースとリンクしてる？
自分が変えた設定を設定ファイルから見つけるのは、なかなか時間の無駄だけど、このファイルをみると一発でわかる。便利。
ラズパイカメラで動体検知する 準備編

##モチベーション
ラズパイで画像認識させていろいろしたい。用途はまだはっきりとはしてないのですが、そのための準備として動体検知を動かしておく。

##環境
- RaspberryPi3B+
- Raspbian 9.8
- HiLetgo OV5647 5MP Raspberry Pi 3 カメラ OV5647 HDカメラモジュール 
- motion

##準備

###motionのinstall

```
sudo apt-get update
sudo apt-get install motion
```

ffmpeg libavcodec57 libavdevice57 libavfilter6 libavformat57 libavresample3
libavutil55 libmariadbclient18 libpostproc54 libpq5 libsdl2-2.0-0
libswresample2 libswscale4 mysql-common　というライブラリに依存していることがわかります。

###カメラモジュールをカーネルに組み込む

```
sudo modprobe bcm2835-v4l2
```

modprobeコマンドはカーネルモジュールの組み込み（ロード）と取り外し（アンロード）を行うコマンドです。
V4L2はVideo4Linux2の略で、
これを実行するとカメラがビデオデバイス(/dev/video0)として認識されます。

OS起動のたびに組み込むために/etc/modulesに一行追加します。

```　/etc/modules
bcm2835-v4l2
```


###設定

/etc/motion/motion.conf
設定は多岐に渡るが、ひとまず動いていることを確認したいので、
ブラウザから画像が見えるようにstream_localhost をoffにする。

```
# Restrict stream connections to localhost only (default: on)
stream_localhost off
``` 

###動かしてみる
```　
pi@raspberrypi:/var/log/motion $ sudo motion -n
[0:motion] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf
[0:motion] [NTC] [ALL] motion_startup: Motion 4.0 Started
[0:motion] [NTC] [ALL] motion_startup: Logging to file (/var/log/motion/motion.log)
```

ちなみにmotionコマンドのオプションは以下の通り。-nはbackgroundではなく、foreground動かすという意味です。そのため停めるときはCtrl-Cで止めます。

``` 
-b                      Run in background (daemon) mode.
-n                      Run in non-daemon mode.
-s                      Run in setup mode.
-c config               Full path and filename of config file.
-d level                Log level (1-9) (EMG, ALR, CRT, ERR, WRN, NTC, INF, DBG, ALL). default: 6 / NTC.
-k type                 Type of log (COR, STR, ENC, NET, DBL, EVT, TRK, VID, ALL). default: ALL.
-p process_id_file      Full path and filename of process id file (pid file).
-l log file             Full path and filename of log file.
-m                      Disable motion detection at startup.
-h                      Show this screen.
``` 

chroniumからhttp://192.168.0.13:8081/　(192.168.0.13はラズパイのIPアドレス)にアクセス。

リアルタイムでブラウザからカメラ画像を見ることは確認できました。
まだ、動体検知しているかまではわかりませんね。
/var/lib/motion にいくと、動画(aviファイル)、静止画(jpeg)が残っていたので、意図せずカメラの前での動きを検知したようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29032/54e51c64-55bd-fd50-c86a-6826f7ffb9cb.png)
groovyでDDL/DMLを実行する、ついでにgradleタスク化する。

## 概要・背景
[前回の記事](https://qiita.com/TATETATE4545/items/5dd023e877111a3e1df3)で、DDLを自動生成するgradleタスクを作成したので、「DDL生成 ⇒ DDL実行 ⇒ DML実行」という一連の流れを行うgradleタスクを作っておくことでOpen Sourceで公開したときに、だれでも簡単に環境構築できるようにする。
そのために、DDL/DMLを実行するgroovyを作成する。ついでにそのgroovyをgradleタスク化する。

## DDL/DMLを実行するgroovyの作成

大した事はなくて、指定ディレクトリに配置されているSQLファイルの中身を1行ずつ実行できるようにした。
sqlのフォーマットは[前回の記事](https://qiita.com/TATETATE4545/items/5dd023e877111a3e1df3)で作成した場合は、1行1コマンドで";"終わりであることを考慮した実装としている。
ちなみにgradleタスク化することを見越して、@TaskActionを付与しているが、def renewTable()以下のみのgroovyを作成すればそれ単体で実行できる。

```groovy:RenewTable.groovy
// renewTable.groovy
import groovy.sql.Sql
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class RenewTableTask extends DefaultTask {

    @TaskAction
    def renewTable() {

        def props = [user: "TATEISHI0927", password: "TATEISHI0927"] as Properties
        def sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:orcl", props, "oracle.jdbc.driver.OracleDriver")

        // 方法1: drop.sql と create.sqlの中身を実行。既存Objectだった場合のケア必要。回避策としてdrop_user_objects.sqlの実行をする。
        String dropSqlFilePath = "/build/generated-schema/drop.sql"
        String createSqlFilePath = "/build/generated-schema/create.sql"
        (new File(dropSqlFilePath).text.split("\r\n")).each {
            sql.execute(it.substring(0, it.length() - 1))
        }
        (new File(createSqlFilePath).text.split("\r\n")).each {
            sql.execute(it.substring(0, it.length() - 1))
        }
    }
}
```

## groovyのgradleタスク化

やることは

- groovyファイルをgradleが認識できるようにDeaultTaskを継承させ、@TaskActionを付与すること。
- build.gradleの設定に下記を追加する。
注意点としては、gradleのカスタムタスクとして作成するならbuildSrc配下のbuild.gradleに上記の設定を記載すること。

```gradle:buildSrc/build.gradle
plugins {
    id 'groovy'
}
dependencies {
    compile gradleApi()
    compile localGroovy()
}
task RenewTable(type: RenewTableTask)
```

## 参考記事
groovyのgradleタスク化について参考にした記事↓
http://gradle.monochromeroad.com/docs/userguide/custom_tasks.html
https://kazuhira-r.hatenablog.com/entry/20120805/1344172437

## まとめ
今回はgenerateSchemaのプラグインで作成されたSQLファイルを1行ずつ実行するという手法にしたが、
gradleからsqlplusを直打ちしたりと、もっといけてる手法はあるだろうなと。必要に応じてupdateしようかなと思います。

[前回の記事](https://qiita.com/TATETATE4545/items/5dd023e877111a3e1df3)と合わせて、
DDL生成: generateSchema
DDL実行: renewTable
DML実行: initialDataSetup
というgradleタスクをそれぞれ作ることで、これら「DDL生成 ⇒ DDL実行 ⇒ DML実行」という一連の流れを行うgradleタスクを作っておくことでチームメンバーの誰でも同様にDBの初期環境構築ができるようになります。

ここまで読んでいただきありがとうございました。:bow:
ALBにCognitoの認証をかける

# はじめに
ベーシック認証のようなものを、ALBとCognitoを使って実現する話です。
こんなやつ。

![スクリーンショット 2020-12-27 21.28.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/91e7b6c3-4e2f-61e3-6816-df25861adb76.png)


# やり方


### userpoolの作成

AWSコンソールからcognitoを開き、右上の「ユーザープールを作成する」ボタンをクリックします。
![スクリーンショット 2020-12-27 21.05.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/6a08106f-2c28-3737-ddee-681978297228.png)

プール名を入力し、「デフォルトを確認する」をクリックし、「プールの作成を」クリックします。
設定を変更したい方は、お好みで変更してから作成してください。
![スクリーンショット 2020-12-27 21.05.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/77585fdb-3587-d8b0-826b-0450e0437c80.png)

続いて、アプリクライアントを作成します。左側のメニューのアプリクライアントから作成します。設定内容はデフォルトのままで大丈夫です。
<img width="30%" alt="スクリーンショット 2020-12-27 21.13.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/d3dad1b2-a8c7-942d-64ea-4a319626d411.png">

続いて、ALB認証時に使うドメインの登録をします。同じく左メニューの「ドメイン名」から好きなドメインを登録してください。

最後に、左メニューから「アプリクライアントの設定」をクリックし、以下のようにします。<ALBにアクセスするためのドメイン>は実際に認証をかけるALBの物に書き換えてください。

* 有効なIDプロバイダの「Cognito User Pool」にチェック
* 認証されているOAuthフローの「Authorization code grant」にチェック
* 許可されている OAuth スコープの「openid」にチェック
* コールバックURLに「https://<ALBにアクセスするためのドメイン>/oauth2/idpresponse」を入力

![スクリーンショット 2020-12-27 21.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/539a2989-20c8-e1ab-e29a-799e986d9e8e.png)


### ALBの設定

httpsで接続できるALBが必要です。作成の仕方はこちらを参考にしてください。https://qiita.com/ggg-mzkr/items/9924f729df15762dda28

AWSのALB一覧から、認証をかけるALBを選択し、したのメニューから「リスナー」タブを開きます。そして、認証をかけたいリスナーに対して「ルールの表示/編集」をクリックします。

詳細画面が出てくるので、上にある鉛筆マークをクリックすると、リスナーの横に鉛筆マークが現れるので、そちらをクリックします。

![スクリーンショット 2020-12-27 21.39.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/97989f57-af11-606e-6be3-d9abff7a186a.png)

![スクリーンショット 2020-12-27 21.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614264/5b256340-e076-cf5d-6085-ae6add7d751e.png)


「アクションを追加」 → 「認証」 を選択し、先ほど作ったuserpoolとアプリクライアントを選択して、右上の「更新」ボタンを押します。


### 画面表示

この時点で、ALBへアクセスを行うと、冒頭のような画面にリダイレクトされます。
ログインするためのユーザーは、cognitoの「ユーザーとグループ」から作成することができます。

以上。
Ruby の && や || は条件演算子じゃない

Ruby の初心者向け記事で `&&` や `||` を「条件演算子」と書いているものをときどき目にします。
おそらく条件式で使うのでそう呼んでしまっているのだろうと思いますが，これらは「論理演算子」です。

一方，条件演算子というのは，

```rb
(1..9).each do |n|
  puts "#{ n } is #{ n.odd? ? "odd" : "even" }"
end
```

に出てくる式

```rb
n.odd? ? "odd" : "even"
```

の `? :` という二つの記号で表される演算子のことです。
三つの項を取るので「三項演算子」とも呼ばれます（Ruby では条件演算子以外に三つの項を取る演算子はありません）。
[演算子式 (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/3.0.0/doc/spec=2foperator.html)
【Unity】 自分で作成した画像をUnity2Dにテクスチャとして組み込む

2Dゲームを作成する際に自分でイラレで書いた画像をUnityにテクスチャとして組み込む方法がわからなかったので自分用のメモとして記事を書きます。 

#illustrator
イラレ側でしておくことは後ほどの切り分けのことを考えて四角で囲えるようにそれぞれのパーツをわけておくこと& png形式で保存しておくこと。背景は別にしておく。
↓この形での保存が望ましい![アートボード 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/2c60c76c-606e-2632-222f-dfec3e7c4887.png)
↓このように背景をつけておくと後で切り分けた時に背景も合わせて切り取られてしまうのでよくない
![アートボード 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/cc67a498-de18-bd54-f452-a733f12751eb.png)
#Unity
###1.プロジェクト内にTextureフォルダを作成し、そこに先ほど作成したpng画像を入れる
![スクリーンショット 2020-12-27 15.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/0a74bf7b-c636-897d-e468-26a900b30e0d.png)
###2.Inspector画面において、緑の丸の部分を設定し、赤丸の部分でApplyした後、青丸でSprite Editorを開く  
(今回は一つのpngから複数のテクスチャを切り抜く場合を想定しているのでSpriteModeをMultipleに設定しているが、一つの画像をそのままテクスチャとして用いる場合はSingleで良い)
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/5732754b-9cea-6770-3b54-a441a4282984.png" width=40% >
</div>
###3.スプライトエディタにてテクスチャ分割をする
####-形がオートで決まる場合
赤のSliceを押し、Sliceタブを出す。
TypeをAutomaticに設定し(青)、緑のSliceを押してテクスチャを分割。
この後は右上のApplyボタンを押すことで、分割されたシェーダーがフォルダに入る。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/5199b9e5-178a-2546-bc69-fe363172dff3.png" width=70%>
名前を変更したい場合はSlice後に各スプライトを選択後Nameを変更する。
フォルダ内ではRenameができないので注意。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/27ce0674-abea-8ffe-0269-a0d279e703a2.png" width=70%>
####-形を自分で設定したい時(背景透過で使いたいロゴなどの場合)
自分でドラッグしてサイズを決める。青色の四角で切り取った部分がShaderとなる。
青の線と緑の線がずれてしまった場合はBorderの部分のどれかの値が0で無くなっている場合だと思うので、0に直してあげればズレは直る。
サイズが決まったら右上のApplyを押してあげればそれぞれのShaderとして毎回保存される。
**ひたすら上書きされてうまくいかない時は諦めてもう一回画像読み込みからやり直すと直った**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984400/abfa8535-f39b-d196-948a-0dda7481d925.png" width=70%>
###4.できたシェーダーはそのままSceneビューにドラッグすれば使える！

#まとめ
次回、自分で作った画像をボタンとして使えるようにするメモ！
まだまだ理解が甘いので間違ってるところなどあったら教えてください！！
USB のブロックデバイス (USB メモリや HDD)を列挙する方法 (Part2)

# USB のブロックデバイス (USB メモリや HDD)を列挙する方法 (Part2)

[USB のブロックデバイス (USB メモリや HDD)を列挙する方法](https://qiita.com/m-tmatma/items/a6595895382b53e72830) で書いたのとは別の方法で、USB のブロックデバイスを列挙する。

## 方法

```
ls /dev/disk/by-id/usb* -1 | xargs readlink -f | grep -E '[a-z]+$'
```

## 解説

`/dev/disk/by-id/usb*` を実行すると、USB のブロックデバイス一覧とその実デバイスへのシンボリックリンクを取得できる。

```
$ ls /dev/disk/by-id/usb* -l
lrwxrwxrwx 1 root root  9 12月 27 21:28 /dev/disk/by-id/usb-BUFFALO_USB_Flash_Disk_xxxxxxxxx-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 12月 27 21:28 /dev/disk/by-id/usb-BUFFALO_USB_Flash_Disk_xxxxxxxxx-0:0-part1 -> ../../sdb1
```

`readlink -f` により、シンボリックリンクの実体を取得できるので、以下で　USB のブロックデバイスの実体のリストを取得できるが、

```
$ ls /dev/disk/by-id/usb* -1 | xargs readlink -f
/dev/sdb
/dev/sdb1
```

`/dev/sdb1` などパーティションに対するデバイスファイルも表示されるので、grep で正規表現を使ってフィルタリングする。

```
$ ls /dev/disk/by-id/usb* -1 | xargs readlink -f | grep -E '[a-z]+$'
/dev/sdb
```
要素を両端に置いて揃えたい時

飲食店のHPでよく見るヘッダーがあり左にはロゴ、右には自店のsnsのアカウントの画像がある。
そして、その２つの要素を両端に置きたい時は親要素にdisplay:flex;とjustify-content:space-between;を使えば綺麗に納まる。
また、親要素にmargin,paddingでスペースを空けると見やすくなります。
Gemfile.lock にはインストールされている gem のバージョンが書かれている，わけじゃない

Ruby の初心者向け記事を眺めていると，Gemfile.lock について誤解していると思われる記述が目につきます。
そんなアレコレをこの記事では見ていきます。

最初に，Gemfile と Gemfile.lock についておさらいをしておきましょう。

まず，Gemfile は**そのプロジェクトで**使用する gem を指定するものでしたね。
gem の名前だけでなくバージョンも指定することができます。「○○以上」「○○未満」のような幅をもった指定もできます。また，

```rb
gem "hoge", "~> 3.5.2"
```

と書けば，`hoge` gem で，「3.5.2 以上，3.6.0 未満」という意味の指定になるのでした。

一方，Gemfile.lock は，Bundler によって生成されるファイルでした。
Gemfile.lock がまだ存在しない状態で，

```shell
bundle install
```

とすると，Bundler は Gemfile の記述を元に gem をインストールしていくのですが，さきほどの記述を例に取ると，`hoge` gem の「3.5.2 以上，3.6.0 未満」を満たすバージョンのうち，**実際に存在している最も高いバージョン**の gem を選びます。そしてそのバージョンを Gemfile.lock に記録し，まだインストールされていない場合はインストールします。

ここで以下のような誤解が生じます。

* Gemfile.lock にはインストールされている gem のバージョンが書かれている。

確かに上述の状況ではそのようになります。
しかし，Gemfile.lock が生成されたあとで当該の gem をアンインストールすることができます。
また，チーム開発などでは，誰かの環境で作られた Gemfile.lock が Git 管理されて自分の手元にやってくることもありますね。この場合，そこに書かれた gem はこちらではまだインストールされていないかもしれません。
それに，Gemfile.lock に書かれていないバージョンの gem もインストールされているかもしれません。

こうしてみると，Gemfile.lock の記述と（あなたの環境に）インストールされている gem（のバージョン）は無関係と言えることが分かります。
Gemfile.lock は，「そのプロジェクトにおいて現時点で**使うことになっている** gem（のバージョン）」が記述されている，と考えればいいと思います。

次に，よくある誤解が

* Gemfile.lock が存在する場合，`bundle install` すると，Gemfile.lock に従って gem がインストールされる。

です。
わりと正しいのですが，既にインストールされている場合はインストールは行われませんし（当たり前），Gemfile.lock に従わないケースすらあります。
それは Gemfile.lock に書かれたバージョンが Gemfile に書かれたバージョンの条件を満たさない場合です。
例えば，Gemfile.lock が `1.0.3` となっているときに，Gemfile のほうを `>= 1.1` と書き換えたら，`bundle install` では `1.0.3` は採用されず，`>= 1.1` を満たすバージョンが選ばれ，Gemfile.lock は書き換えられることになります。

Gemfile と Gemfile.lock の関係はちょっぴりだけ複雑です。
業務用 Windows PCセットアップ〜虎の巻〜

# はじめに

この記事は生産性向上のための環境整備2020 【PR】 Lenovo Advent Calendar 2020 - 03 の1日目の記事です。


Lenovo製品は季節の折り、セールをしているときがあります。セールを狙えば、20万円を切る価格帯で Ryzen 7 のメモリ 32GB のマシンが買えてしまうので、経営大丈夫かなと心配するぐらいです。私は10年来のMacユーザーなのでApple製品の良さは知っているのですが、コストパフォーマンスを考えると、開発マシンは Windows でもいいのではないか、と思っています。

MacはOSのアップデートや Linux ライクな操作により Web系エンジニアのみならず一般ユーザにも優しいつくりになっています。一方で Windows は Shell 周りが Linux ライクではない、Web系エンジニアは Mac という風潮や、技術記事も Mac / Linux ベースで記述されていることが多いです。

しかし、Windows Subsystem for Linux 2(WSL2) をきっかけに、この潮目は変わるかもしれません。 Appleシリコン(M1)による仮想環境が動かない問題も解決しつつあるので、Windows と Mac どちらを選ぶのかについては、本当に好みと予算、そして作りたいアプリケーションの問題になっていくのではないかなあと思います。

以下、私の備忘録とともに、Windows の開発環境の構築のために設定したほうがよいであろう一覧を公開いたします。

本記事については Windows を対象としておりますが、個々のアプリケーションについては Mac でも使えるものがあります。

# セットアップのはじめの一歩

## OS 関連

### Windows Update

新品の Windows は、OSのアップデートが行われおりません。手順を以下に記載します。

- windowsキーを押下し、「windows update」と入力、すると、「Windows Update の設定」が見つかりますので、それをクリックします
- 更新プログラムをチェックすると、利用可能な更新プログラムが見つかります
- 更新には15分ぐらいかかることもありますので、少し放っておきましょう。セキュリティパッチなども含まれているため、購入後の初期 Windows PC では対応が必須となります

### Windows 10 Pro へ OS をアップグレード

Microsoftストアより Windows 10 Pro を購入します。
BitLocker というドライブの暗号化ソフトを利用できるようになったり、リモートデスクトップ接続をつかえるようになります。
個人で使う分には、Pro にしないという選択肢もありうるでしょう。

## セキュリティ関連

セキュリティソフトを入れる。以上。
**Norton** や **カスペルスキー** といったソフトをインストールしますが、そこはIT資産管理部などの領域なので割愛します。
一般的には、セキュリティソフトは導入している（*ISMSをもとにした社内規定として通常は明記されている*）はずです。

## VPN クライアントソフト

いろんなものがあります。Cisco 関連のソフトを使うケースが多いんじゃないかなあと思います。GitHub のようなホスティングサービスを使っているようなケースだと、あんまり使うことはないかもしれません。

## 作業環境共有

### ドライブファイルストリーム

Google Drive を外付けディスクのようにマウントして使えます。わざわざブラウザ画面を経由する必要はないのが便利です。

### Microsoft One Drive

あまり共有ディスクのようには使えておりませんが、こちらも Google Drive と同じように使えます。

## 開発環境

### VirtualBox & Vagrant

自身のマシン内に Linux 環境を作成したいときに。LPIC の勉強で FHS(ファイルシステムの標準的な階層) を理解するために、よく Vagrant に CentOS を起動させて勉強しておりました。

- Oracle の公式DLページから取得 https://www.virtualbox.org/
- HashiCorp の公式DLページから取得 https://www.vagrantup.com/

### WSL2 & Docker for Windows

最近ホットな WSL2、Windows 環境内で Linux 環境が起動できるという優れものです。その Linux 環境を使いつつ、Docker も使うという技術の組み合わせとなります。

- 基本的には公式をもとに従えばOK https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
- Docker は https://www.docker.com/ から DL しよう！

### Git

どこかのリモートリポジトリへの push はなくとも、ローカルコミットだけを残すためだけに使うだけでもぜんぜん価値を感じるのが Git、もはや説明不要。ただし、リモートリポジトリがクライアント証明書が必要だったりする場合には、以下のような設定をすることがあります。ということが実際にあったので、備忘録。

- 証明書関係の設定が必要な場合は、対応が必要。ローカル単位でもいいとは思うのだけれど、あまり気にしていないのでグローバルに設定してあります。
 
```bash
$ git config --global http.sslCert /Users/marshmallow88/.ssl-cert/xxxxx.cert.pem　　
$ git config --global http.sslKey /Users/marshmallow88/.ssl-cert/xxxxx.key.pem　　
```

### Node.js

NVM(Node Version Manager)を使ってバージョン管理されることも多いですが、Node.js は後方互換性が高いこともあり、LTS の最新版を選んで Install しておきます。
https://nodejs.org/ja/

パッケージマネージャーについては、yarn を使っていきましょう。
https://classic.yarnpkg.com/ja/docs/install/#windows-stable

# おわりに

パソコンを買ったら有無もいわずに Windwos Update、忘れずに行きましょう。
prettierでgo fmt的なことをする


## インストール

```
npm install -D prettier
```

## 整形

```
prettier --write src/Orders.js
```

```
npx prettier --write src/*
```

## あ、
- package.jsonなどのコマンドを定義すれば再帰的に一気に整形とかもできるっぽいのだけどよくわからない
macOS Big SurでPythonをはじめてみる

+ はじめる人は、Unix系OSの基本的な知識はある
+ Pythonははじめてで、知識ゼロ
+ 環境はAppleのiMac(mid 2020、x86_64の最後のiMac??)、macOS Big Surにアップデート済み

2021/1/9更新：Python3というコマンドがインストールされていたのに気づいて、記述を変更追加。

---

#現状確認

iMacにはおそらくPythonはプリインストールされていると思うので、ターミナルを起動して現状確認してみる。

```
% which python
/usr/bin/python
```

Pythonのコマンドがあった。
どう使うのかな？

```
% man python

PYTHON(1)                                                                                                                                                    PYTHON(1)

NAME
       python - an interpreted, interactive, object-oriented programming language

SYNOPSIS
       python [ -B ] [ -d ] [ -E ] [ -h ] [ -i ] [ -m module-name ]
              [ -O ] [ -OO ] [ -R ] [ -Q argument ] [ -s ] [ -S ] [ -t ] [ -u ]
              [ -v ] [ -V ] [ -W argument ] [ -x ] [ -3 ] [ -?  ]
              [ -c command | script | - ] [ arguments ]
```

Vオプションで、バージョンが確認できるみたいだ。

```
% python -V
Python 2.7.16
```

インストールされているPythonは、2.7.16みたいだ。
binディレクトリも見てみる

```
% ls -l /usr/bin/python*
-rwxr-xr-x  1 root  wheel  137536  1  1  2020 /usr/bin/python3
```

python3というコマンドがあった。

```
% man python3   
No manual entry for python3
```

manはない。

```
% python3 -V
Python 3.8.2
```

バージョン3.8.2もあるみたい。
今の最新バージョンはいくつなのかな？
manでpython(1)の下の方を見ると、Webサイトがいくつか書いてある。

```
INTERNET RESOURCES
       Main website:  https://www.python.org/
```

Pythonのメイン・ウェブサイトを見てみると、2020/12/21にバージョン3.8.7がでているみたい。
Pythonのメイン・ウェブサイトを眺めていると、Pythonのバージョン2系とPythonバージョン3系には、大きな？違いがあるようだ。
2系から3系へのポーティング・ガイドもあるので、おそらくは言語仕様の非互換を伴うバージョンアップらしい。

現状確認ができたので、今日はここまで。
次は以下を満たす参考書を探そうかな。

+ Pythonのバージョン2系とバージョン3系の解説があること
+ プログラム経験はあるけど、Pythonは初心者という人向けであること
[Swift] PanModalでお手軽にモーダルを実装する

アプリを作るときに、モーダルシートを使うことは結構ありますよね。
そこで、簡単に実装できるようにライブラリを使っていきたいと思います。
今回は`PanModal`を使って実装していきます。

詳しく見たい方はこちらどうぞ↓
[PanModal] (https://github.com/slackhq/PanModal)

# ライブラリの導入
Podfileを作成して、以下の記述を行います

``` 
pod 'PanModal'
```

# 表示するものを作る
まずは、PanModalをインポートしましょう

```
import UIKit
import PanModal
```

モーダルに表示させるクラスは`PanModalPresentable`が適用されていなければいけません。
今回モーダルに表示するクラスを`ModalViewController`とします。

```ModalViewController.swift
class ModalViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBlue
    }
}
```

```ModalViewController.swift
extension ModalViewController: PanModalPresentable {
    var panScrollable: UIScrollView? {
        return nil
    }
    // モーダルの高さを画面下端から200にする(モーダルを表示した時のデフォルトの高さ)
    var shortFormHeight: PanModalHeight {
        return .contentHeight(200)
    }
    // モーダルの高さを画面上端から最大400に制限する
    // この値を設定しないとモーダルが画面の一番上までスワイプできてしまう
    var longFormHeight: PanModalHeight {
        return .maxHeightWithTopInset(400)
    }
    // モーダルの背景色
    var panModalBackgroundColor: UIColor {
        return UIColor.black.withAlphaComponent(0.2)
    }
    // 上にスワイプできるかどうか(デフォルトではtrue)
    var anchorModalToLongForm: Bool {
        return false
    }
    // モーダル上端の角に丸みをつけるかどうか
    var shouldRoundTopCorners: Bool {
        return true
    }
    // ホームボタンがないスマホのホームバーみたいなやつを表示するかどうか
    var showDragIndicator: Bool {
        return true
    }
    // 表示したモーダルをユーザーが操作できるかどうか(falseにすると操作できなくなる)
    var isUserInteractionEnabled: Bool {
        return false
    }
}
```

# 表示させるものを作る

```ViewController.swift
class ViewController: UIViewController {
    
    let button: UIButton = {
        let button = UIButton()
        button.setTitle("表示！", for: .normal)
        button.titleLabel?.font = .boldSystemFont(ofSize: 20)
        button.layer.cornerRadius = 20
        button.backgroundColor = .orange
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        button.center = view.center
        button.addTarget(self, action: #selector(presentModal(_:)), for: .touchUpInside)
        view.addSubview(button)
    }
    
    @objc func presentModal(_ sender: UIButton) {
        presentPanModal(ModalViewController())
    }
}
```

モーダルを表示するときは`presentPanModal`に、モーダル用に作った`ModalViewController`を入れて呼び出してあげなければいけません。
この例で言うとボタンにモーダルを表示する処理を加えて`presentPanModal`を呼び出しています。

# 表示結果
<img width="320" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/774264/f1c03c80-2df4-85cd-039e-2632e4d3c3dd.png> <img width="320" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/774264/28065ba3-c260-a234-e5c8-ec0f4a25e888.png>

# 最後に
Panといえばあるピアニストが思い浮かぶ私ですが、まあまあわかりやすく書けたかなと思います。
ライブラリは便利なのでみんな使っていこう！と言うことで、読んでくださりありがとうがございました。
初学者がLAMP構成について概要とメリットデメリットをまとめる

言語がたくさんある中で、LAMP構成が気になっている人に向けて、初学者が簡単にまとめてみた。

■LAMP構成とは？
Linux,Apache,Mysql,PHPからなる構成。
ただ、現在様々なソフト、言語が開発されていることから、上記の構成でないケースもある。

■各構成の概要
・L=linux
　⇨CUI(CharacterUserInterface)のOS。
　　要はwindowsのコマンドプロンプトやmacのターミナルがメイン操作となるもの。
　　例)Amazonlinux,CentOSmDevian,Ubunts
・A=Apache
　⇨Webサーバ用ミドルウェア
　　現在はApacheの他にnginxというソフトもある
・M=MySQL 
　⇨DBサーバ用ミドルウェア、データベースのこと。
・P=PHP,Python,Perl、サーバサイド言語

■メリット
・低コストのため、導入しやすい。
　⇨オープンソースソフトウェアなので、低コストが実現する。
・低コストのため、コストを気にする中小企業での普及率が高い。
・オープンソフトウェアなので、様々なオープンソフトウェアを扱える事から、
　カスタマイズ性がある。

■デメリット
・オープンソースソフトウェアなのでサポートが確立されているわけではない。
　有償ソフトの場合、定期的なメンテナンスやサポート等があるが、
　オープンソースソフトウェアの場合はそれがない。
HTML５版のDxLibでアプリをブラウザに合わせたい時の処理

#ブラウザ側の処理
ブラウザ側ではキャンバスの幅は”～vw”使えば勝手にやってくれる。

index.html

```
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
      @media screen and (orientation: landscape) {
     /* 横向きの場合のスタイル */
     canvas.emscripten { height:66vh;border: 0px none; background-color: black; }
      }
      @media screen and (orientation: portrait) {
        /* 縦向きの場合のスタイル */
        canvas.emscripten { width:100vw;border: 0px none; background-color: black; }
      }
```
縦向きの場合は『width:100vw;』に好きな幅を書き込む。
間違っても３：２の比率にしたいからといって『height:66vw;』などと書き込まないように。
GetMousePoint関数の取得座Y座標がずれますorz
横向きの場合はデスクトップの場合が多いので、上下にバナーを出すために高さを中心に合わせた方が良い。よって。『height:66vh;』

```
<canvas class="emscripten" id="canvas" width="640px" height="480px" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
```

ここのwidthとheightはDXライブラリの*SetGraphMode()*関数の引数で渡したサイズを書き込むこと。ここで幅と高さを指定しているお陰で*canvas.emscripten*のstyleが高さと幅のどちらかだけで済むようになっている。

#C++側の処理
EM_JS関数を使用する。
これは、この範囲はJavaScriptで書き込むというマクロであり、当たり前だがこの範囲内ではC＋＋の変数などの操作は出来ない。

```
// ウィンドウ幅を取得する関数（正確なマウス座標を取得するのに使用）
EM_JS(int, canvas_get_width, (), {
  return document.getElementById('canvas').clientWidth;
});

// キャンバスの高さを取得する関数（正確なマウス座標を取得するのに使用）
EM_JS(int, canvas_get_height, (), {
  return document.getElementById('canvas').clientHeight;
});

// 横向きかどうかを返す関数
EM_JS(int, landscape_flag, (), {
  if(document.body.clientWidth<document.body.clientHeight){return 0;}
  return 1;
});
```

たとえば、以下の記述はエラーになる。

```
int a=5;
EM_JS(int, canvas_get_width, (), {
  a=6;
  return a;
});
```

変数aはJavaScriptではないし、EM_JS内にCの変数を持ち込むことは出来ない。

#正確なマウス座標を取得する

付け焼刃ではあるが以下のようなメソッドで問題ない。

```
        GetMousePoint(&MouseX, &MouseY);
        #ifdef EMSCRIPTEN
        float Rate = 640.0f / ((float)canvas_get_width());
		if(landscape_flag()==1)
		{
			Rate = 480.0f / ((float)canvas_get_height());
		}
        MouseX = (int)(((float)MouseX)*Rate);
        MouseY = (int)(((float)MouseY)*Rate);

        #endif
        DrawCircle(MouseX, MouseY, 64, CircleColor);
```



![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/976967/757344df-d6e8-c52e-55db-1d2ecd90f232.jpeg)
赤丸の中心にマウスポインタが来ていれば成功。
（これ見てる人はこんな付け焼刃のプログラムじゃなくて、GetMousePoint関数をoverride、しよう！）

#最後に
WebアプリをC++で作れるのは最高！
次はFirebaseとの連携を試してみるつもりです。
Android版ではAndroidStudioを使ってFirestoreまで連携出来たので興味ある方がいればここに記事書きます。お気軽にコメントどうぞ。

#更新履歴
2020.12/29。縦横比の変更に対応しました。
#多謝
DxLibのHTML５版作成して下さったかめ様。
https://qiita.com/nokotan
【AWS】WordPressのサイトをSSL化した際のエラー対処

## はじめに
ドメインをお名前.comで取得して、AWSで作成したWordpressのサーバーでSSLを試みた際に
いくつかエラーに遭遇したので備忘録として残します。



## 環境
- Route53
- ACM( AWS Certificate Manager)
- ALB( Application Load Balancer)
- EC2( Elastic Compute Cloud)
- Apache
- WordPress

## エラー内容
####①リダイレクトループのエラー
![osozaki-engineer_work.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/04ee79bd-795e-0f41-d838-585fe90e1da3.png)
####②wordPress管理画面の権限エラー
![WordPress_›_アクセス権限エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/e930ccf9-ab2b-b14a-c58f-e496ca4c2f3b.png)


## 修正内容
#### Route53の設定変更
- AレコードにELBのDNS名を設定

####お名前.comの設定変更
- NSレコードをRoute53と同様のNSを設定

※digコマンドでDNS情報を確認

#### WordPress管理画面の一般設定変更
- WordPressアドレスとサイトアドレスを`http`から`https`のURLへ変更

####wp-config.phpの編集
以下を`require_once ABSPATH . 'wp-settings.php';`より上に追加

```
if (empty($_SERVER['HTTPS'])) {
    $_SERVER['HTTPS'] = 'on'; $_ENV['HTTPS'] = 'on';
}
```
##最後に
リダイレクト設定は行なっていなかったのに、リダイレクトループのエラーが出たので
最初Apache（.htaccess）を確認していきましたが、特にそちらには問題ありませんでした。
おそらくWordPressにプラグイン等をインストールしていたのでそちらの設定が影響していたと思われます。
環境によって対応方法は異なりますので参考程度に見ていただければ幸いです。
base64 画面に画像を表示させる

javaでDBに保存されている画像情報から画面（html）上に画像を表示させる方法をよく忘れるのでメモとして。

##データベース情報
![スクリーンショット 2020-12-27 203555.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496245/c6a4fcfd-e845-f8d2-fbd2-d85861016cfc.png)

ファイル名：サンプル画像
ファイルパス：画像の保存されているパス
上記のテーブルのような構成

##　ロジック
```java
public imageDto getImage(String id) throws Exception {
	     // DBから情報を取得する 	
         List<TProductImg> imgList = imgRepository.findByid(Long.parseLong(id));
		if (!ObjectUtils.isEmpty(imgList)) {
			List<String> dispImgPath = new ArrayList<>();
			for (TProductImg e : imgList) {
				StringBuffer data = new StringBuffer();
				data.append("data:image/jpeg;base64,");
				productDto.setFilename(e.getFilename());
		        //　取得した画像情報をエンコード化		
                String base64 = new String(Base64.encodeBase64(Files.readAllBytes(Paths.get(e.getFilepath()))), "ASCII");
				data.append(base64);
				dispImgPath.add(data.toString());
			}
			imageDto.setDispImgPath(dispImgPath);
		}
	}
```

最後にエンコード化されたdispImgPathを画面（html）で表示させる。
【Azure】アクセスできる全Azureサブスクリプションの全リソースを取得して一覧をCSVファイルに出力する

## アクセスできる全Azureサブスクリプションの全リソースを取得して一覧をCSVファイルに出力する

Microsoft Azure のリソース一覧が欲しくなることがあるが、Azure Portal には現在リソース一覧を出力する機能がない。（正確には、Azure Resource Explorer を使えば、JSON形式で取得することはできるかもしれない。）
CSV出力する Azure PowerShell コマンドを作ってくださっていた先人がいらっしゃったので、ありがたく拝借する。

**元ネタ**
https://gist.github.com/mahiya/42e39f451fb3a8cd683a

**上記はAzureRMモジュール版のコマンドであったため、Azモジュール版に対応させた。**
https://gist.github.com/yukit7s/b843298fec3c0b06f730b4df384cce71


**動作確認済み環境**
PowerShell Version: 3.2.0
Az module Version:  5.1.18362.1171

```PowerShell:PowerShellとAzモジュールバージョン確認.ps1
$PSVersionTable
Get-InstalledModule Az
```

## 参考
* Azure PowerShell documentation  
https://docs.microsoft.com/ja-jp/powershell/azure/?view=azps-5.2.0
USB のブロックデバイス (USB メモリや HDD)を列挙する方法


# USB のブロックデバイス (USB メモリや HDD)を列挙する方法

[USB のブロックデバイス (USB メモリや HDD)を列挙する方法 (Part2)](https://qiita.com/m-tmatma/items/4769db3d2a3878e02f02) の方法もあります。

## 方法

```
ls /sys/block/ -1 | \
  xargs -I{} echo /sys/block/{} | \
  xargs readlink | \
  grep usb | sed -e 's!.*/\([a-z]\+\)!\1!'
```

## 解説

### ブロックデバイスの列挙

* `/sys/block/` 以下を列挙すると、linux 上のブロックデバイスを列挙できる。
* 各項目はシンボリックリンクになっている。
* usb のデバイスの場合はシンボリックリンクのパスに `usb` という文字列が含まれる。

```
ls /sys/block/ -l
合計 0
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop0 -> ../devices/virtual/block/loop0
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop1 -> ../devices/virtual/block/loop1
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop10 -> ../devices/virtual/block/loop10
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop2 -> ../devices/virtual/block/loop2
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop3 -> ../devices/virtual/block/loop3
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop4 -> ../devices/virtual/block/loop4
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop5 -> ../devices/virtual/block/loop5
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop6 -> ../devices/virtual/block/loop6
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop7 -> ../devices/virtual/block/loop7
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop8 -> ../devices/virtual/block/loop8
lrwxrwxrwx 1 root root 0 12月 27 19:08 loop9 -> ../devices/virtual/block/loop9
lrwxrwxrwx 1 root root 0 12月 27 19:08 sda -> ../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 12月 27 19:19 sdb -> ../devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb
lrwxrwxrwx 1 root root 0 12月 27 19:08 sr0 -> ../devices/pci0000:00/0000:00:17.0/ata2/host1/target1:0:0/1:0:0:0/block/sr0
t
```

### USB のブロックデバイスを列挙する

* `ls /sys/block/ -1` の出力を `xargs` に渡して、更に `readlink` でシンボリックリンクの実体を列挙する

```
$ ls /sys/block/ -1 | xargs -I{} echo /sys/block/{} | xargs readlink | grep usb
../devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host3/target3:0:0/3:0:0:0/block/sdb
```

### USB のブロックデバイスの部分を抽出する

`sed -e 's!.*/\([a-z]\+\)!\1!'` のような正規表現を使うことで `...block/sdb` の最後の `sdb` の部分を抽出する。

最終的に以下のコマンドでデバイスファイルの部分 (sdb など) を抽出できる。

```
ls /sys/block/ -1 | \
  xargs -I{} echo /sys/block/{} | \
  xargs readlink | \
  grep usb | sed -e 's!.*/\([a-z]\+\)!\1!'
```

以下のようなコマンドにすると `/dev/sdb` という形式で出力できる。

```
ls /sys/block/ -1 | \
  xargs -I{} echo /sys/block/{} | \
  xargs readlink | \
  grep usb | sed -e 's!.*/\([a-z]\+\)!\1!' | \
  xargs -I{} echo /dev/{}
```

## 参考情報

### ブロックデバイスのサイズ

以下のコマンドで　`/dev/sdb`　のブロックデバイスのセクタサイズを取得できる。

```
$ cat /sys/block/sdb/size 
15646720
```

`/sys/block/sdb/size` の値に `512` を掛けることでブロックデバイス全体のサイズをバイト単位で取得できる。
クッキーとセッションの仕組み

## 概要
クッキーとセッションについて学習したので自分用メモとしてアウトプットしていきます。

## はじめに

ショッピングサイトで**ログイン情報を入力しなくてもログイン**できたり、**(自分が削除しない限り)カートに入れた商品がしばらくカートに入ったまま**になったりしますよね。これは、**セッション**と**クッキー**の仕組みがあるため実現できています。

## セッション(session)

- Webサービスに情報を一時的に保持してくれる仕組み
- アクセスの開始から終了までの一連の通信
- Railsでは`session`というオブジェクトにハッシュのような形で格納される

[こちらの記事がイメージしやすく参考になりました！](https://wa3.i-3-i.info/word1791.html)
## クッキー(cookie)

- **ブラウザが持っている**データを保存できる領域
- セッション情報(ID)を保存する場所
- 有効期限がある

[こちらの記事がイメージしやすく参考になりました！](https://wa3.i-3-i.info/word1725.html)

## CookieStore

- **Rails**でセッションを利用する際のデフォルトの保存先
- セッション情報は暗号化してブラウザのCookieに保存される
- ハッシュ形式でセッションを保存する

## まとめ

 - セッションとはアクセスのはじめから終わりまでの一連の通信
 - クッキーとはセッションなどユーザーのデータ(ID)を保存するブラウザの領域
 - SessionとはRailsでセッションを利用する際のオブジェクト
 - CookieStoreとはRailsでセッションを利用する際のデフォルトの保存先

## 参考文献

- [Rails セキュリティガイド](https://railsguides.jp/security.html)
- [初心者でもわかる『cookie（クッキー）』講座 危険性やスマホでの設定方法もズバリ解説](https://time-space.kddi.com/ict-keywords/20180726/2392)
- [「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典(クッキー)](https://wa3.i-3-i.info/word1725.html)
- [「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典(セッション)](https://wa3.i-3-i.info/word1791.html)
- [【PHP超入門】Cookieとセッションについて](https://qiita.com/7968/items/ce03feb17c8eaa6e4672)
- [Cookieとセッションをちゃんと理解する](https://qiita.com/hththt/items/07136ad74127999df271)
- [セッションとクッキーの違い](http://ohs30359.hatenablog.com/entry/2015/09/04/235027)
useCallback 学習メモ

# `useCallback()`を利用するメリット
通常、Reactコンポーネント内で宣言したコールバック関数はrender毎に生成される

*`useCallback()`を使うと、、、*
コールバック関数の再生成を抑止（不変値化）
クラスコンポーネントの`bind()`と似た役割

# `useCallback()`の使い方
文法

```javascript
useCallback(() => {}, [hoge]) // (コールバック関数, deps(再描画の条件))
```

子コンポーネントにpropsで関数を渡す場合に使用する

```javascript
const handleClose = useCallback(() => {
  setOpen(false)
}, [])
// 中略
<FormDialog
  open={open}
  handleClose={handleClose}
/>
```
`setOpen`が`useState`由来の関数の場合は、Reactで同一性が保証されているため`deps`に含めなくても問題ない
https://ja.reactjs.org/docs/hooks-reference.html#usestate


クラスコンポーネントとの比較

```javascript
this.handleClose = this.handleClose.bind(this)
// 中略
handleClose = () => {
  this.setState({open: false})
}
```
google recruit

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# google recruit


## 課題

自然対数eの値で連続10桁の数のうち、最初の素数を出力する以下をexp.txtとして入力として使用する

```lisp
2.71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
81323286279434907632338298807531952510190
```


## 解答

コード

```lisp
def prime?(num)
 if (number < 2) return false;
 elsif (number == 2  && num == 3) return true;
 elsif (number % 2 == 0) return false;
 end

sqrt_num = Math.sqrt(num);
3.step(sqrt_num,2) do |i|
 if num % i == 0
  return false
 end
end

 return true
end

def read_exp
 exp = gets.to_s.chomp
end

exp = read_exp()
for i in 0..(exp.length - 10)
 num = exp[i..(i+9)].to_i
 prime = prime?(num)
 if prime 
  puts(num)
  break
 end
end
```


## 結果

```lisp
7427466391
```



------
 - **source** ~/grad_members_20f/members/wjswnsrud12/gool.org
【初心者】PHPの論理演算子について

#論理演算子とは？
論理演算子と言われてもピンとこないかもしれない。
ただ、それが何か言われると知っているし、使っていると思う。
`AND`や`OR`のこと。
例があると非常に分かりやすいが、これらが論理演算子ということを覚えておきたい。
###実際に使ってみる
```php
//ANDを使する
$n = 40;
if($n >= 30 && $n <= 50) {
  echo($n)."は30以上かつ50以下です";
}else {
  echo($n)."は30以上かつ50以下ではありません";
}
//出力結果
40は30以上かつ50以下です

//ORを使用する
$n = 40;
if($n % 2 == 1 || $n >= 30) {
  echo($n)."は30以上もしくは奇数の数値です";
}else {
  echo($n)."は30より小さい偶数です";
}
//出力結果
40は30以上もしくは奇数の数値です
```
`AND`は`&&`、`OR`は`||`と記述することが一般的？なのだろうか。

```php
$n = 20;
if($n >= 30 AND $n <= 50) {
  echo($n)."は30以上かつ50以下です";
}else {
  echo($n)."は30以上かつ50以下ではありません";
}
//出力結果
40は30以上かつ50以下です
```
このように`AND`と記述しても大丈夫だった。`and`も試してみたところ出力できた。
`OR`も同様に`or`でも出力はできていた。

やはり根本的な理解が私には欠けているのかもしれない。
もしくはこのような知識よりも何かアプリケーションを作成できる知識を重点的に学ぶべきなのか…
【Railsアプリ】販売手数料をJavaScriptで計算しようとしたら出てくる「NaN」を解決できたので、備忘録として残しておきます。

## ミス内容
![スクリーンショット 2020-12-27 19.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933481/197f03a1-2d7b-b9d3-43cc-42663dbdf1eb.png)
入力された金額の販売手数料（10%）を、JavaScriptを使って計算しようという実装を行っていた時に突如現れた「NaN」。
最初のコードは以下の通り。

```javascript
function calc (){
  // id="item-priceの要素を取得。
  const itemPrice = document.getElementById("item-price");
  // 値が入力された時にイベントを発火。
  itemPrice.addEventListener('input', function(){
    const Tax = 0.1;
    const tax_fee = itemPrice * Tax;
    const profit = itemPrice - tax_fee;
    const taxArea = document.getElementById("add-tax-price");
    const profitArea = document.getElementById("profit");
    taxArea.innerHTML = tax_fee;
    profitArea.innerHTML = profit;
  })
}

window.addEventListener('load', calc)
```

## 原因
NaN = Not-a-Number（数字ではない）
計算しようとしている値が数字になっていないよ、と伝えているようです。

上記のコードだと、
getElementByIdで取得した「要素」と、
Tax=0.1という「数値」をかけ算しようとしている。

つまり、要素の値を取得した上で、
「数値」と「数値」をかけ算しなければならないのです＞＜
## 解決法
itemPrice.valueで、要素の「値（＝数値）」を取得しましょう。

```javascript
function calc (){
  // id="item-priceの要素を取得。
  const itemPrice = document.getElementById("item-price");
  // 値が入力された時にイベントを発火。
  itemPrice.addEventListener('input', function(){
    // 下記を追記して、要素の値を取得。
    const itemPriceValue = itemPrice.value
    const Tax = 0.1;
    const tax_fee = itemPriceValue * Tax;
    const profit = itemPriceValue - tax_fee;
    const taxArea = document.getElementById("add-tax-price");
    const profitArea = document.getElementById("profit");
    taxArea.innerHTML = tax_fee;
    profitArea.innerHTML = profit;
  })
}

window.addEventListener('load', calc)
```

これで「NaN」が消え、計算機能を実装することができました！

![スクリーンショット 2020-12-27 20.21.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933481/aa8a59e0-c024-bb8a-b5da-44d10396fc58.png)

## おわりに
最初、「NaN」ってナンだよ、、、と思いましたが、要素と数値はかけ算できないという初歩的なミスでした。

このミスを解説してくれたメンターさんが仰った**『JavaScriptはHTMLをほじくりまわす言語だ』**の一言がなぜか胸に刺さりました＾＾

プログラミングは面白い。もっと使いこなしたいです。
[エラー]IOPub message rate exceeded. The notebook server will temporarily stop sending output to the client in order to avoid crashing it.

## エラー
    IOPub message rate exceeded.
    The notebook server will temporarily stop sending output
    to the client in order to avoid crashing it.
    To change this limit, set the config variable
    `--NotebookApp.iopub_msg_rate_limit`.


# 原因

iopun_data_rate_limit の値がとても小さく設定されているため。


# 解決策

設定されている値を変更する

    jupyter notebook --NotebookApp.iopub_data_rate_limit=10000000000



# 追記

最新版では修正されている。


# 参考

https://github.com/jupyter/notebook/issues/2287
【JavaScript】 JSONをオブジェクトに変換　parseメソッド

# JSON.parseメソッドとは?
JSON形式で書かれた文字列をJavaScriptのJSONオブジェクトに変換するメソッドです。
変換した場合は、JavaScriptの中でJSONのデータを自由に扱えるようになります。

# 書き方

```
変数 = JSON.parse(変換するJSON [, 関数])
```

# 実装例

```javascript
const json = '{"firstName":"太郎","lastName":"山田"}';

const obj = JSON.parse(json); // =>JSONをJavaScriptのオブジェクトに変換

console.log(obj.firstName); // =>太郎

console.log(obj.lastName); //　=>山田

```

# parseメソッドの引数に関数を使用する
以下はキーがfirstNameのとき、値をたろうで返し、それ以外はそのまま返します。
指定したキー(firstName)の値のみが変更されています。

```javascript
const json = '{"firstName":"太郎","lastName":"山田"}';

const a = JSON.parse(json,(key,value)=>{
	if (key=="firstName") {
		return "たろう" ;
	}
	return value ;
} ) ;

console.log(a); //　=>{firstName: "たろう", lastName: "山田"}

```

#参照
[JavaScript | MDN JSON.parse()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)
interactive shell, login shellとは

[2.1: Types of shell: interactive and login shells - A User's Guide to the Z-Shell](http://zsh.sourceforge.net/Guide/zshguide02.html#l7)を参照して記述

## interactive shell
* まずshellとは「コマンドのリストを受け取り、ただそれを実行するもの」である。
* interactive shellとは、その言葉通り「対話的」なshellであり、ユーザーが何かコマンドを入力をし、結果を待ち、結果が返ってきた後にまた何か入力する、というやりとりが出来るものをいう。
* 一方fileを読み込んで処理する場合は non-interactiveである。またこのとき実行するfileをscriptと呼ぶ。
  *  interactive shellから `zsh filename` のようにコマンド入力して実行する場合、interactive shell上から、non-interactiveなshellが走っている。 


## login shell
* これも言葉通り password入力などでログインして使えるshellのこと。
* またlogin shellを起動するもう一つの方法として、`-l` optionを使うものがある。たとえば `zsh filename` とするだけなら、これはlogin shellではないが、 `zsh -l filename` とすれば、login shellでscriptを実行可能。

## interactive shell, login shellの判別方法

* 以下をzshにて実行すれば、login shellのときは `yes`、そうでないときは `no` と出力される。

``` zsh
if [[ -o login ]]; then
  print yes
else
  print no
fi
```

* interactive shellかどうかは、対話可能であるかで判断できる。
* またlogin shell同様に以下を実行すれば、interactive shellのときは `yes`、そうでないときは `no` が出力される。

``` zsh
if [[ -o interactive ]]; then
  print yes
else
  print no
fi
```

---

## おまけ - 調査方法
* ***が分からない、そういう時はまずmanualやdocumentを見るべきなはず。
* ということで `man zsh` を見た。

  * なお以下のversionを利用

``` bash
$ zsh --version
zsh 5.4.2 (x86_64-ubuntu-linux-gnu)
```

* manualを斜め読みすると、どうやら http://zsh.sourceforge.net/Guide/ にユーザーガイドがあるとわかる。よってユーザーガイドを詳しく読んだ
  * 正直manualが読みやすいとは思っていない。
【Ruby on Rails】deviseを用いたユーザー認証機能の作成

##アプリケーションに"devise"を読み込ませる

```rb:Gemfile
:
gem 'devise' #追加
```

```terminal:terminal
$ bundle install
```
##deviseコマンドでモデル、ビュー、コントローラを作成

```terminal:terminal
$ rails g devise:install
$ rails g devise User name:string #モデルの作成
$ rails db:migrate
$ rails g devise:views users #ビューの作成
$ rails g devise:controllers users #コントローラの作成
```
`rails g devise "model名" `で作成したモデルには初期値ではnameカラムが存在しない為、上記のようにカラムを同時に作成するか、migrationファイルに記述してテーブルに反映させる。

####・作成されたモデル

```rb:app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
end
```
####デフォルトの機能
* database_authenticatable(パスワードの正確性を検証）
* registerable(ユーザー登録や編集、削除）
* recoverable(パスワードをリセット)
* rememberable(ログイン情報を保存)
* validatable(emailのフォーマットなどのバリデーション)




##ルーティングの変更

```rb:config/routes.rb
...編集
devise_for :users # devise機能の使用の際にURLにusersを含むことの宣言
↓
devise_for :users, controllers: { 
  sessions: 'users/sessions', #usersディレクトリ下のsessionsコントローラを使用
  registrations: 'users/registrations' #usersディレクトリ下のregistrationsコントローラを使用
}
```
上記の`controllers: {}`指定によりルーティング設定が以下のように変更される

```terminal:terminal
devise/sessions#create
↓
users/sessions#create
```

##ビューページの編集

新規登録画面に名前の入力フォームを追加

```erb:app/views/users/registrations/new.html.erb
... +の部分を追加
+ <div class="field">　
+  <%= f.label :name %><br />
+  <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
+ </div>

<div class="field">
  <%= f.label :email %><br />
  <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
:
```
ログイン画面の入力フォームを`email`から`name`に変更
**これによりemailでのログイン認証へと変更させる**

```erb:app/views/users/sessions/new.html.erb
...編集
:
 <div class="field">
   <%= f.label :email %><br />
   <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
 </div>
↓
 <div class="field">
   <%= f.label :name %><br />
   <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
 </div>
:
```
##コントローラの編集

```rb:app/controllers/application_controller.rb
...追加
before_action :configure_permitted_parameters,if: :devise_controller? 

protected

def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up,keys:[:name])
end
```
devise利用の機能（ユーザ登録、ログイン認証など）が使われる場合、その前に`configure_permitted_parameters`が実行

`devise_parameter_sanitizer.permit(:sign_up,keys[:name])`
= ユーザ登録（sign_up）の際のユーザ名（name）のデータ操作を許可

`Strong Parameters`と同様の機能
**・private = 自分のコントローラ内のみで参照**
**・protected = 呼び出された他のコントローラからも参照可能**

##ログアウト機能の実装

```erb:app/views/layouts/application.html.erb

...+部分の追加
  <body>
+   <% if user_signed_in? %>
+     <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
+   <% else %>
+     <%= link_to "新規登録", new_user_registration_path %>
+     <%= link_to "ログイン", new_user_session_path %>
+   <% end %>
:
```

以上

**記載内容に間違い等ございましたらご指摘頂けると幸いです。
ご連絡お待ちしております。**