OmniAICreator/Qiita-1.07M huggingface dataset:
Mathematica でアニメーションを連番画像として出力する

例えばこのようなコードでアニメーションを作ったとします。

```Mathematica
Manipulate[
 ParametricPlot[ReIm@Sqrt[Exp[I t]], {t, 0, tmax},
  Epilog -> {Red, PointSize[0.02], Point[ReIm@Sqrt[Exp[I tmax]]]},
  PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}},
  AxesLabel -> (Style[#, 16] & /@ {Re, Im}),
  TicksStyle -> Directive[12],
  PlotLabel -> Style[Sqrt[Exp[I \[Theta]]], 20]
  ],
 {tmax, 0.01, 2 Pi}
 ]
```
このアニメーションを連番画像として出力するには`Manipulate`の中身を`g`とおいて、このようなコードに改造します。

```Mathematica
dir = "/Users/star-yoshi/Mathematica/gallery";
Table[
 Module[{tmax, g, file},
  tmax = (2 Pi)/100 k;
  g = ParametricPlot[ReIm@Sqrt[Exp[I t]], {t, 0, tmax},
    Epilog -> {Red, PointSize[0.02], Point[ReIm@Sqrt[Exp[I tmax]]]},
    PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}},
    AxesLabel -> (Style[#, 16] & /@ {Re, Im}),
    TicksStyle -> Directive[12],
    PlotLabel -> Style[Sqrt[Exp[I t]], 20]
    ];
  file = FileNameJoin[{dir, ToString[NumberForm[k - 1,3, NumberPadding -> {"0", ""}]] <> ".png"}];
  Export[file, g]
  ],
 {k, 101}
 ]
```
`dir`は出力先の先のディレクトリのパスです。ディレクトリをターミナルにドラッグすると、パスに変換されるのでそれを使うと便利です。
`NumberForm`の第二引数は出力画像のファイル名のゼロ埋めを何個にするか決めます。
これを実行すると連番画像の出力が始まります。Tableの代わりにParallelTableを使うと並列化されて速くなります。

連番画像になったら今度はこれをffmpegなどで動画にすることができます。Mathematicaで直接動画にすることもできますが、
この方法のほうがたぶん速いです。あと再生速度の調整や同じ動画を違うフォーマットで作り直すというとき、連番画像にしておけばffmpegの入力を
変えるだけなので効率的です。
【短い時間で的確に伝える練習ができた】【リベンジ】全員登壇！FlashTalk大会 #1 参加ふりかえり #engineers_lt

トークの練習に最適な勉強会に参加してきました。

イベントの詳細はこちらから確認できます↓
https://engineers.connpass.com/event/153594/

## 良かったこと

合計66個もの多種多様なトークを聴けたことです。１つの勉強会としては最多です。
一分しかないのでトークの内容が必然的に絞られます。
IT以外でも技術なら何でも話せるので、聴いてて飽きなかったです。

特に、面白いと感じたのは、和菓子のお話です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34636/75c4c42a-5ea7-d593-3e43-c1d731c33476.png)

>和菓子の中には必ず餡子が入っていますよね？
でもお菓子の外側を包んでいるのも、実は餡子なのです。
つまり、和菓子は「あんこ in あんこ」なのです。。

導入部分が素晴らしく、トークに惹き込まれました。

全員登壇したためか、懇親会で話すことに困りませんでした。
文化祭の前夜祭のような感覚になりました。参加者全員で登壇するのって良いですね。

## 感じた課題

本番の雰囲気を想定して練習しておけばよかったと思いました。話す内容も大事ですが、表情や声量が豊かであれば、そのぶん熱意を伝えることができるからです。

今回は、トークの内容を覚えること、上手く話すことに集中しすぎました。

勉強会は単なる勉強をする場ではなく、ライブ感を大事にする場だと実感しました。

## 改善しようと思ったこと

トークの脚本をガチガチに決めないようにします。
今回の脚本は290文字だったので55秒に収まるようにしましたが、250文字くらいにしておいて、当日感じたことをその場で盛り込む余裕を設けます。

練習から、表情豊かに喋るように意識します。
具体的には、目をできるかぎり大きく開くようにします。
[VRChat] DynamicBoneの最低限の設定

私がVRChatでDynamicBoneを入れるときの最低限の設定です。
こだわりは一切なくて「とりあえず動かす」ことだけを目的とした指南です。

細かい設定については、ググると良いページがたくさん出てくるので、そちらを参照してください。

# 前提
- Unity 2017.4.28.f1をインストール済み

# 1. DynamicBoneを買う（安くはない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93702/26870c6d-6a26-0cbc-ab37-a7f976aec654.png)

# 2.アバターを用意する
- アバターをUnityに導入
- Boneなども正しく設定
- DynamicBoneで揺らしたいオブジェクトも入れておく
- ちなみにマフラーはこちらからいただきました
  https://booth.pm/ja/items/1101730

# 3.DynamicBoneを入れる

![DynamicBone.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93702/3cb032bc-49c0-b589-74b1-c1b1e8a0cd04.png)

- 入れる場所はアバター内であればどのGameObjectでも動作するようだけど、分かりにくくなるので、動かしたいBoneの根っこに入れるのが分かりやすいと思う
- DynamicBoneのInspectorで設定する最低限の項目は以下の通り（他の項目はデフォルト値で良い）
  - Root: 動かしたいBoneの根っこのオブジェクトを選択（ここを選択しないと動かないので注意）
     - ここでいう「根っこ」というのは、例えば尻尾が tail - tail1 - tail2 - tailend のように構成されていたら、tail部分が該当（この場合、tailにDynamicBoneを入れると、tail～tailendまでが揺れる。なお、tail2に入れると、tail2-tailendが揺れる。そんなイメージ。）

  - Damping: ここだけ1にすればだいたい揺れる
  - Radius: この値を入れると図にあるような「透明の球」が出てくると思いますが、DynamicBoneではその球がゆらゆら揺れる印象なので、なんとなく適度なサイズになるように調整（図だと0.0005ですが、この値は入れる場所（？）によって全然変わってくる）


# 4.Unityで揺れ具合をテストする

- Unity画面上部の三角ボタンで「再生」する
- 再生すると「Game」タブに遷移してしまうが、その状態で「Scene」タブを選択
- アバターを上下左右に動かすと揺れる（この揺れ具合が気に入らなければ、各種パラメータを調整。調整しだすと沼る（笑））

ちなみに「再生」した状態でパラメータを変更しても、再生停止した後に戻ってしまうので、パラメータを変更したい場合は、再生ボタンをもう一回押して停止しましょう。

以上です。
docker windows10home でWEBアクセスできなくてハマった話

