OmniAICreator/Qiita-1.07M huggingface dataset:
match()で任意の文字数を取得する方法　〜javascript〜

#指定文字の数をカウントする方法

matchの使用方法は
基本的に
```文字列.match(検索文字)```

MDN:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/match

```javascript
let test = "あいうえおあいうえおかきくけこ";
let count = test.match('あ')
// let count = test.match(/あ/)←正規表現を使うとこれでも同じ結果に

console.log(count)
//結果は [ 'あ', index: 0, input: 'あいうえおあいうえおかきくけこ', groups: undefined ]

```
上記ではテキストの検索したい**文字の最初にヒットした値**を取得していることがわかる。
ここで「あ」の文字数をとりたい時は「.length」を使用する。

```javascript
let test = "あいうえおあいうえおかきくけこ";
let count = test.match('あ').length // ここに「.length」の記述を追加
// let count = test.match(/あ/).length←正規表現を使うとこれでも同じ結果に

console.log(count)
//結果は 1
```

しかし「あ」は変数testには2つある、、
そんな時に使うものが「g」
この正規表現gについては
MDN:https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions
参考記事：https://qiita.com/mokoaki/items/4740c9bd921d2b8d3d82
が分かりやすい
簡単にいうとgを使うと
```検索文字列全体に繰り返し検索をするということ```


```javascript
let test = "あいうえおあいうえおかきくけこ";
let count = test.match(/あ/g).length 

console.log(count)
//結果は 2

```

**「/あ/」**のあとにgを追加したことで全体を繰り返し処理して数を取得している。

また、検索文字がテキスト似なかった場合に０を返したい時はこう書ける

```javascript
let test = "あいうえおあいうえおかきくけこ";
let count = (test.match(/さ/g) || []).length //ここに追加文あり

console.log(count)
//結果は ０

```

「||」を使用して「さ」の値が取れないときは**空の配列を代入しlengthを０**にしている。


##その他使用例



```javascript


//基本的なやり方
  let sentence = '今日は良い天気。こんな日は外にでで遊びに行きたい。お天気は良いなあ'
  let count = (sentence.match(/良い/g)).length
  
  console.log(count)//結果は２

//検索文字がない場合に０を返したい時
  let count2 = (sentence.match(/くもり/g) || []).length

　console.log(count2)//結果は０
//ここでは最初に実行したくもりの検索がヒットしない時（falseがキーなのかは未検証）||以降の検索を元に
//lengthをとってくる。
```
SharePointで超簡単にファイルを復元する方法


SharePointはとても便利で皆さん情報共有等でお世話になったことがあるかと思います。

今回はそんなSharepointにアップロードしたファイルの復元方法について紹介します。

# あっという間の復元方法


ちなみにSharePointにアップロードしたファイルはこちらです。![①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/39e42556-b22c-e98a-112e-03b4f0fb868a.png)


こちらのファイルをこのように変えました。
![⑥.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/fb3f1451-8fb4-4ffa-ba5e-fe5ae07ff865.png)

でもやっぱりチンパンジーの方が人気があると思ったのでチンパンジーに戻します(笑)
「これくらいなら入力し直せばいいのに」と思うかもしれないですが、今日はせっかくなので復元機能をつかってみましょう！

## ①3点リーダーを右クリックし、バージョン履歴を選択

![②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/75cd5e34-e1d6-e7a3-b03e-a125ed578aa5.png)

## ②復元したい日時を選択

![③.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/f8ee6ab6-9704-2a45-7435-b26da1419e07.png)

## ③右クリックで復元を選択

![④.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/fc455d9b-811b-0a16-1843-4fa8a65c26ed.png)

## ④画面を確認して復元完了！

![⑤.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/3f73f700-7a60-3dd7-e9d9-fae23c14a5bb.png)


確認するとチンパンジーに戻っています(笑)
![①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/827465/0fe9af74-ddfd-43dd-edc3-9855f004802a.png)



# おわりに

いかがだったでしょうか。
本当にあっという間に復元ができちゃいます。
SharePointを使う！という方は試してみてください。

ありがとうございました。
git のすべてのコミットから検索する

# git のすべてのリビジョンから検索する

`git grep` で git リポジトリから grep 検索できますが、

`git grep` では検索対象のコミットを引数に指定できます。
`git rev-list --all` ですべてのコミットをリストアップできます。

あわせて、以下のコマンドでgit のすべてのコミットから検索できます。

```
git grep 検索パターン $(git rev-list --all)
```

以下でも OK (リビジョン数に上限がないのでこちらのほうが便利)

```
git rev-list --all | xargs git grep 検索パターン
```

以下のような alias を作っておくと便利かも

```
alias gg='git rev-list --all | xargs git grep'
```


参考
https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history
bundle installするとnokogiriが入る段階でエラーが出るときの対処法

# 背景
Macを使っているのですが、docker-machine on Parallels Desktop Pro Edition な環境を構築しようとしたときに、dockerコンテナに`bundle install`する段階で何をやってもエラーを吐くので、この記事を書きました。

# 対処法
簡単です。
`bundle install` を実行しようとしているディレクトリにある、`.bundle/config`に以下の内容を追記するだけです。

```yml:プロジェクトルート/.bundle/config
BUNDLE_BUILD__NOKOGIRI: "--use-system-libraries"
```

追記したあとに、dockerコンテナを使って`bundle install`を実行するとすんなり通ります。

