OmniAICreator/Qiita-1.07M huggingface dataset:
rails newからgithubにpushするまでの備忘録

## Qiitaに山ほどあるのに何で書いたの？馬鹿なの？
ぼくが読みやすいのがなかった。それだけ。

## 前提条件
- 環境はCloud9
- 別プロジェクトでgithubにSSH鍵が登録済みとする
    - ここらへんはググれば出てくるので調べてみてね！

## cloud9でrails newする

以下のコマンドでrailsのプロジェクトを作成します。
「＜your_project-name＞」に作りたいプロジェクト名を入れてね！

```
rails new <your-project-name>
```

「tsundoke」というプロジェクトを作成する際の例は以下です。
以降の手順はこのプロジェクトをgithubにぶち込むまでをたどります。

```
ec2-user:~/environment (master) $ rails new tsundoke
      create  
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  Gemfile
         run  git init from "."
　　　　　　：
      (このあとずらずらと続くので省略)
　　　　　　：
ec2-user:~/environment (master) $
```

## cloud9側でリモートに上げる準備をする

1. 作成したプロジェクトに入り、
2. git initし、
3. rails newで作成したファイルを全部addし、
4. 「initial commit」というコメントを付けてコミットします。

それぞれのコマンドの意味は調べてください。ぶっちゃけ思考停止で叩いてます。
4のコメントは自分がわかれば何でも良いです。
「initialじゃねぇfirstだ！」とか「create new projectだ！」とか、そこらへんの感覚は自分のプロジェクトや自分の感性に合わせてください。

```
ec2-user:~/environment (master) $ cd tsundoke/
ec2-user:~/environment/tsundoke (master) $ git init
ec2-user:~/environment/tsundoke (master) $ git add .
ec2-user:~/environment/tsundoke (master) $ git commit -m "initial commit"
```

## github側で受け側になるrepositoryを作る

githubにログインして、トップページ左側の「Repositories」ペインの右上にある「New」ボタンを押下します。
<img width="711" alt="スクリーンショット_2019-02-10_17_49_12.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/947ab9f5-6c53-7e42-4f81-60382fedb92e.png">

「Repository name」にリポジトリ名を入力し、「Create Repository」ボタンを押下します。
途中の「Public/Private」はお好きにどうぞ。
~~ぼくはポートフォリオ的なノリで作ってるので公開プレイです~~
<img width="763" alt="スクリーンショット_2019-02-10_17_49_56.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/8e7e459c-079d-95fc-1fa2-1affe7898f02.png">

無事リポジトリが生成されると以下のような画面になります。
「SSH」を押して、表示されたURLをコピーします。

<img width="1011" alt="スクリーンショット_2019-02-10_18_04_55.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/1d23ec5d-5500-46a2-13de-978df26a1246.png">

## githubに投げ込む

cloud9側のリポジトリとgithubのリポジトリを接続します。
ここで躓いた方は下の方にあるおまけを見てね！ぼくは躓いたよ！！

```
ec2-user:~/environment/tsundoke (master) $ git remote add origin <コピーしたURL>
```

エラーにならなかったらいよいよgithub側にpushしていきましょう。

```
ec2-user:~/environment/tsundoke (master) $ git push origin master
Counting objects: 87, done.
Compressing objects: 100% (72/72), done.
Writing objects: 100% (87/87), 21.64 KiB | 1.20 MiB/s, done.
Total 87 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), done.
To github.com:ginger893/tsundoke.git
 * [new branch]      master -> master
ec2-user:~/environment/tsundoke (master) $ 
```

終わったらgithub側にソースが反映されていることを確認して、作業終了。おつかれさまでした。

<img width="1005" alt="スクリーンショット 2019-02-10 22.41.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/22b8e527-4217-4a94-4109-9a6ecc519afa.png">


## おまけ：git remote add originで「remote origin already exists.」な場合

コマンド叩いた瞬間以下のエラーが返ってきたのだ。

````
ec2-user:~/environment/tsundoke (master) $ git remote add origin git@github.com:ginger893/tsundoke.git
fatal: remote origin already exists.
````

個人開発で聞く人もいないので、とりあえず開発進める方向に舵をきっていこう。
addで足すなら、deleteとかremoveとかで消せるでしょ？とググったらそのとおりでした。まーじーでー？

```
ec2-user:~/environment/tsundoke (master) $ git remote remove origin
```

この後でaddすればOK。
Postgresのカラム数と1レコードサイズの上限に関するメモ

#背景
Postgresを使った大量のカラムが必要なシステムがあり、Postgresのカラム数
制限(250～1600)を信じてテーブルを作ったがエラーが発生したのでメモ。

#環境
- Postgres11
- 1テーブルあたりのカラム数 1500　(実際には数は数千になるがテーブル分割により対応）
- カラム型 double precision
- 言語 Pytnon(psycong2)

#状況
この状況でcreate table は可能だったため、安心していたところ
データをinsertするときになって以下エラーが発生

```
psycopg2.OperationalError: row is too big: size 10728, maximum size 8160
```

#原因
原因としては、1レコードサイズに8160バイトという制限がありそれを超えたため。
double precisionは、8バイトのため、8バイトx カラム数が8160バイト以下になる
ようカラム数を1000にしたところ解決。
Spresenseで”ひっくり返すと音楽が止まるプレイヤー”作ってみた

最近、趣味でマイコンをいじりはじめたので、いろいろ作ってみようかなと思い立ちました。
せっかくなので、自分が経験したことを共有したいと思います！！

# 開発環境
開発環境としては、昨年発売された高性能マイコンボードSpresenseを使ってみようと思います！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/e221695d-6dfb-570e-1079-94b6a5e9c30d.png)

Spresenseとは？
* Arduino 互換のソニーのボードコンピュータ
* マルチコアを内蔵したハイパフォーマンス
* GPSによる測位機能、ハイレゾリューションオーディオの再生・録音機能、低消費電力
* DNNを動かせるライブラリが存在
などの特徴を持ちます。
- https://developer.sony.com/ja/develop/spresense/developer-tools/introduction

# なんでSpresense？
勉強のために、RTOSとかArduinoをいじってみたかったのが一番です！あとは、画像処理、ディープラーニングに興味があって、それを動かせる性能がある手ごろなものがSpresenseでした。
たぶんこれを買う人はみんな同じような動機な気がします笑

# 苦労したこと
情報が全然ない！！知識がある方だったら大丈夫だと思うんですが、私のような初心者には厳しかったです。。。

サンプルコードなんてのも、全然ないので手探りでしたね。もっといろいろサンプルアプリがあれば楽だったのになぁ。

# 今回作りたいこと
ここからが本題です、今回は、”ひっくり返すと音楽が止まるプレイヤー”を作ってみました。着想は、加速度センサとAudio機能を使って何かできないか、というところです。