#docker windows10home でWEBアクセスできなくてハマった話
##ビルドは、とりあえずできた。
参考にしたサイト
[Docker | docker build と Dockerfile でイメージをビルドする基本](https://qiita.com/YumaInaura/items/e7155b309e109bc75cf8)
Dockerfileがあるディレクトリに移動して、以下のコマンドでＯＫでした。
```$ docker build ./ -t hello1201_2
```
##はまりポイント
```$ docker run --init -d -e PORT=81 -p 0.0.0.0:8081:81 hello1201_2 
```
このコマンド後、ブラウザで、http://0.0.0.0:8081
だと、アクセスできませんでした。
いろいろ試したけど、ダメめでした。

参考にしたのは、こちらのサイト
[Docker入門日誌-その2- Webサーバ立ち上げ編](https://techracho.bpsinc.jp/ebi/2017_05_24/40406)
```$ docker-machine ls
```で出てくるURLを再確認します。

私の場合、
```$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.5
```となっていたので、ブラウザで、http://192.168.99.100:8081
として、アクセスできました。

解決できない気がしてたけど、Google先生！　ありがとう！
Google検索は、以下の通りでした。
”docker ローカルPC WEBアクセスできない”
Flutterで画面遷移してから戻ってきたことを検知する

この記事は [Flutter Advent Calendar 2019 １日目](https://qiita.com/advent-calendar/2019/flutter) の記事です。


Flutterで画面遷移で `Navigator.push` を使って画面遷移を行い、その後、 `Navigator.pop()` したり、 `AppBar` から戻るをおしたり、 Androidのバックキーをタップなどで前の画面にもどってきたことを検知して処理をする方法について書きます。


## `Navigator.push` の実装

Flutter SDK内の `Navigator.push` の実装は下記のようになっています。

```dart

  @optionalTypeArgs
  Future<T> push<T extends Object>(Route<T> route) {
    assert(!_debugLocked);
    assert(() { _debugLocked = true; return true; }());
    assert(route != null);
    assert(route._navigator == null);
    final Route<dynamic> oldRoute = _history.isNotEmpty ? _history.last : null;
    route._navigator = this;
    route.install(_currentOverlayEntry);
    _history.add(route);
    route.didPush();
    route.didChangeNext(null);
    if (oldRoute != null) {
      oldRoute.didChangeNext(route);
      route.didChangePrevious(oldRoute);
    }
    for (NavigatorObserver observer in widget.observers)
      observer.didPush(route, oldRoute);
    RouteNotificationMessages.maybeNotifyRouteChange(_routePushedMethod, route, oldRoute);
    assert(() { _debugLocked = false; return true; }());
    _afterNavigation(route);
    return route.popped;
  }
```

まあなにしてるかはとにかく置いておいて、返却される型が `Future<T>` になっているので、　`).then((value)` や、 `await` とかを使って処理が終わった後に何か処理をすることができるようになります、



## 画面遷移してから戻ってきたことを検知して処理をする

実際に画面遷移してから戻ってきたことを検知するコードはこうなります。

```dart
Navigator.push(
 context,
 CupertinoPageRoute(
   builder: (_) => // なんかのWidget,
 ),
).then((value) {
  // ここで画面遷移から戻ってきたことを検知できる
});
```

自分の場合は、画面遷移から戻ってきたときにアニメーションを再開するみたいな処理で使っています。

```dart
Navigator.push(
  context,
  CupertinoPageRoute(
     builder: (_) => MyPage(
       widget.observer,
       widget.analytics,
       otherUser: _currentItem.user,
     ),
   ),
).then((value) {
  animationController.forward();
});
```


## 前の画面に引数を渡す


前の画面にデータを渡すことも可能です。

(下のコードでは前の画面に `false` というデータを渡しています。)

- 渡す側

```dart
Navigator.pop(context, false);

```

- 受け取る側

```dart
Navigator.push(
 context,
 CupertinoPageRoute(
    builder: (context) =>
          Setting(widget.observer, widget.analytics),
    ),
).then((value) {
  // valueに `false` が返ってくる
  print(value);
});

```


地味に使うと思って書いてみました。
Heroku Dataclipsでお手軽公開クエリ

Heroku Dataclipsで、[Heroku Postgresに対するクエリの結果を手軽に公開する](https://devcenter.heroku.com/articles/dataclips)ことができます。この機能で、Herokuで稼働しているアプリケーションそのものからは提供されていない方法でも、データを活用することができます。この記事では利用手順の概略と利用例を紹介します。

この記事は、[Heroku Advent Calendar 2019](https://qiita.com/advent-calendar/2019/heroku)の2日目の記事です。1日目は狩野さんによる『[DeveLove関西で、アジャイル開発におけるHerokuFlowの運用について登壇してきました](https://developers.tam-bourine.co.jp/entry/2019/12/01/100000)』でした。アジャイルちゃんと実践してみたいなあ！3日目はsho7650さんによる『[Heroku で Linux コマンドを巧みに使いこなす](https://qiita.com/sho7650/items/995b921da7b8be8f11b6)』です。手元のマシンをLinuxにしてもいいのよ？(それができないから苦労してるんだ)

## Dataclipを作成する
1. https://data.heroku.com/dataclips を閲覧し、New Dataclipボタンをクリックします
1. タイトルを入力し、クエリ先のアプリケーションとデータベースを選択します
1. 必要なら「Published」状態を「Draft」状態にします
1. 入力欄にクエリを入力します
1. Save & Runボタンを押しクエリの結果が表示されるのを待ちます
1. 満足できるまでクエリを編集しSave & Runボタンを押します
1. 「Draft」状態を「Published」状態にします

これで、アプリケーションにアクセスのある人はDataclipを閲覧できるようになります。

## Dataclipを公開する
1. https://data.heroku.com/dataclips を閲覧し、公開するDataclipを選びます
1. 「Share」ボタンを押し、「Create Public URL」を押します
1. 表示されたURLをコピーして、公開します

## 公開されたDataclipを確認する
筆者はHerokuで[ぼっちマストドンサーバ](https://mastodon.zunda.ninja/)を運用しています。下記のようなクエリで、過去2日間のどの時間にたくさん投稿していたかがバレてしまいます。本来はHeroku Postgresへのアクセス権がないとクエリを実行できませんが、Dataclipsによってクエリの結果を公開することができます。

```sql
WITH toots AS (
SELECT
DATE_TRUNC('hour', created_at) AT TIME ZONE 'UTC' AT TIME ZONE 'HST' as hour,
id
FROM statuses
WHERE account_id = 1
        AND created_at >= DATE_TRUNC('hour', NOW()) - interval '2 days'
        AND created_at < DATE_TRUNC('hour', NOW())
), hours AS (
SELECT hh AT TIME ZONE 'UTC' AT TIME ZONE 'HST' as local
FROM generate_series(
  (DATE_TRUNC('hour', NOW()) - interval '2 days')::timestamp,
  (DATE_TRUNC('hour', NOW()))::timestamp,
  '1 hour'::interval) hh
)
SELECT local, COUNT(id)
FROM toots RIGHT JOIN hours ON toots.hour = hours.local
GROUP BY local ORDER BY local;
```

このクエリをDataclipにしてありますので、ちょろっと覗いてみましょう:  https://data.heroku.com/dataclips/zwfqiwbctjswnxvukzbnblyfvwnh

右上のボタンでChartを選択することで、簡単なグラフとして表示することもできます。金曜日の10時台に何かあったのかな？

![Screen Shot 2019-11-30 at 3.21.31 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105088/6e80451f-f836-fa91-43a3-3b7d2ec18af5.png)

「Share」ボタンから限定されたHerokuアカウントのみに公開することもできます。活用してみてください。
アクションとHTTPメソッド

| アクション　　　　　　| HTTPメソッド | 役割 　　　　　| URLのパス　　　　　　　 |
|:--------|:------|:--|:--|
| index   | get | 一覧表示 | /works |
| show    | get | 詳細表示 | /works/1 |
| new     | get | 新規作成 | /works/new |
| create  | post | 登録 | /works/create |
| edit    | get | 編集 | /works/1/edit |
| update  | patch/put(post) | 更新 | /works/1/update |
|destroy  | delete(post) | 削除 | /works/1/destroy |
ブラウザ上で、マウス + `Ctrl` + `C`でおこなうことをキーボードのみで完結する

# 環境

- Chrome（2019.12.01時点最新版）
- Windows 10

# Chrome拡張機能のVimiumを利用します。

- https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb

# やりたいこと


- マウスと`Ctrl` + `c`を利用してのテキストコピペをキーボードで完結する

テキストを選択する際、範囲選択をミスることがちょくちょくあるため、それを減らしたい。

# 使用する機能

- `Visual mode`, `Caret mode`

https://github.com/philc/vimium/wiki/Visual-Mode

# 動作の一連の流れ

ウェブサイトにアクセスし...

1. `v`を押す。（`Visual mode`に入る。）
2. `c`を押す。（`Caret mode`に入る。1の実行時に何も選択されていない状態なら自動的に`Caret mode`に入る。）
3. `j`, `k`, `h`, `l`, `w`, `e`, `b`を利用してカーソルの起点を決める。（これらアルファベットはVimでのカーソル移動に利用するものと同一らしい。）
4. `v`を押し、`Visual mode`に入り、3で利用したのと同じキーで文字列の範囲を選択する。
5. 範囲を選択後、`y`を押して選択範囲の文字列をクリップボードにコピーする。

おわり

# おまけ

## `Caret mode`の起点は`/`を押すことで利用できるページ内検索で決定した方が良い（と感じた）

たとえばQiitaのようにページ構成が2カラム（左ブロックに記事本文、右ブロックに目次）の場合、左カラムから右カラムへの移動が先に紹介したキーではどうにも上手くいかなかった。（逆も然り）

そのため、起点位置から大きくカーソル移動が生じるような状況は避けた方が良いと感じた。
gitパスワード省略(gitbucket)


# https://qiita.com/sudahiroshi/items/3d8adca693cd21d0b849

vi ~/.netrc

machine 192.168.xx.xx
login xxx
password yyy

chmod 600 .netrc

##################

# https://qiita.com/r-tamura/items/c6e49a3eb7f7f8aafb9d

GPGでパスワードを暗号化する
GPGとは
GPG (GNU Privacy Guard)はOpenPGPの規格に沿って作られた暗号化ソフトで、GNU GPLのもとで公開されているオープンソースソフトウェア。

.netrcの暗号化
GPGで作った鍵を持っていない場合は以下のコマンドで鍵を生成する
$ gpg --gen-key
鍵生成には時間がかかる場合がある。今回行った環境では30分ほどかかった。
参考 : ssh 越しに「gpg --gen-key」を実行したときに乱数生成の段階までくるとハングしてしまったかのようになるのは，「単に時間がかかっているから」らしい．約20分もかかった．

.netrcを暗号化する
暗号化を行うとホームディレクトリに.netrc.gpgファイルが生成される。次に元の.netrcファイルを削除

$ gpg -e -r <email> ~/.netrc
$ ls .netrc*
.netrc  .netrc.gpg
$ rm .netrc

git credential helper用のスクリプトに実行権を与え、gitの設定にcredential helperとして追加する
gitで用意されているgpgを使ったnetrc利用のスクリプトがあるので、それに対して実行権を与えることで使えるようになる。

$ sudo chmod +x /usr/share/doc/git-1.8.3.1/contrib/credential/netrc/git-credential-netrc
$ git config --global credential.helper /usr/share/doc/git-1.8.3.1/contrib/credential/netrc/git-credential-netrc
これで、git push,git pullするときに自動的に復号されるので、ユーザ情報の入力なしでpush,pullができるようになる。
【技術ブランディングをすると、誰にとって何が嬉しいかが分かった】第4回 転職透明化らぼ-技術ブランディング編 参加ふりかえり #転職透明化らぼ

遅くなりましたが、振り返りをしていきます。

イベント情報、発表資料はこちらから確認できます↓
https://rtlabo.connpass.com/event/152001/

## 良かったこと

「技術ブランディング」とは何かについて、いろんな意見が聞けたことです。
漠然と、「メリットありそうだけど、誰にメリットがあって何が良いことで、どのように目指していけばいいのか」が分からなかったためです。

メリットがある人は、以下の２つのタイプです。
1. 働く人。労働力を提供する個人。
2. 採用する人。労働者に対価を提供する企業。

**エンドユーザーに対してはメリットがありません**。なぜなら、企業の提供するサービスの価値を上げることが目的ではないからです。

あくまで、**求職者と採用側のマッチング率を上げるためのもの**だと理解しました。

では、具体的にどうすればいいのでしょうか？

**働く人は、何ができるのかを発信し、自分の働く領域で「この人はこれが出来る人なんだ」と認知してもらうと良いです**。たとえば、「Webフロントエンジニアの領域で、シングルページアプリケーションと静的サイトジェネレーターに非常に詳しいため、他のエンジニアよりも早く、しかも使い捨てではないプロトタイプを作ることができます」という感じです。

**採用側は、事業活動で得た知見をブログで発信したり、OSSやコミュニティを牽引すると良いです**。なぜなら、働く人が自分の価値を高めるために必要だからです。たとえば、「事業でJavaを専門に使い、知見をブログで発信し、書籍を出版し、プラグインを作り、イベントのスポンサーになり、登壇し、コミュニティの主導的立場になる」という感じです。できれば、企業に所属する個人ではなく、経営陣が率先して活動できると、継続しやすくなります。

## 感じた課題

自分は労働者の立場なので、「これが出来る人なんだ」を認知してもらうことが弱いと感じました。目指すものを追うことはできます。しかしそれは抽象的であって、「今ある市場で、具体的に何ができるか」を発信してきたことは少なかったです。

自分が企業側だった場合、たとえば、技術的に優れた自社サービスを保有している企業に対しては、「具体的に何が良くて、何が好きで、今後どの分野を活性化させてゆきたいか」を働く人に向けて発信したいと思いました。

## 改善していこうと思ったこと

自分にできることと、自分が認めてもらう領域を具体的にしようと思いました。

具体的には、「Webサーバサイドの領域」で、「パフォーマンスチューニング」に詳しくなり、サービスの安定供給に貢献しようと思いました。

具体化がまだ弱いと思いますが、いきなりゴールに辿り着くのも無理なので、継続して活動してゆきます。
製薬企業研究者がRの制御文についてまとめてみた

# はじめに

ここでは、R初心者向けに「制御文」について解説していきます。


# 条件分岐

条件によって処理を分けたい場合に使います。

## if文

`if`に続く条件式が`TRUE`なら、処理が実行されます。

```r:if_1.R
x <- 2
y <- 2

if (x == y) {
  print("xとyは等しい。")
}
```

この例では、`x == y`は`TRUE`となるので、`xとyは等しい。`と出力されます。

また、`else`を入れると、`if`に続く条件式の判定が`TRUE`でなかった場合の処理を記述できます。


```r:if_2.R
x <- 2
y <- 3

if (x == y) {
  print("xとyは等しい。")
} else {
  print("xとyは等しくない。")
}
```


さらに、`else if`を入れると、それより上の条件式の判定が全て`FALSE`で、`else if`に続く条件式が`TRUE`だったときの処理を記述できます。

```r:if_3.R
x <- 2
y <- 3

if (x == y) {
  print("xとyは等しい。")
} else if (x == 2){
  print("xとyは等しくないが、xは2である。")
} else {
  print("xとyは等しくなく、xは2ではない。")
}

if (x == 2 && x != y){
  print("xは2であり、xとyは等しくない。")
}else if (x == y || y == 4) {
  print("xとyは等しい、またはyは4である。")
} else {
  print("よく分からない。")
}

if (x == 2) {
  if (y == 3) {
    print("xは2であり、yは3である。")
  } else if (x == y) {
    print("xとyは2である。")
  } else {
    print("xは2であり、yは2でも3でもない。")
  }
} else if (x == 3) {
  print("xは3である。")
} else {
  print("xは2でも3でもない。")
}
```


## switch文

変数の値によって処理を分けたいときなどに使います。

```r:switch_1.R
z <- 3

switch (z,
        "1" = print("zは1です。"),
        "2" = print("zは2です。"),
        "3" = print("zは3です。"),
        print("それ以外です。")
        )
```


以下のように、`if`でも書き換えることはできますが、やや長くなり可読性も下がります。

```r:switch_2.R
z <- 3

if (z == 1) {
  print("zは1です。")
} else if (z == 2) {
  print("zは2です。")
} else if (z == 3) {
  print("zは3です。")
} else {
  print("それ以外です。")
}
```


# 反復処理

同じ処理を複数回繰り返す時に使います。

## for文

一定回数だけ同じ処理を繰り返す時に使います。

```r:for_1.R
for (i in 1:5) {
  print(i)
}


nums <- seq(1, 5)

for (i in nums) {
  print(i)
}
```


`break`を使うと、反復処理を中止することができます。`if`と組み合わせて、特定の条件が成立した時に処理を中止するといったときに使うことが多いです。

```r:for_2.R
nums <- seq(1, 5)

for (i in nums) {
  if (i == 3) {
    break
  }
  print(i)
}
```

`next`を使うと、反復処理をスキップすることができます。こちらもifと組み合わせて使うことが多いです。


```r:for_3.R
nums <- seq(1, 5)

for (i in nums) {
  if (i == 3) {
    next
  }
  print(i)
}
```


## while文

ある条件が成立する間のみ反復処理をする場合に使います。

```r:while_1.R
num <- 1

while (num < 5) {
  print(num)
  num = num + 1
}

while (num < 5) {
  num = num + 1
  print(num)
}
```

whileの中も上から下へ順番に処理が実行されるため、書き方によって実行結果が変わる場合があります。

変数の値の更新を書き忘れると、処理が無限回数繰り返される（無限ループとなる）ので注意が必要です。

```r:while_2.R
num <- 1

# while (num < 5) {
  # print(num)
# }

# while (TRUE) {
  # print(num)
# }
```


## repeat文

無限ループになります。
処理を止めるために、`break`などを書く必要があります。

```r:repeat_1.R
num <- 1

repeat {
  if (num < 5) {
    print(num)
    num <- num + 1
  } else {
    break
  }
}
```


反復回数が決まっている場合はforを、反復回数が決まっていない場合はwhile（またはrepeat）を使うようにすると良いです。


# まとめ

ここでは、Rの制御文として「if」「switch」「for」「while」「repeat」を紹介しました。
プログラミングの中心とも言える構文なので、実際に使いながら身につけていくと良いでしょう。



# 参考資料・リンク

[プログラミング言語Rとは？統計分析に強い？](https://pharma-engineer.com/basic-programming/r-summary/)
とあるパブリック・リポジトリに設定されたGitHub Actionsから別のパブリック・リポジトリにgit pushしたい

GitHub Actions、もといGitHub自体、初心者ということもあって、時間をかなり溶かしたので、メモとして残しておきます(´・ω・｀) とあるパブリック・リポジトリに設定されたGitHub Actionsから別のパブリック・リポジトリに`git push`したい場合、おおよそ以下の通りに記述すればOKです。

```yml
jobs:
  sample-job:
    runs-on: sample-latest
    steps:
    - name: sample-step
      env:
        ACCESS_TOKEN:  ${{ secrets.ACCESS_TOKEN }}
      run: git push https://x-access-token:${ACCESS_TOKEN}@github.com/sample-user/sample-repository sample-branch
```

ここで大事なのが、リモートレポジトリのURLの形式です。ここでは`ACCESS_TOKEN`と`secrets.ACCESS_TOKEN`という環境変数を利用していますが、これはGitHub Actions組み込みの変数ではありません。ユーザが自分で設定する必要があります。

1. ["Personal access tokens"](https://github.com/settings/tokens) において、アクセストークンを作成します。このとき"Access public repositories"を有効化し、発行されたアクセストークン文字列を控えておきます。
2. GitHub Actionsが設定されたリポジトリのページ → Settings → Secrets において、次のような変数を作成します。
    - "Name": ACCESS_TOKEN
    - "Value": 1.で控えておいたアクセストークン文字列
3. すると、GitHub Actionsの`secrets.ACCESS_TOKEN`が2.で作成した`Value`の値を指すようになるはずです。

要するにアクセストークンをSecrets経由でGitHub Actionsに渡しているだけです。パブリックなレポジトリにハードコーディングするのはセキュリティ上避けたいので、こういう迂回策をとっているわけです。

また`ACCESS_TOKEN`という名前は一例に過ぎません。任意の名前をつけても大丈夫です(´・ω・｀)
Cloud9 Laravel cross-env のパス指定

# Cloud9のLaravel6の環境下にてjavascriptを実行するためにいろいろ設定します

````qiita:cross-env.jsのパス
node_modules/cross-env/src/bin/cross-env.js
```

package.jsonのscript内のエイリアスを修正
"cross-env"と明記されているところへ

```
node node_modules/cross-env/src/bin/cross-env.js
```
を上書きする。

```qiita:package.json変更前
"scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env  NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env  NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
```

実際のcross-env.jsへのパスを上書きする。(3項目)
`cross-env` → `node node_modules/cross-env/src/bin/cross-env.js`
・development
・hot
・production


```qiita:package.json変更後
 "scripts": {
        "dev": "npm run development",
        "development": "node node_modules/cross-env/src/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "node node_modules/cross-env/src/bin/cross-env.js NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "node node_modules/cross-env/src/bin/cross-env.js NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },

```
あら、こんなところに副作用

JavaScriptを書いていると、意外なところで副作用を発生させることができてしまいます。

## プロパティ参照

たとえば、こんなコードを考えてみます。

```javascript
const foo = new Foo();
foo.bar;
```

ここでの2行目は無意味な文にも見えますが、`Foo`の中身によってはこれが副作用を持つことがありえます。

```js
class Foo{
  get bar(){
    alert('副作用');
  }
}
```

ということで、プロパティ参照はその見た目によらず、他のコードを実行可能、ということになります。

## 文字列展開

これは比較的わかりやすいかもしれませんが、文字列変換に際してはオブジェクトの`toString`メソッドが呼び出されます。

```js
const obj = {
  toString() {
    alert('副作用');
    return '文字列';
  }
}

`${obj}`; // 文字列を定義しただけでアラートされる
```

## `Proxy`オブジェクト

ES6で追加された`Proxy`オブジェクト（[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy)）は、意外なところにもフックを仕込めて、副作用を発生させられます。

* `in`演算子によるプロパティチェック
* `delete`演算子によるプロパティ削除
* `Object.***`による各種のオブジェクト操作

## 実運用に与える影響

もちろん、「`toString()`が余計な副作用を持つオブジェクト」なんてものは使いづらいので、実用することはないかと思います。とはいえ、考慮しないといけない場面はありえます。

* DOMプロパティの中には、[参照するだけで再描画を行うものがあります](https://qiita.com/jkr_2255/items/5cdead4ee7fa289bfeed#reflow%E3%81%8C%E8%B5%B7%E3%81%8D%E3%82%8B%E6%99%82)ので、あえて使うにしろ、うっかり使って余計な再描画が入ってしまうパターンにしろ要注意です。
* コードのminifyを行う際も、「元のコードの動作を変えられない」というのは大前提になりますので、`obj.propertyWithVeryLongName`のようなものが大量にあっても、1つにまとめることはありません。自分で変数に受けるなどしたほうがいい場面もあるかもしれません。
新しい技術や概念を学ぶときはスライド共有サービスが便利という話

## TL; DR
- Slideshareなどのスライド共有サービスを使った学習法が便利という話
- スライドは要点が簡潔にまとめられており、かつ図解があり理解しやすい上に短時間で読み切れる
- 図解の書籍などは有料だが、スライドなら基本的に無料
- とはいえスライドだけで技術を全て学習できるわけではなく、単なるエントリーポイントなので注意が必要

## はじめに
先日[いかにして未経験から4年間でフルスタックエンジニアになったか](https://qiita.com/wildmouse/items/6310f5dc1e15b04fed6d) という記事を書きましたが、細かな学習方法についての言及はしていませんでした。

私の学習法としては基本的には、

- 公式サイトのドキュメントを読みこみ、Getting Startedなどでざっくり使い方を学ぶ
- オライリーなどの技術書をしっかり読み込む
- ハンズオンの書籍を手を動かして学ぶ
- Udemyなどの動画を使ってざっくり概要を掴みつつハンズオンの学習をする

というような学習方法をとっていますが、私はそれに加えてSlideshareなどにアップされているスライド資料を使った学習をしています。

2019年11月30日時点でトレンドに上がっている[エンジニアが活用したい情報リソースまとめ](https://qiita.com/EaE/items/eb8f28223c9c2926b44f#%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E5%85%B1%E6%9C%89%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9) という記事でもスライド共有サービスの項目があります。

使っている人にとっては基本的なことになると思いますが、書籍や動画だけで学習をしている方にとっては幾らかの参考にはなると思うので、この記事でスライドを使った学習のメリットや方法について紹介したいと思います。


## スライドごとに要点がわかりやすくまとめられている
まず前提として、スライドというのは特定の場所で限られた時間で発表するために、発表者が要点をまとめて聴く人にとって分かりやすく概念や技術、あるいは別のなにがしかをまとめたものです。

そのため内容は不要な記述が排除されており、聴く側にとって必要なことだけがまとめられています。

理解したい概念、技術があったときに、それに関するスライドをいくつか読めば、いくらかその技術に関する理解が進むはずです。


## 図があって理解しやすい
スライドは要点がまとめられているだけでなく、図が多用されているものも結構あったりします。

あなたも文章だけを読んでいてもよく分からなかったけど、図でまとめられているものを見たらすぐに理解できた、という経験があるのではないでしょうか。

そのためスライド図でまとめられていると、要点をまとめた文章と一緒に図が示されているため、より理解しやすくなるということです。


## 基本的にフリーで閲覧可能
上記の図に関しては、図解系の書籍でも同じ効果が得られますが、いかんせん書籍だと有料になってしまいますよね。

技術の習得のために費用は惜しむべきではないと僕は思っていますが、それでも金銭的な制限があることもあるでしょうし、必要ないコストは削減すべきです。

その点slideshareなどで共有されているスライドは、基本的に無料で閲覧することが可能です。

書籍に関しては業務で本格的に利用する必要があるものや、プライベートで学びたいと思うようなものについて出費すれば良いのでは無いでしょうか。


## 短い時間で読み切れるので短時間で概念の習得が可能
ITの分野の概念はかなりの量あるので、全てを1から10まで見ていると一向に学習が終わりません。

しかしスライドであれば数十ページ程度で読み切れるので、サクサク読めば15~30分程度で読み切ることができます。

書籍や動画であれば全体を見るのに数時間、長いと数日間やそれ以上になってしまいますが、スライドであればどれだけ長くても1時間以上にはならないでしょう(100ページあるような巨大なスライドはかかってしまうかもしれませんが...)

## スライドの探し方

### 各サイトでキーワード検索する
手っ取り早いスライドの探し方としては、各スライド共有サービス上の検索機能を使って調べることですね。

主なスライド共有サービスは下記の二つでしょう。


- [Slideshare](https://www.slideshare.net/)
- [Speaker Deck](https://speakerdeck.com/)

### Googleで`site:`オプションを使って検索する
Googleでは検索バーに`site:{検索対象のサイトドメイン}を含めることで、そのサイトだけに絞った検索結果を表示することができます。

なのでこのオプションを使って先ほどのスライドサービスに絞って検索すれば、Googleの検索アルゴリズムを使ってスライドを検索することが可能です。

例えば「site:slideshare.net テスト駆動開発」などで調べると、SlideShareについての検索結果が表示されます。

そして上位に検索されるということはview数が多く、たくさんの人が閲覧した＝勉強になったスライドであると考えられるので、一つ目の方法よりもいいかもしれません。


### 上記に加えて英語で調べる
今紹介した二つの探し方を、英語のキーワードを使って調べるとより多くのスライドが見つかるはずです。

もしかすると英語に抵抗があるかもしれませんが、最初の方でお話しした通りスライドは要点がまとめられて図がついているものが多いので、英語でも結構理解できたりします。

日本語で分厚い書籍を読むよりも、英語のシンプルな文章と図でまとめられたスライドの方が短い時間で理解できると思いますよ。


## スライド学習の注意点

### あくまで概要であって、省略されている部分がある点を意識すること、
スライドは要点がまとまっているということをお話ししましたが、これは裏を返せば色んなものを切り離しているということでもあります。

つまり要点以外の細かな情報がなく、技術に関して実際に手を動かすために必要な情報が不足している可能性もあるということです。


### slideshareだけで全てが理解できるわけでは無い
そのため当たり前のことですが、スライドだけで全てが理解できるわけではありません。

個人的な感覚としては、スライドを利用した学習は本の速読程度のもので、あくまで理解を助けるものです。

- 業務で使う技術が出てきたときにまずは公式サイトを調べてざっくり内容を理解しようとして、その技術そのものや関連する概念が分からなければスライドを見つけて概要を掴む。

- そして大枠について理解できたら、今度は公式のチュートリアルや技術書を使って本格的に学習をする

という流れの中でスライドを使うのがいいかもしれませんね。

以上、スライドを利用したメリットと学習法についてまとめさせていただきました。

最終的には公式サイトや書籍、動画を使って手を動かさなければ技術は理解しづらいですが、概要の理解にスライドは確実に役に立つはずです。

この記事があなたの学習の助けになれば幸いです。
vagrant up で 「Failed to create the host-only adapter」が発生した場合の対応

VirtualBox6.0 + vagrantで「Failed to create the host-only adapter」が発生して、「vagrant up」ができない。

~~~
==> default: Setting the name of the VM: centos7_default_1575127270766_28
Vagrant is currently configured to create VirtualBox synced folders with
the `SharedFoldersEnableSymlinksCreate` option enabled. If the Vagrant
guest is not trusted, you may want to disable this option. For more
information on this option, please refer to the VirtualBox manual:

  https://www.virtualbox.org/manual/ch04.html#sharedfolders

This option can be disabled globally with an environment variable:

  VAGRANT_DISABLE_VBOXSYMLINKCREATE=1

or on a per folder basis within the Vagrantfile:

  config.vm.synced_folder '/host/path', '/guest/path', SharedFoldersEnableSymlinksCreate: false
==> default: Clearing any previously set network interfaces...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["hostonlyif", "create"]

Stderr: 0%...

Progress state: E_FAIL

VBoxManage.exe: error: Failed to create the host-only adapter

VBoxManage.exe: error: Operation canceled by the user

VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component VirtualBoxWrap, interface IVirtualBox

VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleCreate(struct HandlerArg *)" at line 94 of file VBoxManageHostonly.cpp

~~~

調べていくと、下記のブログにセキュリティソフトをOFFにして、インストールできたとのことで、試してみた。
https://blog.officekoma.co.jp/2018/04/vagrant-up-failed-to-create-host-only.html

> 今回、Vagrant のプロバイダはVirtualBoxにしているのですが、
結論から言うと、
一度VirtualBoxをアンインストールして、「ウイルスバスター」が停止している状態で、VirtualBoxを再インストールする必要があります。
その上で、再度「vagrant up」試してみると、うまく行きました。
（再インストールから「vagrant up」まで、ウイルスバスターは停止させています。）
> 
> ※一度、仮想環境まで作成出来れば、後はウイルスバスターが起動していても大丈夫です。

今回、私はカスペルスキーを使ってましたが、同様にカスペルスキーをOFFにしてVirtualBoxを再インストール。その後、カスペルスキーを起動。そして、「vagrant up」してもエラーは起きてない。とりあえず、これで、様子見をしよう。
motoを初めて使うまでの道のり

# はじめに
こんばんwifi

motoを使用してAWSサービスをmockする手順を
自分用の備忘録として
初心者用に書き記したいと思います。

今回はEC2をローカル上で作成し、
そのインスタンスIDを取得するというテストを実施していこうと思います。

# まずmockって何？
"モックオブジェクト"という言葉は、テストのために本物のオブジェクトをまねる特殊なオブジェクトを表す言葉らしいです。

テストやコンパイル用に用意されたダミーのクラスで、実際に処理は行わない。
呼び出しが行われたかどうか、どんな引数で呼び出されたかなどを記録してくれるもの。

自分の中では、テストで扱う疑似の環境を用意してくれるものと思っています。

# そしてmotoとは
AWS ServiceをMockしてくれる素晴らしいものです。
AWSサービスを実際に動かすことなく、疑似環境でテストが行えることができます。

# 環境
作業するのに必要な環境を整えます。
以下のサイトがわかりやすかったので、そちらを手順にしてみて下さい。

- pythonのダウンロード　→　[こちら](https://www.python.jp/install/windows/install_py3.html)を参考
- vs codeのダウンロード → [こちら](https://eng-entrance.com/texteditor-vscode)を参考　(開発環境は何でもいいと思います)
- AWS CLIのダウンロード → windowsは[こちら](https://qiita.com/C_HERO/items/711edd101ea79198bdfb)、macは[こちら](https://dev.classmethod.jp/cloud/aws/mac-aws-cli/)

#仮想環境構築
こちらも以下を参考にディレクトリに仮想環境を作ってください。

[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)

作成するとディレクトリ構成が以下のように

```
├── project_dir
│   ├── [newenvname]
```

venvをActivateさせると

```
(venvname)$
```
こんな形になると思います。
そしたらこの状態で次の作業を実行してみて下さい。

# 仮想環境にboto3とmotoを入れる
### boto3
```
(venvname)$ pip install boto3
```
### moto
```
(venvname)$ pip install moto
```
仮想環境に`boto3`と`moto`のパッケージをインストールしました。
試しにActivateとDeactivateの両方で`pip list`と入力してみて下さい。
Activateの時にしか`boto3`と`moto`のパッケージが出力されないと思います。
そうなっていれば仮想環境の完成！！

# 必要ファイルの作成
下記のようなディレクトリ構成になるよう、`app`,`tests`ディレクトリを作成して下さい。

```
├── project_dir
│   ├── [newenvname]
│   ├── app
│   ├── tests
```
`app`配下に`app.py`ファイルと`__init__.py`を作成します。
`tests`配下に`test.py`ファイルと`__init__.py`を作成します。

全体の構成が以下のようになると思います。

```
├── project_dir
│   ├── [newenvname]
│   ├── app
│       ├── __init__.py
│       └── app.py
│   ├── tests
        ├── __init__.py
        └── test.py
```

# mockするプログラミング作成
EC2を起動させて、そのインスタンスIDを取得するコードになります。
`test.py`で`@mock_ec2`は忘れずに記述してください。
これがないと実際のAWS上に操作してしまうことになります。

```python:app.py
import boto3

def describe():
    ec2 = boto3.client('ec2')
    # インスタンスIDを取得
    instances = ec2.describe_instances()
    instance_id = [instance['InstanceId'] for r in instances.get('Reservations') for instance in r.get('Instances')]
    print(instance_id)
```

```python:test.py
import unittest
import boto3
from moto import mock_ec2
from app import app

class MyTestCase(unittest.TestCase):
    @mock_ec2
    def test_start_instance(self):
        ec2 = boto3.client('ec2')
        # EC2を作成
        ec2.run_instances(
            ImageId='xxxxx',
            MinCount=1,
            MaxCount=1,
            KeyName="ec2-1",
            TagSpecifications=[{'ResourceType': 'instance',
            'Tags': [{'Key': 'Name', 'Value': 'ec2-1'}]}])
        # appファイルを実行
        app.describe()

if __name__ == '__main__':
    unittest.main()


```

boto3、motoの詳細は以下を参考ください

- moto

https://github.com/spulec/moto
https://github.com/spulec/moto/blob/master/IMPLEMENTATION_COVERAGE.md


- boto3

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.run_instances

# テスト実行
下記コマンドで実行します。
実行する際は`app`,`tests`ディレクトリの両方が見える位置に注意！

```
(venvname)$ python -m unittest tests.test
```
これでローカルの仮想環境内でEC2を起動させ、そのインスタンスIDを取得できます。
AWSのコンソール画面で操作することなくAWSサービスをテストできるなんて本当にすごいですね。
機械学習とは

# 少し、勉強してわかったこと

人工知能(Artificial Intelligence)は、大きく３つに別れる。

- AI学習：SFに近いもの
- 機械学習：線形解析、決定木を使うもの
- 深層学習：ニューラルネットワーク


学習エンジン

- 決定木
- 線形回帰
- ニューラルネットワーク

基本的な考え方

- 目的変数: 予測したい変数
- 説明変数: 目的変数を説明する変数
- 誤差: 学習した結果と実際の差
- 重み: 誤差が最小になるように最適な値を探る（ここがポイント）
＊更に、学習を効率よくさせるために、ハーパーパラメータ、ブースティング、バックプロパゲーション等のテクニックを使う


参考資料
機械学習の情報を手法を中心にざっくり整理
https://qiita.com/ishizakiiii/items/f6909696c616fd6294ca

ニューラルネットワークのコスト関数とバックプロパゲーション
https://qiita.com/yusayusa/items/0b0a7a56c30b685aa521
UnityエンジニアがMagic Leap Oneを初めて触る際に参考にした記事

# 公式

[Unity Get Started](
https://creator.magicleap.com/learn/guides/unity-setup-intro)

[API Reference](https://creator.magicleap.com/learn/reference/public/v0.22.0/UnityAPI/index.html)

# 環境構築

[MagicLeap入門以前](
https://iwaxlab.com/articles?id=6)

[[Unity]Unityで始めるMagicLeap開発](https://qiita.com/iwax10/items/c4f0867e579bdfc262c3)


# 動画のキャプチャ

[Magic Leap/mldbコマンドのヘルプ](https://littlewing.hatenablog.com/entry/2019/03/19/215542)


# 個人的開発メモ

## Main Camera

必ず、[Magic Leap]>[Core]>[Prefabs]>[Main Camera]を使用する。
これがある状態でビルドする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/cf172374-7411-90b7-256f-e8453114d4cf.png)

# Audio
[Project Setting]>[Audio]で
[Spatializer Plugin]を `MSA Spatializer`にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/1413c903-1c31-bc0d-ec38-faa9c699d6f5.png)

https://creator.magicleap.com/learn/guides/gsg-create-your-first-unity-app
を参考にしてます。

(随時更新)
git 学習中

#まとめて git pull したいときは

```
$ find . -name .git -printf '%h\n' | xargs -I{} sh -c 'cd {}; git pull;'
```

これをaliasにでも登録しておけば、OK

もう少しスマートな方法が分かれば、更新します。

#checkoutをすべて破棄したい

```
$ git checkout master
$ git status
```

# 壊しちゃった

特定のSHAに戻して、何事もなかったことにしたい

```
git push -f origin <SHA#>:<Branch Name>
```

自分のローカルブランチなら、簡単です。メインブランチなど重要なものは管理者でロックされている可能性はあります。そうなると、本コマンドは実行できません。

## そうなる前に

なにをcommitするか、確認しましょう

```
git ls-files -m
```

変更対象のファイルが表示されます。注意事項は、自分のディレクトリ以下の情報しか表示しません。全体を表示したければ、gitのルートディレクトリまで移動してから実行しましょう。
"-m"は、modify。変更したファイルを表示してくれます。


# 過去commitをまっさらにする

過去commitをまっさらにするには、次の手順で進めます。平たく言うと、次の手順です。
- 新しくブランチを設定
- そこに、master/mainブランチを移動
- (option) github/gitlab側から、デフォルトの設定を変更

```
$ git checkout --orphan main
$ git add -A
$ git commit -m "The first commit"
$ git push origin main
$ git branch -D master
(GUIからデフォルトの設定とブランチの削除)
```
普通の人は使わないと思います。


# 直前のcommitをまっさらにする

pushしようと思って、準備をしたが、

```
$ git reset --soft HEAD^    (commit状態からadd状態へ戻す。git statusでadd/new表示される)
$ git reset HEAD .          (add状態を解除する)
```



# Remote Branchを削除する

もう使わないリモートブランチを根こそぎ削除

```
$ git push origin --delete (branch name)
```


おしまい
マンガでわかる Abstract Factory

![CDD515F3-EE04-4F58-A560-CD5E3E2B57C6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/dd6ad5ee-27a2-6832-541f-86f093f912f7.png)

誰か作ってくれる人がいることにして、遊ぶほうに意識が行っちゃってますね。いいですね、これこそオブジェクト指向の醍醐味です。

複雑なものをできるだけシンプルにするには「関心の分離」が重要です。とくに、操作に関する知識と生成に関する知識とを分離するのは良いアイデアです。操作のたびに、どういう作りなのかを気にして `if - else` を書いてしまうと、「ラジコンのプロポをガチャガチャするだけで楽しい」では済まない複雑さになってしまいます。サーボの設定事情などは、どんなちょうぜつ操作をしてもいい感じに動くように生成して、隠蔽すればよいのです。判断を前倒しした結果を生成物に閉じ込めてしまうわけです。

というふうに生成と操作を別のクラスに分離しましょう...で話は終わりません。ここで、操作する人が具体的に誰かに作ってくれと言ってしまう(具象クラス型を利用してしまう)と、操作は生成者に直接依存してしまいます。本当に生成の詳細に無関心でいるためには、作り方だけでなく、誰が作ってくれるのかにさえ関心を払ってはいけないのです。というわけで出てくるのが「作ってくれる誰か」という抽象概念です。依存する先はそこです。

めもりーちゃん(作れないのになんで買ってきた)は姫なので、誰に頼むかまで考えていません。「まあ誰か作ってくれるんでしょ」としか思わないのです。それでいいんです。関心があるのは操作の方なので、そっちに集中してもらうのが健全で、そこまででパッケージを完結させてしまいましょう。あとは単体テストで「誰か」としてモックファクトリを使えば、パッケージに含まれるコードはすべて完成ですね。やりたいことしかしないので、テストケースも簡単です。作ってくれる人は別パッケージの責務なので気にしたら負けです。

要するに、オブジェクトを生成するオブジェクトに関して、このように詳細のわからない依存をいったん抽象のままにして、オブジェクトを利用する方にのみ着目すること、つまり、依存関係逆転原則 (Dependency Inversion Principle = DIP) のファクトリ版が Abstract Factory パターンです。

- - -
って感じで、マンガと解説(コードはノイズになるから書かない)で概念だけわかるシリーズをあと22パターン、ソロアドベントカレンダーでやっていこうと思います。

たまたま初回がいきなり最重要パターンで、解説がやや多くなってしまいました。解説の量はパターンによってムラが出てくると思いますが、どうぞよろしくおねがいします。

Twitter でも [ちょうぜつエンジニアめもりーちゃん](https://twitter.com/hashtag/%E3%81%A1%E3%82%87%E3%81%86%E3%81%9C%E3%81%A4%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%81%E3%82%82%E3%82%8A%E3%83%BC%E3%81%A1%E3%82%83%E3%82%93) をよろしくおねがいします。
高階関数を作ってみたかった

### 動機
昔からrecursive functionの計算を考えるのは好きだったけれど、高階関数はどう考えればよいのか思い付かず。そこで、何か考えられるようになりたいと思い、試し始めた。

言語はSchemeを使うべきなのだろうけれど、わたしのMacbook proにインストールしてあったDr.Schemeが起動できないので、Juliaを使っております。
Juliaもこういう用途にはシンプルに書けるので、たいがいの役には立つようにみえる。(femtolispは使っていない)

### ためす
まずは適当な関数を作って、高階関数の雰囲気に慣れることにした。
複数の関数を引数にとって、呼び方の組み合わせを変えるようなのを作ったりしたけれど、すこし動くものがこれ。発狂している。

```julia
fb(f)=(x)->f(x(fb))
hb(f)=(x)->f(x)

julia> fb(hb)(hb)
#35 (generic function with 1 method)
```
これは、fb(f)は引数に関数をとる関数で、その関数にfb自身を与えるなど、意味不明なことをしている。楽しい。
hb(f)はapply(f,x)みたいなもの。

当然、fb(hb)は関数を生み出す関数しか生み出さないので、何かの値が得られるわけではない。

おもしろいのは、fb(hb)(hb)とか、引数をふやしても、同じような関数ができるだけなので、話がすすまない。

何がかわるのかはよくわからない。たぶんトリビアルな気がする。

いろいろやってみたら

```julia
fb(f)=(x)->f(x(fb))
hb(g)=fb(hb)(g)

julia> fb(hb)(hb) 
# infinite loop
```

となった。まあそうか。

### 関数の順序関係で再帰

そんなこんながあって、再帰の減少していく値として関数を使うことが考えられてきた。

```julia
f -> f^2 -> f^3 -> ... -> f^k
```

で関数の順序として小さくなっていけばrecursionにつかえる。
が、関数定義を書き換えて別の関数定義を作り(これはmacroの仕事か?)
その間の順序関係を定義するのはなかなかむずかしい・・・

単純に、

```julia
f -> one -> zero
```
となるようなfを定義して、上に考えたようなことを書いてみたらこうなった

```julia
function decl(f)
  if f==zero; return 0
  elseif f==one; return zero
  else return one end
  println(f(x))
  return (x)->decl(f)
end

step(x) = println(x)

# step is a function in a step
# cntf in 3rd arg is just a counter
# looper in 2nd arg is for loop

# the if in looper2 cah be change to throw
function looper2(step, looper, cntf)
  (x)->begin
        if x<0; return end
        step(x)
        looper(step, looper, decl(cntf))(x-1)
       end
end

julia> looper2(step, looper2, looper2)(3)
3
2
1
0
```
期待したようにはなっているようだ。

とはいえ、まだまだトリビアル。

### おわり

なかなか高階に達しないけれど、関数の定義を変えてrecursionの終了条件にするというのはありうる。
問題は、先にも書いたように、関数fから新しい関数を作り出す部分。
これは、数式処理で微分するようなものを考えればよいのかもしれないが、そういう知識がないので、残念。
n階微分をやって定数になったら終わり、みたいなことだろうか。

もっといろいろ可能性がありそうなので、続けたい。
紫の本をよめばわかるのだろうか・・

プログラミング言語は、構成的なので、野生の関数というのは作れない(はず)。
だから、高階といっても、低階関数から作られるので、自由はないのかなあと思った。
そうでもないような気もしてきた。

(この件続く)
いいね機能 ❏Rails❏

ツイートアプリにいいね機能をつけていきます。

#【その１】 jQueryを入れる

`gem 'jquery-rails'`を加え、`bundle install`

```ruby:Gemfile
gem 'jquery-rails'
```

```:ターミナル
bundle install
```

<br>
`application.js`に`//= require jquery`を追記。

```ruby:app/assets/javascripts/application.js
//= require jquery  #一番上に書く
//= require rails-ujs
//= require_tree .
```

#【その２】ルーティング
`create`アクションと`destroy`アクションの２つ

```ruby:routes.rb
resources :tweets do
  resources :likes, only: [:create, :destroy]
end
```

#【その3】コントローラー

```:ターミナル
rails g controller likes
```

```ruby:likes_controller.rb
class LikesController < ApplicationController
  before_action :set_tweet

  def create
    @like = Like.create(user_id: current_user.id, tweet_id: @tweet.id)
  end

  def destroy
    @like = Like.find_by(user_id: current_user.id, tweet_id: @tweet.id)
    @like.destroy
  end

  private
    def set_tweet
      @tweet = Tweet.find(params[:tweet_id])
    end
end
```

#【その４】モデル

```ruby:tweet.rb
class Tweet < ApplicationRecord
  has_many :likes  #追記
end

```

```ruby:user.rb
class User < ApplicationRecord
  has_many :likes  #追記
end

```

<br>
`Like`モデルと`likes`テーブル作成

```:ターミナル
$ rails g model like user:references tweet:references
$ rails db:migrate
```

```ruby:like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :tweet

  validates :user_id, presence: true
  validates :tweet_id, presence: true
  validates_uniqueness_of :tweet_id, scope: :user_id
end

```

#【その５】ビュー

部分テンプレートとして作成↓

```ruby:app/views/likes/_like.html.haml
- if Like.find_by(user_id: current_user.id, tweet_id: tweet.id)
  = link_to tweet_like_path(tweet_id: tweet.id, id: tweet.likes[0].id), method: :delete, remote: true do
    %i{class: "fas fa-heart"}
- else
  = link_to tweet_likes_path(tweet), method: :post, remote: true do
    %i{class: "far fa-heart"}
= tweet.likes.length
```

`font-awesome`のアイコンを使っています。
使い方の解説はこちらへ
https://qiita.com/ITmanbow/items/2679109dd886dd5e6844

<br>
実際に置く場所↓

```ruby:app/views/tweets/index.html.haml
略
#好きな場所へ配置
%div{id: "like-#{tweet.id}"}
  = render "likes/like", tweet: @tweet
```

#【その４】jsファイルを作成

`erb`の場合

```ruby:app/views/likes/create.js.erb
$("#like-<%= @dream.id %>").html("<%= j(render partial: 'users/like', locals: { dream: @dream }) %>");
```

```ruby:app/views/likes/destroy.js.erb
$("#like-<%= @dream.id %>").html("<%= j(render partial: 'users/like', locals: { dream: @dream }) %>");
```

<br>
`haml`の場合

```ruby:app/views/likes/create.js.haml
$("#like-#{@tweet.id}").html("#{j(render partial: 'like', locals: { tweet: @tweet })}");
```

```ruby:app/views/likes/destroy.js.haml
$("#like-#{@tweet.id}").html("#{j(render partial: 'like', locals: { tweet: @tweet })}");
```

<br>
Qiitaの記事をいくつか参考にしてなんとかできました。
先人は偉大です。。。いつも本当にありがとうございます。。。
>https://qiita.com/fumikao/items/373caa60b77f27f2dbdd
https://qiita.com/shiro-kuro/items/f017dce3d199f06d1dcd

<br>
ではまた！
ロールバックせずにマイグレーションファイルを削除してしまった。。。 ❏Rails❏

マイグレーションファイルをいじる時はあれだけ気をつけろと言ったのに、、、

なぜロールバックする前にマイグレーションファイルを削除したんや俺ぇぇぇぇ！！！

ということで解決方法

#【現状】
`rails db:migrate:status`を叩くと`NO FILE`と出ます。

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191123230155  Create tweets
   up     20191124013808  Devise create users
   up     20191127115414  ********** NO FILE **********
  down    20191124030050  Create comments
```

・`upがmigrate実行後`
・`downがmigrate実行前`

upなのにNO FILEはよろしくない

#【その１】
`Migration ID`をコピーし新たにマイグレーションファイルを作成。

```:ターミナル
$ touch db/migrate/20191127115414_manbow.rb
```

どうせ削除するから名前は適当

```ruby:20191127115414_manbow.rb
class Manbow < ActiveRecord::Migration[5.2]
  def change
  end
end
```

<br>
もう一度 `$ rails db:migrate:status`を叩くと名前が付与されている。

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191123230155  Create tweets
   up     20191124013808  Devise create users
   up     20191127115414  Manbow
  down    20191124030050  Create comments
```

#【その２】
`VERSION`に`Migration ID`を代入し、upをdownに変える

```:ターミナル
$ rails db:migrate:down VERSION=20191127115414
```

<br>
`$ rails db:migrate:status`でdownに変わっていることを確認。

```:ターミナル
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20191123230155  Create tweets
   up     20191124013808  Devise create users
  down    20191127115414  Manbow
  down    20191124030050  Create comments
```

あとはマイグレーションファイルを削除するだけ。

マイグレーションファイルを削除する際は十分に注意しましょう。

参考
>https://qiita.com/sakatan_1/items/9bf321f81d3b84042694

<br>
ではまた！
MacでWindowsをvagrant up

# 環境

- macOS Catalina 10.15.1
- VirtualBox 6.0.14
- Vagrant 2.2.6
- 仮想マシンは公式の開発用"MSEdge on Win10 (x64) Stable 1809"

# Vagrantを用意する

## VirtualBoxをインストール

### dmgを実行

Downloads – Oracle VM VirtualBox
https://www.virtualbox.org/wiki/Downloads

### 失敗した場合はセキュリティを緩和して再度実行

macOS Mojave以降はセキュリティ制限で失敗する場合がある。
　失敗した場合は「システム環境設定　→　セキュリティとプライバシー　→　一般」を開くと開発元"Oracle America, Inc."が出ているので許可してもう一度、実行する。

How to Install VirtualBox in MacOS Mojave if Installation Fails or Shows Kernel Driver Errors
http://osxdaily.com/2018/12/31/install-run-virtualbox-macos-install-kernel-fails/

## Vagrantをインストール

Download - Vagrant by HashiCorp
https://www.vagrantup.com/downloads.html

 失敗した場合は　以下略

# Vagrant boxを用意する

## boxを登録

Free Virtual Machines from IE8 to MS Edge - Microsoft Edge Development
https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

"MSEdge on Win10 (x64) Stable 1809", "Vagrant"をダウンロード、zipを解凍してboxを得る

```zsh
# 登録
vagrant box add ${解凍したboxのパス} --name msedge
# 確認
vagrant box list
```

## Vagrantfileを作成


```zsh
# 適当な空フォルダを作って
mkdir myEdge
# 移動
cd myEdge
# Vagrantfileを作る
vagrant init
```

作成されたVagrantfileを編集して、box名を指定する。一部をコメントアウトする。

```
Vagrant.configure("2") do |config|
  config.vm.box = "msedge"
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
  end
end
```

# Vagrant boxを起動・終了する

## 起動

Vagrantfileのあるフォルダで `vagrant up`

- 仮想マシンのダウンロードページに書いてある通り、パスワードは`Passw0rd!`である
- 特にネットワーク設定しなくても、ホストOSと同様にインターネットに繋がる
- 特に共有フォルダ設定しなくても、Vagrantfileのあるフォルダが読み書き可能な状態で共有される


起動時に`Progress state: VBOX_E_IPRT_ERROR` エラーが出た場合は下記リンクを参照すること。
　VirtualBoxの「設定　→　一般　→　デフォルトの仮想マシンフォルダー」が誤っている場合がある。この場合、自分のホームの下の`VirtualBox VMs`ディレクトリを指定すると解決する。

Vagrant: 自分のミスで仮想マシン作成に失敗していた - すたらブログ
http://sutara79.hatenablog.com/entry/2015/06/28/104150

## 終了

ゲストOSをシャットダウンすればOK.

# Vagrant boxを捨てる

```
vagrant box remove msedge
```

上記コマンドを実行しても、VirtualBoxの仮想マシンは残る。




Hope this helps.
アプリの企画

自分はアラフィフの素人プログラマである。

やりたいことは多々あるのであるが、まず自分で思っていること

それは

自分が使いたいツールを自分が作ること
→　つまり、仕様は自分が決めて、自分が満足できること

これは、自分が３５年も前に、ゲームを開発していた時の頃を
思い出してしまう。

あの頃は、BASCI+Z80でゲームを雑誌に出していた頃であるが。。。


ゲームと言うもの同じくであるが、そのモチベーションというのは、

-自分がゲームセンターに行く

-新しいゲームを発見する

-そのゲームにハマる（大人に嵌められると、言った方がいいだろうな）


その次のステップであるが

・そのゲームを真似した投稿が、雑誌に投稿される
・大体のところが、PC-9801、PC-8801とかのメジャーな機種である。
・PC-8001に移植されることを願う


そして最後の行動は

・お小遣いでゲームセンターに通う
・親の財布から、お金を盗んで、ゲームセンターに通う
・ゲームセンターで不良に絡まれる
・友達と一緒に、カツアゲされてお金を失う
・他の人がやっているゲームを、一日ながめている
・自動販売機等の下で、お金が落ちていないか探す
・CREDITにお金が残っているゲーム機を探す
・・・

なんて、パターンに陥る。


ということで、結局は

・自分が得たいと思うゲーム体験と、自分が発揮できる技術の、トレードオフを考えて
・これならば、アルゴリズムはできそうだろうと思った瞬間
・そこの部分のみを、プログラムで作っていく


そういう感じで仕上げたソフトは、
・カーゲーム　→　スクロールして道が乱数で変わっていくゲーム
・ブロック崩し　→　アルカトラスのように、ボールがぬるっと動くゲーム
などなど

いまでも、自分の掲載された、BASICマガジンが記念である。


し、しかしながら
自分が雑誌に載せようと（急に欲が出てきてしまった）
ところから、急に発想が浮かばなくなって、
パソコンに向かうことが嫌になってしまう。


つい最近も、自分の仕事の中で、アプリケーションの必要性があり
さくっと、プログラムを完成させたのであるが・・・

そのときも、同じで
自分が嫌な作業を、なんとか自動化したいというのがきっかけで
最終的には、自分が気になる部分を、極力自動化していき
最後には、それがスタンダードになったのであるが


というわけで、一番最初の教訓を得たのであるが、
やはりソフトというのは、自分が人から請け負いして
仕様を決めるようなものではなくて、
まずは自分が、その仕事や刺激の本質をしっかりと理解して、
それをどうやってプログラムで肩代わりさせるのかと言った
そういうことを真っ先に考えた方がいいだ

Windowsだって、スマホだって、それは
その形を描く才能があったから、実現できたわけで

やはりvisionや構想がしっかりして、
始めてソフトウェアは成り立っているのである。


そこで、最終的な結論としては、

１）何を作りたいのか
その機能の本質に特化してスタートさせる。

吉野家は牛丼を売るための店であって、
松屋のように、そこでカレーを売ろうという発想は
最初に牛丼を売る店をまねて作ったのであり、
差別化のために、カレーを売り出したのであって。。。

最初に牛丼屋を作るところが、やっぱりこの店のコンセプトとしては
正解であり、そこで本業をずれるとおかしな話になるのである。


横道にぶれてしまうことは、アプリの開発でも良くあることで
これは、やはり問題に突き当たったときに実施する行為であって、
最初から、横道からスタートしていては、
描いた時期に、描いたものが手に入らなくなってしまうのである。


ゆえに、最初のスタートをどうやって切るのか？
ここが大事である。


２５年も大企業で製品開発設計をやっていると、
この入り口での作業が重要だということに
いまさら気づかされる。

ソフトも一緒で、いきなりパソコンの前に座って
コードがバリバリ書けるわけではない。


曲がりくねった話だが、とりあえず自分がこれから
薦めていくテーマを、まずは吐き出させるところから
やって行こうと思う。

この段階で、既存のアプリケーションを使うのは、
もちろん、アリだと思う

https://docs.google.com/presentation/d/1nUapViQKd69KYfoo9A4RWEQXEbsxBL6a3JMGDToRdVM/edit#slide=id.p
リモートのメンバーとオンラインもくもく会形式で仕事をしたら生産性が上がった話

## はじめに

例えば「ベテランと新人」といった組み合わせのように、チームメンバー間のスキル差が大きい場合においては、コードレビューやペアプログラミングなどによる教育の効果をもって、チーム全体の技術力の底上げを図っていくことが考えられます。

この時、例に挙げたベテランのような**スキル上位者の側がフルリモート**で働いていたとしたら、どうでしょうか？

## チームの特徴

本記事で紹介するチームでは、スキル最上位者であるテックリードがフルリモート[^1]で働いています。

[^1]: 正確には拠点Aの支社に出社することもあり「フル」リモートではありません。ただ、拠点Bのメンバーから見るとフルリモート。逆に拠点Aのテックリードから見たら、拠点Bのメンバーもフルリモートですね。

- チームは3名
- 拠点が2つあり、拠点Aにテックリード1名、拠点Bに残りのメンバー2名
- 拠点間は1,500km離れており、頻繁に対面で会うことは時間やコストの観点から困難

絵にすると以下のような状況です。 

![qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317369/fca2799f-1730-c96a-658f-72d9fdd90e2e.png)

また、チームで担当する領域がPHPやGoといったプログラミング言語のコードだけでなく、AWS全般や各種監視ツールの設計や管理なども含まれるため、コードレビューやペアプログラミングといった手法だけではチームの扱う技術をカバーできないといった特徴があります。

## チームの課題

テックリードから見ると、遠方の拠点のメンバーをいかにフォローしてチーム全体の生産性を上げていくかが課題です。

こうしたこともあって、チーム内では常日頃から「何かわからないこと、詰まったことがあれば遠慮無く質問して良い」という雰囲気が醸成されており、実際にそのような質問のやり取りは以前からSlackを使って行われています。

しかし、内容の複雑度合いによっては、テキストではなく画面を共有しながらの会話が適しているケースがあります。

そのような時、

1. メンバーがビデオ通話(Slackのビデオ通話等)での接続をテックリードに打診する
2. テックリードはこれを了承
3. ビデオ通話を開始し、画面も共有
4. 問題が解消したら通話終了

といった流れになるわけですが、同じオフィスの近くの席にいて声を掛けるのと比較すると手間が多く、そのことがメンバーを「必要なタイミングに必要な質問をする」行為から遠ざけてしまう傾向にありました。

テックリードから見ても、タスクの進行に大なり小なり問題が生じているにも関わらずメンバーから質問が上がって来ないわけで、テックリード側もメンバー側も何となく「やりづらさ」のようなものを感じていました。

## 課題に対して取り組んだこと

チームの定例ミーティングで先に挙げた課題が議題となり、検討した結果、以下の施策を導入することにしました。

- あらかじめ時間を設け、その間は自席PCからビデオ通話を繋ぎ、画面を共有しながら各自のタスクを行う

いわば、**オンラインもくもく会形式で仕事をする**、というものになります。

また、このビデオ通話にはGoogle Meetを使うことにしました。

Google Meetでは、

- 参加者全員のPC画面を**同時に**共有可能であり、各参加者のPCには全員分のPC画面(と顔)が表示される

- 各参加者は共有された全員の画面の中から、**自分が見たい画面**を選んで大きく表示できる

と柔軟な表示が可能であったためです。

*以下は、オンラインもくもく会実施中のGoogle Meet画面の様子。*
*テックリードが説明しながら操作するAWSマネジメントコンソール画面をメンバーが見ているところ。*
![ぼかし後2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317369/82d3db57-5e10-52ce-dfff-1875cd34ccfb.jpeg)

このオンラインもくもく会を1回あたり2時間、週3回開催で運用することにしました。

## 得られた効果

### 1. 口頭での質問を行うことへの心理的障壁が下がった

既にビデオ通話の接続と画面共有も済んでいることから、質問を開始するのに必要となるのは「声を発することのみ」です。

事前のSlackでの打診が不要となり、メンバーからは質問がしやすくなりました。

また、以前であれば、ビデオ通話での質疑応答終了後、すぐに新たな疑問が出た時に、あまり間を置かずに再度ビデオチャットの接続を依頼することは何となく憚られるところがありましたが、オンラインもくもく会の実施中は常時接続しているため、そのような遠慮を感じることも無くなりました。

### 2. 案件の進捗に改善傾向が見られた

オンラインもくもく会の実施中に取り組む各自の案件としては、

- 要所要所でテックリードのフォローが必要となることが想定される、比較的難易度の高い案件
- 進捗がやや遅れており、追い上げが必要な案件

を優先的に選定することにしました。

遅れそうな、あるいは遅れている案件をテックリードからのリアルタイムのフォローを受けながら取り組むことで、「詰まる」「悩む」時間をできるだけ少なくし、進捗の改善を図ることができました。

## 最後に

メンバーからは「遠方にいるテックリードが、まるで自分の席の隣にいるように感じられた」との意見もありました。

今回紹介したチームのように、チーム内にフルリモートのメンバーがいて同様の課題がある場合に、参考にしていただければと思います。
[初心者向け]色んなサーバ達の役割を知る

#はじめに
IT業界に入ったばかりの新人やあまりインフラの知識がない人たち向けに、ザックリとサーバのことを知ってもらいたい

#対象
- ITの知識に乏しい人
- インフラの基本的なことを勉強したい人
- サーバ構築などの勉強を始めるにあたり、ザックリとしたイメージを付けたい人

#ゴール
以下のサーバ群について大体の役割が分かる。
基本情報なんかで出てきたとき、あーあれね！ってなる。

- Webサーバ
- DBサーバ
- DNSサーバ
- Mailサーバ

#本題
まずは各サーバについて機能の概要を説明する。
そのあと、各サーバが連携して色んなサービスが提供されることを説明できたらいいな。

###Webサーバ
ホームページなどいわゆるWebサイトを作りたい時に使う。
Webサービス用のプログラム自身（Apache HTTP Server / IIS）やこれらのプログラムがインストールされたサーバを指す。

なお、クライアントとの通信にはHTTP(80/tcp),HTTPS(443/tcp)を使用する。

###DBサーバ
ユーザ毎のデータを貯めたい時などに使う。
Databeseサービス用のプログラム自身（Oracle Database / PostgreSQL）やこれらのプログラムがインストールされたサーバを指す。

また、Webサーバと連係して、動的コンテンツ（ユーザ毎のログインページなど）を実現したいときに利用する。

なお、クライアントとの通信は製品によって異なり、Oracle Database(1521/tcp),PostgreSQL(5432/tcp)を使用する。

###DNSサーバ
IPアドレスとFQDNを紐づけたい時に使う。
IPアドレスはインターネット上で考えるとパソコンやサーバの住所のようなものと考えてもらうとよくて、
IPアドレスは数字だけで表示されるから、人間には理解しずらい。だから、名前つけようね的な話。

なお、クライアントとの通信にはDNS(53/udp)を使用する。

ちなみに、qiita.comのサイトは以下のようにサーバのIPアドレスを確認することができる。（Webサーバは３台の冗長構成なのかな？？）

```
$ dig qiita.com

〜省略〜

;; ANSWER SECTION:
qiita.com.		14	IN	A	13.114.166.234
qiita.com.		14	IN	A	176.34.13.209
qiita.com.		14	IN	A	13.113.58.5
```

###Mailサーバ
メールを送受信する時に使う。
メールを利用する際はクライアントソフト（Outlookなど）を思い出す人が多いけど、中の仕組み的には、メールサーバ間でメールを送受信しあっている。

また、メールサーバは、DNSサーバにメールアドレスの@以降を問い合わせし、送信先のメールサーバを特定している。

なお、クライアントとの通信にはメール送信SMTP(２５/tcp)、メール受信POP3（110/tcp）,IMAP4(143/tcp)を使用する。

##イメージ図
上記のサーバ群を使うとこんな風になるよのイメージ図
*IPアドレスは、プライベートアドレスを振ってますが、本来ならグローバルアドレスです。
*sierbc.co.jpというドメインは例なので存在しません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159147/c3128f47-cefe-1915-2941-9187aadcfdab.png)

上段、緑色のラインはパソコンからブラウザでWebサイトにアクセスしようとした時をイメージしてみました。
まずブラウザで（sierbc.co.jp）にアクセスしようとした時には

- ①DNSサーバに名前解決を行いIPアドレスを特定
- ②IPアドレスを元にWebサーバへアクセス
- ③必要に応じて、DBサーバへアクセス
された結果が、表示される

下段、オレンジのラインはパソコンから別の会社の人にメールを送ろうとした時をイメージしてみました。
まず（test@sierbc.co.jp）にメールを送信しようとした時には

- ①メールソフトからメールサーバにメールを送るタスクが実行され
- ②メールサーバはDNSサーバに名前解決を行いIPアドレスを特定
- ③相手先のメールサーバへ送信された結果を、相手先の人がメールソフトで確認する。


以上、書いてみましたがザックリすぎたらごめんなさい。
Graph apiの基本

#Facebookのapi、Graph Apiとは？
Graph Apiは簡単にいうと、ユーザーのFacebookの情報を持ってくるための手段です。
アプリでソーシャルグラフ(人間関係をグラフ化したもの)にデータを取り込んだり、データを取り出したりする時に使います。

#Graph apiの構成
Graph apiの構成は以下の三つからなります
ノード
エッジ
フィールド
大切な概念なので一つ一つ説明していきます。


###ノード
ノードとは写真や投稿、コメントやfacebookページなど個々のオブジェクト(物)のことを指します
ネットワークの繋がりを点と線で表すならばノードは点の部分です。
個々のオブジェクトについてのデータを取得するために使います。
###エッジ
エッジとはネットワークの繋がりを表したときの線の部分のことです。
単一のオブジェクト上にあるオブジェクトのコレクションを取得したり、オブジェクトをこれらのコレクションに向けて公開したりするために使います。

###フィールド
フィールドとはユーザーの情報や、ページの名前などオブジェクトに対する情報のことです。
単一のオブジェクトまたはコレクション内の各オブジェクトに関するデータを取得するために使います。
どのデータを応答に含めるか指定することができます。


#まとめ
以上の3点は今後もいろいろなところで出てくる用語だと思います。
しっかりと理解して、今後に役立ててください！
gdmではログインできるのにlightdmだとログインできなかったときの解決方法

なぜかログインできない、非rootユーザーの`~/.Xauthority`の所有者、所有グループが`root`になっていたから

```bash
sudo chown 1000:1000 ~/.Xauthority  # インストール時に作ったユーザーなら大抵UID,GIDどちらも1000なはず
sudo chown ${USER}:$(id -gn) ~/.Xauthority  # こっちのほうがいいかも
```
してあげたらログインできるようになった
2行目のやつを実行する際は修正するユーザーで実行してね

環境: Ubuntu 18.04.3 Japanese remix amd64