OmniAICreator/Qiita-1.07M huggingface dataset:
愚者のマネジメント

## 愚者は経験に学び、賢者は歴史に学ぶ

どうも愚者です。

掲題は、ビスマルク氏が「人の振り見て我が振り直せ」を最高にカッコよく言った歴史上の名言ですね。
一人の人間に経験できることには限りがあるし、痛みも伴わないし歴史から学ぶのはスマートにも思えます。

ということで賢者と愚者を題材にマネジメントについて雑多に書きたいと思います。

## 賢者チェック

以下の様な追加開発案件があったとします。

**『A機能に類似した機能を持つB機能を作ってください』**

あなたは、どの様に取り組みますか？

a. A機能のソースをコピペ
b. A機能のソースを理解する
c. A機能に関連する機能のソースを理解する
d. ソース全体を理解する
e. 使ってるライブラリも一通り理解する
f. 変更部分仕様書を読む/理解する
g. 仕様書全体を読む/理解する

こうして見ると、『A機能のソースをコピペしてビルドを通してエラーが出なくなるようにして、言われた機能を追加する』のは愚者の行為であり、何も学んでいないという事が分かります。

ITの仕事には納期があるので当然最短ルートを選択するのは理解に苦しくないですが、長いIT人生を見た時に本当に最短ルートか一考してみるのもおもしろいかもしれません。


## 人の振り見るだけで我が振り直せるの？

何かを見て理解するためには **基本的な知識量と知覚力** が必要です。
また、それを自分で使いこなしてアウトプットするためには **反復練習(=経験)** が必要です。

先の例では、移植元ソースを自分で書けるだけのスキルがない場合、単にコピペするだけではなく、写経したり、似た様な機能を考えてA機能を参考にしながら１から作るなどの反復演習をしないと自分でアウトプットできるようにならないと思います。

写経や反復演習は「経験」に属すると思いますが、これは愚直にやるしかないです。
愚直に続けて、基本的な知識量と知覚力が上がってくれば、ショートカットできるようになり賢者に近づけます。


## 対人スキルは歴史から習得できない

部下のマネジメントには1on1が有効、などの手法は書籍から **知識として** 学ぶことはできる。
1on1で何をしゃべったらいいの、というのも **知識として** 学ぶことはできるだろう。
しかし、1on1のゴールは、相手との相互理解であったり、自分や会社の希望と非面接者の希望をすり合わせることだったりするため、ひたすら経験から学ぶ分野と感じる。

自分の発言に対して相手が何を感じるのか、ポジティブ/ネガティブな反応をするのかなどを、多く知っていて相手によって使い分けられることが望ましい。

日常のコミュニケーションでは、場の空気を悪くしてまで自分の意見を通さなければいけないケースは少ないと思うが、仕事でのコミュニケーションは利害関係が異なる人々との意見調整が基本であるため、いわゆるコミュ力と仕事のコミュ力は全く異なる物と考えた方が分かりやすいのではないだろうか。

例えば、顧客は低予算で思ったとおりの物を作って欲しいし、開発側はより具体的な指示がなければ物は作れないし、プログラムを覚えたらより高い給料が欲しい。これらは全部、当然の要求だ。

スタッフに悪い賃金を提示したらいなくなるかもしれないし、交換価値に変わる体験価値を提示したら同じ賃金でも喜んで働くかもしれない。
この時、どの様に話しをするかを決定する根拠は **経験** 以外には思いつかない。


## まとめ

賢者・愚者の話をしました。
学ぶことは、学ぶことの必要性に気づきさえすれば自分の力でできます。
経験は、**丁度よい機会**がないと自分の力だけではできません。

マネージャのやるべきことは、**体験をつくる** ことだと考えています。

丸投げするのではなく、チームのメンバーには適切なタスクを切り出し正しいフィードバックを与える。正しいコメントを口に出して伝えることで、本人が気づいてない物事を **知覚させて体験の価値を高める**。

自分で気づいた事、学んだこと、体験したことは、自分で一歩を踏み出すための血肉になります。

わたし自身まだまだ学びながら試行錯誤をしておりますが、皆様の毎日の仕事の質を高める一助となれていれば幸いです。
Rails link_toメソッドで開いたリンクを新しいタブで開くようにしたい。

通常、link_toメソッドで設定したリンクは普通にそのタブで開かれます。

ユーザー目線に立った時に、それが自分のサイト内であれば、問題ないと思いますが、特に外部リンクに行く時は新しいタブの方が便利だなぁと感じます。

ということで、link_toを使って新しいタブで開くリンクの設定方法

```ruby
<%= link_to "#{archive.archiveurl}",:onclick=>"window.open(this.href,'#{archive.archiveurl}', 'height=400, width=800');return false;" do %>
<% end %>
```

こんな感じになりました。
私の場合はdo~endで結んでいますが、単純にリンクを設置するということであれば、特に必要はありません。
問題はonclick以降。

これをすることで、クリックされた時の挙動が選択できます。

参考文献
https://sakuramochi702.hatenablog.com/entry/2013/05/28/225612
よく使うDockerコマンド

#背景
dockerを使う機会が増えたので、特にdocker imageを作り直すときによく使うコマンドをメモしていきます。

#コマンド一覧

- `docker-compose down`
    - コンテナを停止し、削除する
- Docker desktopで、不要なimageとvolumeを削除する
    - コマンドでやっても良いか、GUIの方が簡単
- `docker system df -v`
    - image/container/volume/cacheの使用量を確認する
- `docker system prune`
    - container/network/image/cacheを削除する
- `docker system df -v`
    - 削除後の状態を確認する
- `docker-compose build`
    - コンテナをビルドする
- `docker-compose run web bundle exec rake db:create`
    - DBを作成する
- `docker-compose run web bundle exec rake db:migrate`
    - DBにマイグレーションする
- `docker-compose run web bundle exec rake db:seed`
    - DBへデータを移植する
- `docker-compose up`
    - コンテナを起動する
- `docker-compose stop`
    - コンテナを停止する
- `$ docker volume rm $(docker volume ls -qf dangling=true)`
    - 不要な volume を削除する
【Mac難民】WSL2でのreactの環境構築

#はじめに
ポートフォリオサイトを作りたいと思い、どうせ作るなら流行のreactで作りたいと考える。
ただ環境構築関係のサイト、Udemy、メンターなどもだいたいmac前提が多い。
Macは持っていなかったし、メインのデスクトップPCがwindowsなのと、外に出ないのでラップトップである必要性がない。
あと**高い**。
よってwsl2での最小限のreact環境構築をしてみた。
#環境
windows10Home 
wsl2 Ubuntu 20.04LTS

**目標環境**
nodebrew 
nodejs 14.17.0
yarn 1.22.5
create-react-app コマンドのインストール

#環境構築
こちらのサイト[[1]]を参考にした。
nodejs公式[[2]]2021年6月12日現在ではv14.17.0がLTS版における最新のようなのでそこだけ変更。
nodejsのダウンロードはうまくいったが、yarnのインストールがうまくいかないので別のサイト[[3]]を参考にして進めた。
ただ、create-react-appコマンドのパスが通っていない。
記事内にも対策が書いてあったがそれをしてもパスが通っていない。
findコマンドでパスを検索。

```
cd /
find ./ -name create-react-app
```
パスが見つかったのでそれを.bashrcに追加してsourceコマンドで更新。
具体的にはexport PATH=$PATH:'/home/ユーザー名/.yarn/bin' を追加。
whichコマンドでパスを確認。

```
which create-react-app
```
出力されたらパスが通っています。

あとは[[1]]の通りcreate-react-appコマンドを実行後cdしてからyarn startしたら実行できました。

#おわりに
思ったより簡単でしたが、ある程度linuxの知識がないとやはり環境構築は難しいですね。
dockerも使えるようになったようですし、wsl2でいいのではと思わなくもない。
まあ情報があまりになさすぎるので、お金に余裕がある人はMac買った方がいいとは思います。
それではまた。

#参考文献
[1]:https://www.illumination27.com/105/
[[1]]:WSLでReactを使ってHello Worldしてみた
[2]:https://nodejs.org/ja/download/
[[2]]:nodejs公式
[3]:https://yanor.net/wiki/?Node.js/yarn/yarn%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB+-+Ubuntu
[[3]]:yarnのインストール - Ubuntu
【RxJS】mergeMapはmap+subscribe

#mergeMapはmap+subscribeと考えるとわかりやすい
以下の例ではストリームの中にストリームを作成しているため、中の値を取り出すのに２回subscribeが必要となってしまっています。


```typescript
import { of, from } from 'rxjs'; 
import { map, delay } from 'rxjs/operators';

const getData = (param) => {
  return of(`retrieved new data with param ${param}`).pipe(
    delay(1000)
  )
}

from([1,2,3,4]).pipe(
  map(param => getData(param))
).subscribe(val => val.subscribe(data => console.log(data)));
```

そこで、mergeMapの出番です。