使用するモジュール類はこんなものを使いました。
- Spresense：[公式](https://developer.sony.com/ja/develop/spresense/specifications)
- Spresense拡張ボード：[公式](https://developer.sony.com/ja/develop/spresense/specifications)
- ROHM センサAdd-onボード SPRESENSE-SENSOR-EVK-701 [公式](https://www.rohm.co.jp/support/spresense-add-on-board)

このRohmのAdd onボードに加速度センサがくっついています。

# さあやってみよう 
こんな流れで、実装まで行ってみました。

* 機能決め
* ざっくり設計、実装
* 結果

## どんな機能をもたせる？？

今回は、初めて触るマイコンのお勉強なので、簡単な機能に絞ります！

* 本体が上向きで、音楽が再生できること
    * 初めから再生されること
* 本体が下向きで、音楽が停止できること
* 音楽が最後までいったら、ループすること

調べてみると、ひっくり返すと止まる目覚ましがあるみたいですね。
[LEXON レクソン 置き時計 アラームクロックFLIP amazon リンク](https://www.amazon.co.jp/LEXON-%E3%83%AC%E3%82%AF%E3%82%BD%E3%83%B3-%E7%BD%AE%E3%81%8D%E6%99%82%E8%A8%88-%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%A0%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AFFLIP-%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%A0%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF/dp/B06ZXRW37V?th=1)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/205071/64483c87-a77b-6169-f97d-7f9c50f38b00.png)


## どんな設計？？
やたらめったらやっても失敗するので、それっぽい状態遷移図だけ書いてみました。
![statechart.JPG](https://qiita-image-store.s3.amazonaws.com/0/205071/12a3cb20-e199-80d7-5269-713fdab806dc.jpeg)

## どうやって実装する？？
今回はArduino IDEを利用するため、ポーリングのみとしました！（加速度センサから割り込み発生させるやりかたもよくわからないし。。。）

アクティビティ図はこんな感じ。
![activity.JPG](https://qiita-image-store.s3.amazonaws.com/0/205071/7ece5da0-95ad-b7a8-1bc1-9f8009fb8cb2.jpeg)

SpresenseのAudio APIをどうもうまく使いこなせず、今回はFileのopenとcloseを音楽の停止と再生と同時に行っています。

# うごかしてみると・・・？
こーんな感じに動作します。いろんな曲をランダム再生とかだったら案外つかえるかも？

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/vZ_Fo5380CE/0.jpg)](http://www.youtube.com/watch?v=vZ_Fo5380CE)


# github
https://github.com/sugupoko/spresense-peripheral-test/tree/master/flip_audio_player

# 最後に
これからもいろいろSpresenseをいじっていこうと思っています！
SpresenseでOpenPoseとか動かしてみたいなぁ。。。
Macでwgetコマンド を使ってみるメモ

#　wgetとは
　「wget」コマンドは“ノンインタラクティブなダウンローダー”です。「wget URL」で指定したURLのファイルをダウンロードします。

#　wgetの書式

  - wget [オプション] URL
  - wget -r [オプション] URL （指定したURLからのリンクも含めて保存する（再帰ダウンロード））

#　Macにwgetインストール
Homebrewを使ってwgetコマンドをインストールしてみていきます。ターミナルを開けてwgetをインストールします。

```bash
$ brew install wget
```
wgetコマンドがインストールされます。次のコマンドを実行してみましょう。

```bash
$ wget -h
```
上記のコマンドが実行されたら、次のような内容が表示されます。

```bash
GNU Wget 1.20.1, 非対話的ネットワーク転送ソフト
使い方: wget [オプション]... [URL]...
```
**:eight_pointed_black_star:wgetの主なオプション**


オプション|意味
:--|:--
-b<br>--background<img width=400px/> | バックグラウンドで実行する。経過のメッセージは「-o」オプションで指定したログファイルへ、指定がない場合は「wget-log」に出力する 
-o ファイル名<br>--output-file=ファイル名 | 経過のメッセージを全て指定したファイルに出力する 
-a ファイル名<br>--append-output=ファイル名 | 「-o」オプションのように経過のメッセージを指定ファイルに出力するが、指定したファイルが既にある場合は上書きではなく追加する。ファイルがない場合は新規作成される 
-d<br>--debug | 動作内容を詳しく出力する 
-q<br>--quiet | 経過のメッセージを出力しない 
-v<br>--verbose | 経過のメッセージを出力する（デフォルト） 
-i ファイル名<br>--input-file=ファイル名 | 指定したファイルからダウンロードするURLを読み込む 
-t 回数<br>--tries=回数 | リトライ回数を指定する（デフォルトは20回） 
-T 秒数<br>--timeout=秒数 | タイムアウトするまでの秒数を指定する（デフォルトは900秒） 
-w 秒数<br>--wait=秒数 | リトライの待ち時間を指定する 
-nc<br>--no-clobber | ファイルを上書きしない 
-c<br>--continue | 途中までダウンロードされていたら続きをダウンロードする 
-N<br>--timestamping | ファイルのタイムスタンプをサーバ上のタイムスタンプに変更する 
--no-use-server-timestamps | ファイルのタイムスタンプを変更しない（「wget」で保存した時刻とする） 
--spider | ファイルをダウンロードせず、URLの存在だけチェックする（“Web spider”として動作する）。例えば、ブックマークをチェックするなら「wget --spider --force-html -i bookmarks.html」のように指定する 
--user=ユーザー名 | ダウンロードする際の「ユーザー名」を指定する 
--password=パスワード | ダウンロードする際の「パスワード」を指定する 
--ask-password | 接続毎にパスワードを入力する（プロンプトが表示される） 
-p<br>--page-requisites | ローカル環境で表示するための必要なファイルも含めてダウンロードする 
 -r<br>--recursive | 再帰ダウンロードを行う（URLで指定したファイルからのリンクもダウンロードする。デフォルトは5階層まで：実行例3を参照） 
-l 数<br>--level=数 | 指定した回数分リンクをたどる（「-r」オプションは「-l 5」相当） |
-k<br>--convert-links | ダウンロード後に、ダウンロードファイル内のURLをローカル閲覧用に変換する 
-K<br>--backup-converted | ファイルを変換した際のバックアップを「.orig」という拡張子を付けて保存する 
-nd<br>--no-directories | 再帰ダウンロード時にディレクトリを作成しない 
-nH<br>--no-host-directories | 再帰ダウンロード時にホスト名のディレクトリを作成しない 
--max-redirect=回数 | URLリダイレクトの回数を指定する（デフォルトは20回） 
-R 拡張子<br>--reject 拡張子 | 指定した拡張子のファイルはダウンロードしない（複数ある場合は「-R jpg,png」のように「,」で区切って指定する） 
-A 拡張子<br>--accept 拡張子 | 指定した拡張子のみ取得する（複数ある場合は「-A jpg,png」のように「,」で区切って指定する） 
-D リスト<br>--domains=リスト | ダウンロードするドメインのリスト（デフォルトでは別サイトへのリンクはダウンロードしないが、「-D」で指定したドメインはダウンロードの対象とする。複数ある場合は「,」で区切って指定する） 
--exclude-domains リスト | ダウンロードしないドメインのリスト 
-np<br>--no-parent | 親ディレクトリは対象としない
vue.jsでlazyload

メモ

カスタムディレクティブでlazyloadの処理を定義する
以下を参考に
https://jp.vuejs.org/v2/cookbook/creating-custom-scroll-directives.html

```js
import Vue from 'vue'

Vue.directive('lazyload', {
  inserted: function (el, binding) {
    let f = function (evt) {
      if (window.scrollY + window.innerHeight > el.offsetTop) {
        el.setAttribute('src', binding.value)
        window.removeEventListener('scroll', f)
      }
    }
    window.addEventListener('scroll', f)
    f()
  }
})
```

imgタグに設定する

```vue
<template>
  <div>
    <template v-for="src in imageList">
      <img src="~/assets/images/loading.gif"
        v-lazyload="src"
      >
    </template>
  </div>
</template>
```
【concat】JavaScript 配列の要素に対する操作

# この記事の対象
配列の基礎を知っていて、ES6に触れたことがある人
Webエンジニアに転職して1ヶ月経ち、覚えたことをアウトプット

# concatとは？
concatはJavaScriptのメソッドで、引数として渡した配列内の要素をバラバラに分解し、元の配列の最後に追加します。

## 基本的な例
下記の例では、配列arr1とconcatの引数を用意します。
基本的には**concatとは？**で説明したとおりの処理になるので、実行結果も配列とconcatの引数がマージされます。
concatでは配列や引数がコピーされて全く新しい配列が作られるので元の配列や引数に変更を与えることはありません。

```js
let arr1 = [1, 2, 3];
let arr2 = arr1.concat(4, 5, 6);

console.log(arr1); //[ 1, 2, 3 ]
console.log(arr2); //[ 1, 2, 3, 4, 5, 6 ]
```

## 配列の要素が配列の場合
**基本的な例**で挙げた引数とは違い、引数内の要素に配列を含みます。
その場合は、引数を要素ごとにバラらに分解まではできますが、要素である配列の分解まではできません。
そのため、新しい配列となるarr2には要素の一つとして配列がマージされます。

```js
let arr1 = [1, 2, 3];
let arr2 = arr1.concat(4, [5, 6]);

console.log(arr1); //[ 1, 2, 3 ]
console.log(arr2); //[ 1, 2, 3, 4, [ 5, 6 ] ]
```
欠損があるカラム一覧を、パッと出してくれる関数！


KaggleのHomeCreditコンペのKernelを写経していて、
これはコピー＆ペーストで今後も使える！と思ったコードを共有します！

参考もとのカーネルは[こちら](https://www.kaggle.com/willkoehrsen/start-here-a-gentle-introduction)です。


以下の定義コードを用いることで、

・dfのカラム数
・そのうち、欠損のあるカラム数
・欠損のあるカラム名＆欠損割合

がパッと出ます。


```python
def missing_values_table(df):
    mis_val = df.isnull().sum()
    mis_val_percent = 100 * mis_val / len(df)
    mis_val_table = pd.concat([mis_val , mis_val_percent] , axis= 1 )
    mis_val_table_ren_columns = mis_val_table.rename(columns={0:"Missing Values" , 1:"% of Total Values"})
    mis_val_table_ren_columns = mis_val_table_ren_columns[mis_val_table_ren_columns.iloc[:,1] !=0].sort_values("% of Total Values",ascending=False).round(1)
    print("Your selected dataframe has ",str(df.shape[1]) , "columns. \n"
         "There are" , str(mis_val_table_ren_columns.shape[0]) ,"columns that have missing values.")
    return mis_val_table_ren_columns
```


※HomeCreditコンペの[このカーネル](https://www.kaggle.com/willkoehrsen/start-here-a-gentle-introduction)、初心者にはむちゃ有難いです！！！
Angularのチュートリアルで使うコマンド

[Angularのチュートリアル](https://angular.jp/tutorial)を実行して雰囲気を掴んだ。その後、なにか自前Webアプリケーションを作ってみようとするも、コンポーネント作ったりするコマンドをいちいち見返すのが大変なので、ここにまとめることとします。

## プロジェクトを作る

```sh
ng new angular-tour-of-heroes
```

## アプリケーションをサーブする

```sh
cd angular-tour-of-heroes
ng serve --open
```

## `heroes`コンポーネントを作成する

```sh
ng generate component heroes
```

## `hero-detail`コンポーネントを作成する

```sh
ng generate component hero-detail
```

## `HeroService`を作成する

```sh
ng generate service hero
```

## `MessageComponent`,`MessageService`を作成する

```sh
ng generate component messages
ng generate service message
```

## `AppRoutingModule`を作成する

```sh
ng generate module app-routing --flat --module=app
```

## ダッシュボードビューを作成する

```sh
ng generate component dashboard
```

## データサーバーをシミュレートする

`npm`からインメモリWebAPIをインストールし、`InMemoryData`サービスを作成します。

```sh
npm install angular-in-memory-web-api --save
ng generate service InMemoryData
```

## `HeroSearchComponent`を作成する

```sh
ng generate component hero-search
```

## おわり

以上です。
Gulp v3 -> v4

webpack4を使おうとしたら、NodeJSのバージョンアップが必要になり、芋づる式にgulpもv4になって、既存スクリプトの修正が必要になったので、メモる。

* 依存タスクの書き方が変更された (参考: https://satoyan419.com/gulp-v4/)
    * タスク名のリスト　→ gulp.seriesとgulp.seriesを使う
* "apply..."のエラーが出る場合 (参考: https://zzz.buzz/2016/11/19/gulp-4-0-upgrade-guide/)
    * グローバルのgulpとローカルのgulpのバージョン不整合が原因らしい
    * グローバルのgulpをいったんアンインストールして再インストール
* タスクから何か返さないといけない
    * ストリームをreturnで返す or コールバック関数を引数で受けて、最後にそれを呼ぶ

```js
gulp.task('xyz', function() {
  return gulp.src(...)...pipe(...);
}
```
or

```js
gulp.task('xyz', function(cb) {
  ....
  cb();
}
```
コメント書き込み時に、ログインしているユーザーの情報をいれる。

手順：
コメント書き込み時に、ログインしているユーザーの情報をいれる。
- DBの作業
└ コメントのデータベースに情報を加える
　└ migration fileをつくる
　└ テーブルにユーザーidを加える↑同様
　└ テーブルに時刻を加える
└ コメントにユーザー名を表示する
　└ controllerで設定
　└ htmlを変更

参考とするサイト：
Rails/データベース/ユーザーid/時刻情報/カラムを加える/
上記のキーワードの方向で2,3サイトをリサーチする。

[Ruby on Rails カラムの追加と削除]
(https://qiita.com/azusanakano/items/a2847e4e582b9a627e3a)
例：
rails generate migration クラス名
rails generate migration AddColumnTitles
rails generate migration クラス名 カラム名:データ型( カラム名:データ型)
rails generate migration AddDetailsToTitles price:integer author:string

疑問：
・クラス名、カラム名、データ型？書き方どうでしたっけ・・・	└ カラム名と種類”user_id" integer
・この後$ rails db:migrate
・時刻の加え方は？→デフォルトで入っている模様
・mysqlでmysql> describe Myblogをしたい→sqliteで.schemaする。

以下.schemaの情報。

```
CREATE TABLE "comments" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "body" varchar, "post_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, CONSTRAINT "fk_rails_2fd19c0db7"
FOREIGN KEY ("post_id")
```

以下rails generateした際のログ

```
[vagrant@localhost Myblog]$ rails generate migration AddUser_idComments
Running via Spring preloader in process 13071
      invoke  active_record
      create    db/migrate/20190210091816_add_user_id_comments.rb
```

20190210091816_add_user_id_comments.rbファイル

```rb
class AddUserIdComments < ActiveRecord::Migration[5.2]
  def change
  	add_column :users, :username, :string
  end
end
```

コメント箇所に追記

```comment.controller.rb
  def create
    @post = Post.find(params[:post_id])
    comment = @post.comments.create(comment_params)
    comment.user_id = current_user.id
    comment.save
    redirect_to post_path(@post)
  end
```

```show.html.erb
<%= comment.user.username %>
```

```comment.rb
class Comment < ApplicationRecord
  belongs_to :post
  belongs_to :user
  validates :body, presence: true
end
```
Amazon ECS で NVIDIA GPU を使用するための AMI 作成方法

以前の記事（[Docker コンテナで NVIDIA GPU によるハードウェアエンコードを動かす](https://qiita.com/clerk67/items/d8897b97b5cd93b2d752)）でビルドしたコンテナを、Amazon ECS や AWS Batch などの基盤上で動作させるためには、Amazon ECS で通常提供される Amazon ECS-optimized AMI ではなく、GPU ドライバなどをインストールした独自の AMI を用意する必要がある。その作成方法を以下に記した。

## AMI 作成手順

1. Amazon EC2 G3 インスタンスを起動
    - AMI (Amazon Machine Image) は **Amazon Linux 2 AMI** `ami-0a2de1c3b415889d2` を選択
    - インスタンスタイプは G3 インスタンスの中では比較的安価な `g3.4xlarge` や `g3s.xlarge` を推奨
    - EBS ルートボリュームは 8 GB だと空き容量が不足する可能性があるため注意
2. 起動した EC2 インスタンスに SSH 接続
3. 最初にタイムゾーンを設定

    ```bash
    sudo timedatectl set-timezone Asia/Tokyo
    ```
4. Docker のインストール
    Amazon Linux 2 では *Extras Library* を使用することで Docker を簡単にインストールすることができる。

    ```bash
    sudo amazon-linux-extras install docker
    ```
5. `ecs-init` のインストール
    これにより Amazon ECS エージェントがインストールされ、ECS のコンテナ実行環境として使用できるようになる。

    ```bash
    sudo amazon-linux-extras install ecs
    sudo systemctl enable ecs
    ```
6. NVIDIA Graphics Driver のインストール
    最新のドライバは https://www.nvidia.com/Download/index.aspx で Tesla M60 を検索することで取得可能。
    なお、NVIDIA Graphics Driver の使用には [NVIDIA Software License Agreement](https://www.nvidia.com/content/DriverDownload-March2009/licence.php?lang=us) への同意が必要である。 

    ```bash
    sudo yum install gcc kernel-devel-$(uname -r)
    wget http://us.download.nvidia.com/tesla/410.72/NVIDIA-Linux-x86_64-410.72.run
    sudo bash NVIDIA-Linux-x86_64-410.72.run --ui=none --no-questions --accept-license
    ```
7. `nvidia-docker2` のインストール
    [nvidia-docker2](https://github.com/NVIDIA/nvidia-docker) は Docker コンテナで NVIDIA GPU を使用するために必要なランタイムである。

    ```bash
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
    sudo yum install nvidia-docker2
    ```
8. デフォルトランタイムの設定
    `docker` コマンドをオプションなしで実行した場合でも上記でインストールした `nvidia-docker2` ランタイムが使用されるよう、 `/etc/docker/daemon.json` を以下のように編集する（ファイルがない場合は新規に作成する）。

    ```json:/etc/docker/daemon.json
    {
        "runtimes": {
            "nvidia": {
                "path": "nvidia-container-runtime",
                "runtimeArgs": []
            }
        },
        "default-runtime": "nvidia"
    }
    ```
9. シャットダウン

    ```bash
    sudo shutdown -h now
    ```
10. EC2 マネジメントコンソールから AMI を作成
他の人の投稿 div（”right_header”および”right_column”）においてfloatを実行して横並びにする。

お題：
他の人の投稿 div（”right_header”および”right_column”）においてfloatを実行して横並びにする。

手順１：
stylesheetに記述するclass名は“right_header”を想定。
floatで右隣に行ってくれて、
right_columnはright_headerの下にあるのでは…という淡い期待。

手順２：
“header”と”column”それぞれを”class = left””class = right”としてdivでくくる。
その後”class = right”をfloatで右側に。

結果：
手順２の通りでやったが、
class = left{}内にfloatがfloat:left;だったわ。。
【最新サービス試用②】Markdownで簡単な年表が作れる「Markline」を試用。

- 日々輩出される素晴らしき最新サービスを素早く試して、不鮮明な先見性を堂々と誇示する記事第二弾。
- 「最新・流行・先端」という言葉に何度も狂わせられている私は、今回もまたなりふり構わず飛びついてしまう。
- 「そんなことよりもエンジニアなのだから、中身のコードをきちんと見ようよ」という、混じりっけ無しの高純度正論を、入る隙間もない耳の中に入れたふりをしながら、手を動かすことにしよう。
- 今回は、マークダウンで簡単に年表が作れちゃうサービスを試用してみよう。

## 試用サービス名
### 「[Markline](https://github.com/hotoo/markline)」

## 概要
- マークダウンで簡単な年表が作れる。
- 横スクロールページのため、説明付加時でも見やすい。
- タグや色付けも可能。

## 結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/edcdb3ad-1759-3727-c9df-8fca0de5ea0c.png)

## 基本手順
### 1. Node.jsのインストール
- [こちら](https://nodejs.org/en/download/)にアクセスして、各OSに応じてインストールする。  
※[詳細な手順はこちら](https://qiita.com/Masayuki-M/items/840a997a824e18f576d8)。

- nodeコマンドが使用できるか、コマンドプロンプト（ターミナル）で下記のコマンドを入力して、確認。

```console
node -v
```

### 2. marklineのインストール
- コマンドプロンプト（ターミナル）で、下記のコマンドを入力して、marklineインストール。  
※エラーの場合は、管理者権限（sudo）で実行してみる。

```console
npm install markline -g
```

### 3. マークダウンファイルの用意
- 使用するマークダウンファイルを任意のフォルダに作成する。  
※今回は例として、「C:\work」のフォルダの中に「test.md」ファイルを作成する。

### 4. コードを入力
- 作成したマークダウンファイルに、下記を入力して保存する。

```markdown:test.md
* 1986 1年間
* 1986/06 一か月
* 1986/06/28 一日
* 1986~ year 現在まで
```

### 5. ローカルサーバー起動
- コマンドプロンプト（ターミナル）で、下記のコマンドを入力して、ローカルサーバーを起動。

```console
cd /work
markline server test.md
```

※正常に起動すれば、コマンド上に「Server Started 127.0.0.1:8000」と出る。

### 6. 画面確認
- ブラウザで「`localhost:8000`」でアクセスして、年表ができているか確認する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/2ba09a79-679d-6fa8-bb81-a4b8d7f23757.png)

### 7. サーバー停止
- 作成ファイルの完成や休憩等で、サーバーを停止する場合は、「Ctrl(cmd) + C」で終了。

## サンプルコード

```markdown
# ページタイトル

## グループ１

* 1986/06/28 一日
* 1986/06 一か月
* 1986 1年間
* 1986~1995 年間指定
* 1986/01/01~1995/03/01 詳細期間指定
* 1986~ year 現在まで

- 1986~1990 期間指定（主）
  - 1987/07~1989/07 期間指定（補）

## グループ２

* 1986~1995 **太字**
* 1986~1995 [リンク](https://bit.ly/2GAxdik)
* 1986~1990 画像: ![image.png](https://bit.ly/2GAxdik)

- 1986~1995 期間 #タグ名
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/336499/1bfd50e4-b3cf-ef57-d66e-0dd33589e0e1.png)





## まとめ
- 今回はマークダウンでの年表作成ということで、「自己年表はきっと高需要だから、作ってみよう。」という、そう思うことでしか幸福を図れない私をなぐさめながら、記事を書く。
- 簡単な記述で、いとも簡単に期間や年表の作成ができることへの感動を覚えながら、同時に自分のこれまでの歴史の低品質ぶりを思い返してみると、複雑を通り越して、初めての境地に入る。
- 毎回同様、試用後の開発者への礼拝を目にもとまらぬ速さで終了して、早速次の崇拝対象開発者を探しにいく、都合で生きる生活。


## 参考
- https://www.moongift.jp/2019/02/markline-markdown%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%B9%B4%E8%A1%A8%E8%A1%A8%E7%A4%BA/  
→こちらの記事から見つけてきました。大変お世話になりました。
- https://qiita.com/Masayuki-M/items/840a997a824e18f576d8  
→Node.jsのインストールは、こちらの記事を参考にしました。大変お世話になりました。
Nuxt.jsでGithubキーワードランキング検索サービス開発した話

# TL;DR
※元ネタ
[プログラムのネーミングに迷ったら GitHub でコード検索すると参考になる説](https://qiita.com/kyoshidajp/items/c5d4f060df636ea20cbb)

すごく便利だったので、視覚的に見れるWEBサービスを作成しました！
https://hogehoge.netlify.com/

ソースコードはこちら
https://github.com/satokibi/hogehoge.io


# 作ったもの

**hogehoge.io**
https://hogehoge.netlify.com/


![hogehoge.gif](https://qiita-image-store.s3.amazonaws.com/0/260131/3ea25b69-6d87-7cbd-845f-752579a8b118.gif)

検索したいキーワードを複数打ち込み、検索すると
結果のテーブルと円グラフ、また各キーワードの検索に引っかかったファイルのリストが出てくるようになっています。

chartjsで表示している円グラフのアニメーションがすごくかっこよくてお気に入りです。

# 使った技術

- [Docker](https://www.docker.com/)
    - 開発環境の構築に用いています。
    - いつもありがとう。

- [Vue.js](https://jp.vuejs.org/index.html)
    - こいつのおかげでフロントエンド入門できた(T_T)

- [Nuxt.js](https://ja.nuxtjs.org/)
    - Vue.js フレームワーク
    - [Nuxt.js ビギナーズガイド](https://www.amazon.co.jp/dp/B07J5434JB/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) のおかげで少し入門できた...。

- [Vuetify.js](https://vuetifyjs.com/ja/)
    - UIフレームワーク
    - Webサイトをいい感じにかっこよくしてくれた...。

- [chart.js](https://www.chartjs.org/)
    - グラフの作成を担当
    - 今回は円グラフでしたが、他のグラフも多数！

- [Netlify](https://www.netlify.com/)
    - 今回のデプロイ先
    - 静的ホスティングサイト！
    - 基本無料でいつもありがたく使用させていただいています

# 仕組み
1. ユーザの入力を空白で分割
2. それぞれのキーワードをGithub APIで検索！
3. 結果を表示

②のAPIへの検索を並列で行っているため?か、たくさんのキーワードで検索を行うと
たまに403エラーが帰ってきてしまいます。

# ハマったところ
## 空白除去

```javascript
 var keywords = this.user_input.replace(/\s+/g, ' ').split(' ')
```
意外に半角全角まじりのスペースを良い感じに分割するのは難しかった...
正規表現で半角全角の空白すべてを半角空白１つに置換してから分割しています。

## 並列処理
Promiseに関する知識がなく、調べながらの作業で
最終的にはこのコードに落ち着きました。

```javascript
  const result = await Promise.all(
    keywords.map(async (keyword) => {
      return this.$axios.$get('/code?q=' + keyword)
    })
  )
```

## 

# これから
## option検索
- 言語指定検索
- リポジトリを限定した検索

## oauth認証


## バックエンド開発
検索結果を保存していきたい！

予測変換のようなもので良く検索されるキーワード順に出したり、
一緒に検索されるキーワードを提案できるようにしていきたい。


# おわりに
変数名や関数名決めるのすごく悩んでしまうタイプなんですが
これでhogeなんて変数名を付けなくなる、、、かな？


# 参考文献
- [プログラムのネーミングに迷ったら GitHub でコード検索すると参考になる説](https://qiita.com/kyoshidajp/items/c5d4f060df636ea20cbb)
- [Nuxt.js使って個人開発やってみた　〜時間割を円グラフで表示するサービスをリリースした話〜](https://qiita.com/mitsudaman/items/b30b5e905ff348bf35bc)


- [Github API](https://developer.github.com/v3/)
A3RTのTalk APIを活用したLINE雑談ボット


#はじめに
以前下記の記事にてLINEチャットボットを作成したのですが、雑談ができるボットを作成してみたいと思い、リクルートが提供しているA3RTのTalk APIを試してみました。
LINEMessagingAPI＋Herokuでのチャットボット実装に関しては、下記をご覧ください。（こちらの内容を前提の上で記載をしております。）

・LINE+Python+天気API を活用してチャットボットを作成してみた
https://qiita.com/neonsk/items/807e7398e71e18da1b01
・A3RT TalkAPIに関して
https://a3rt.recruit-tech.co.jp/product/talkAPI/

#実装
実装したpythonファイルの全体像はこちらです。

```python:main.py
from flask import Flask,request,abort
from linebot import LineBotApi,WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent,TextMessage,TextSendMessage
import os
import requests
import pprint
import pya3rt

app=Flask(__name__)
#環境変数の取得
YOUR_CHANNEL_ACCESS_TOKEN="＜各自で取得した値＞"
YOUR_CHANNEL_SECRET="＜各自で取得した値＞"
line_bot_api=LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler=WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback",methods=["POST"])
def callback():
    signature=request.headers["X-Line-Signature"]

    body=request.get_data(as_text=True)
    app.logger.info("Request body"+body)

    try:
        handler.handle(body,signature)
    except InvalidSignatureError:
        abort(400)
    return "OK"

@handler.add(MessageEvent,message=TextMessage)
def handle_message(event):
    #入力された文字列を格納
    push_text = event.message.text
    
    #A3RTのTalkAPIにより応答
    reply_text = talkapi_response(push_text)
    
    #リプライ部分の記述
    line_bot_api.reply_message(event.reply_token,TextSendMessage(text=reply_text))

#A3RTのTalkAPIにより応答
def talkapi_response(text):
    apikey = "＜各自で取得した値＞"
    client = pya3rt.TalkClient(apikey)
    response = client.talk(text)
    return ((response['results'])[0])['reply']

if __name__=="__main__":
    port=int(os.getenv("PORT",5000))
    app.run(host="0.0.0.0",port=port)
```

#A3RT TalkAPI 実装内容
Talk APIは下記の通りの実装となります。「talkapi_response」としてメソッドを作成しております。

```python
#A3RTのTalkAPIにより応答
def talkapi_response(text):
    apikey = "＜各自で取得した値＞"
    client = pya3rt.TalkClient(apikey)
    response = client.talk(text)
    return ((response['results'])[0])['reply']
```

A3RTのTalkAPIのKeyに関しては、A3RTのHPにて、メールアドレス登録をすることで発行できます。
発行されたapikeyを上記コードの「apikey」に入力をします。

#Herokuへの環境変数の追加
A3RTより取得したapikeyをHerokuの環境変数として追加します。

```
$ heroku config:set apikey="＜各自で取得した値＞"
```


#requirements.txtの更新
またgitにてpushするrequirements.txtにpya3rtを追加しておきます。

```:requirements.txt
Flask==0.12
line-bot-sdk
pya3rt
```

#出来たもの
一問一答で返答をしてくれるボットが出来ました。全然コミュニケーションは取れておりませんが、、、
![a3rt_talkapi.png](https://qiita-image-store.s3.amazonaws.com/0/310010/83bb41ca-0a8a-12ff-710e-c1bd5fca2c22.png)

#所感
API連携で簡単に雑談ボットを実装出来たのは感動しました！A3RTには他にも様々なAPIがあるので、色々試してみると面白いかもしれません。
2^pの最小完全ハッシュ関数

2^p (0 <= p < 32)の最小完全ハッシュ関数を見つけました。

## 2^pの最小完全ハッシュ関数

```
// x = 2^p (0 <= p < 32)
uint32_t mph_power_of_2(uint32_t x) {
  return ((73743071 * x) >> 27) & 31;
}
```

## 見つけ方

適当にそれらしい式を考えて、パラメータを総当たりで探索しました

## __builtin_clzで良い
__builtin_clzで良いことにきづきました。


```
uint32_t IntLog2(uint32_t x) {
  return 32 - __builtin_clz(x) - 1;
}
```
朝起きられない系エンジニアがIoTの力で毎朝起きられるまでの話

#朝起きられない...！！
さて、エンジニア界隈は圧倒的に夜型人間が多いですよね。

***「夜10時からがゴールデンタイムだよなっ！！」***などという
社会不適合者が多いのがエンジニアだと思っています。(偏見）

自分も完全にこっち側の人間で、放っておくと
夜〜深夜にかけて俄然調子が上がっていき、
AM4時ごろから疲れてきてAM6時に寝る、みたいになります。

#ちょっと1回朝型人間になってみたい
そんなことを雑に考えて、朝型を目指してみました。
しかし！iPhoneのアラームなんかで起きられるはずもなく。。

ここで思ったのです。
***IoTの力を借りて、起きたくなるような環境をデザインしよう！***
~~無駄にガジェットを使いたがるタイプのエンジニアです~~

#最終的にどうなったのか
朝の9時に
・エアコンがついて適温になる
・電気が自動でマックスで点く
・カーテンが自動で開く
***・テレビがついて、メンタリストDAIGOのYoutube動画が流れてくる***

自分がベッドの中にいる状態で、上の動作が自動で行われます。

#使っているガジェット
・Google home mini
全ての操作の起点。朝やることをルーティンという形で時間設定＆登録して順番に行ってくれる。

[・Nature remo mini](https://amzn.to/2GkH7Wh)
スマートリモコン。
家中にある全ての***リモコンの赤外線パターンを記憶、再現する***ことにより全部のリモコンの代わりとなる。めっちゃすごい。

・Chrome Cast
Google homeからyoutube動画を再生させたいと思った時に必要だった。
これを使うと「Ok google 猫の動画を再生して」とかで、再生してくれる。

[・mornin plus](https://amzn.to/2SLAG46)
カーテンを自動で開くロボット。
カーテンレールに取り付ける小さいロボットという発想が神。

・IFTTT
google homeとnature remoの接続に使用。

#どうやっているの？

Google homeにはルーティンという機能があります。
これは「何時に決められたこれらの動作を全て実行しますね」というものです。

9時になるとGoogle homeのルーティンが起動して、家電を操作しまくります。

1、Nature remoでテレビをつける
2、Nature remoで電気をつける
3、Nature remoでエアコンをつける
4、メンタリストDAIGOの動画をChrome castで再生する

#考えたことは「意志の力に頼らない」

まず、***「意志」とかいうくそ脆弱なもの***には頼りません！

起きるということは分解すると2つの要素に分けられます。

1、マイナス要因により起きられない
2、プラス要因が足りないことにより起きられない

つまり、
***マイナス要因を無くしてプラス要因を増やせば起きられるはず！***

#★マイナス要因をなくす
##1, 「寒くて起きられない」をなくす
寒いと布団から出られずに、結局二度寝してしまう。
これを無くします。

これはエアコンをつければ良いです。

ここではiftttを使ってGoogle home miniとNature remo miniを連携しました。
[ifttt連携の方法](https://nature.global/jp/ifttt-setup/2017/10/8/google-home)

エアコンと言うと、エアコンをつけるように設定しています。

##2, 「暗くて起きられない」をなくす
暗いと起きるモードにならない。
これを無くします。

ここでは電気を点けて、カーテンを開けて朝日を入れます。


まず、上記iftttを使ってgoogle homeとnature remoを連携、電気をつけます。

そして、もう一つ出てくるデバイスが[mornin plus](https://amzn.to/2SLAG46)です。
カーテンレールに取り付けて、時間設定したら自動でカーテンを開いてくれます。
めっちゃ面白いです。

#★プラス要因を増やす
明るくなって、部屋が適温になって、確かに起きられる環境は整いました。
しかし、***積極的に起きる理由がない***という問題により、結局二度寝するということが起きました。

これを解決するために***「自動で見たいYoutube動画が流れている」*** という状態を作りました。

##1,「なんとなく動画が気になる」を作る
みなさんが実家で二度寝している時に、***家族が「なんか面白そうなテレビ番組見てるなー。」と気になって起きたこと***はありませんか？

その状況を自力で作ります！

使うものはGoogle homeとChrome castです。

「ねぇGoogle テレビでメンタリストDAIGOの動画を再生して」などと言うと再生してくれるので、これを朝9時に自動で起こるように設定します。


# まとめ
ここまでやると流石に朝起きるのがそんなに苦じゃなくなりました。

まだまだ、最高の環境ではないと思うので
「起きる楽しみ」を増やしていきたいです！

***朝一にやってる楽しみ***が何かあったらコメントにて共有お願いします！
【push,pop,unshift,shift】配列の要素に対する操作

# この記事の対象
JavaScriptの配列の特徴を知り、ES6に触れたことがある人
Webエンジニアに転職して1ヶ月経ち、覚えたことをアウトプット

# 配列の先頭もしくは、最後に要素を追加、削除する
なんでもないフルーツの配列を用意してあげます。

```js
const fruits = ["apple", "orange", "banana", "cherry"];
```
この配列に対して、push(配列の最後に要素を追加)、pop(配列の最後の要素を切り取る)、unshift(配列の最初に要素を追加)、shift(配列の最初の要素を切り取り)の4つの操作を行います。

## push
配列の最後に要素を追加します。

```js
fruits.push("grape");
console.log(fruits); // [ 'apple', 'orange', 'banana', 'cherry', 'grape' ]
```
## pop
配列の最後の要素を切り取ります。

```js
fruits.pop(); 
console.log(fruits); //[ 'apple', 'orange', 'banana', 'cherry' ]
```
## unshift
配列の最初に要素を追加します。

```js
fruits.unshift("lemon");
console.log(fruits); //
```
## shift
配列の最初の要素を切り取ります。

```js
fruits.shift();
console.log(fruits); // [ 'apple', 'orange', 'banana', 'cherry' ]
```
CentOS7.6 ネットワーク設定

# 確認環境

macOS 10.14.3
VirtualBox 6.0.4
CentOS 7.6.1810

# ネットワークデバイス設定

> $ nmcli
> enp0s3: disconnected
>         "Intel 82540EM"
>         1 connection available
>         ethernet (e1000), 08:00:27:93:3E:D8, h2, Mts 1500
>
>lo: unmanaged
>        "lo"
>        loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536
>
>User "nmcli device show@ to get complete information about known devices and
>"nmcli connection show" to get an overview on active connection profiles.
>
>Consult nmcli(1) and imcli-examples(5) manual pages for complete usage details

disconnected となっている enp0s3 をネットワークへ接続する。

>$ nmcli connection up enp0s3
>
>Connection successfully activated (D-Bus action path: /org/freedesktop.NetowrkManager/ActiveConnection/3)

接続できていることを確認する。

> $ nmcli
> enp0s3: connected to enp0s3
>         "Intel 82540EM"
>         ethernet (e1000), 08:00:27:93:3E:D8, h2, Mts 1500
>         ip4 default
>         ienet4 10.0.1.12/24
>         route4 0.0.0.0/0
>         route4 10.0.1.0/24
>         inet6 fe80::a638:f7cd:86d9:439f/64
>         route6 fe80::/64
>         route6 ff00::/8
>
>lo: unmanaged
>        "lo"
>        loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536
>
>DNS configuration:
>        servers: 10.0.1.1
>        interface: enp0s3
>
>User "nmcli device show@ to get complete information about known devices and
>"nmcli connection show" to get an overview on active connection profiles.
>
>Consult nmcli(1) and imcli-examples(5) manual pages for complete usage details

以下のコマンドで切断する

>$ nmcli connection down enp0s3
> 
>Connection successfully deactivated (D-Bus action path: /org/freedesktop.NetowrkManager/ActiveConnection/3)


# 起動時のネットワーク設定

下記サイトを参考に修正しました。

[CentOSで起動と同時にネットワーク設定がされない（eth0が起動しない）ときの対処](https://qiita.com/asuzuki2008/items/d50ac90b127a55b4622c)


>$ vi /etc/sysconfig/network-scripts/ifcfg-eth0

以下を修正

> ONBOOT=yes


# ミラーサイト設定

下記サイトを参考に修正しました。

[CentOS7 yum updateでエラーが出るとき](https://qiita.com/zinntikumugai/items/aae78a72a6fdec055089)
CSSだけで無限ループの画像ギャラリーを作ってみる

今作っているwebサイトで、コンテンツの一つとして無限ループの画像ギャラリーを使いたかったので、作って見ました。
今までこういうものはJSで作るものだと思っていたのですが、以外にCSSだけで出来た。CSSは奥が深い。

# DEMO

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="kawamataryo-the-sans" data-slug-hash="JxLEjO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="css-infinite-slider">
  <span>See the Pen <a href="https://codepen.io/kawamataryo-the-sans/pen/JxLEjO/">
  css-infinite-slider</a> by kawamata@元🚒エンジニア (<a href="https://codepen.io/kawamataryo-the-sans">@kawamataryo-the-sans</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# ポイント解説

### 画像の配置とダブリ
違和感なくループするように、6枚の画像をスクロールさせたい場合、1,2,3番目の画像と同様のものを7,8,9番目に配置します。
ダブリの画像を入れることで、切れ目なくループしているように見えます。

```stylus
    .item-1
      background-image url(https://picsum.photos/400/300?image=101)
    .item-2
      background-image url(https://picsum.photos/400/300?image=102)
    .item-3
      background-image url(https://picsum.photos/400/300?image=103)
    .item-4
      background-image url(https://picsum.photos/400/300?image=104)
    .item-5
      background-image url(https://picsum.photos/400/300?image=106)
    .item-6
      background-image url(https://picsum.photos/400/300?image=107)
    .item-7
      background-image url(https://picsum.photos/400/300?image=101) // item-1と同様
    .item-8
      background-image url(https://picsum.photos/400/300?image=102) // item-2と同様
    .item-9
      background-image url(https://picsum.photos/400/300?image=103) // item-3と同様

```

# 参考
ほぼこちらの丸々使わせてもらいました。
https://css-tricks.com/infinite-all-css-scrolling-slideshow/
Raspberry PiにA/DコンバータMCP3002をつなぐ（spidev 3.3対応）

Raspberry PiでADコンバータを利用したくて、[Raspberry PiにA/DコンバータMCP3002をつなぐ](https://qiita.com/f_nishio/items/4b9723c4e622a51aaeb5)の記事を見ながらやってみたものの、応答が全部ゼロになって困っていました。

いろいろ調べたところ、原因が判明。
####原因（１）MOSI、MISO、SCSK等をGPIOで使うとspidevが使えなくなる。
よく見ると[カラー図解 最新 Raspberry Piで学ぶ電子工作](https://raspibb1.blogspot.com/)に書いてありました。
[前回](https://qiita.com/Zensa55/items/fc0df5069c76418ef7e2)の方法を使うと、再起動するまでspidevは使えなくなるとのこと。

####原因（２）spidevがバージョンアップしていた
これも[カラー図解 最新 Raspberry Piで学ぶ電子工作](https://raspibb1.blogspot.com/)の補足情報にありました。「spi.max_speed_hz = 1000000」のように最大周波数の設定が必要になったとのこと。

以上を参考に、プログラムを改造してみました。

##Pythonコード

```python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import spidev

#MCP3002からSPI通信で10ビットのデジタル値を取得。0から１の２チャンネル利用可
def readadc_spidev(adcnum):
    if ((adcnum > 1) or (adcnum < 0)):
        return -1

    command1 = 0xd | (adcnum<<1)
    command1 <<= 3
    ret = spi.xfer2([command1,0,0])
    adcout = (ret[0]&0x3)<<8 | ret[1]
    return adcout

GPIO.setmode(GPIO.BCM)
spi=spidev.SpiDev()
spi.open(0, 0) # bus0, CE0
spi.max_speed_hz = 1000000  # 1MHz


try:
    while True:
        inputVal0 = readadc_spidev(0)
        print(inputVal0)
        time.sleep(0.2)

except KeyboardInterrupt:
    pass

spi.close()
```

###MCP3002の入力（MOSI）
データシートを見ると入力は8ビットです。SINGLE ENDED MODEでCH0なら0b01101000、CH1なら0b01111000です。（出力はMSBフォーマット）
ここでは`readadc_spidev(adcnum)`の引数で、CH0か1で切り替えられるようにしています。

###MCP3002の出力（MISO）
データシートを見ると出力は8ビット＋8ビットの2バイトに分割されていることがわかります。1番目のバイトは最後の2ビットだけが使用されており、これと2番目のバイトの8ビットを足して合計10ビットで出力値を表します。
そこで最初のバイトの末尾2ビットと、2番目のバイトの8ビットをつなぎ合わせて1個の数値として出力するように`adcout = (ret[0]&0x3)<<8 | ret[1]`としています。

##実行結果
ここではMCP3002の出力値をそのまま出していますので、0～1023までの1024段階で結果が表示されます。

```
848
869
804
799
581
583
725
809
818
811
789
768
780
624
746
811
```

##使用機材
- Raspberry Pi 3 model B+
- MCP3002（ADコンバータ）
- 可変抵抗10kΩ
- ジャンパー線など

##配線図
[前回](https://qiita.com/Zensa55/items/fc0df5069c76418ef7e2)のを見てください。

spidevが使えないときの方法も見つけましたが、やはりspidevを使ったほうがプログラムが短くてすっきりするので助かります。
ArduinoにLCDを繋いで文字を表示する

Arduinoにて何かしらの情報をLCDに表示したい場合があります。HD44780 1602 LCDディスプレイを使い文字を表示した手順を記します。
# 準備
・[Arduino UNO R3 互換品](https://www.amazon.co.jp/スイッチサイエンス-SSCI-GettingStartedArduinoKit-Arduinoをはじめようキット/dp/B0025Y6C5G/ref=sr_1_4?s=toys&ie=UTF8&qid=1548518133&sr=1-4&keywords=Arduino+正規品)
・[HiLetgo® 2個セットDC 5V HD44780 1602 LCD ディスプレイモジュール 16×2キャラクタ LCDブルーブラックライト](https://www.amazon.co.jp/gp/product/B010GXB9NM/ref=ppx_yo_dt_b_asin_title_o04__o00_s00?ie=UTF8&psc=1)
・[HiLetgo® 5個セット5V 1602LCD IIC/I2C/TWI/SPIシリアルインターフェイスモジュールポートarduinoに対応](https://www.amazon.co.jp/gp/product/B010Q175VY/ref=ppx_yo_dt_b_asin_title_o00__o00_s00?ie=UTF8&psc=1)
・ブレットボード
・ジャンパワイヤ （オス-メス）×４個

↓
届きました。
LCD
![002.png](https://qiita-image-store.s3.amazonaws.com/0/344880/2860681b-492f-1120-61c2-76443db7a405.png)

シリアルインタフェースモジュールポート
![003.png](https://qiita-image-store.s3.amazonaws.com/0/344880/475fe8e3-bbb6-5ddc-ad2c-4a17fc8222ea.png)


# 回路作成
Step1. HD44780 1602 LCD ディスプレイとシリアルインターフェースモジュールポートを接続
下記図のように接続します。直接はんだ付けしてもOKです(ショートしないよう気を付けて下さい)。詳細は[Datasheet](https://opencircuit.nl/ProductInfo/1000061/I2C-LCD-interface.pdf)ご参照です。
![004.png](https://qiita-image-store.s3.amazonaws.com/0/344880/3858f574-8327-79fc-f6f2-16934c288e6c.png)

Step2.シリアルインタフェースポートとArduinoを接続
下記の通り接続します。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/344880/e38c74b1-92ba-2f00-5fda-2e01626fd337.png)

# Sketch
LiquidCrystal_I2C.hライブラリをインストールし、HelloWorldサンプルコードを参考にさせて頂きました。
ライブラリは、ArduinoIDEの[スケッチ | ライブラリをインクルード | ライブラリを管理] からライブラリマネージャを開き、"LiquidCrystal I2C" を検索してインストール可能です。

・今回の場合はI2Cアドレスを0x27と指定しています。アドレス設定はシリアルインタフェースボードのAddressJumperに依存するようです。詳細は[参考](https://ht-deko.com/arduino/lcd_i2c.html)に記載されている通りのようです。

```3
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Hello, world!");
  lcd.setCursor(0,1);
  lcd.print("Arduino LCM IIC 2004");
}


void loop()
{
}
```

# テスト
Hello, world!
Arduino LCM IIC 2004
と表示されればOK
![001.png](https://qiita-image-store.s3.amazonaws.com/0/344880/bd012bb1-ab9d-b4ea-1667-f0ae1255e97c.png)

マイコンに書き込んだがLCDに何も表示されない場合は下記を確認下さい。
　・LCDディスプレイのコントラスト調整が適切であること。L
　　⇨CD裏面の青色のプラスネジの半固定抵抗でコントラスト調整をしてみて下さい。（私の場合はコントラスト調整が足りず、調整したら文字が見えました。）

# 参考
・[1602LCDをI2C変換アダプタを使ってArduinoで表示する。](https://qiita.com/clses/items/b4940804eb0a663fdc41)
・[[I2C] 1602 LCD ディスプレイ (HD44780 + PCF8574](https://ht-deko.com/arduino/lcd_i2c.html)
・[Datasheet I2C 1602 Serial LCD Module](https://opencircuit.nl/ProductInfo/1000061/I2C-LCD-interface.pdf)
・[組み込みエンジニアでなくても週末にArduinoを使って遊ぶ](https://qiita.com/seigot/items/958d3f2817a4bdac8754)
iOSでのみPWAを無効化する方法を解説

(ここでいうPWAとは、ホーム画面に追加することでアプリのように使える機能のことを言います。)

以前、[iOSのPWAはSNSログインが出来ないので今だに使い物にならないという話](https://qiita.com/ToshioAkaneya/items/f8c59726ffe8c5127050)という記事を投稿しました。

そこでiOSの場合のみPWAを無効化したいという場合があるかと思います。
その時には、以下のJavaScriptを使用することで、解決できます。
 
```javascript
const iOS = !!navigator.platform && /iPhone/.test(navigator.platform);
if (iOS) {
  document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
}
```

このコードでは、iOSかどうかを判別して、iOSの場合のみ`rel="manifest"`なlinkタグを探して、`rel`の値を適当な値に書き換えるということを行います。
これで解決します。<a href="https://yurubo.me">ネコチャ</a>もこの方法を採用しています。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Gnuplotで、はやぶさ2の軌道アニメーションを作ってみた

# はじめに
　JAXAのサイトで小惑星探査機はやぶさ2の空間座標が公開されていたので、gnuplotでGIFを描いてみた。

# 完成例
　t=0 [day]（打上げ、2014年12月3日）から、t=1832 [day]（リュウグウ滞在の最後の頃、2019年12月9日）まである。
![haya2.gif](https://qiita-image-store.s3.amazonaws.com/0/282333/fe840fca-cdb7-c96f-b679-9ff8e7a53be4.gif)

# データファイルの出典
　まずは、以下のサイトから**"Trajectory_20180226.txt"**を拾ってくる。

 - 「はやぶさ２」の小惑星遷移軌道（改訂版）を公開します| こちら「はやぶさ２」運用室 | JAXA はやぶさ２プロジェクト  
http://www.hayabusa2.jaxa.jp/topics/20180228/

# プログラムの作成
　上記サイトからダウンロードした**"Trajectory_20180226.txt"**と、以下に作成する**"haya2.plt"**と**"haya2plot.plt"**を同じディレクトリに用意する。

**"haya2.plt"**

```haya2.plt
set terminal aqua font 'ヒラギノ丸ゴ ProN W4, 8' 
#　aquaじゃなければx11でも良いと思います。試してないですが。
set zeroaxis
set ticslevel 0 # z軸を底面にくっつける
set xlabel "x [au]" font 'ヒラギノ丸ゴ ProN W4, 8'
set ylabel "y [au]" font 'ヒラギノ丸ゴ ProN W4, 8'
set zlabel "z [au]" font 'ヒラギノ丸ゴ ProN W4, 8'
set xrange [-1.5:1.5];set yrange [-1.5:1.5];set zrange [-0.15:0.15]
set view 45, 300, 1, 1 # 視点を調整

set terminal gif animate delay 5 optimize size 640, 480
# delay 5 ぐらいがちょうど良い再生速度になる。
set output "haya2.gif"

load "haya2plot.plt"
i = 0
```

**"haya2plot.plt"**

```haya2plot.plt
if (exist("i")==0 || i<0) i=0 #変数の初期化
title(i) = sprintf("t = %d [day]",i)  #タイトル名
unset label 
set label title(i) font 'ヒラギノ丸ゴ ProN W4, 12' at 1.2,-1.2,0
set label sprintf("提供：JAXA") font 'ヒラギノ丸ゴ ProN W4, 8' at 1.5,-1.5,-0.4
set label sprintf("「はやぶさ２」、地球、リュウグウの位置 \n ※z軸は10倍にしてある。") font 'ヒラギノ丸ゴ ProN W4, 12' at -1.9,1.9,0.4

splot "Trajectory_20180226.txt" every ::57::57+i using 3:4:5 lc rgb "yellow" notitle with lines\
    ,"Trajectory_20180226.txt" every ::57::57+i using 6:7:8 lc rgb "blue" notitle with lines\
    ,"Trajectory_20180226.txt" every ::57::57+i using 9:10:11 lc rgb "grey" notitle with lines\
    ,"Trajectory_20180226.txt" every ::57+i::57+i using 3:4:5 pt 5 lc rgb "yellow" title "Hayabusa2" with points\
    ,"Trajectory_20180226.txt" every ::57+i::57+i using 6:7:8 pt 7 lc rgb "blue" title "Earth" with points\
    ,"Trajectory_20180226.txt" every ::57+i::57+i using 9:10:11 pt 13 lc rgb "grey" title "Ryugu (1999 JU3)" with points

if (i<1832)  i=i+1; reread
```

　ターミナルを開く。**"Trajectory_20180226.txt"**などがあるディレクトリへ移動する。以下のようにコマンドを打てば、**"haya2.gif"**が同じディレクトリに出力される。

```
$ gnuplot
gnuplot> load "haya2.plt"
```
# 補足
　他にもこのデータファイルを使って色々プロットしたので良かったらどうぞ。
　https://github.com/m-kunugi/gnuplot/tree/master/haya2

# 参考サイト
　GIFにする際、以下のサイトを参考にさせていただきました。 

- gnuplotでアニメーション直接 gif アニメーションを出力する  
http://www.natural-science.or.jp/article/20101203183935.php
Lorcaで作ったアプリケーションを静的なコンテンツごとビルドする

[Lorca](https://github.com/zserge/lorca)でアプリケーションを作る場合ある程度規模が大きくなってくると、静的なコンテンツをGolangのコードと分離して構築すると思います。
このときのビルドの手順をメモしておきます。

## 1. 静的なコンテンツを配置
公式の[example](https://github.com/zserge/lorca/tree/master/examples/counter)を参考にしています。
ここでは、wwwディレクトリ以下に静的なコンテンツを配置しています。

## 2. gen.goを準備
[gen.go](https://github.com/zserge/lorca/blob/master/examples/counter/gen.go)を配置します。

静的なコンテンツのパスをlorca.Embedn第三引数に指定します。

```go
lorca.Embed("main", "assets.go", "www")
```

こんな感じになります。

```
.
├── gen.go
└── www
    ├── favicon.png
    └── index.html
```


## 3. gen.goを実行

以下のコマンドを実行します。

```
go run gen.go
```

## 4. assets.goが生成される
コマンドで[assets.go](https://github.com/zserge/lorca/blob/master/examples/counter/assets.go)が生成されます。

assets.goでは指定したパスに存在するコンテンツをバイナリに変換したものがコード内に直接定義されています。FSにてパスに対するコンテンツを返却するファイルシステムが定義されています。
ここで定義されたFSを[こちら](https://github.com/zserge/lorca/blob/master/examples/counter/main.go#L68)のようにFileServerに渡すことで、静的コンテンツをGoの世界だけで利用することができます。

## 5. ビルドする
[build-linux.sh](https://github.com/zserge/lorca/blob/master/examples/counter/build-linux.sh)などのビルドスクリプトを実行すると、各プラットフォームに対応したバイナリがビルドできます。
MacでSQLPlusとSQLLoaderを使用する

# MacでSQLPlusとSQLLoaderを使用する

## 目的
* バッチ処理等でsqlコマンドやsqlldrコマンドを発行するコードをMacでも動くようにする

## インスタントクライアントをダウンロードする
https://www.oracle.com/technetwork/topics/intel-macsoft-096467.html
からダウンロードします。
なお、SQLLoaderは12gのみで利用できます。

* 必須ライブラリ
    * instantclient-basic-macos.x64-12.2.0.1.0-2.zip

* SQLPlus（SQLPlusを利用したい場合）
    * instantclient-sqlplus-macos.x64-12.2.0.1.0-2.zip 

* SQLLoader（SQLLoaderを利用したい場合）
    * instantclient-tools-macos.x64-12.2.0.1.0-2.zip


## ダウンロードしたファイルを解凍する

解凍すると必要なライブラリが「instantclient_12_2」ディレクトリに作成されます。

```
$ unzip instantclient-basic-macos.x64-12.2.0.1.0-2.zip 
$ unzip instantclient-sqlplus-macos.x64-12.2.0.1.0-2.zip
$ unzip instantclient-tools-macos.x64-12.2.0.1.0-2.zip
$ ls
instantclient_12_2/
```

## instantclient_12_2を任意の場所に移動する
適当にmvしてください。

## tnsnames.oraを作成する
tnsnames.oraを作成します。
以下はtnsnames.oraの例です。

```
oracle11 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = xe)
    )
  )
```

## 環境変数を設定する
SQLPlusやSQLLoaderで使用する環境変数を設定します。
.bashrcや.bash_profileに書いておくと便利です。

```
export ORACLE_HOME=<インスタントクライアントのディレクトリ>
export PATH=\$ORACLE_HOME:\$PATH
export DYLD_LIBRARY_PATH=\$ORACLE_HOME
export TNS_ADMIN=<tnsnames.oraがあるディレクトリ>
```

## 動作確認する
* SQLPlus

```
$ sqlplus TEST_USER@oracle11

SQL*Plus: Release 12.2.0.1.0 Production on Sun Feb 10 20:31:08 2019

Copyright (c) 1982, 2017, Oracle.  All rights reserved.

Enter password: 

Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL>
```

* SQLLoader

```
$ sqlldr TEST_USER@oracle11 control=TEST_TABLE.ctl 
Password:

SQL*Loader: Release 12.2.0.1.0 - Production on Sun Feb 10 20:34:08 2019

Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 1

Table "TEST_USER"."TEST_TABLE":
  1 Row successfully loaded.

Check the log file:
  TEST_TABLE.log
for more information about the load.
```


できました！！！
docker-composeを使いつつgulpでブラウザを自動更新する

PHPを使いつつSCSSを使いたい場面があり、作業効率を確保する為にDockerとgulpを同時に使用する方法を選びました。
もっと楽に出来る方法がありそうですが、さくっと環境構築を終わらせたかったので自分の知っている方法だけで終わらせました。
※MAMPを使っている方は、記事に記載している `Docker` ・ `docker-compose` のインストールと使用は不要です。

## 叶えたいこと
* PHPを使いつつSCSSの自動コンパイルを行いたい。(ApacheとNode.jsを同時に使用したい。)
* 作業ファイルを保存したらブラウザを自動更新したい。(手動でリロードする手間を省きたい。)

## 環境
* MacOS
* npmのバージョン・・・6.4.1
* Node.jsのバージョン・・・10.6.0
* gulpのバージョン・・・4.0.0 

## 前提
以下がインストール済みであることを前提としています。

* Docker
* docker-compose
* Node.js
* npm
* gulp

## ディレクトリ構造

``` 
作業ディレクトリ             
├── gulpfile.js
├── htdocs ・・・「localhost:8080」で見るディレクトリ
├── node_modules
├── package.json
├── src　・・・作業ファイルを入れるディレクトリ。gulpで更新後のファイルをhtdocsに入れる。
└── yarn.lock

```

## 設定ファイルの内容

``` docker-compose.yml
version: '3'

services:
  apache:
    image: php:7-apache
    volumes:
      - $PWD:/var/www/html
    ports:
      - 8080:80
```


``` gulpfile.js
const gulp = require('gulp');
const watch = require('gulp-watch');
const browserSync = require('browser-sync').create();
const runSequence = require('gulp4-run-sequence');
const DEST_DIR = './htdocs/';

gulp.task('browser-sync', function(){
	browserSync.init({
    proxy: 'localhost:8080' // ←docker-composeで指定したport
	});
});

gulp.task('bs-reload', function(){
	browserSync.reload();
});

gulp.task('hoge', function() {
	return gulp.src(['src/hogehoge/**/*.hoge'])
	.pipe(gulp.dest(DEST_DIR))
});

gulp.task('default', gulp.series(
  gulp.parallel('browser-sync', 'hoge', function() {
    watch([/*作業対象のファイル*/], function() {
  		return runSequence(
  			'hoge',
  			'bs-reload'
  		);
  	});
  })
));

```

※ `hoge` は任意で設定
※途中の設定は諸々省略して記載しています。


## 使い方

* 作業ディレクトリのルートで `npm i` を実行し、必要なパッケージをダウンロード
* `htdocs` に移動し、 `docker-compose up -d` を実行し、ダウンロードが完了したら `docker-compose start` を実行
* 作業ルートに戻りgulpコマンドを実行し、ローカルサーバーを起動する

※ ローカルサーバー起動後は `localhost:8080` ではなく `localhost:3000` で表示されます。(port3000が使用済みなら3001)
Height FieldのWorkflow

#Height Field Workflow


![2019-02-10_20h24_24.png](https://qiita-image-store.s3.amazonaws.com/0/242799/140a8cdc-2f80-8733-e24e-602b69377b14.png)

###Massing
Massing(量塊化、要するにボリューム感を出すこと) は、3次元の広大な構造の地形を遮断するために必要。

山の地形で例えると、山の占有面積をどれほどにするのか、山が取り囲んでいる空間の形状をどうするのか、山の高低をどうするのかを決める。

Height Fieldに当てはめてみると、これは、最終地形の 全体の特徴 の基礎となる低解像度フィールドを作成することを意味する。
<img width="712" alt="terrain_massing_model1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/565c1f15-29f0-6c9e-9e2b-9753bae56533.jpeg">
<img width="713" alt="terrain_massing_model2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/680666ad-4ed1-762e-954f-b31e10267deb.jpeg">

**how to make Massing?**
・Height Fieldを直接ペイントする



###Seeding
Seeding(亜種化、要するにバリエーションを加えること) とは、滑らかな表面に少しの擾乱を追加して、より自然な感じを出すための処理のこと。
表面が滑らかでないほど、後工程での侵食がより現実的な見た目になる。
<img width="711" alt="terrain_seeding.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/936a5364-ddf5-bebd-82ed-8f3b11f3628f.jpeg">


###Lobing
Lobing(ロービング) とは、低解像度のHeight Fieldを受け取り、Heightfield Erodeを使って、山を小さく区画に分ける処理のことです。
Heightfield Erodeノードの Precipitation(降水量) 、 Cut Angle(カット角度) 、 Sediment Capacity(流送土砂の度合い) を上げることで、侵食作用を強くすることができます。
<img width="710" alt="terrain_lobing.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/5b8647f6-a109-1fe9-3a36-bae0858aae63.jpeg">


###Remapping
Remapping(再マッピング) は、何回もMassing/Seeding/Lobingの工程を繰り返すことで色々なレベル(例えば、山麓、低山、高山)を生成するために必要です。


###Upsampling
"Lobing"を終えたら、侵食のディテールが細かくなるように解像度を上げたいので、そのHeight Fieldを Upsampling する必要があります。

###Shaping
Shaping は、Heightfield TerraceとHeightfield Clipを使って、地質学的な特徴部を追加するために必要です。

マスクを使えば、山頂を削ったり、特定の領域に段々畑を追加して、より面白い侵食のバリエーションを生成することができます。
![terrain_terrace.jpg](https://qiita-image-store.s3.amazonaws.com/0/242799/83fb8ba7-5416-252c-921e-8368c7db17e6.jpeg)


###Re-seeding
Re-seeding(再シーディング) とは、高解像度で前述のSeeding処理を繰り返すことです。侵食の方向を変更させるためにもっと障害物を追加したい時に行ないます。

###Erosion
<img width="706" alt="terrain_erosion.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/3d45aa5b-2184-9ebb-4a74-12b4ac56493f.jpeg">

###Final
目的の地形が表現できたら、後は、地形をシェーディングしたり、岩や木の配置を調整します。
<img width="477" alt="terrain_shading.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/242799/d338ddd0-46c4-3bc6-863e-e432b465d67d.jpeg">
jupyterでセルにリンクを貼る

# はじめに
Jupyter環境（JupyterLabまたはJupyter Notebook）で個別のセル（特にMarkdownセル）にリンクを貼る方法についてメモする。
自分への備忘録なので説明不足は平にご容赦。
<a id='anchor'></a>

# どうやるの？
[ググったら出てきた](https://stackoverflow.com/questions/28080066/how-to-reference-a-ipython-notebook-cell-in-markdown)。

# もう少し詳しく
MarkdownでURLへのリンクを貼る場合、

```
[Qiitaへのリンク](https://qiita.com/)
```

とかくと、

>
[Qiitaへのリンク](https://qiita.com/)
>

のように表示される。

外部サイトへのリンクは上記でよいが、ページ内の任意の場所にリンクを貼りたいこともある。その場合、まずリンクしたい場所にアンカータグを書く。

```
ここにリンクを貼りたい。
<a id='anchor'></a>
```

その後、上記の記法でアンカーにリンクを貼ればよい。

```
[アンカーに飛ぶ](#anchor)
```

実際に[ここをクリックすると](#anchor)、ページ冒頭に飛ぶ……と思ったけど、Qiitaだとうまく動かなかった（404になる）。
JupyterLabだとうまく行くので、まあいいか（投げっぱ）。
なお、当然アンカータグそのものは表示されない。

# 簡易目次
実際にやりたかったのは見出しへのリンクで簡単な目次を作ることだった。
デフォルトで見出しがそのままアンカーになっているので、それは普通にできる。

```
[はじめに](#はじめに)
```

こう書けば[はじめに](#はじめに)のリンクが作れるので、これを並べれば簡易目次ができる（これはQiitaでも動く）。
見出しの表記が日本語でも問題なく動作するが、半角スペースがある場合はハイフンで埋める必要があるっぽい（見出しが`# First Heading`とかだったら`[link](#First-Heading)`とする）。

# まとめ
簡易目次を作ることそのものには別のスマートなやり方があるとは思うのだが、調べてもよくわからんかったので当分はこの方法を使うことにする。
最終的にはJupyterLabからLaTeXで吐いてPDF化するからそのときに目次を入れればいいんだけど、HTMLでもいい感じの目次が欲しいときなんかには使えるかも？
Googleフォトでアップロードした日付ごとに写真を表示する方法

## アップロード日ごとに写真を表示する方法は3つある
- 方法1: 検索ボックスから探す
    - 検索ボックスに「最近」と入力
    - 予測で表示される「最近追加した写真」をクリック
- 方法2: メニューから探す
    - サイドメニュー「:mag_right:データ検索」をクリック
    - 下部「あなたのアクティビティ」項目内「:clock:最近」をクリック
- 方法3: URL直打ち
    - https://photos.google.com/search/_tra_

## できること
アップロードした日付ごとに写真を表示・選択する