# 見つけたきっかけ
nokogiriのエラーの前に、therubyracerでエラーを吐いていて[`$ bundle config --local build.therubyracer --with-v8-include=/usr/local/opt/v8@3.15`を実行すれば解決するという情報](https://qiita.com/misogi@github/items/3445a7f9068ca15b38ca)を見て実際に解決したのですが、このコマンドは実行すると`.bundle/config`に`BUNDLE_BUILD__THERUBYRACER: "--with-v8-dir=/usr/local/opt/v8@3.15"`が追記されるようになっていました。
しかし、nokogiriでも同じように`bundle config build.nokogiri "--use-system-libaries"`を実行してもなにも`.bundle/config`に変化になかったので、「もしかしたら手動で追記したら通るんじゃね？」と思ってやってみたら通った感じでした。

ほかの対策が成功に繋がったのでは、と思って一応追記した内容を削除して、`bundle install`で入れたgemが入っているディレクトリを削除してもう一度`bundle install`実行してみたところ通りませんでした。さらにもう一度追記した内容を戻して`bundle install`を実行してみたところ成功しました。この方法が一番シンプルだと思います。
SOLID原則のDIPまとめ

# DIPとは
DIP（Dependency Inversion Principle：依存関係逆転の原則）とは、
***「上位モジュールは下位モジュールに依存してはならず、どちらのモジュールも抽象に依存すべきである。抽象は実装の詳細に依存してはならず、実装の詳細が抽象に依存すべきである」***
というルール

DIPを特に意識せず実装を進めていくと、「上位モジュールが下位モジュールに依存」しているプログラムが出来がち。

例えば、DB操作クラスとそれを使うAPIクラスで考えると、APIクラスの中にDB操作クラスを呼び出す処理をベタ書きしてしまい、APIクラスがDB操作クラスに依存してしまう状態のこと。
このような状態では、DB操作クラスの変更がAPIクラスにまで波及してしまい、保守が難しくなる。

```
 APIクラス
　　 ↓　　　　APIクラスがDB操作クラスに依存
DB操作クラス
```

一方でDIPに従い、DB操作クラスとAPIクラスがともに抽象（インタフェース）に依存するようにすると、依存関係が逆転してDB操作クラスの変更はそこだけにとどまる。

```
 APIクラス　→　DB操作インタフェース
　　　　　　　　　　　　↑　　　　　　　DB操作クラスとAPIクラスがDB操作インタフェースに依存
　　　　　　　　　DB操作クラス
```

すなわち、モジュール間にインタフェースを噛ませることで疎結合にして、下位モジュールの変更が上位モジュールへ波及しないようにしましょうという考え方。

# 具体例
DIPに則り、先程の例の実装を考えると次のようになる。

```python
from abc import ABCMeta  
from abc import abstractmethod  

#APIクラス
class api_class:
    def __init__(self, repogitory):
        self.repogitory = repogitory
    def put(self):
        self.repogitory.save()

#DB操作インタフェース
class db_operation_interface(metaclass = ABCMeta):
    @abstractmethod
    def save(self):
        pass

#DB操作クラス
class db_operation_class(db_operation_interface):
    def save(self):
        print('実際のレコード書き込み処理')

if __name__ == '__main__':
    api = api_class(db_operation_class())
    api.put()

# => 実際のレコード書き込み処理
```

APIクラスに注目すると、DB操作クラスを直接に呼び出すような記述はなく、インスタンス作成時に渡す「repogitory」が「save」メソッドを持っているということ（DB操作インタフェース）に依存していることがわかる。

同様にDB操作クラスに注目すると、DB操作インタフェースの「save」メソッドを実装することが強制されており、DB操作インタフェースに依存していることがわかる。


# DIPのデメリット
DIPに従って実装した場合と直感的に実装した場合を比較すると、DIPを遵守したほうが単純にコード量は増えるし複雑性も増している。
そのため、開発期間に余裕がない場合や保守していく必要のないプログラムの場合では、DIPを守るメリットは少ないと思われる。
一方で、今後保守していかなければならない長く使用されるプログラムであれば、モジュールの変更に対する保守が容易になるという点でDIPの恩恵が受けられる。
レビュワーとしての心得

## はじめに
みなさんコードレビューしてますか？
初めてレビュワーとして挑戦するコードレビューはなかなかハードルが高いものです。

私が所属している開発チームは全員がレビュワーとしてコードレビューに参加するのですが、新しく参入してきた人はやはり戸惑ってしまいます。

ここでは弊チームのレビュワーとしてのお気持ち的な心得を大公開しちゃいます！
マサカリなどなどあると思いますが、誰かの参考になれば幸いです。

## 心得
### 1. レビュイーをリスペクトしよう！
まずはコードを修正してくれた人に感謝しリスペクトしましょう！
相手も人間なので、不必要に貶めたりしないようにしましょう！

### 2. プルリクが大きすぎても頑張る！
たまにトンデモなく大きなプルリクが飛んできます...。
来ちゃったものはしょうがないので、一生懸命にレビューしましょう！

作った側もやっちゃったなーとか思ってるはずです！
いつまでもプルリクを見られないと不安になってくるので、大きなプルリクこそ早めに見てあげましょう！

それでもどうしても辛い場合は、一緒にプルリクを分割してあげよう！

### 3. 細かいことに腹を立てるのはやめよう！
レビューしていると細かいことに気がつくこと多くなりますよね！
コーディングルール守ってないなんて日常茶飯事です。

細かいことに腹を立てたところで解決しないので、どうすれば小さい問題が解決できるか一緒に考えてあげましょう！

### 4. 間違いの指摘なのかアドバイスなのかハッキリしよう！
多くの場合でレビュイーは未熟です。
レビュワーの言っていることが正しく思えてきます。

アドバイスならアドバイス！間違いの指摘ならハッキリ伝えてあげましょう！
少し気をつけるだけでお互いハッピーになります！

### 5. 間違いを恐れない！
誰だって間違いはあります。
疑問に思ったことは積極的に発言し議論を交わし、自分が間違っていると感じたら撤回しましょう！

### 6. 答えを出すのはやめよう！
直接的な答えを出すのは出来るだけ避けましょう！
答えを出しちゃうと考えることを放棄し出して、同じ指摘をしばらく繰り返すことになります。

ヒントを出して出来るだけ自分で答えを出せるように誘導しましょう！
レビュイーも成長を実感できて、お互いWin-Winの関係になります！

### 7. 解決するまで付き合おう！
レビューは指摘して終わりじゃありません！
放置してしまうと指摘された側はどうすればいいか困ったり、あらぬ方向に行ってしまいます...。

レビュワーとして正しく解決に導けるように、根気強く最後まで付き合いましょう！

### 8. 時には厳しくしよう！
何回指摘しても同じミスを繰り返したり、指摘の内容を理解せず直しておかしくなったりとか経験ありますよね？

そんな時は厳しく対応しましょう！
答え出したりレビュー通しちゃうなんていうのは、優しさではなく相手にも自分にも甘くしちゃっているだけです。

厳しくするのはとても疲れますが、チームとしていい方向に向かうことができるように厳しくいきましょう！


### 9. 積極的にレビューに参加しよう！
レビュワーになることで、あの時の自分のソースはダメだったなーとか振り返ることもできます！
相手のためにも自分のためにも、ぜひ積極的にレビューに参加してください。
Google Search Consoleの使い方

#Google Search Console
Google Search Consoleと検索したら、最初に下記の画面が出てきます。
今回静的サイトをサイトの掲載順位を改善したかったので、URLプレフィックスを選択。
![スクリーンショット 2020-10-29 7.52.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/4b487700-c8ca-7fb6-288a-ac1414bc50e5.png)

その後、自分の静的サイトのTOPページにメタタグを入れると、下記のように自分のサイトを管理できます。

```html
<meta name="google-site-verification" content="xxxxx" />
```

![スクリーンショット 2020-10-29 7.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/2fda594e-8925-6fd1-e2c7-1c5cb8122dd8.png)
【備忘録】ページアクセススピードが早くならない場合

#本稿について
PageSpeed Insightsにて計測をしている際、下記のクリティカルチェーンがページ読み込みの遅延になっていると予見される場合の対応をまとめておきます。
（2020年10月29日時点）
![スクリーンショット 2020-10-24 20.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810435/1ddb0a3f-5068-9681-19c6-ab8c9754e9f1.png)

#htmlファイルにpreloadとcrossoriginを記載
私はこれをすることで読み込みスピードが落ち着きました。
※下記はbootstrapを導入した際に使われるフォントになります。stylesheet読み込む前に記載

参考サイト
https://developer.mozilla.org/ja/docs/Web/HTML/Preloading_content
https://developer.mozilla.org/ja/docs/Web/HTML/Attributes/crossorigin

```ruby:application.html.erb
<link rel=”preload” as=”font” type=”font/woff2” href=”http://自分のサイトのドメインかIP/assets/bootstrap/glyphicons-halflings-regular-fe185d11a49676890d47bb783312a0cda5a44c4039214094e7957b4c040ef11c.woff2” crossorigin>
<link rel=”preload” as=”font” type=”font/woff” href=”http://自分のサイトのドメインかIP/assets/bootstrap/glyphicons-halflings-regular-a26394f7ede100ca118eff2eda08596275a9839b959c226e15439557a5a80742.woff” crossorigin>
<link rel=”preload” as=”font” type=”font/ttf” href=”http://自分のサイトのドメインかIP/assets/bootstrap/glyphicons-halflings-regular-e395044093757d82afcb138957d06a1ea9361bdcf0b442d06a18a8051af57456.ttf” crossorigin>
<%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```

以上
クロムブックで vmc が使えなくなった時の対策

クロムブックで canary チャンネルに切り替えたところ、vmc が使えなくなりました。
バージョンは 88.0 です。
![chrome_oct29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/7db55dc4-cc73-d702-d64d-ddc20ebcdd20.png)

ネットには、次のような情報がありました。
[Chromebook(CloudReady)を開発機としてお使いの方々へ: アップデートは控えたほうがいい](https://huequica.hatenadiary.jp/entry/2020/05/02/221123)

次のような状況でした。

```text
crosh> vsh termina
[ERROR:vsh.cc(103)] Failed to get VM info for termina
[ERROR:src/main.rs:184] ERROR: command failed
crosh> vmc start termina
Error: routine at frontends/vmc.rs:238 `vm_start(vm_name,&user_id_hash,features,user_disks)` failed: failed to start lxd: `FAILED`: Starting LXD failed: Failed to connect to LXD daemon: Timed out waiting for LXD to start. Last error was: Get http://unix.socket/1.0: dial unix /mnt/stateful/lxd/unix.socket: connect: no such file or directory
[ERROR:src/main.rs:184] ERROR: command failed
```

そこで、vmc list とキーインすると次のようになりました。

```text
crosh> vmc list
arch (1463341056 bytes, min shrinkable size 2052063232 bytes, raw, sparse)
termina (8053202944 bytes, min shrinkable size 8053063680 bytes, raw)
Total Size (bytes): 9516544000
```

arch というのは、切り替え前に使っていたコンテナの名前です。
そこで、vmc start arch とキーインすると、chronos に切り替わりました。

```text
crosh> vmc start arch
(termina) chronos@localhost ~ $
```

また新たにコンテナをインストールします。

```text
lxc launch images:alpine/edge alpine
```
Firebase のHostingの機能をつかって、ウェブを公開するときのメモ。

#Firebaseのホスティング機能をつかってウェブを公開するときのメモ。
Macでのやり方ですが、Winでも適宜調整して、参考になれば幸いです。

#1.Firebaseの登録をする。（グーグルのアカウントがなければ、以下で作る。）
  基本有料ですが、毎月の転送量が10G以下であれば、無料です.

  https://firebase.google.com/?hl=ja

#2.Firebase 

    A.コンソールへ移動
    B.プロジェクト名を入力
    C.プロジェクトの作成

#3.プロジェクトフォルダーをデスクトップに準備（フォルダーの階層が大事）

![スクリーンショット 2020-10-28 21.56.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607502/b3e92f2f-f983-834b-febf-34139eb05e3f.png)


　　A.このpublicと命名したフォルダーに必要ファイルを全部いれる。
　　B.またtopページは必ずindex.htmlに名前をかえる。
 　　 そうしないと、initの際に、かってに変なindex.htmlが生成されて、変な画面に飛ばされる。


#4.Node.jsを下記からインストールする。（してなければ。）
  
　https://nodejs.org/ja/


#5.Firebaes-toolsのインストール。

　　A.terminal を開く。Winの場合は、powerShell.

　　B.node -v でバージョンを確認。
　　C.npm  -v でバージョンを確認。

　　D.sudo npm install -g firebase-tools (Mac)
  　　npm install -g firebase-tools (Win)

　　E. で、PCのパスワードを入力。

　　F. firebase -V(大文字)

　　G. firebase login

　　H. cd で自分のプロジェクトフォルダーまで移動。（注：public フォルダーではない）

　　I. firebase projects:list　で出てきた、project id をコピー

　　J.  firebase init --project=(project id)

　　K.  Hositing の場合は、それを選ぶ。
   　　 なんか英語の質問が三つあるが、基本リターンでオッケー。

　　L.  firebase deploy（注：public フォルダーではなく、一個上の階層のプロジェクトフォでする。）


#更新したい場合

　　もう一回、ターミナルでフォルダーにいって、
　　firebase deploy で更新できる。

#プロジェクトの削除

　　firebase のホームページで、

　　1.コンソールへ移動
　　2.プロジェクトを選択
　　3.左上の歯車マークから、プロジェクトを設定を選ぶ
　　4.一番下までするロールダウンしたら、削除ボタンがある。

参考になれば幸いです。
TFSへの自動ログインを解除する

#背景
開発メンバーが変更になった際に、Visual Studioを起動すると、以前の開発メンバーでTFSにログインされたままに待っている事象を解決した。

#資格情報を削除する。
ログイン情報は、Windowsの資格情報に保持されているので、TFSサーバーの資格情報を削除し、
Visual Studioを再起動すれば、TFSサーバー接続時にログインを求められる。
在宅勤務が普通となった今、自分の仕事をどう見える化するか

10月の開発作業の振り返りです。[先月までのふりかえりはこちら](https://zenn.dev/e99h2121/articles/4c064cf70645a66172ce)


## 今月の教訓

**仕事の可視化、それにもとづいた冗長体制の確保。**

過去に自らが書いていた[掟](https://qiita.com/e99h2121/items/f1847b338c17086f0e95)をUpdateしつつ意識したい。（下は2019年に書いたもの）

「どう見える化するか」は現状Slackでの「[分報](http://c16e.com/1511101558/)」が自分の最適解ですが、これはチームの体制やメンバー、雰囲気によるのでこれだけと決めないのが良いと思っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/f5c9a6ec-340a-3e58-c5c0-0e3dc025791e.png)





## 今月良かったこと

まず言っておくが私は今月とてつもなく働いた。

### 内訳
出荷済：シングルサインオン画面修正２チケット、Copyright関係修正２チケット、「ジョブ実行キューの振り分けがうまく行かない」チケット、「[Fargate](https://qiita.com/e99h2121/items/cd0dea16b946869e1846)」１チケット。

11月評価準備済：シングルログアウト追加修正１チケット、アプリ画面レイアウトの修正１チケット、細かいスクリプトの修正１チケット。

[log4jのオプションによるOutOfMemoryE](https://qiita.com/e99h2121/items/d92b84e43678cbcdf874#%E3%83%8F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B) のための緊急Patch的作業。

シングルログアウト出荷のための後方支援作業。


## 今月もっとこうしたかったこと

全力でやれたけど、いろいろ手から水が零れ落ちるように漏れた。とりわけ「自分があえてやらなくても大丈夫なんじゃないかな」とか感じてる作業は自分がそう感じているだけであってそんな「阿吽の呼吸」がこのコロナ禍での在宅勤務状態で達成できるかと言うとそんなことはない。色々初心に帰るべき。


## まとめ
- [週休3日、1日6時間勤務達成したい](https://qiita.com/e99h2121/items/f1847b338c17086f0e95)



## 補足

### 弊チームでの振り返り活動

開発チームでは1か月毎に振り返りを行い、

- 失敗
- 問題、改善点
- そして成功、良かった点

を皆で前向きに発表して次に生かすということを行っています。

### 履歴

2020.04 [2020年、（3歳1歳と）私のリモートワーク](https://qiita.com/e99h2121/items/c8878d027603745a6426)
2020.05 [在宅育児（と勤務）を支える技術](https://qiita.com/e99h2121/items/475045cabd005a7add57)
2020.05 [子連れで在宅育児（と在宅勤務）を開始して１か月が経ちました](https://qiita.com/e99h2121/items/cb7471fd833b086b7233)
2020.06 [緊急事態宣言が解除されてリモートワークはどうなるのか](https://qiita.com/e99h2121/items/086822c3f74ebca75364)
2020.07 [新しい開発様式](https://qiita.com/e99h2121/items/ae4f480cb074b3905749)
2020.08 [2020.07振り返り](https://qiita.com/e99h2121/items/c039bd281c7a62a19412)
2020.09 [2020.08振り返り](https://qiita.com/e99h2121/items/baf9b468e25da273b49b)
2020.10 [2020.09振り返り](https://zenn.dev/e99h2121/articles/4c064cf70645a66172ce)
【Mac】3つのアプリでWin10のような使い心地を実現しよう【初心者】

#はじめに
７年くらい前から、ずっとWindowsを使っていました。しかし、最近は、ReactNativeなどのフロントエンド寄りのプログラミングをする事が多くなりました。インターネットで読む記事がMacで書かれている事が多く、Windowsだと、OSの違いで、プログラムが動かないのか、コードが間違っているからなのかがわかりづらかったです。
その問題を解消するために、Macを購入しました。

しかし、Windowsのキー配置とショートカットが染み付いていたため、初めてのMacに戸惑いました。そこで、使い方をWindowのような慣れた使いごごちにできるだけ近付けようと考えました。

そこで、キーボード周りの操作やクリップボードの使い方を満足するくらいまで近付けさせていただきました。

少しでも、この記事を見て、WindowsとMacの行き来ができるようになっていただきますと幸いです。

このアプリを使うと

#標準の設定
Windowsでは、Fキーを使って、文章を書く事が多かったです。MacBookAirを使っていますが、画面の明るさや音量を帰る機会がそう多くありません。
そのため、ファンクションキーとFキーを同時に押すよりも、Fキーだけで、動作をできるようにした方が楽だと思っています。なので、標準の設定を使い、

[MacでもF7・F8・F9・F10を使ってカタカナや英数字を全角や半角に変換する方法](https://itbenricho.com/mac-f7-f10.html)

#必須級
##MacをWindowsのように便利に使うために必要なアプリ
元々Windowsを使っていたので、Macの標準の設定だと、すごく使いにくかったです。そこで、Windowsのように便利にMacを使うためのツールを記述しました。
クリップボードに２個以上の物を保存できるようにし、今まで使っていたおきに入りのキーボードを使えるようにしました。さらに、Windowsボタンと矢印キーを同時に押したような動作を実現する為のアプリを入れました。

1. [Macのクリップボードの中身を見る方法をご紹介！【履歴/消去/アプリ】](https://clipy-app.com/)
2. [MacでWindows用キーボードを使用する方法（Catalinaにも対応）](https://creative89.com/2017/05/27/how-to-use-windows-keyboard-on-mac/)
3. [mac 画面分割アプリ「shiftlt」が超絶便利な件](https://iphone-trouble.biz/mac-screen-split-shiftlt-apps)
4. [Windows の「Explorer」ライクな２ペイン型ファイルブラウザ](http://www.macsoft.jp/posts/view/4912)
5. [Altキー+Tabキーによるウィンドウ切り替えをWindows風に](https://blogenist.jp/2017/10/28/1298/#AltTabWindows)

2つ目のアプリの設定です。Windowsのようにするためにしているアプリの設定です。
上の写真がMacのキーボードの設定で、したの写真が、外付けのWindowsキーボードの設定です。
![スクリーンショット 2020-10-29 14.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559163/a1b50407-e5f7-55b5-0a1d-cd2f34b9fae5.png)
![スクリーンショット 2020-10-29 13.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559163/5b7723b2-5b66-9bf4-09b2-7c14f32a9e27.png)

３つ目のアプリの設定です。Windowのようにアプリをうまく切り替えるための設定です。
Alt＋Command＋Shiftと各矢印キーを使う事で、簡単にWIndowを移動する事が可能です。
![スクリーンショット 2020-11-12 12.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559163/16f26f89-a473-9f9c-a692-0ed2f4fdf0a2.png)



##使えるブラウザ
1. [Chrome](
https://www.google.co.jp/chrome/?brand=CHBD&gclid=CjwKCAjwyo36BRAXEiwA24CwGV9hQxJuMqocK_jesWtbBO0hmK5QBes0zJ8MmgdN-hGURz9gTPUgmhoCv0wQAvD_BwE&gclsrc=aw.ds)
1. [Biscuit（ビスケット） |  いつものアプリがタブに埋もれない無料ブラウザ](https://eatbiscuit.com/ja)
1. [PowerPointやWordなど](
https://www.office.com/?auth=2)

#メモリに余裕があったら入れておきたい便利ツール
僕が買ったMacは、２０１３年のMacBookAir(i7,8GB,128GB)なので、これらのアプリを入れた状態で、プログラミングをすると、重くなってしまいます。そのため、メモリや要領に余裕がありましたら、ぜひお使いください。

1. [DeepL](https://www.deepl.com/ja/translator)
2. [Gyazo](https://gyazo.com/ja)
3. [Slack](https://slack.com/intl/ja-jp/downloads/windows)

#リモートワーク時代の必須アイテム
後ろの背景を変えたり、リモート会議をするために必要なアプリです。
1. [zoom](https://us02web.zoom.us/)
2. [SnapCamera](https://snapcamera.snapchat.com/)


#Programing
Windowsで、プログラミングをするときに必須のアイテムでした。なので。このMacでも入れました。
C#やC＋＋などの重い言語は使わないので、これだけあると十分です。

1. [VSCode](https://code.visualstudio.com/download)
2. [Node.js](https://nodejs.org/ja/)
3. [PyCharm](https://www.jetbrains.com/ja-jp/pycharm/download/#section=windows)
4. [Anaconda](https://www.anaconda.com/products/individual)
5. [Xcode](https://apps.apple.com/jp/app/xcode/id497799835?mt=12)

#最後に
使い心地をよくするために、もっといいアプリなどがありましたら、教えていたdかいますと幸いです！！
LGTMやストックもお待ちしています！！
codebuild-localを使ってみる

##はじめに

数多あるCIツールの一つであるCodeBuild。buildspec.ymlにコマンドを書いたりとかでテストやデプロイなんかができるようになります。

ただし、確認するためには一回Gitに上げたりする必要がある。

それを毎回やるのは面倒くさい。

そうだ。ローカルで動かそう。

##作るもの

ローカルのCodeBuild。

材料は以下。

- [CodeBuildのdocker image](https://github.com/aws/aws-codebuild-docker-images)

##対象読者

-  CodeBuildをとりあえず動かしてみたい人

##内容

### まずは材料を手に入れる

Githubからリポジトリをcloneしてきましょう。

cloneしたら`al2`、`ubuntu`というディレクトリがありますが、その配下にそれぞれ`Dockerfile`があるのでお好みのものを選びましょう。

この記事では[ubuntu:4.0](https://github.com/aws/aws-codebuild-docker-images/tree/master/ubuntu/standard/4.0)を使っていきます。

### 材料を使える形に整える

CodeBuildで使うubuntuイメージを作りましょう。

cloneしてきたプロジェクトの直下にいることを前提として、以下のコマンドを順次実行します。

```bash
$ cd ubuntu/standard/4.0
$ docker build -t aws/codebuild/ubuntu:4.0 .
```

ビルド時間は長いので待っている間に映画でも見てみましょう。

キャプテン・アメリカ/ウィンター・ソルジャーが面白かったです。

### イメージを使ってみる

プロジェクト直下に`local_builds`というディレクトリがいるはずです。

ここに移動したら中にある`codebuild_build.sh`を使って実際に動かしてみましょう。

以下は例です。

```bash
$ ./codebuild_build.sh -i aws/codebuild/ubuntu:4.0 -a ./output -m
```

動かしてみるとdocker imageのpullが始まり、やがて実行に失敗するでしょう。

もしも実行結果の中にbuildspec.ymlが無いというエラーを見つけたのならここまでの工程は成功になります。

では、buildspec.ymlを`local_builds`配下に作成して見ましょう。

以下のような中身であればきっと動くでしょう。

```bash
version: 0.2

phases:
    install:
        commands:
            - echo 'hello world'
```

buildspec.ymlを作成したらもう一度同じコマンドを打ってみましょう。

今度はinstallのphaseまで動き正常に終了したでしょう。

これであなたはローカルでCodeBuildを試すことができるようになりました。

しかし注意してください。cacheの機能は動きません。

### ちょっと解説

`codebuild_build.sh`に指定のオプションを渡すことでよしなに実行してくれます。

中身としてはdockerコマンドを最終的に実行している形のため、詳しく見たい人は[見てみるといいでしょう](https://github.com/aws/aws-codebuild-docker-images/blob/master/local_builds/codebuild_build.sh)。

では、指定するオプションについて軽く説明です。

ドキュメントは[こちら](https://github.com/aws/aws-codebuild-docker-images/tree/master/local_builds)。

| オプション | 説明                                                         | 必須 |
| ---------- | ------------------------------------------------------------ | ---- |
| -i         | CodeBuildを動かすベースのコンテナイメージ                    | ○    |
| -a         | 生成物の出力先（アーティファクトと呼ばれるもの）             | ○    |
| -l         | 使用するCode build agent iamgeの変更                         |      |
| -c         | ホストマシンのAWS credentialsなどの情報のインポート          |      |
| -p         | 使用するAWSプロファイルの指定                                |      |
| -b         | buildspecの指定。指定が無い場合はソースディレクトリのbuildspec.ymlが使われる |      |
| -e         | 環境変数の指定。.envの形式などのファイルを指定する           |      |
| -m         | カレントディレクトリをソースディレクトリとしてマウントする   |      |
| -d         | privilegedモードでdockerを動かす                             |      |
| -s         | ソースディレクトリの指定                                     |      |

##終わりに

途中まではノリノリで書いてたけど途中から若干迷走した。
Macでlocal by flywheelでlocal's router is having trouble startingというエラーがでた時の解決法

#local's router is having trouble starting
一番簡単だと言われているflywheelが動いてくれない。
ここでつまづく人は間違いなくずぶずぶの素人でしょう。
一年前の僕も訳が分からなくてteratailで投稿したらやって欲しいことを丸投げした投稿と言われ低評価がたくさんつきました。（未だにこのエラーを検索すると上のほうに来ます）
そして当時は諦めてMAMPで仮想環境を構築しました。

何でteratailはあんなに厳しいのかあそこは未だに怖いです。
みんなが優しくした方がいいと思います。

一年経ってパワーアップした僕が当時の僕のような方を救いたくこの記事を書いています。

##原因は？？
![スクリーンショット 2020-10-29 1.09.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700075/67a2381c-7c07-0fa8-c03b-4bd5cb8b49f4.png)

local's router is having trouble starting
訳すとローカルのルータにトラブルが起きてて始められないと言ってます。
・何かローカルのルーターが他で使用されてるするとこのエラーが出るようですね

##解決法　設定を変えましょう
根本的な原因解決にはならないですがこれで問題なく使えるようになります。

手順
macの上のメニューバーからLocal→preferences→ADVANCEDと進んで
![スクリーンショット 2020-10-29 1.35.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700075/00823057-72d2-32cb-269e-9de6e4c02248.png)

![スクリーンショット 2020-10-29 1.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700075/96d1558f-cb2a-43b6-4df3-3e14f742b997.png)

Router Modeをsite domainからlocalhostに切り替えAPPLYしましょう

エラーメッセージがwarningになりますが気にせず FIX IT
![スクリーンショット 2020-10-29 1.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700075/2007dae0-d30b-590b-5d13-d711838cfcf4.png)

これでlocal by flywheelが使えるはずです

###なぜ根本的な解決しないの？
難しいから

多分ターミナルをいじって80番ポートと443番ポートを開けてあげないとダメなのですがそれは難しいので初学者の方たちは上記の応急処置をしましょう。

ターミナルとは↓のようなやつですまだ触らなくて大丈夫です。

もしどうしてもやりたいなら
https://menta.work/plan/2100
で教えてるのでお問い合わせお願いします笑

![スクリーンショット 2020-10-29 1.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700075/7332d5fe-4fa6-8ffc-4cea-ac1db20e41a9.png)

###終わりに
過去の自分を救うつもりで丁寧に書きました。
1年間続けたら少しは成長したかな笑

もし分からないことがあればお気軽にコメントなどお願いします
twitterのフォローもお願いします！！
【awk】行が長い SQL の in 句などを数個単位でまとめて行を短くするスクリプト

SQL の in 句を編集するときがたまにあります。

テキストエディタでシングルクオートを付与したり、置換などして加工しますが、こんなときこそさくっと加工したいところです。

また、 in 句が縦に長いとコピペなどにも苦労するので、数個単位でまとめてみました。
サンプルは4個単位でまとめています。


```bash
echo 'A001
A002
A003
A004
A005
A006
A007
A008
A009
A010
A011' \
| awk '
  BEGIN {
    SQ="\047"
  }

  count++ {
    printf ","
  }
 
  {
    printf SQ $0 SQ
  }

  !(count%4) {
    printf "\n"
  }
'
```
結果は以下のように表示されます。

```sql
'A001', 'A002', 'A003', 'A004'
, 'A005', 'A006', 'A007', 'A008'
, 'A009', 'A010', 'A011'
```

こちらでも良さそうです。

```bash
echo 'A001
A002
A003
A004
A005
A006
A007
A008
A009
A010
A011' \
| awk '
  BEGIN {
    SQ="\047"
  }

  count++ {
    print ","
  }

  {
    printf SQ $0 SQ
  }
' \
| paste - - - -
```
結果は以下のように表示されます。

```sql
'A001', 'A002', 'A003', 'A004',
'A005', 'A006', 'A007', 'A008',
'A009', 'A010', 'A011'
```
備忘録No.3「入力された文字列を条件によって、文字ごとに入れ替え」[Java]

#はじめに
いわゆるLeet表記作成

#やりたい事
1.文字列を一つ入力(字数は自由)
2.文字ごとに判定し、変換を行う
3.変換された文字列を出力

#コード
```java
        public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();

        List<Character>list = new ArrayList<>();
        for(int i = 0; i < s.length(); i++) {
            list.add(s.charAt(i));//入力した文字列を一文字ずつCharacter型のリストに追加
        }

        for(int i = 0; i < s.length(); i++) {
            char c = list.get(i);
            switch(c) {
            case 'A':
                list.set(i, '4');
                break;

            case 'E':
                list.set(i, '3');
                break;

            case 'G':
                list.set(i, '6');
                break;

            case 'I':
                list.set(i, '1');
                break;

            case 'O':
                list.set(i, '0');
                break;

            case 'S':
                list.set(i, '5');
                break;

            case 'Z':
                list.set(i, '2');
                break;
            }
        }

        for(char word : list) {
            System.out.print(word);
        }
    }
```
ぐるなびAPIの使い方

##ぐるなびAPIについて
ぐるなびが提供しているAPIです。
店の名前や緯度経度などの店舗情報を取得できます。
詳しくは[こちら](https://api.gnavi.co.jp/api/manual/)を参照。
##使い方
手順に沿って使い方を説明していきます。
###手順１：アクセスキーを発行する
アクセスキーがないと何もできないためアクセスキーを発行します。
[公式サイト](https://api.gnavi.co.jp/api/manual/)の右上にある新規アカウント発行を押しアカウントを作成します。
メールでの本人確認が完了すると同じメールアドレスにアクセスキーが届きます。
###手順２：URLを生成する
ぐるなびAPIには[APIテストツール](https://api.gnavi.co.jp/api/tools/)というものがあり項目を入力するとURLを作成してくれます。
今回は東京駅の近くのお店の名前を表示したいと思うので、
API名はレストラン検索APIを選択。
keyidには自分のアクセスキーを入力します。
latitude(緯度)
longitude(経度)
range(範囲)
を追加して入力。
今回は緯度経度は東京駅の座標を、範囲は一番小さい1(300m)を使用します。
URLはあとで使用するのでコピーしといてください。
![03123b59c8b30f8d97428ae815ad6014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686889/871f5fcb-ad6c-6c88-94ba-dda5f3a6ae05.png)
###手順３：コードを入力する
以下のコードを入力してください。
URLは自分のものを入力してください。

```haml
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>
    <script>
        async function callapi() {
            const res = await fetch("https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=[自分のアクセスコードを入力]&latitude=35.681382&longitude=139.76608399999998&range=1"); //コピーした自分のURLを入力
            const users = await res.json();
            const rest = users.rest;
            console.log(users);
            Object.keys(rest).map(key => document.write('key:' + key + ' value:' + rest[key]["name"] + "<br>\n"));
            document.write("Supported by ぐるなびWebService : https://api.gnavi.co.jp/api/scope/");
        }
        callapi();
    </script>
</body>


</html>
```
コードを実行すると店名が表示されます。
![beb5eae42546b68fb87884dcd7c2b54b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686889/9f4e7f3c-b7e1-e0fd-cb14-c5e5bb2ebb00.png)
##コードの説明
少しコードの説明をします。
非同期処理でAPIの取得を行っています。

```javascript
const res = await fetch("https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=[自分のアクセスコードを入力]&latitude=35.681382&longitude=139.76608399999998&range=1"); //コピーした自分のURLを入力
            const users = await res.json();
```
ここではAPIからjsonファイルを取得しています。

```javascript
Object.keys(rest).map(key => document.write('key:' + key + ' value:' + rest[key]["name"] + "<br>\n"));
```
restをmapで取り出して店の名前を表示しています。
["name"]の部分を変更すると他の値を表示できます。
受け取れる値はこの[サイト](https://api.gnavi.co.jp/api/manual/restsearch/)のレスポンスを確認しましょう。
PR文(short)を表示してみます。

```javascript
Object.keys(rest).map(key => document.write('key:' + key + ' value:' + rest[key]["pr"]["pr_short"] + "<br>\n"));
```
![aaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686889/56202f5e-16e8-7501-66df-91f440ad6882.png)
PR文が表示されました。
##利用規約について
最後にぐるなびAPIは利用規約でクレジットを表示しなければならないという物があります。
忘れずにつけましょう。
詳しくは[こちら](https://api.gnavi.co.jp/api/guide/)
IBM Cloudの認定資格をとろう（IBM Certified Professional Developer - Cloud v4編）

# IBM Certified Professional Developer - Cloud v4とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5756e45e-90d3-b0d7-d6e4-3324d892cb65.png)

過去記事[IBM Cloudの認定資格をとろう（概要編）](https://qiita.com/teruq/items/62fe97cd25c0110ee030)のとおり、IBM Certified Professional Developer - Cloud v4はIBM Cloud認定資格のProfessional（中級）レベルの1つです。しかし、難易度は**非常に**高いです。個人的にはこれを獲れたら上級者と言っていいのではと思います。

# 出題範囲

公式の[Study Guide](https://www.ibm.com/certify/api/getpdf/studyguides/stuc1000_109)がベースです。ただし、例によってこれ以外の出題も多少ありえます。

試験規約により具体的なアドバイスはできないのですが、出題範囲はFoundationsとあまり変わらず、問題文や選択肢がかなり難しくなっていた印象でした。

アプリケーション開発の認定試験のように見えますがアプリケーション開発の知識は問われませんでした。

# 無料で受けられるe-ラーニング

この試験に特化したものは残念ながらなさそうです。

# 有料で受けられるe-ラーニング

## Cloud Developer Professional - Learning Path

* URL https://www.ibm.com/training/path/137
* 所要時間 61.7時間

有料で、なんと年間$3600のサブスクリプション購入が必要です。ただし、このコースだけではなく、他のProfessionalレベルのIBM Cloud認定資格のe-ラーニングも含まれているようです。

> https://www.ibm.com/training/subscriptions/SUBR014G

IBM Cloudの認定資格をコンプリートしたい、会社がお金を出してくれる、英語でも大丈夫、という方は利用してみるといいかもしれません。

なお、私はこれを受けていないので、本番試験で有用なものかはわかりません。

# 受験方法

PersonVUE社のサイトから「C1000-109: IBM Cloud Professional Developer v4」を予約し、最寄りの会場で受験してください。受験料は2万円（税抜）です。

> https://www.pearsonvue.co.jp/Clients/IBM.aspx

テストセンターによって試験を開催している日にバラツキがあります。東京駅近辺ですと、秋葉原のテストセンターはほぼ毎日開催していますし、前日予約も可能ですので、急に受けたくなったときはお勧めです。

# 出題形式

1/4択はまた2/5択がほとんどです。基本的には「正しいものを全て選べ」系の問題はないので、そこは安心です。

ちなみにもちろん試験は英語です。

試験時間は90分です。私の場合、足りないということはありませんでしたが、あまり余裕はありませんでした。

# 合格条件

64問中43問以上の正解で合格となります。正答率67%以上に相当します。Foundations試験が71%でしたので甘くなってはいますが、その分難しいです。

# リトライしたい場合

1回で駄目でも記憶がフレッシュなうちに2回目を受験することをお勧めします。IBMの認定試験は同じ試験を30日間に2回まで受験できます。もちろん別料金です。

# アドバイス

繰り返しますが、難易度はかなり高いです。自慢ではないですが私はIBMの認定資格はこれまで10科目以上無敗だったのですが、このときは試験終了ボタンを押すときに初めての敗北を覚悟しましたがなんとかぎりぎり合格でした。
to_iメソッド

#to_iメソッド

**文字列が持つメソッドです。文字列を数値に変換してくれます。**
ちなみに、 to_iのiの意味は「integer(整数)」です。
以下の例を見てください。

```java:【例】irb
# 文字列「30」にto_iメソッドをつけて実行
irb(main):001:0> "30".to_i
=> 30
```

もし数字以外の文字列だった場合は、すべて数値0に変換されます。

#irbで以下のコードを実行しましょう

to_iメソッドを試してみましょう。

```java:irb
# to_iで文字列を数値に変換
irb(main):001:0> "100".to_i + 400
=> 500
```

#まとめ

**to_iメソッドとは、文字列を数値に変換するメソッド。**


#####以上。
Xcodeでプロジェクトを作成してGitHub管理するまでの環境構築

# はじめに
Xcodeでプロジェクトを作成してから、GitHubでソースを管理するまでの環境構築手順をまとめました。

AppleアカウントとGithubアカウントの登録がXcode上で行われていることが前提です。
アカウント設定等のインストールからの初期設定はこちらの記事で行いました。
[Xcodeをインストールして実機でHello Swift!](https://qiita.com/amatsukix/items/97158c8bac4ca1d07472)

# プロジェクト作成
Create a new Xcode projectからプロジェクトを作成します。
![スクリーンショット 2020-10-29 0.40.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/73bb8107-fc5e-3188-4ea0-ed60a766cdce.png)

Appを選択します。
![スクリーンショット 2020-10-29 0.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/fa724b59-bf20-6911-c34f-39923aeccee3.png)

Project NameにSampleProjectと入力します。
その他の項目については自動的に設定されているはずです。
![スクリーンショット 2020-10-29 0.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/c57096af-2605-5f76-0445-7a9c25515709.png)

ローカルにGitリポジトリを作成するので、チェックをつけてプロジェクトを作成します。
![スクリーンショット 2020-10-29 0.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/9929f412-22de-1322-60b6-e39eaf26c4be.png)

# リモートリポジトリ作成
[Show the Source Control navigator]を選択して、Remotesを右クリックします。
[New "SampleProject" Remote...]を選択します。
![スクリーンショット 2020-10-29 0.42.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/48a7a156-70a0-245b-ab6e-65774db7370b.png)


この画面からリポジトリの設定をして作成完了です。
![スクリーンショット 2020-10-29 0.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/b65616c7-968b-9283-bd90-fa89ad0d548b.png)
M75q-1のArchLinuxでlm_sensorsを使う

# やりたいこと
せっかくM75-qにLinuxを入れたので、ハードウェアの状態を取得したい。
特に、[Folding@home実行](https://qiita.com/air-gh/items/c60e1bcf0ff449db46db)前後でどう変化するのか…

# 環境
- ハードウェア: M75q-1
- OS: ArchLinux
- カーネル: `linux-zen`

# M75q-1のSuper I/O
[こちらの貴重なお写真](http://www.neko.ne.jp/~freewing/hardware/lenovo_m75q_amd_ryzen_5_pro_3400ge/)によると、M75q-1はIT8738Eの模様。
しかし、[本家](https://www.kernel.org/doc/html/latest/hwmon/it87.html)によると、対応チップに入っていない…無念。

# IT8738E対応it87.c
[こちらのソースのコメント](https://github.com/a1wong/it87/blob/master/it87.c)には、IT8738Eという記述がある。

それではこちらをM75q-1のArchLinuxに入れてみよう。

## ビルド

パッケージは他にも入れたかも…

```shell-session
sudo pacman -Syu base-devel linux-zen-headers dkms lm_sensors
git clone https://github.com/a1wong/it87.git
cd i87
make dkms
```

dkmsで簡単。

## 設定
[先ほどのソース](https://github.com/a1wong/it87/blob/master/it87.c)によると、

```c:it87.c
#define IT8738E_DEVID 0x8738
```

とのことなので、

```:/etc/modprobe.d/it87.conf
options it87 force_id=0x8738
````

```:/etc/modules-load.d/it87.conf
it87
```

## 確認
```shell-session
$ sudo modprobe it87
modprobe: ERROR: could not insert 'it87': No such device
```

ん? [lm_sensorsのArchWiki](https://wiki.archlinux.jp/index.php/Lm_sensors)にもある、`acpi_enforce_resources=lax`のやつか?

## カーネルコマンドラインパラメーターの設定
```:/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet acpi_enforce_resources=lax"
```

```shell-session
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
```

## 再確認
再起動して…

```shell-session
$ lsmod | grep it87
it87                   69632  0
hwmon_vid              16384  1 it87
```

```shell-session
$ sensors
: (前略)
it8738-isa-0a30
Adapter: ISA adapter
: (後略)
```

動いた。

# 宿題
- 肝心のFolding@home実行前後での測定
- ファン制御
AWSでSlackへのPOST先を限定する仕組みを構築する話（成功ルート）

# 0. はじめに

今年の7月にAWSアソシをギリで取得した初心者が、AWSでそれっぽいことをする奮闘記である。の続き。
https://qiita.com/haman/items/3ab610dd4f3c00584dd0

一応、成功ルート。


# 1. やりたいこと
これはおさらい。
情報流出を防ぐために、みんなで作るLambdaのPOST先をSlackだけに**システム的に絞りたい**。

![slackAWSPOSTAPI-1-Page-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/7979e506-f16f-4fca-f0bf-42132fa90a6b.png)


# 2. 失敗ルートを活かして
上の図のsomething new!のところは、既存のものではなかなか実現できなそう。
であれば、自分たちで作れば良い。

言葉にすると、
みんなで作成するLambdaとAPI-GW（UserLambdaとでも呼ぼう）の後ろに、
検疫所の役割を担うLambdaとAPI-GW（Post_Lambdaとでも呼ぼう）を準備する。

構成図にすると、こちら。
![slackAWSPOSTAPI-1-todo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/fc908c0e-976a-f6d5-4a0c-78b1d619104f.png)

# 3. リサーチ＆トライ
そもそも出来るんだっけ？を調べる。
この記事を見るに、うん、出来そう。（実際はこんなに早くない、検索は相当してる。）
[AWS Lambda関数の呼び出し方を改めて確認する(2)](https://qiita.com/horit0123/items/86c727d8d3ae74b9e52a)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/ee85268b-fe14-61fe-7979-195f70e4770e.png)




## UserLambda
UserLambdaは、自力でインターネットに出れないようにするために、
前回と同様に、VPCを設定しプライベートサブネット内に閉じ込める。
これで外部へはいけない。
※CloudWatch logsなどはエンドポイント経由でアクセスする。

通常、インターネットゲートウェイをVPCにアタッチして、外へ出ていけるけど、
今回UserLambdaが連携する先は、AWS内にあるサービスであるAPIGWのため、
APIエンドポイント({api-id}.execute-api.{region}.amazonaws.com)を配置して通信する。
インターネットゲートウェイは不要。

## Post_Lambda
Lambda側はチェックして、基本はUserLambdaから渡された情報をバトンパスするくらい。
API-GWはリージョンAPIではなく、プライベートAPIを利用する。

> インターフェイス VPC エンドポイントを介して公開された API エンドポイント。これにより、クライアントは VPC 内部で安全にプライベート API リソースにアクセスすることができます。プライベート API はパブリックインターネットからは分離されており、アクセス権限を付与されている API Gateway の VPC エンドポイントを使用してのみアクセスできます。

こちらの記事のこの画像がとても参考になった。わかりやっす。
https://cloudpack.media/52328
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/725f6229-1331-fb8a-1347-7c32555ed180.png)

# 4. 小石につまづく
なんかうまくいかない…なぜ…。
こういう時は、くだらない理由ってのは分かっているけど、まぁ先に進まない。
数時間つまづいた…

**① urllibの使い方を間違える**
　完全な思い込み。
　ゴミ情報も一緒に送っていた。

**② API-GWデプロイし忘れ**
　最終的な疎通検証で一向に変化がなく、通知されない！
　なんでだ…………からの気づいた時のあのアハ体験。アドレナリン惜しまない。
　このデプロイし忘れ、「あるある」なんだろうな。


# 5. さて、次はこっちへ
さて、この仕組みをみんなに使ってもらう必要がある。
正直、しんどい。

UserLambdaは下記のとおり「閉じ込め」がとても重要なんだけど、
この「閉じ込め」のための設定（VPCやサブネット等の設定）を
ミスる可能性があり、うまく機能してくれないという問題がある。
そして何よりも、設定すべき項目が多くて非常にダルい。
これはいけない。

> UserLambdaは、自力でインターネットに出れないようにするために、
前回と同様に、VPCを設定しプライベートサブネット内に閉じ込める。


LambdaやAPI-GWをテンプレ化して、もっと簡単にこのUserLambdaを作れるようにしたい！
Lambda テンプレで検索すると、CloudFormation…ふむ、君に決めた！
　　　　　　　<img width="300" alt="君に決めた_Cloud.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/92a1ff76-94dd-3d0e-df5b-2dfd1ba205d4.png">


それはまた、別のお話で。
プロゲート【JQuery中級】modal,hover,addclass,removeclass,hasclass

# progate:JQuery中級コース

- jQueryは.js形式
- HTMLファイルで、<script src=“ファイルのURL”></script>と書くことで、jQueryのコードを記述するファイルが読み込まれる
- scriptはbodyの直前に書くことで、WEBページの表示速度をより早めることが出来ます。

```script.js
// JQuery基本の方
$(document).ready(function(){

});

// 略
$(function(){ });
```

```index.html

<!-- headタグでjqueryの読み込み -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" type="text/javascript" charset="utf-8">
  </script>


<!-- bodyタグでjsファイルの読み込み -->
  <script  src="script.js" type="text/javascript" charset="utf-8">
  </script>


```

## モーダルの表示/非表示
モーダルを表示させる手順
①htmlにモーダルを作る
②cssを整えて、display: none;で非表示にする
③script.jsでclickイベントを作る(fadeIn)

```script.js
$(‘#login-show’).click(function(){
    $(‘login-modal’).fadeIn();
  });
```

モーダルを隠す手順
①htmlにモーダルを閉じるボタンを作る
③script.jsでclickイベントを作る(fadeOut)

※共通で使う場合はclassを使う

## hover機能
　hover機能を使う手順
①htmlでclassを追加
②script.jsでhoverイベントを作成

```script.js
  $('.lesson-hover').hover(
    function(){
      
    },
    function(){
      
    }
    
    );
// hoverの引数はカーソルを乗せた時と外した時で２つ作る
```

### addClassとremoveClass

※addClassとremoveClassの引数にドットは不要

```script.js
$('.lesson-hover').hover(
    function() {
      $(this).find('.text-contents').addClass('text-active');
    },
    function() {
		$(this).find('.text-contents').removeClass('text-active');
      
    }
  );
```

## アコーディオン
①答えの部分はCSSで非表示。
②3つの質問部分には同一のclass名を付与
③それらのclickイベントを作成。質問をクリックした時に、対応する答えを隠すのか表示するのかを判断するため、openというclassを用います。
答えの表示中はopenをつけ、非表示中は外す。

### hasClassメソッド
> hasClassメソッドは、引数に指定したクラスを、オブジェクトが持っているか判定するときに使用します。オブジェクトがそのクラスを持っていればtrue、持っていなければfalseを返します。[-progate-](https://prog-8.com)

```script.js
$('.faq-list-item').click(function(){ // clickイベント
    var $answer=$(this).find('.answer'); // 変数の定義
    
    if($answer.hasClass('open')){
      $answer.removeClass('open') // $answerにopenがあった場合の処理
    }else{
      $answer.addClass('open'); //openがなかった場合の処理
    }
    
  });
```

### アコーディオン完成形
```script.js

  // FAQのアコーディオン
  $('.faq-list-item').click(function() {
    var $answer = $(this).find('.answer');
    if($answer.hasClass('open')) { 
      $answer.removeClass('open'); 

      $answer.slideUp(); 
      $(this).find('span').text('+');  
    } else {
      $answer.addClass('open'); 
      $answer.slideDown();
      $(this).find('span').text('-');
      
    }
  });
```
kaminariで"ページネーションのhtml要素"を非同期に出す

「kaminari 非同期」で検索すると、ページネーションの"リンク先のページ"を非同期で表示する方法が出てきます。kaminariのREADMEで紹介しているのもコレです。
https://github.com/kaminari/kaminari

そうではなくて、"ページネーションのhtml要素"を非同期で後から出す方法の紹介です。
検索してもあまり出てこなかったんですよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694808/dc7abfd3-4f93-86af-f3bb-93d6a1a300cf.png)
(↑ページネーションのhtml要素)

Gemのバージョンは`kaminari (1.2.1)`, `rails (6.0.3.4)`です。

## なぜ非同期に?

普通にkaminariでページネーションの要素を出すときは、ビューで`<%= paginate(@users) %>`のように書きます。
でもこれ、最後のページが何ページ目なのか求めるために、「レコードの全件数を取得するクエリ」が流れるんです。

```sql
SELECT COUNT(*) FROM users;
```

この場合は軽そうですが、色々と検索条件を付けていくと重いクエリになりそうです。なのでページネーションの要素は非同期で表示させたい、というのが動機です。

## 実装

最初に全体像を載せます。Railsで、Userモデルのindexページ、という想定です。

```ruby:routes.rb
resources :users
```

```ruby:users_controller.rb
def index
  users = User.all.page(params[:page]).per(3)
  respond_to do |format|
    format.html { @users = users.without_count }
    format.json { render :json => view_context.paginate(users).gsub('.json', '') }
  end
end
```

```html:users/index.html.erb
<div id="paginator"></div>
<script>
  document.addEventListener('DOMContentLoaded', () => {
    const path = location.pathname + '.json' + location.search;
    const paginator = document.querySelector('#paginator');
    fetch(path).then(response => response.text()).then(html => {
      paginator.insertAdjacentHTML('afterbegin', html);
    })
  })
</script>
```

## 解説

処理の流れを順に説明します。最初、usersコントローラーのindexアクションにhtmlのリクエストが来たら、モデルに`.without_count`メソッドを付けてからviewに渡します。

```ruby
format.html { @users = users.without_count }
```

このメソッドをつけると、先程載せた「レコードの全件数を取得するクエリ」が発行**されなく**なります。
ページネーションの要素が付いてないhtmlが返され、同期処理は終わりです。

ここからが非同期です。返したhtml(内のjavascript)では、ページネーションの要素を非同期で要求します。
このときURLを`location.pathname + '.json' + location.search;`として、
「URLのパスの末尾をjsonに変えただけのURL」を送ります。元のパスが`/users?age=10`なら送るパスは`/users.json?age=10`です。

送られてきたリクエストは、同じくusersコントローラーのindexアクションに送られます。
URLに`.json`が付いているので、`respond_to`は`format.json`の方が呼ばれます。

```ruby
format.json { render :json => view_context.paginate(users).gsub('.json', '') }
```

`view_context`はビューのインスタンスを返すメソッドです( https://apidock.com/rails/ActionView/Rendering/view_context )。 これを使うとビューのメソッドをコントローラー等から使うことができて、`paginate(user)`が呼べます。
ここで使う変数`user`には`without_count`は付けていませんので、「レコードの全件数を取得するクエリ」が発行**されます**。
`paginate`メソッドで作られたページネーション要素ですが、formatがjsonだと(html以外だと)、リンクの末尾が`.json`となってしまいます。ですのでgsubで消します。
出来上がったhtml文字列をjsonで包んで返します。

受け取ったjavascript側では、それを適当な要素にくっつければ完了です。

```js
fetch(path).then(response => response.text()).then(html => {
  paginator.insertAdjacentHTML('afterbegin', html);
})
```

非同期でページネーション要素を出せました。
(↓の例ではsleepを入れています)

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694808/c658239f-212d-bbe8-6a78-21192b2c7815.gif)

いいですね、非同期。
この記事が誰かの役に立てればです。
Xcodeをインストールして実機でHello Swift!

# はじめに
XcodeでiPhoneアプリを実機で動かすまでをまとめました。
ついでにXcodeからGitHubでソース管理もしてみます。

# Xcodeインストール
App Storeで`xcode`と検索してでてくるアプリをインストールします。

私は古いバージョンのXcodeがインストールされていたためアップデートしようとしたのですが、
空き容量は十分あるにも関わらず、`空き容量が足りないため製品をインストールできません`とエラーが出てしまいました。

おそらくタイムマシンがアプリインストールの容量に影響してしまっていたようです。
Xcodeを一度アンインストールし、ゴミ箱を空にすると無事インストールすることができました。

直接Xcodeをインストールする方法もあるようです。
[App StoreからXcodeインストール時、空き容量があるにも関わらず「使用可能な空き容量がない」となる問題の解決方法](https://monaga.site/not-enough-disk-space-available-to-install-the-product/)

# Xcodeでアプリ作成

無事インストールが終わったので、アプリを作成します。
実機で動かしてみることが目的なので、HelloSwiftとだけ表示させるアプリを作ります。

## プロジェクト作成

Xcodeを起動して`Create a new Xcode project`からアプリを作成します。

次にAppを選択してNext
![スクリーンショット 2020-10-28 23.29.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/545c273b-03e6-11c6-d241-381185c92fac.png)

Project Name:アプリの名前
Team:未設定（後から設定）
Organization Identifier:メアドのようにユニークなID
Interface:Story board
Life cycle:UIkit App Delegate
Language:Swift
![スクリーンショット 2020-10-28 23.30.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/79afb7a2-e87d-a5c4-db06-45b1b8aceb4d.png)

ローカルにGitリポジトリを作成したいのでSource Controlにチェックをします。
Git管理が必要ない場合は外します。
![スクリーンショット 2020-10-28 23.30.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354517/c582d459-b48f-2def-943a-f55d6b7db185.png)

## hello swift
`Main.storyboard`を開いて右上の +ボタン(Library) を開いて`Label`を画面上にドラッグ&ドロップで配置します。
画面右側の`Show the attribute inspecter`メニューのTextを`Hello Swift`に変更します。

## シミュレータで動かす
▶︎ボタンの横にある枠(アクティブスキーム)からデバイスの種類を選び、▶︎ボタンを押してシミュレータを実行できます。

Hello Swiftと表示されていれば成功です。

# 実機で動かす
今回は手持ちのiPhone8Plusを使用しました。
まずはMacとiPhoneを接続します。

## AppleIDの登録
[Xcode]→[Preference]→[Accounts]の設定画面で+ボタンを押してアカウントを登録します。

メアドとパスワードを入力して登録完了です。

## Teamを設定

左側の[Project Navigater]でアプリ名が表示されているフォルダを選択します。
[Signing & Capabilities]メニューで先ほど登録したAppleアカウントのTeamを設定します。

## Could not launch "xxxxx"
アクティブスキームでデバイスを選択したら▶︎ボタンを押して実行しますが、このようなエラーが表示されました。
xxxxxはアプリ名です。

iPhoneの画面から[設定]→[一般]→[デバイス管理]を開きます。
Appleアカウントで登録したメアドが表示されているので、このアカウントを信頼となるように設定します。

再度 ▶︎ボタン で実行して起動完了となります。

# GitHubで管理

今回作成したプロジェクトをGitHubで管理できるようにします。

## Githubと連携

Appleアカウントと同じように[Xcode]→[Preference]→[Accounts]から+ボタンを押してGithubアカウントを登録します。

## リモートリポジトリの作成

ローカルには既にリポジトリができているので、リモートリポジトリを作成します。
画面左側の`Show the Source Control navigator`を選択し、[Remotes]を右クリックし、`New xxxxx Remote...`を選択してリモートリポジトリを作成します。

## コミット

[Source Control]→[Commit...]からコミット&プッシュするファイルを選択します。
あとはコミットメッセージにコメントを記載して、`Push to remote`にチェックを入れてコミットすればGithubのリポジトリに反映されています。
typescript × springboot

##アプリをサーバサイド Java、クライアントサイド TypeScript で作りたい

フロントエンド：typescript
バックエンド：springboot
でアプリを作りたい。

どうやって環境構築をすればいいのからわからないが、調べてみると
いくらか資料は見つかる。


typescript×springbootをどうやって連携させればいいのか？そのためにどんな知識が必要なのか？
その勉強も含めて取り組んでいきたいと思う。


参考記事（いつもありがとうございます）
---

[Spring BootのThymeleafとTypeScriptを組み合わせてみたかったのでやってみた](https://gup.monster/entry/2019/01/27/171022)

[Angular + TypeScript + Spring Bootをやってみた](https://gup.monster/entry/2018/02/25/063945)


[仕事ですぐに使える TypeScript](https://future-architect.github.io/typescript-guide/typescript-guide.pdf)

[続・Java と TypeScript をタイプセーフにツナグ](https://tc.hatenablog.com/entry/2015/07/10/073045)

[React + TypeScript の Examples 作ったので誰かレビューしてｗ](https://tc.hatenablog.com/entry/2015/10/31/220257)

[SpringBoot + TypeScriptをGradleでビルドする](https://qiita.com/jun-1/items/f0305d759161bff96333)

[How to Create REST with Spring-rest-2-ts and TypeScript
](https://morioh.com/p/977fbe7ce903)

[william-frank/typescript-service-generator
](https://github.com/william-frank/typescript-service-generator)

[JavaウェブアプリプロジェクトにJavaScript/TypeScriptなどの静的アセットをどう配置するか](https://blog.kengo-toda.jp/entry/2019/12/01/005852)

[Modern Web Apps with Spring Boot, Angular & TypeScript](https://speakerdeck.com/toedter/modern-web-apps-with-spring-boot-angular-and-typescript)

[TypeScriptとMavenを使用してAngular2アプリケーションを構成する方法は？](https://www.it-swarm-ja.tech/ja/maven/typescript%E3%81%A8maven%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6angular2%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%EF%BC%9F/823955873/)
EC2にSSH接続した際、Permission denied (publickey,gssapi-keyex,gssapi-with-mic).と表示される時の対処法

#注意
かなり初心者向けなので、めちゃくちゃ初歩的な内容です。
それでもエラーで詰まってしまった人が挫折しないように備忘録的に残しておきます。

#環境の前提
macOSのterminalからEC2にSSH接続しているという前提とします。
tera termだとGUIでキーペア指定できるので、まずこのエラーと遭遇することはないかと思います。



```
ssh -i <キーペア名> ec2-user@<EC2のIPアドレス(ホスト名)>
```

と入力すると

```
Warning: Identity file <キーペア名> not accessible: No such file or directory.
ec2-user@<ホスト名>: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```
のエラー...

## 対処法

カレントディレクトリ(Macだと``pwd`` ,windowsだと``cd``でわかるやつ)にキーペアがないとエラーが出ます。
キーペアがあるディレクトリに移動する

```
cd (キーペアがあるディレクトリ)
```


かもしくは

ホームディレクトリにキーペアをコピー

```
cd ~
mv (ダウンロードしたディレクトリ)awskey.pem .
```

して

```
ssh -i <キーペア名> ec2-user@<EC2のIPアドレス(ホスト名)>
```

と入力すればSSH接続できるはずです。

## 改訂(2020/12/7)
だいぶ知識のない状態でこの記事を書いたので(~~恥ずかしい...~~)
訂正させていただきました。
間違っている場所とか、お気づきの~~マサカリ~~点があればコメント等頂けたら再度訂正します。
JavaScriptでのオブジェクトコピーについてのメモ

JavaScriptでのオブジェクトコピーについてのメモ


※2020/10/31 追記
@standard-softwareさんのコメントより、Object.assignを非破壊的に使う方法を教えていただいたので追記しました。

## 概要

JavaScriptでオブジェクトをコピーしたいときに２つの書き方がある

1. Object.assign(コピー先, コピー元)を使う
2. スプレッド構文を使う

## Object.assign(コピー先, コピー元)を使う
> Object.assign() メソッドは、すべての列挙可能な自身のプロパティの値を、1つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。
[Object.assign() - JavaScript | MDN](
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

※ Object.assignはコピー先のオブジェクトそのものを書き換える`破壊的メソッド`

```javascript
const targetObj = {
    key1: 'value1',
    key2: 'value2'
};

const copyObj = Object.assign(targetObj, {key3: 'value3'});

console.log(copyObj); 
// { key1: 'value1', key2: 'value2', key3: 'value3' }

// Object.assignはtargetObj自体を書き換える破壊的メソッドであることを確認
const targetObj2 = {
    key1: 'value1',
    key2: 'value2'
};

console.log('before : ', targetObj2);

const copyObj2 = Object.assign(targetObj2, sourceObj);

console.log('after : ', targetObj2);
// before :  { key1: 'value1', key2: 'value2' }
// after :  { key1: 'value1', key2: 'value2', key3: 'value3' }
```

※ Object.assignを非破壊的に使うことも可能（2020/10/31追記）

```javascript
// Object.assginを非破壊的に使うこともできる
const targetObj1 = {
    key1: 'value1',
    key2: 'value2'
};

const targetObj2 = {
    key3: 'value3',
    key4: 'value4'
};


console.log('before : ', targetObj1);
// before :  { key1: 'value1', key2: 'value2' }

// 空オブジェクトに1と2をコピーすれば、targetObj1を汚染しない
const resultObj = Object.assign({}, targetObj1, targetObj2);

console.log('after : ', targetObj1);
// after :  { key1: 'value1', key2: 'value2' }
console.log('result : ', resultObj);
// result :  { key1: 'value1', key2: 'value2', key3: 'value3', key4: 'value4' }
```

## スプレッド構文を使う
※ Object.assignと異なり、`非破壊的メソッド`
コピー先を変えずに、プロパティを追加した新しいオブジェクトを作成できるため、こちらを使う方がよい

```javascript
const targetObj = {
    key1: 'value1',
    key2: 'value2'
};

const sourceObj = { key3: 'value3'};

const copyObj = {...targetObj, ...sourceObj};

console.log('copyObj : ', copyObj);
// copyObj :  { key1: 'value1', key2: 'value2', key3: 'value3' }
console.log('targetObj : ', targetObj);
// targetObj :  { key1: 'value1', key2: 'value2' }

```

## 注意事項
どちらもシャローコピーになるため、プロパティの値がオブジェクトだった場合、参照のみがコピーされる。
下記では、
・ bookCopy.nameを変更してもbook.nameに影響はない
・ bookCopy.relatedBook.nameを変更すると、book.relatedBook.nameも変更されてしまっている。

```javascript
const book = {
    name: '独学大全',
    author: '読書猿',
    relatedBooks: {
        name: '問題解決大全'
    }
}

const price = { price: 1000 }

const bookCopy = {...book, ...price}
console.log(bookCopy);
/*
{
    name: '独学大全',
    author: '読書猿',
    relatedBooks: { name: '問題解決大全' },
    price: 1000
}
*/

// bookCopyオブジェクトのnameを変更する
bookCopy.name = 'アイデア大全';
// bookCopyオブジェクトのrelatedBooks.nameを変更する
bookCopy.relatedBooks.name = '新刊?'
console.log('bookCopy : ', bookCopy.relatedBooks.name);
console.log('book : ', book.relatedBooks.name);
// bookCopy :  新刊?
// book :  新刊?

```

## 参考
[Object.assign() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)