```typescript
import { of, from } from 'rxjs'; 
import { map, delay } from 'rxjs/operators';

const getData = (param) => {
  return of(`retrieved new data with param ${param}`).pipe(
    delay(1000)
  )
}
from([1,2,3,4]).pipe(
  mergeMap(param => getData(param))
).subscribe(val => console.log(val));
```
mergeMapがmapを実行した後に内側のストリームと外側のストリームをマージしてくれます。
map+subscribeと考えると分かりやすいと思います。

以下の記事を参考にさせていただきました。

https://luukgruijs.medium.com/understanding-rxjs-map-mergemap-switchmap-and-concatmap-833fc1fb09ff#:~:text=MergeMap%20essentially%20is%20a%20combination,into%20the%20'outer'%20Observable.
Qt C++ 3Dグラフ表示 QtDataVisualization .objファイル

#実行サンプル
3D-CGデータ(サーフェスモデル）である
.objファイルを読み込み、表示する。

下図では、.objファイル1(紫色) と　.objファイル2(緑色、半透明表示）
を重ねている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/db1f6483-ca75-442b-5d3c-34dbac27502f.png)


※マウス操作でズームのみ可能。
※視点移動(=グラフ回転）はスライダーでする。（マウス操作はできない。）
※今時点のソースコードでは、スライダーを動かすと先にズームしていたのものが
　初期の位置に戻ってしまう。
　これから調べて、方法がわかれば修正するが
　それまでは、まず回転をスライダーでする→ズームするの順番で見たい位置を見る操作になる。

#実行環境
windows10
Qt5.9
VisualStudio2019

#実行手順
通常通り　QtCreatorでコード作成して、実行する。


#ソースコード
https://github.com/sakurataiko1/Qt_Cplus_DataVisualization/tree/main/QtDataVisual_my_3Dobj

#コード作成手順ポイント
■　Qt project 作成は通常通り (Qt Widget)

■　.proファイルに下記記述が必要

```
QT       += core gui datavisualization qml quick
```

■ MainWindow.cpp / h ファイルどちらも下記記述を記述する。
※記述する位置は　
・\#includeの後　
・MainWindow::MainWindow(QWidget *parent)の手前

```
using namespace QtDataVisualization;
```

<!--
■　Mainwindow.h ファイルに下記記述が必要

```
#include <QtDataVisualization/q3dscatter.h>
```

■　Mainwindow.cpp ファイルに下記記述が必要

```
#include <QtDataVisualization/QScatter3DSeries>
```

■ MainWindow.cpp  散布図グラフ表示のため下記記述が必要だった。

```
    //初期設定 
    QScatter3DSeries *series = new QScatter3DSeries;
    series->setItemLabelFormat(QStringLiteral("@xLabel, @yLabel, @zLabel"));
    series->setMesh(QAbstract3DSeries::MeshCube);
    series->setItemSize(0.15f);
    m_graph->addSeries(series);
```

```
    // Add data from the QVector to datamodel 行、データを生成する
    QScatterDataArray *dataArray = new QScatterDataArray;
    dataArray->resize(itemList.count());
    QScatterDataItem *ptrToDataArray = &dataArray->first();
    for (int i = 0; i < itemList.count(); i++) {
        ptrToDataArray->setPosition(itemList.at(i));
        ptrToDataArray++;
    }

    m_graph->seriesList().at(0)->dataProxy()->resetArray(dataArray);
```
-->

#参考資料
参考：
■ 3D objファイルの表示
  →Qt公式サンプルcustomitems　
  　https://doc.qt.io/archives/qt-5.9/qtdatavisualization-customitems-example.htm

■　3D　立方体の自動回転表示　（マウス操作：ズームあり、視点移動なし）
https://github.com/fengfanchen/Qt/tree/master/3D%20move%20rotation

■　3D　objファイルから散布図でデータ表示（マウス操作：ズームあり、視点移動なし）
https://blog.csdn.net/qq78442761/article/details/103678544
https://github.com/fengfanchen/Qt/tree/master/3DScatter%20Demo

■　参考：Qt付属のExampleコード
　・サンプル　customplot　（マウス操作：ズームあり、視点移動なし？）
　・サンプル　bars (視点移動=グラフ回転）
　　↑スライダーで視点移動（マウス操作ではない。）

#今後の参考予定
・マウス操作での視点移動のサンプルは、見つかっていない。
　これから調べる。
CML2を使いこなす。（その７：パケットキャプチャ）

# はじめに
今回は構築したネットワークでパケットキャプチャを行ってみます。

尚、前回`CML2`のアップグレードを行ったため、今回から**2.2.1**での作業となります。

- 【前】[CML2を使いこなす。（その６：CML2のアップグレード）](https://qiita.com/sakai00kou/items/88fb3cdc661431efd131)
- 【次】[CML2を使いこなす。（その８：WAN Emulator）](https://qiita.com/sakai00kou/items/04c043b3e9a1189efd90)

# CML2でのパケットキャプチャ
以前のバージョンでは`Dashboard`上でしかパケットキャプチャの結果を見れなかったり不便なイメージがありましたが、**2.1**で`PCAP`形式のファイルをダウンロードできるようになり、大分使いやすくなりました。

ネットワークを設計・調査するうえで必須となる機能なので、使いこなせるようしっかり覚えていきます。

# パケットキャプチャの実行方法
実行方法は簡単で、`Dashboard`からパケットキャプチャを行いたい経路のリンクをクリックして、`PACKET CAPTURE`タブから実行することで以下のようにパケットキャプチャの情報を確認することができます。

![capture_08062021_080650.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/e9962779-9cc8-cddb-04f8-6988ba56560c.jpeg)

`PACKET CAPTURE`タブには以下のようなボタンが並んでおり、左から**パケットキャプチャ実行/停止**、**表示のクリア**、**パケットキャプチャのダウンロード**、**キャプチャ設定**となっております。

![capture_08062021_080734.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/e06e057b-deaa-2e8a-7544-8344c3e9c886.jpeg)

# キャプチャ設定
上図の歯車ボタンをクリックすることでパケットキャプチャ実行時に適用するフィルタの設定や取得するパケット数、時間などを設定できます。

![capture_08062021_081435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/6100be76-66e1-49c5-486f-d08f68cbe781.jpeg)

## Max Packets
パケットキャプチャ実行時に指定した数のパケットまでキャプチャを取得します。

デフォルトでは50パケットまで取得するようになっており、50パケット取得したら自動的にパケットキャプチャが停止するようになっているため、しばらくキャプチャを取り続けたい場合は調整するようにしましょう。

また、`Max Packets`か次の`Max Time`のどちらかは設定を行う必要があるようなのでどちらかは設定するようにします。

## Max Time
パケットキャプチャ実行時に指定した秒数までキャプチャを取得します。

デフォルトでは無制限となっておりますが、`Max Time`を設定した場合は、`Max Packets`を無制限にすることも可能です。

## BPF Templates、BPF
パケットキャプチャを取得する場合、単純に全パケットを取得すると、目的のパケットが埋もれてしまい、確認しづらくなるため、特定の条件でフィルタリングを行って目的のパケットを見つけ出します。

フィルタリングの方法も、パケットキャプチャ自体はすべて取得し、後から`WireShark`等でキャプチャファイルを見る際にフィルタリングを行う方法と、パケットキャプチャを実行する際にフィルタリングを行い、条件に合致するパケットのみ取得する方法がありますが、BEF Templates、BEFの設定は後者の条件に合致するパケットのみ取得するフィルタを作成する方法となります。

`BPF`は`Berkeley Packet Filter`というフィルタリング形式で、指定の書式で記載することで特定のプロトコルや特定の送信元のみのパケットを取得したりできるようになります。

`BPF`の書式が分かる人であれば、`BPF`欄に直接書式を記載しても良いですが、書式が分からない場合は、いくつかの例が`BPF Templates`として登録されているため、`BPF Templates`から選んで使うことも可能です。

`BPF Templates`は**CML2.2.1**では以下が登録されています。

|BPF Templates|BPF|
|:--|:--|
|DHCP|udp port 68 or port 67|
|Spanning Tree|stp|
|ip (src)|src host ＜ip＞|
|ip (dst)|dst host ＜ip＞|
|ethernet (src)|ether src host ＜mac＞|
|ethernet (dst)|ether dst host ＜mac＞|
|vlan|vlan <id>|

＜＞の部分は任意のアドレスやIDを入力する必要があるので、指定したい値を入力する必要があります。

もっと細かく指定したい場合は`BPF`の書式を別途調べてみて下さい。

# おわりに
ネットワークの調査を行ったり、想定通りの動きをするか確認するためにはパケットキャプチャは必須の作業となります。

想定通りの動きになっておらず、障害が発生した事例はいくつもあるので、パケットキャプチャでパケットの動きを把握できるようにしましょう。
初心者がROSチュートリアルをやってみた#3

この記事も3回目に突入しました。
本記事では[ROS公式チュートリアル](http://wiki.ros.org/ja/ROS/Tutorials/UnderstandingTopics)を初心者がやっていってメモ感覚で書いていく記事です。
今回は、6.ROSトピックの理解です。

#01セットアップ
![Screenshot from 2021-06-12 13-26-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/f55ecd35-76f7-13c3-b7cc-c2b6eef8fabb.png)

亀が動く！！！可愛い！！！！！

#1.ROSトピック
チュートリアルに従っていい感じにいっております。

```
rosrun rqt_graph rqt_graph
```

![Screenshot from 2021-06-12 13-37-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/b7844f60-fb8d-66da-9168-2d783160a332.png)

でシステムの進行状況とかどんな感じになってるかわかるのね。色によってnodeかトピックもわかるようになってるのか。

```
rostopic
```
でトピックについての情報も得られると。
そのうち、

```
rostopic echo
```

![Screenshot from 2021-06-12 13-46-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/1e4b4138-c4b3-799c-7bb8-751b952a3a8f.png)

を試してみた！すげええ！見えちゃうやん！

しかも

```
rostopic pub [topic] [mag_type] [args]
```

![Screenshot from 2021-06-12 14-01-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/71fd8450-8d9d-d198-bc04-97bbf9b6e110.png)

で動かせちゃう！え！楽しすぎない？(ここで自身がhydroであることを知る。)
ついでに

```
rosrun rqt_plot rqt_plot
```

![Screenshot from 2021-06-12 14-07-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/ab1d3168-78ab-2a55-1ace-d99561fa51c2.png)

も試してみた！いい感じー。今回のところ楽しさマシマシになってきたので、もっと遊んでみて追記します！
【kotlin】コンテキストメニュー

#■ コンテキストメニュー
リストビューを長押しタップすると
新たなメニューが表示される。

###1
コンテキストメニュー用の.xmlファイルを作成する。

resフォルダ右クリック
[New] -> [Android Resource Directory]
専用画面出てくるので
Resource type: menu に変更。
OK

[menu]フォルダ作成
[New] -> [Menu Resource File] 
作成専用画面で[File Nmae]好きな名前
[OK]

``` kotlin
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/menuListContextDesc"
        android:title="@string/menu_desc"/>

    <item
        android:id="@+id/menuListContextOrder"
        android:title="@string/menu_order"/>

</menu>
```

オプションメニューと違いshowAsActionはいらない。


###2

表示したいアクティビティに記述する。

■overrideしてonCreateContextMenu()を実装
親クラスのメソッドを呼び出す。


``` kotlin
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
        super.onCreateContextMenu(menu, v, menuInfo)
    }
```

###3
コンテキストメニューを表示


``` kotlin
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
        super.onCreateContextMenu(menu, v, menuInfo)
       //表示したいメニューファイルをR値で渡す
       menuIntflater.inflate(R.menu.作成したContextMenuの名前,menu)
    }
```

###4

コンテキストメニューのヘッダタイトルを設定

その後
onCreate()に
registerForContextMenu(リストビュー)
で画面部品を登録

``` kotlin
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
        super.onCreateContextMenu(menu, v, menuInfo)
       menuIntflater.inflate(R.menu.作成したContextMenuの名前,menu)
       //タイトルを表示する。
       menu?.setHeaderTitle(タイトルに表示したいstringのR値)
    }

override fun onCreate(savedInstanceState: Bundle?) {

   省略
  registerForContextMenu(リストビュー)
}


```

###5
item選択時の処理

■引数のitemのmenuInfoプロパティをAdapterView.AdapterContextMenuInfo型にキャストする
長押しされたビューに関する情報
■AdapterContextMenuInfoオブジェクトにpositionプロパティがありどの行を選択したかの値が格納されている。
長押しされたリストのポジション

``` kotlin
override fun onContextItemSelected(item: MenuItem): Boolean {
  //戻り値用の変数
  var returnVal = true
  //長押しされたビューに関する情報
  val info = item.menuInfo as AdapterView.AdapterContetxMenuInfo
  //長押しされたリストのポジション
  val listPosition = info.position
}

```

###6
長押しされたポジションのメニュー情報を取得

``` kotlin
override fun onContextItemSelected(item: MenuItem): Boolean {
  //戻り値用の変数
  var returnVal = true
  val info = item.menuInfo as AdapterView.AdapterContetxMenuInfo
  val listPosition = info.position
  //プロパティで用意した_menuListのポジションとして変数menuに入れる。
  val menu = _menuList[listPosition]
}
```

###7
when文で処理を分岐する。

```kotlin
override fun onContextItemSelected(item: MenuItem): Boolean {
  //戻り値用の変数
  var returnVal = true
  val info = item.menuInfo as AdapterView.AdapterContetxMenuInfo
  val listPosition = info.position
  val menu = _menuList[listPosition]

  when(item.itemId) {
    ContextMenuのitemのR値 -> 処理
    ContextMenuのitemのR値 -> 処理
    else ->
     returnVal = super.onContextItemSelected(item)
  }
  return returnVal
}
```
【TypeScript】index.tsでimport文を簡素化する【基本】

#index.tsの使い方
以下のようなindex.tsをserviceディレクトリの中に作成します

```typescript:index.ts
export * from './Service1'
export * from './Service2'
```
すると、以下のようなインポート文を

```TypeScript
import { Service1 } from '../service/Service1';
import { Service2 } from '../service/Service2';
```
一行にまとめることができます。

```TypeScript
import { Service1, Service2 } from '../service/
```

#public-api.tsとの違い
似たような使い方をpublic-api.tsというファイル名で行うことがあります。
機能としては同じですが、import文を書く時ファイル名の省略ができません。

```typescript:index.ts
export * from './Service1'
export * from './Service2'
```
このようなファイルをserviceディレクトリで作成した場合、import文は以下のように書く必要があります。

```TypeScript
import { Service1, Service2 } from '../service/public-api
```
【アルゴリズム】JavaScriptで部分配列問題を解く

#はじめに
Qiitaの競技プログラミング研究月間ということで、アルゴリズムの記事を書いています。
今回は部分配列に関する問題をまとめました。

JavaScriptでアルゴリズムの勉強をされている方の参考になれば幸いです。
記事を順次まとめていきますので、その他の記事についてはマイページからご覧ください。

https://qiita.com/suzuki0430

https://qiita.com/official-events/5a0502a2d94ed6a00c30

#チャンク(Chunk)
配列とチャンクサイズを引数で与えたとき、配列内にチャンクサイズと同じ長さの部分配列をつくってください。

```
chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]]
chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]]
chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]]
```

#解答
以下の処理を考えて実装します。

- 部分配列を包含する空配列`chunked`をつくる
- 引数で与えた配列の各要素`element`に対してforをまわす
    - `chunked`の最後の要素(部分配列)`last`を取り出す
    - (if) `last`がない、また`element`の長さがチャンクサイズと同じ場合
      - `chunked`に`element`を含んだ配列`[element]`を追加する
    - (else) 該当しない場合
      - `last`に`element`を追加する

```js:index.js
function chunk(array, size) {
  const chunked = [];

  for (let element of array) {
    // chunkedの最後の要素(部分配列)
    const last = chunked[chunked.length - 1];

    if (!last || last.length === size) {
      chunked.push([element]);
    } else {
      last.push(element);
    }
  }
  return chunked;
}
```

#スパイラルマトリクス(SpiralMatrix)
引数に整数Nを与えたときに、NxNのスパイラルマトリクスを返してください。

```
  matrix(2)
     [[1, 2],
     [4, 3]]
  matrix(4)
     [[1, 2, 3, 4],
     [12, 13, 14, 5],
     [11, 16, 15, 6],
     [10, 9, 8, 7]]
```

##解答
以下の処理を考えます。
初期値1の`counter`という変数をつくって、1ずつ増やしながら部分配列に格納していくイメージとなります。

- 部分配列を包含する空配列`results`をつくる
- `counter`という変数をつくる(初期値1)
- 1, 2, 3, 4の順番でforを回し、counterを格納する(1ずつ増やしていく)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/5175c3d4-8fff-1049-7b3a-db7ac5eaa98f.png" width="500" />

配列`results`には空の部分配列を先に格納してしまい、その後に処理を行っていきます。

```js:index.js
function matrix(n) {
  const results = [];

  for (let i = 0; i < n; i++) {
    results.push([]);
  }

  let counter = 1;
  let startColumn = 0;
  let endColumn = n - 1;
  let startRow = 0;
  let endRow = n - 1;

  while (startColumn <= endColumn && startRow <= endRow) {
    // Top row
    for (let i = startColumn; i <= endColumn; i++) {
      results[startRow][i] = counter;
      counter++;
    }
    startRow++;

    // Right column
    for (let i = startRow; i <= endRow; i++) {
      results[i][endColumn] = counter;
      counter++;
    }
    endColumn--;

    // Bottom row
    for (let i = endColumn; i >= startColumn; i--) {
      results[endRow][i] = counter;
      counter++;
    }
    endRow--;

    // start column
    for (let i = endRow; i >= startRow; i--) {
      results[i][startColumn] = counter;
      counter++;
    }
    startColumn++;
  }

  return results;
}
```

#参考資料
https://www.udemy.com/share/101WNkCEEZd11VRno=/
Ruby on Rails 6のbundle installが重すぎる

Ruby on Rails 6にしてから、`bundle install`にかなり時間がかかるようになってしまった。
Dockerを使って開発・デプロイをしているのだが、新規作成したばかりのプロジェクトでもCloud Build上でのビルドに10分以上かかってしまう状況だ。

# 原因: sasscのインストールが遅い
調べてみると`bundle install`で発生する時間のうち、ほとんどの時間は`sassc`のインストールで発生している。同様の報告は多数上がっている。

[sass/sassc-ruby - sassc is very slow to compile and install #189](https://github.com/sass/sassc-ruby/issues/189)

> Up to version 2.1.0, sassc shipped precompiled Linux binaries, but as of 2.2.0, the only precompiled versions are for mingw32.
> ...
> In the meantime, a workaround might be to pin sassc-ruby to version 2.1.0.

[Rails: Why is bundle install frozen up by sassc 2.4.0](https://stackoverflow.com/questions/62720043/rails-why-is-bundle-install-frozen-up-by-sassc-2-4-0)

> Using an older version of sass solves the issue. I advise changing 6 to 5.1.0 in the Gemfile. This file will be located in your rails folder (the name you used when creating a new rails)

[sassc 2.2.0](https://github.com/sass/sassc-ruby/blob/master/CHANGELOG.md)以降で`migw32`用以外のコンパイル済みバイナリが含まれなくなり、linux系の環境では`bundle install`時にネイティブビルドが発生することが直接的な原因のようだ。どうやら不具合ではなく、意図的にLinux系のコンパイル済みバイナリを含めるのをやめたようだ。

# 対策: 古いバージョンのsasscを指定するか、sass-railsのバージョンを下げる

ワークアラウンドとして、`sassc`の2.1系を使うか`sassc`に依存している`sass-rails`のバージョンを下げる方法が紹介されている。
基本的には`sassc`のバージョンを下げる方が影響範囲が小さくて良さそうだ。
sass-rails(が参照しているsassc-rails)の最新版のdependencyをみると、[必要なsasscのバージョンは「2.0以上」となっている](https://github.com/sass/sassc-rails/blob/master/sassc-rails.gemspec#L26)ので、2.1に下げることは可能だ。

```Gemfile
# Use SCSS for stylesheets
gem 'sassc', '2.1.0'
gem 'sass-rails', '6'
```

# 結果: Cloud Buildでのビルド時間は10分から4分に短縮

`sassc`のバージョンを2.1に下げたことで、`bundle install`にかかる時間が大幅に短くなった。Cloud Buildでのビルドでも、10分かかっていたものが4分まで短縮され、大分開発・デプロイが快適になった。
はじめてのQiita書き込みについて！

# はじめてのQiita書き込み！

皆さんこんにちは、駆け出しエンジニアの小島です！
駆け出し過ぎてマークダウン記法とは、なんぞや？
レベルからのスタートです（泣）

なので今回は、マークダウン記法について記述して
行きたと思います！
ドラクエの勇者みたいに着実にエンジニアレベルを上げて行きたと思います:point_up:

文章の頭に（シャープ）を付けると見出しを作る事が出来るみたいですね！
(シャープ）の数で見出しの大きさを変える事が出来るみたいです！

![スクリーンショット 2021-06-12 13.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1405238/50a3c0be-00a7-f08b-8795-da817efcffff.png)




例
# (シャープ1個）スライム
## (シャープ2個）キータン
### (シャープ3個）ゴールデンスライム

他にもいろいろと記入方法があるみたいですね！
はじめての事や慣れていない事を一気に長時間とすると、
脳の前頭前野に負担が掛かって三日坊主になりやすいので、
本日は、このぐらいにして置こうと思います！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1405238/d80568d8-2bed-3b66-68c5-702a5ef001eb.png"width=50%>
DockerでNode.jsのインストールに失敗する

Dockerで`docker compose up --build`した際に
node-jsをインストールするとこでエラーが出たので、再発用に残しておきます。

## エラー箇所
Dockerfile内

```
RUN apt-get install -y gnupg \
&& curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& apt-get install -y nodejs
```
## エラー内容

```
Error executing command, exiting
```

## 対処法

### STEP1 エラー箇所をコメントアウト

```
# RUN apt-get install -y gnupg \
# && curl -sL https://deb.nodesource.com/setup_10.x | bash - \
# && apt-get install -y nodejs
```

### STEP2 docker compose up --buildを再度実行

### STEP3 dockerコンテナに入る

```
docker exec -ti コンテナ名 bash
```

### STEP4 ソースの削除

```
rm -rf /var/lib/apt/lists/*
rm -rf /etc/apt/sources.list.d/*
apt-get update
```

参考:https://askubuntu.com/questions/1141035/error-executing-command-exiting
(sudoがあると怒られたので、sudoなしで実行)

### STEP5 コメントアウトしたコマンドを実行

```
RUN apt-get install -y gnupg
```

```
curl -sL https://deb.nodesource.com/setup_10.x | bash -
```

```
apt-get install -y nodejs
```

### 完了

理由については、まだよくわかってませんが、とりあえず動くようにはなりました！
AWSs3上でお名前.comで取得した独自ドメインを反映させる手順

#何の記事か
AWSのS3上で構築したサイトを、お名前.comで取得した独自ドメインにしようと思ったものの、意外と情報がまとまっておらずメモに残そうと思いました。
※作業として目的を果たすためのメモであり、技術的には正しい理解はできていないかと思いますのでご了承ください。

#最終的に参考になった記事
https://deep.tacoskingdom.com/blog/12
https://qiita.com/wannabe/items/17060e244c50d5b467cb

#やるべき作業
お名前.comとAWS上でそれぞれやるべきことがあります。
AWS上では「S３」「Route53」「CertificateManager」「CloudFront」の４つの設定が必要。

##①お名前.comで独自ドメインの取得
ここは特に迷うことはない。

##②Route53でAWS上に独自ドメインを認識させる
ホストゾーンの作成
お名前.comで取得した独自ドメインを入力して作成をクリック
出てくる４つのネームサーバーのアドレスをメモ（お名前.comでの反映作業のため）


##③お名前.comでDNSの設定を行う
step②で取得した４つのアドレスをお名前.com上で反映させる


##④CertificateManger
SSL認証をしてくれる
お馴染みのLet's Encryptを使う必要なく、AWS上で完結してくれる
バージニア北部(us-east-1)リージョンで作業をする。CloudFrontで証明書を使用するには、バージニアである必要があるため。
以下の記事「AWS Certificate ManagerでSSL証明書の発行」の箇所に従う（大変参考になりました）
https://deep.tacoskingdom.com/blog/12#part-h2-3

CNAMEの情報が発行されるのでメモ（お名前.comでの反映作業のため）


##⑤お名前.comでSSL認証設定を反映させる
お名前.com上での該当箇所が探しづらい。。。
DNS>ドメインのDNS設定>ドメイン選択>DNSレコード設定を利用するの「設定する」を選択

以下の記事「お名前ドットコムに外部のCNAMEを設定する」の箇所に従う
（大変参考になりました）
https://deep.tacoskingdom.com/blog/12#part-h2-3


##⑥CloudFrontでの設定
この記事の「S3にファイルをアップロードして静的サイトを取得したドメインで公開」の箇所に従う
（大変参考になりました）
https://qiita.com/wannabe/items/17060e244c50d5b467cb

「Create Distribution」をクリックして指示に従う。
「Deployed」となるまで対応。

##⑦Route53でCloudFrontでの設定を定義する
wwwをCloudFrontで作成した内容に向ける。

#まとめ
作業として１つのサイトで完結できるものがなかったので、本記事にまとめました。
私は参考にした２つの記事の内容を組み合わせて作業をして、SSL認証独自ドメイン運用ができたので、少しでも参考になれば幸いです。
DBMSは何をしてるのか調べてみた

DBMSの概要は知ってるけど
「あれ、そもそもDBMSってなにしてるんだっけ？」
って思った瞬間がありまして
ちょうどいい機会だったので調べてみました

##DBとDBMSの違い

まずはDBMSって何だったっけ
DBと何が違うんだっけってとこから整理

###DBとは
データ形式をあらかじめ定義して、統合的に管理できるファイル構造のこと。
リレーショナル形のデータベースや、ツリー型のデータベースなどのモデルがある。

###DBMSとは
データベースを管理するためのシステム。DBMSの利用により、データの共有化やデータ保護、データ検索、更新などの処理を簡単に実現することができる


###じゃあDBとDBMSの違いは？
「DB」は一言で言うと、色んなデータが格納されてる引き出しみたいなもので
そのDB全体を管理したりDBを便利にしてるシステムが「DBMS」ってことですね

![dbms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1567359/237e9e2d-71f2-b886-3424-e23ab296a8c1.png)


じゃあ、「DB」を管理って「DBMS」は何してるの？って話に戻ります

##DBMS4つの機能

DBMSには主に以下4つの機能があります

<ol>
<li>クエリ評価エンジン</li>
<li>バッファマネージャ</li>
<li>ディスク容量マネージャ</li>
<li>リカバリマネージャ</li>
</ol>

それぞれなんなのか、というのを解説していきたいと思います

###1.クエリ評価エンジンとは
端的に言うと
`「ユーザから送信されたクエリ（SQL）を1番最初に受け取って
　データにアクセスするまでの手続きを決めるモジュール(部品)」`です
以下詳細な説明になります

クエリ評価エンジンは、Webサービスなどのアプリケーションや、
DBの値を知りたいユーザーから受け取ったSQLを解釈し、
どのような手順でデータにアクセスするか計画を立てます。

この計画を「実行計画」または「実行プラン」と呼びます。

この実行計画を立てるために、クエリ評価エンジンの中には
「プラン実行機能」「パーサ」「演算評価機能」「オプティマイザ」
などの機能が用意されています。


###2.バッファマネージャとは
端的に言うと
`「どのようなデータをどの程度の期間、バッファに載せておくかといったことを管理する機能」`です
HDD上のデータにアクセスするよりも、
メモリ(バッファ/キャッシュ）にアクセスする方が高速になるためですね
以下詳細な説明になります

DBMSでは、処理を高速にするためメモリ上に一時的にデータを格納します。そのメモリ領域をバッファと呼び、バッファマネージャは適切にバッファを管理する役割を担います。

###3.ディスク容量マネージャとは
端的に言うと
`「どこにどのようなデータを保持するかを管理し、それに対して読み出し/書き込みをする機能」`です
以下詳細な説明になります

永続的にデータを保管するために、DBMSではディスクを使用します。ディスク容量マネージャはどのデータをどこに保存するのかを管理します。

###4.リカバリマネージャとは
端的に言うと
`「有事に備えて定期的にバックアップを取ったりデータを復旧させるための機能」`です
以下詳細な説明になります

DBMSが管理するデータには、消してはいけないデータが含まれます。
しかし、システムは必ず障害が発生します。
その時に大切なデータを消したり、壊したりしないように、リカバリマネージャには定期的にバックアップをとり、障害が発生した際はバックアップを利用して、データを復旧する機能があります。
Node.js(Express)を使用してCloudinaryに画像をアップロード・更新する

Cloudinaryに画像をアップするには、まずはcloudinaryとmulterをインストールします。

```
npm i cloudinary multer
```

続いてCloudinaryのWebサイトにログインし、ダッシュボードのアカウント詳細欄にある「クラウド名・APIキー・APIシークレット」の値をコピーする。そして.envファイルを作成し、それぞれの変数にコピーした値を代入します。

```js:.env
CLOUD_NAME=クラウド名
API_KEY=APIキー
API_SECRET=APIシークレット
```

今度はutilsフォルダーを作成し、このフォルダー内にcloudinary.jsとmulter.jsファイルを作成します。
それぞれのファイルの中身は次のようになります。

```js:cloudinary.js
const cloudinary = require("cloudinary").v2;
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
}); 
module.exports = cloudinary;
```

```js:multer.js
const multer = require("multer");
const path = require("path"); 
// Multer config
module.exports = multer({
  storage: multer.diskStorage({}),
  fileFilter: (req, file, cb) => {
    let ext = path.extname(file.originalname);
      if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") {
      cb(new Error("File type is not supported"), false);
      return;
    }
    cb(null, true);
  },
});
```
2つのファイルの記述が終わったらindex.jsに移動し、ファイルのパスを作成します。

```js:index.js
app.use('/user', require('./routes/user'))
```

上で通したパスのファイルを作成します。routesフォルダーを作成し、その中にuser.jsファイルを作成します。ファイルの中は、以下の通りです。

```js:user.js
const router = require("express").Router();
const cloudinary = require("../utils/cloudinary");
const upload = require("../utils/multer");
const User = require("../model/user"); 
router.post("/", upload.single("image"), async (req, res) => {
  try {
    // Upload image to cloudinary
    const result = await cloudinary.uploader.upload(req.file.path);
     // Create new user
    let user = new User({
      name: req.body.name,
      avatar: result.secure_url,
      cloudinary_id: result.public_id,
    });
    // Save user
    await user.save();
    res.json(user);
  } catch (err) {
    console.log(err);
  }}); 
 module.exports = router;
```

cloudinary.uploader.uploadを画像をアプロードする記述になります。cloudinaryから帰ってきたレスポンスにはsecure_urlとpublic_idが含まれているので、avatarとcloudinary_idに保存します。

cloudinaryにアップしている画像を更新するにはputではなく、cloudinary_idを指定して削除し、再度アップする処理が必要となります。

具体的には次のようになります。

```
// まずcloudinary上の画像を指定して削除
cloudinary.uploader.destroy(user.cloudinary_id)
// 再度画像をアップロード
cloudinary.uploader.upload()

これでNode.jsからCloudinaryへの画像のアップロード・更新は完璧です！
```

## 参照
https://dev.to/itsmefarhan/cloudinary-files-images-crud-operations-with-nodejs-express-multer-2147
**
初心者がROSチュートリアルやってみた#2

今回は前回に引き続き、[ROSチュートリアル](http://wiki.ros.org/ja/ROS/Tutorials/BuildingPackages)の4.ROSのパッケージをビルドする。に取り組んでいきたいと思います。

##1.パッケージをビルドする
なるほどなるほど、catkin_makeは使えるってことね（あまりわかってない）
#5.ROSのノードを理解する
4のチュートリアルはあまりボリュームがなかったため、今回は一つの記事で5に突入したいと思います。
##0.1準備:ros_tutorialsのインストール
これは実行したけれど既にインストールされていた模様。過去の自分、やるやん。
##0.1グラフ概念についての手っ取り早いおさらい
Nodes,Topics,Messages,Master,rosout,roscoreは話せるようにしよう。
##0.1ノード

```
rosnode list
```

でアクティブなノードのリストを表示してくれると。なるほど。でそこからさらに情報が見たかったら、

``` 
rosnode info <nodeの名前>
```


で情報が見られると。なるほど。
#0.1 rosrunの使い方

```
rosrun [package_name] [node_name]
```

![Screenshot from 2021-06-12 12-39-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727850/59b84e70-1527-ddc8-f8bd-deec3001b1cf.png)

お！！出た！感動！
では次にリマップ引数を使ってみるか！
と思って意気込んだものの、/my_turtleじゃなくて、turtlesimのままだな。みた感じ、/turtlesimで始まっちゃってるから、引数がうまく与えられていないっぽい。そこでもう一回チュートリアルのコマンドをよくみた。

```
rosrun turtlesim turtlesim_node __name:=myturtle
```

って、リマップ引数の_って二個か！全角みたいなスペースしてんなとは思ったけど、2個なのね！


上手くできました。

これで5は終わり。
#参考
http://wiki.ros.org/ja/ROS/Tutorials/BuildingPackages
http://wiki.ros.org/ja/ROS/Tutorials/UnderstandingNodes
AWS Data Analytics - Specialty 合格記録

# この記事

**AWS Data Analytics Specialty** を取得したので、学習内容や感想を記録します。

# about me

**インフラエンジニア**
AWS関連のインフラ構築や保守を４年ほど経験しています。
これまでのAWS資格は以下の流れで取得しました。

```
2019
Solution Architect Associate （7月）
SysOps Administrator Associate (9月)
Solution Architect Professional (11月)
Developer Associate (12月)
2020
DevOps Engineer Professional (3月)
Security Specialty（5月）
Advanced Networking(10月)
2021
Database Specialty（1月）
Data Analytics Specialty(6月)
```

# about DAS試験

AWS 認定 データベース – 専門知識
https://aws.amazon.com/jp/certification/certified-data-analytics-specialty/

# 試験対策でやったこと

## 試験ガイドとサンプル問題

まずは、どんな内容の問題が出るのか目を通します。
上記リンクの「試験ガイド」「サンプル問題」です。

どんな問題が出るのか？具体的な対象サービスは？シチュエーションは？
といった部分を確認します。

## AWS公式ドキュメントによる学習

まず、各サービスについて知る必要があるのでこちらの公式資料で学習です。
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/
※Analyticsの主要なサービス部分

何もわからない状態で問題集をやるよりは、
公式ドキュメントで「見たことある」状態にしてから演習すると、Input効率が格段に上がります。
もちろん、やってみてからでも場合(分野)によってはありです。

## 問題演習

問題集は主にkoiwaclubです。
https://aws.koiwaclub.com/

Udemyもいくつかやりましたが、私が買って解いたものは回答が違っているものもあったので途中でやめました。
どれを使うかしっかり選べば良いかと思いますが、特に英語のものはいくつかやってみてから選んだほうが良いかと思います。


## 不足していた知識補完

学習前半で、個人的に知識不足だったのは以下でした。

・Kinesis系サービスのそれぞれの用途
・各サービスの便利オプション（例：Glueのジョブブックマーク機能や、Redshiftの外部テーブル参照機能とか）
・AthenaやQuicksightでできることやユースケース

## 最も役に立った書籍

今回、データ分析の分野自体が経験がなく不安だったので、書籍でしっかり学習しようと思い
後半戦は主にこちらの書籍での学習/ハンズオンをやりました。

「AWSではじめるデータレイク: クラウドによる統合型データリポジトリ構築入門」
https://www.amazon.co.jp/dp/491031301X

正直はじめに読むべきだったなと思ったくらい、初級者にも適切な内容だと思います。

- データレイク分野は、一体誰が何のために使用するのか？
- どんな登場人物が出てくるのか？
- 従来の方法と比べて、AWSクラウドで実装することでどの様なメリットが有るのか？
- 各AWSサービスはどうやって使うのか？(例えばQuicksightの画面や出来る操作等)

この辺がはっきりと理解できる内容でした。
（全分野で出してほしいくらいです。。）



# 結果&まとめ

点数はギリギリでしたが、無事合格。
試験対策としての学習時間は、45時間程度です。
やはり今回も、場合によっては英語で解いたほうがわかりやすいこともあるのでそちらもおすすめです。

私はテストセンターで受験しましたが、たまたまシステム障害で遅れて試験が始まりました。
復習で必死だったので、個人的には全然問題ありませんでしたが…（笑）


## 次の試験
いよいよラスト、**Machine Learning Specialty**を、CLFと共に取ります。
経験は多少あるので、思い出しながら短期で学習します。

この記事が何かのお役に立てられれば幸いです。
ありがとうございました。

# 戦いの記録

SAA
https://qiita.com/shinon_uk/items/5525178bf98034676b2f

SOP
https://qiita.com/shinon_uk/items/e60bcb946b49bf5cabda

SAP
・勝利編
https://qiita.com/shinon_uk/items/c6b599d1cd3000e84d59
・敗走編（資料集め）
https://qiita.com/shinon_uk/items/ba839ba048ba439cc3ff

DVA
https://qiita.com/shinon_uk/items/8015953c792ef4bc7223

DOP
https://qiita.com/shinon_uk/items/5646d536e649b60b962a

SCS
https://qiita.com/shinon_uk/items/67fab096f9b85c47de55

ANS
https://qiita.com/shinon_uk/items/05f90e2ff6e9c9e732e8

DBS
https://qiita.com/shinon_uk/items/996edfa2ceab274c38cb
ARMのCコンパイラではcharが符号無しだった❣（x86は符号有り）

追記：M1 MacのX codeのcharは符号有り

```c
#include <stdio.h>
#include <limits.h>

int main(void)
{
  char c = -1;
  printf("%d\n", c);
  printf("(CHAR_MAX == SCHAR_MAX) = %d\n", CHAR_MAX == SCHAR_MAX);
  return 0;
}
```

を`x86` アーキテクチャで実行すると

```shell-session
-1
(CHAR_MAX == SCHAR_MAX) = 1
```

となりますが、 `AArch64` (ARM 64bit) では

```shell-session
255
(CHAR_MAX == SCHAR_MAX) = 0
```

となります。`char` と書いたときに符号有りになるか符号無しになるかでこの違いが生じます。これは未定義動作ではないので `-fsanitize=undefined` で捕まえられないし、 `-Wall -Wextra` を付けてもコンパイラは教えてくれません…😭

確認は gcc 10.2 と LLVM CLang 11.0 で行いました。
STM32L010で温度,S-5851Aをシリアル出力 (RawSerial)


x 愛用していたSTTS751の入手が難しくなったので代用品は、S-5851A。(おもにアドレスの違い)

x Mbedのリビジョン125

目的
愛用していたSTTS751の入手が難しくなったので
代用として、S-5851Aを採用した。
基本的には、IDアドレスが違うだけ
0x48の左シフト1回がアドレス
STM32L010の軽量コンパクト版を移植していく。
STTS751を使っていた理由は、単に安かっただけ。


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり





```c++


#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//#define S5851A 0x48
#define ADDR        ((0x48)<<1)   //  address

//Serial pc(SERIAL_TX, SERIAL_RX); //767
RawSerial pc(PA_2, PA_3); //010

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

int     tempval;        //温度
char    data_read[6];   //i2cバッファー
int     n10;            //10の桁

int main()
{
    
    //pc.printf("\r\n767\r\n"); //767
    
    while (1) {

        //初期化
        //set address 0
        i2c.write(ADDR, "\000", 1); //addres 0

        //温度の読み込み
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  data_read[0];
    
        //tempval = 12; //debug
    
        //計算
        // Calculation temp
        //tempval = 12;
        n10 = DVI10(tempval);             //10の桁
        tempval = tempval - ( n10 * 10 ); //1の桁

        //液晶に出力
        // Display result
        data_read[0] = '0' + n10;
        data_read[1] = '0' + tempval;
        data_read[2] = '\r';
        //data_read[3] = '\n';
        data_read[3] = 0;

        //温度の出力
        puts(data_read); //010
        //pc.printf(data_read); //767

    //1秒待つ
        wait_ms(1000);
    }//while

}//main

//容量削減
void error(const char* format, ...){}


```


![i2c_s5851a_010_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b7a39d8a-77a3-9328-2483-5ff4d597e62d.jpeg)


![i2c_s5851a_010_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9746d5e4-e62a-557c-8fc7-9579f85065c8.jpeg)
779. K-th Symbol in Grammar

LeetCodeの["K-th Symbol in Grammar"](https://leetcode.com/problems/k-th-symbol-in-grammar/)
グラフで解けて気持ちよかった。

親子の関係を使って、分割統治法で解ける。計算量もメモリもO(n)。

```python
class Solution(object):
    def kthGrammar(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        if n == 1 and k == 1:
            return 0
        
        parent = self.kthGrammar(n-1, (k+1)//2)
        
        if parent == 0:
            if k % 2 == 0:
                return 1
            else:
                return 0
        else:
            if k % 2 == 0:
                return 0
            else:
                return 1
            
```
【2021年6月現在】Udemyの英語字幕を日本語化する方法

# TL;DR
Microsoft Edgeの標準機能「日本語に翻訳」を利用するだけです。

# 手順
日本語に翻訳したい講座を開く
![スクリーンショット 2021-06-12 12.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/44d920b9-ac9e-2fba-c769-cfe093025676.png)

画面上右クリック＞日本語に翻訳を選択
![スクリーンショット 2021-06-12 12.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/c01efc1c-4fff-511f-e168-46b052461af2.png)

翻訳完了
![スクリーンショット 2021-06-12 12.16.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/45ebc119-e906-f494-69a7-82a180713250.png)

（補足）
アドレスバー右側に表示されている「aあ」の翻訳ツールからも翻訳可能です。
![スクリーンショット 2021-06-12 12.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/cf51f398-9a06-9008-f584-c916902ad7c8.png)

# この記事を書いた理由
Udemyの英語字幕を日本語化する方法を調べたところ、アフィリエイト盛りだくさんのブログやGoogle Chromeの翻訳機能を使った方法（現在は利用不可）に苦しめられたので、最もお手軽に翻訳できる手順をサクッとまとめました。

AWS認定資格のSysOpsアドミニストレーターのような、どメジャーではない試験の対策だと、日本語講座の数が限られています。
![スクリーンショット 2021-06-12 12.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/8ec9a4de-efb8-bfdb-6ad4-e99b88be2703.png)
SysOpsで検索しているのに、クラウドプラクティショナーやDevOpsの講座が出てくる（＝対応した講座がない）

一方、検索条件の言語を英語に変更してみると、SysOpsの講座が複数開講されていることが分かります。
![スクリーンショット 2021-06-12 12.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344264/11b86685-8bf8-b9bc-4a87-ac64ace56160.png)
講座の質、量ともに日本語とは段違い。

世界中の講座が、言語のハードルを取り払って受講できると考えると、ワクワクしませんか！？
翻訳を活用して、よいUdemyライフを！
セッションって結局なんだろう？

## 始めに
おはようございます、プレイライフの熊﨑です！
最近お腹周りがぷにぷにしてきたので、そろそろ夏にむけてトレーニングしないとと焦っております💦

そんなぷにぷにの私が、今回はセッションについてまとめていきたいと思います。

## 対象読者
- セッションについて名前は聞いたことがあるが、詳しいことあまりわかっていないという方

## 前提知識

### どうやってwebページを見れているか？
HTTPという通信プロトコルを使用して、クライアント側がサーバーへ「こんなページをください！」と指示を出す（HTTPリクエスト）。サーバーはクライアント側からのHTTPリクエストを受け取って、リクエストに応じたwebページを返す（HTTPレスポンス）。このようなやりとりを通して私たちはwebページを見ることができています。

### ログインしないと見られないページを見るときは？
HTTPはステートレス（ステートレスの意味については参考記事をご覧ください）なので、今リクエストを送ってきたユーザーがログインしているのかといったことを判別できません。では、ユーザーログインが必要なwebサイトではどのようにしてユーザーがログインしているかどうかを判別しているのか？
そんな時に使われるのがセッションです。

## セッションとは？
>コンピューターネットワークにおけるセッションとは、通信の開始から終了までを指します。クライアントとサーバーで通信を行う場合であれば、クライアントからサーバーへ接続した時点でセッションが始まり、サーバーから切断するとセッションが終了します。この一連の流れを管理することをセッション管理と言います。

[https://www.ntt.com/bizon/glossary/j-s/session.html](https://www.ntt.com/bizon/glossary/j-s/session.html)

要するに、サーバーと通信を開始（ログイン）してから、切断（ログアウト・時間切れ・ブラウザを閉じる）するまでの認証情報などの保存場所ということです。

## セッション管理とは？
>セッション管理は、Webサーバー上でサービスを提供するといった際に、アクセスしているユーザーの識別や処理の状態を管理するために必要になります。セッションを管理する方法はいくつかありますが、たとえばセッションを識別するためのID（セッションID）を生成し、その内容をCookieに保存します。このセッションIDにユーザー情報や処理状況を紐付けておき、通信時にCookieに保存したセッションIDを読み取ることで、その通信がどのユーザーからのもので、どういった処理状態にあるのかを把握することが可能になります。

[https://www.ntt.com/bizon/glossary/j-s/session.html](https://www.ntt.com/bizon/glossary/j-s/session.html)

### 具体例（ログイン後にページをリクエストする場合）

- クライアントがメールアドレスとパスワードをサーバー側に送る。
- メールアドレスとパスワードが正しければ、クライアント側にセッションIDを返す。この時のセッションIDはcookieなどに保存される。
- クライアントが、ログインの必要があるページのリクエストをサーバー側に送る。（この時、cookieに保存されているセッションIDも一緒に送る）
- セッションIDから、ログイン中のユーザーであることを確認できたら、リクエストされたページをクライアント側に送る。

このような流れで、ログインが必要なwebアプリケーションでのページリクエストは送られています。

## まとめ
- HTTPプロトコルはステートレスなため、セッションを用いてログイン情報等を管理しておく必要がある。
- セッションはサーバーとの通信開始〜終了までの認証情報等の保存場所である。
- cookieやセッションを用いることでユーザーの状態管理（ログインしているかどうか、など）を行うことができる。

## 参考文献
HTTP通信について
[https://wa3.i-3-i.info/word1841.html]([https://wa3.i-3-i.info/word1841.html])
ステートレスについて
[https://www.slideshare.net/carotene4035/sessionrailscookie-store](https://www.slideshare.net/carotene4035/sessionrailscookie-store)
セッションについて
[https://www.ntt.com/bizon/glossary/j-s/session.html](https://www.ntt.com/bizon/glossary/j-s/session.html)

## 最後に
ここまで読んでいただき、ありがとうございました！
記事等に間違いなどがあればご指摘いただけますと幸いです！
`Uncaught Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js)` の解決法

Dockerを利用した個人開発で遭遇した下記エラーの対処方法について解説します。

```console
Uncaught Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
Error: Missing binding /myapp/node_modules/node-sass/vendor/linux-x64-72/binding.node
Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 12.x

Found bindings for the following environments:
  - OS X 64-bit with Node.js 12.x
```

## 開発環境
```
$ sw_vers
ProductName:	macOS
ProductVersion:	11.3
BuildVersion:	20E232
```

## 解決策

```bash
docker-compose run --rm <container_name> yarn add node-sass --force
```

docker-compose経由でDockerコンテナ上でアプリケーションを開発していたにもかかわらずdocker-composeコマンドを使わず`yarn add`してしまったため、ホスト(Mac OS X)環境用のnpmライブラリがインストールされてしまっていたことが原因だとわかりました。

再ビルドすることで、Dockerコンテナ上のLinux用のnode-sassをインストールでき、無事エラーが解決しました。
RDP公開は危ない？~オリンピック・パラリンピック中のテレワーク要請を受けて~

2021/06/12　日本政府は、オリンピック・パラリンピック中の民間企業へのテレワーク要請として、テレワーク・デイズ2021 なるものを発表しました。
https://www.watch.impress.co.jp/docs/news/1331042.html

これを受けて、「外部にRDPを公開するケースがまた増えちゃうのでは…？」と私は考えました。
そこで、Shodamを使って現時点でのRDP公開機器数をまず調べてみました。

<font color="Red">他人のサーバ・機器に侵入を試みることは犯罪行為ですので、絶対にやめましょう!!</font>!!

Shodan: https://www.shodan.io/dashboard

Shodanの詳しい利用方法などはここでは割愛させてもらいますが、無料登録を行えばフィルター検索を行うことができるようになるので、
これを機にまだの方は登録してみるのも良いと思います。

###１．まずは、世界全体でどれぐらいの機器でRDPが公開されているのかを確認してみます。
port:3389
で検索します。

<strong>結果：3648728 台</strong>
![210612w.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336532/93da3c6c-db18-46f4-171d-5d28f164451a.png)

###2．更に、日本国に絞り込みます。
port:3389 country:"JP"
で検索します。

<strong>結果：83854 台</strong>

![jp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336532/b0503336-49ff-1862-d8aa-5ab66fcc9b60.png)


世界の総台数の2%なので、まぁ結構多い方だと感じますね。


###結果を受けて
今回検索結果の詳細については割愛させていただきましたが、
中にはWindows サーバ2012を使っています、というような情報まで分かるものも多く、
攻撃者からすると格好の標的となっています。
既にテレワークを導入している企業の方は、RDPが意図せず公開されていないかの確認を、
やむを得ずに公開してしまっている場合は、必ずセキュリティ対策が十分に施されているかの確認を行うことを推奨いたします。

今後、「テレワーク・デイズ2021」の発表を受けてRDPが公開されるケースも増える可能性があると思います。
公開されているRDPの数の推移について、今後もウォッチしていきたいと思います。
mixhostでLaravelのMySQL設定

##はじめに
アプリケーションをローカルで作成し、mixhostにデプロイしたので、その時の備忘録です。


##操作
mixhostのコントロールパネルから操作します。
MySQLデータベースをクリック
![スクリーンショット 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325744/150821d3-6076-bce4-0bb0-f22b54733578.png)

---

新しいデータベースを作成します。
![スクリーンショット 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325744/94eadf3a-fee8-e532-869e-c044df4cc235.png)

---

新しいユーザーを追加します。
![スクリーンショット 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325744/069a0671-b7da-12f7-821f-e5b2ee91ab0d.png)

---

ユーザーをデータベースに追加します。
![スクリーンショット 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325744/e59b071c-e55c-927a-afbf-d8dfb9ebeaed.png)

---

ユーザー権限は細かく設定できます。
![スクリーンショット 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325744/5262ff7f-f7f5-44e7-6457-9062192b31a4.png)

---

ここからはLaravelの設定です。

```php:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=XXXXX_test //作成したデータベース名
DB_USERNAME=XXXXX_user01 //作成したユーザー名
DB_PASSWORD=******** //ユーザー作成の時に設定したパスワード
```

以上で完了です。
STM32F767で温度,S-5851Aをシリアル出力 (Mbed)


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり



```c++

#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//#define S5851A 0x48
#define ADDR        ((0x48)<<1)   //  address

Serial pc(SERIAL_TX, SERIAL_RX); //767
//RawSerial pc(PA_2, PA_3); //010

I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
//I2C i2c(PA_10, PA_9); //010

int     tempval;        //温度
char    data_read[6];   //i2cバッファー
int     n10;            //10の桁

int main()
{
    
    pc.printf("\r\n767\r\n"); //767
    
    while (1) {

        //初期化
        //set address 0
        i2c.write(ADDR, "\000", 1); //addres 0

        //温度の読み込み
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  data_read[0];
    
        //tempval = 12; //debug
    
        //計算
        // Calculation temp
        //tempval = 12;
        n10 = DVI10(tempval);             //10の桁
        tempval = tempval - ( n10 * 10 ); //1の桁

        //液晶に出力
        // Display result
        data_read[0] = '0' + n10;
        data_read[1] = '0' + tempval;
        data_read[2] = '\r';
        data_read[3] = '\n';
        data_read[4] = 0;

        //温度の出力
        //puts(data_read); //010
        pc.printf(data_read); //767

    //1秒待つ
        wait_ms(1000);
    }//while

}//main

//容量削減
//void error(const char* format, ...){}



```
NumbaでCUDAが動かないときに試すこと

*本記事で報告する不具合はNumbaのPR #7106 で修正予定です。質問者が私で、いちおう日本語訳まとめ的に書いておきます。
https://github.com/numba/numba/issues/7104

# 背景
Ubuntu-20.04 on WSL2にCUDAを何度か入れ直した結果、/usr/lib/wsl/lib/配下にlibcudaとつくファイルがいくつもできてしまった。このためNumbaがドライバを認識できず動作しなかった。

# 対応策
もちろんベストはアップデートにPR #7160が反映されるのを待つ。
一刻も早く対処したい場合、応急処置的に環境変数 `NUMBA_CUDA_DRIVER`に値`"/usr/lib/wsl/lib/libcuda.so`を設定すると問題なく動作する。
【備忘録】Angularのselectorの種類

Angularには以下の三つのディレクティブの種類があります。
・コンポーネント
・構造ディレクティブ
・属性ディレクティブ
ディレクティブはselectorを使うことで効果を及ぼす対象を決めることができます。
セレクターには三つ種類があります。
##要素セレクター

```typescript
@Component({
    selector: 'app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
```
以下のHTMLに対して有効。

```html
<app-element></app-element>
```

##属性セレクター

```typescript
@Component({
    selector: '[app-element]',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
```
以下のHTMLに対して有効。

```html
<div app-element></div>
```

##クラスセレクター

```typescript
@Component({
    selector: '.app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
```
以下のHTMLに対して有効。

```html
<div class="app-element"></div>
```
MaixduinoをWiFiに接続する！（MaixPyを使ったPythonコード）

#1.概説

Maixduinoには、ESP32-WROOM-32チップが搭載されているため、WIFI通信が可能です。
以下のSipeed社公式Githubサイトに参考となるコードがあるので、これを踏まえて、Socket通信ができるところまでのコードを紹介します。試しにヤフージャパンのIPアドレスを取得しています。内容の信憑性と実行については自己責任でお願いしますね。

https://github.com/sipeed/MaixPy_scripts/tree/master/network


#2.コード（Maixduino）

```python
import socket
import network
import gc
import os
import lcd, image
import machine
from board import board_info
import utime
from Maix import GPIO
from fpioa_manager import *

#iomap at MaixDuino
fm.register(25,fm.fpioa.GPIOHS10)#cs
fm.register(8,fm.fpioa.GPIOHS11)#rst
fm.register(9,fm.fpioa.GPIOHS12)#rdy
fm.register(28,fm.fpioa.GPIOHS13)#mosi
fm.register(26,fm.fpioa.GPIOHS14)#miso
fm.register(27,fm.fpioa.GPIOHS15)#sclk

nic = network.ESP32_SPI(cs=fm.fpioa.GPIOHS10,rst=fm.fpioa.GPIOHS11,rdy=fm.fpioa.GPIOHS12,
mosi=fm.fpioa.GPIOHS13,miso=fm.fpioa.GPIOHS14,sclk=fm.fpioa.GPIOHS15)

wifi = nic.scan()
for v in wifi:
    print(v)
print()

nic.isconnected()
nic.connect("<SSID>", "<WifiPassword>")
print(nic.isconnected())

s = socket.socket()
addr = socket.getaddrinfo("www.yahoo.co.jp", 80)[0][-1]

s.connect(addr)

```

#3.最後に
MaixPyはMicropythonをベースにしていると思われるのですが、今のところ、なんとインターネット通信でお決まりのSSLやREQUESTSモジュール（MicropythonでいうところのUSSLやUREQUESTS）が使えません。SIPEED社の更新を待つか、もしインストールの仕方がわかる人がいれば教えてほしいのですが、これは結構面倒な話です。つまり、Socket通信でコードを書いていくしかないということ。SSLが使えないとすると、データベースへのセキュアアクセスなどもできないのではないか？と心配になります。このあたりの解決策をご存知の方、ぜひ教えてください！
ここがMaixduino、Maixpyの改善点だと思います。少し価格で妥協ができるのであれば、やはりRasberryPiの方がモジュールの多様性という点では、優れているように思います。
Google My Maps

## マイマップヘルプ
https://support.google.com/mymaps/answer/3024836?hl=ja&ref_topic=3024924

## マイマップ
表示テスト

<iframe src="https://www.google.com/maps/d/u/0/embed?mid=1OHQ1GqdKUfEaYI6UgP8MJMra_QdnItE_&z=15" width="640" height="480"></iframe>
Salesforceオブジェクト項目一覧の取得

###・要件
Salesforceオブジェクト項目一覧はワンタッチで取得する。
###・対応案
ワンタッチできないが、ステップで取得方法は検討した。
####
①開発コンソールで、下記を実行する

```
Map<String, Schema.SObjectField> mapFields = Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap();
for (String fieldName: mapFields.keyset()){
    System.debug('fieldName_Label:' +mapFields.get(fieldname) 	
                 + ',' + mapFields.get(fieldname).getDescribe().getType()	
                 + ',' + mapFields.get(fieldname).getDescribe().getLabel()	
                 );	
}	


```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801991/ac71e04b-1ade-6305-4d91-b4b4d62ef9f4.png)

上記ログをクリックし、ロカールに保存する
例：c:\tmp\apex-07_Accout.log
####
②PowerShellで一括抽出

```
 (select-string '\|fieldName_Label' apex-07_Accout.log ) | foreach-object -Begin{new-item -type file -force  a.csv} -Process { $b = $_ -replace '.*?Label\:'	
	''; write-output $b |out-file a.csv -append } -End{ get-content a.csv | sort-object | get-unique > Account.csv }

```
####
結果（Name,Type,Label）

```
AccountNumber,STRING,Account Number
AccountSource,PICKLIST,Account Source
......
```
[Rails] 中間テーブルの特定のレコードを削除する

## はじめに
私が作成中のオリジナルアプリで中間テーブルの特定の一つのレコードを削除したいときに、起こったエラーについて解説したいと思います。
各々の変数の名前の付け方が下手くそなのは目を瞑っていただけると幸いです。笑

簡単に、私の作成しているのはこのような中間テーブルです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/54ce4570-956a-1b9b-a88b-5afd32adf15c.png)


一方的なフォロー機能のようなもので、studentがtextbookに対して「学習を始める」というボタンを押すと、students_textbookという中間テーブルにstudent_idとtextbook_idが一つのレコードに保存されるといった機能です。（イベントに参加するようなイメージの方がわかりやすいかも）

そして、「学習をやめる」ボタンを押すと、その特定の中間テーブルのレコードが削除される仕組みです。
ここでエラーが起きました。

## ArgumentError 発生

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552346/d975f9b7-3d56-21d5-55ae-a17bfa71fdc2.png)

どうやら、destroyアクションの記述に問題があるようです。

```Ruby:現在のソースコード
def destroy
  @found_recode = StudentsTextbook.where(student_id: current_student.id).where(textbook_id: @textbook.id)
  @found_recode.destroy
  redirect_to students_textbook_path(@textbook.id)
end
```

ちなみにbefore_actionで＠textbookは下記のように定義されています。

```Ruby:現在のソースコード
private

def set_textbook
  @textbook = Textbook.find(params[:textbook_id])
end
```

＠found_recodeに代入した中身は、students_textbookテーブルの中の特定のレコードを消すために、whereメソッドで現在ログインしているstudent_idが含まれているレコードを全部取り出し、その中からさらに、whereメソッドで学習をやめるtextbookのidが含まれているレコードを取り出すと、特定の消したい一つのレコードが絞り出せると思ったのです。

結果的にこの考え方は間違っていなかったのですが、whereメソッドがどのような形で値を返していたかに問題がありました。あとdestroyの使い方です。


## binding_pryで中身を確認
＠found_recodeの中身をbinding.pryで調べてみます。
適当なtextbookに「学習をやめる」ボタンを押して＠found_recodeを見ると

```pry
[#<StudentsTextbook:0x00007fbb7f1d2e90
  id: 29,
  student_id: 1,
  textbook_id: 16,
  created_at: Mon, 31 May 2021 17:46:02 JST +09:00,
  updated_at: Mon, 31 May 2021 17:46:02 JST +09:00>]
```

このように表示されました。
たくさんあるレコードの中から特定の目的の一つのレコードが取り出せているかに見えます。しかし、これは**配列**で返ってきているのです。そして、その次の処理でdestroyメソッドを使用していますが、destroyメソッドは配列には使えないのです。これがエラーの原因でした。

そこでfind_byを使います。

## find_byメソッドで解決する
先ほどのdestroyの記述の最後のwhereメソッドだけをfind_byメソッドに変更するだけで解決できました。

```Ruby
def destroy
  @found_recode = StudentsTextbook.where(student_id: current_student.id).find_by(textbook_id: @textbook.id)
  @found_recode.destroy
  redirect_to students_textbook_path(@textbook.id)
end
```

## 最後に
今回学んだことはwhereメソッドは配列で値を返していたことと、destroyメソッドは配列には使えないってことですね。
後者は考えたら確かに、、、って感じですね。配列持ってこられても、どうやって削除するのかdestroyさんも困りますよね。すみません。

いつも思うんですが、エラーが発生して自分なりに答えを出して、それが解決につながったときの脳汁の分泌量は半端ないっすね。やめられないです。