OmniAICreator/Qiita-1.07M huggingface dataset:
基本情報技術者試験の対策方法

# はじめに
2018年秋に、基本情報技術者試験を合格することができました。
2018年夏に、午前免除試験を合格し、秋に午後試験を突破しました。
基本情報技術者試験の対策方法についてまとめます。

# 投稿時スペック
IT系企業に勤務歴4年目です。
新卒入社(IT系企業)4年目で転職を一回しております。
大学では数学専攻でしたが、ITスキルに関しては未熟者でした。
・言語経験
-VB.NET
-R
-Python
#使用した参考書
参考書は⑥冊(購入したが最後まで読んでない本もあります。)
①キタミ式イラストIT塾 基本情報技術者
②イメージ&クレバー方式でよくわかる栢木先生の基本情報技術者教室
③情報処理教科書 出るとこだけ! 基本情報技術者[午後]
④うかる! 基本情報技術者 [午後・アルゴリズム編] 2018年版 (福嶋先生の集中ゼミ)
⑤改訂3版 基本情報技術者 らくらく突破 表計算
⑥基本情報技術者 パーフェクトラーニング過去問題集

①キタミ式イラストIT塾 基本情報技術者に関して
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/6aeaba94-47f8-c3e6-5695-1ba4fbe49f0c.png)

文字ベースの説明よりも図や絵が多く、初心者にはわかりやすい表記が多いと感じました。
非常に良本と考えていて、3周くらいはしたと思います。午前対策に向いていると思います。
書籍版とKindle版の両方あります。

②イメージ&クレバー方式でよくわかる栢木先生の基本情報技術者教室
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/1cd16846-0aa0-f11e-a17f-912df0a6eb1c.png)

こちらはザ・教科書という感じで丁寧かつわかりやすく、キタミ式の補助役として読んでいました。購入したのは、試験の1週間前くらいにしたのですが、最後まで読んでいないですが、良本だと思います。

③情報処理教科書 出るとこだけ! 基本情報技術者[午後]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/1030afbc-b052-d8f6-f0e9-6ad80ee49fc4.png)

午後対策のために購入した一冊でした。この本はテクニック的な要素が満載でした。
時間がない時の対策にはいいと思いますが、この本一冊で午後は通過できるほど甘くはないと試験を受けて感じました。2周はしました。

④うかる! 基本情報技術者 [午後・アルゴリズム編] 2018年版 (福嶋先生の集中ゼミ)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/840f100c-2086-508c-78d4-0e23b35bb9bc.png)

この本だけは、あまり私には向いていないと感じており、最後まで読んでいません。
100ページくらいまで読みましたが、途中で疲れて読むのを辞めました。
プログラミング初心者向けでやったことがある人にとっては少々退屈になると思います。
試験のレベルもアルゴリズムはこの本と段違いで難しいと思います。

⑤改訂3版 基本情報技術者 らくらく突破 表計算
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/0caf481f-8639-efbc-f635-a51ea0b02f0f.png)

この本は表計算を選択する人はマストになると言っても過言ではないくらい参考になりました。2周はしました、普段の業務からExcelは触っていましたし、マクロもよく組んでいましたが、この本を読んでさらに理解が深まりました。
また普段の業務でもレベルを上げれたかなと感じています。

⑥基本情報技術者 パーフェクトラーニング過去問題集
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/287be2df-539f-0724-9ba9-bbd4e87f8b52.png)

最後は過去問です。
結構分厚い本ですが、解説が充実していて過去問4回分(午後試験のみ)は回しました。
試験1か月前くらいから始めました。2周はしました。良本だと思います。

#所感
午前試験に関しては、私は午前免除試験で合格しました。午前は暗記試験だと思います。
キタミ式を周回した後に、基本情報技術者試験過去問道場(https://www.fe-siken.com/fekakomon.php)
で腕慣らしをすれば合格できます。午前試験は過去問の使いまわしも多いので問題文を読まずに解ける問題も多数あります。

午後試験が鬼門だと思います。(国語の試験です。)
一気にレベルが上がります。というものの私はガチガチの理系人間で国語が全然得意ではないためそう感じているかもしれません。個人的な見解ですが、文系の方が午後試験に関していえば合格に近いのではないかと感じています。読めばほとんどの場合答えが問題文にあります。ちなみに私が選択した分野は以下の通りです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277025/ebcd21f8-df4c-496b-ccca-d4b650f9a77c.png)

ギリギリ合格でひやひやしましたが何とか無事合格できました。
基本情報技術者試験はIT業界の方は持っていることに越したことはないと思います。

勉強時間は100時間あれば十分です。
以上で基本情報技術者試験の勉強法まとめは終了です。現在統計検定準一級に向けて勉強を頑張っていますのでまた記事をアップします。少しでもお力になれれば幸いです。
Maya で Mel/Python で BlendShapes を作る

漢なら Maya で BlendShapes 作りたいですね!

しかし Maya でノード選択とか ShapeEditor で編集とかめんどくさいですね...


Mel/Python スクリプトで簡単に BlendShapes を作れます.

https://help.autodesk.com/cloudhelp/2018/ENU/Maya-Tech-Docs/CommandsPython/blendShape.html


勝てました. ありがとうございます.

## skinning(bone) を持つモデルから BlendShapes を作る.

timeframe を移動して作りたい BlendShapes に変化させる.
Edit -> Duplicate(or Duplicate special のほうが確実かも)でメッシュを複製する

このメッシュを BlendShape(target shape)に使う.

freeze transform をしておく. local space を使うとより確実.

作った BlendShape(のノード)は非表示(`H` hotkey)にしておくとよい
(デザイナーによっては遠く離れたところに並べたりするっぽい)


## TODO

* skinning -> freeze して blendshapes 生成あたりをスクリプト化する
* 優秀な BlendShapes 若人さまが, 人類史上最速で優秀な Maya BlendShapes 若人さまへ昇華なされるスキームを確立する旅に出たい
CloudFormation ドリフト検出の検出パターンを調べてみた

スタック構成後に行われた手動変更を検出する CloudFormation ドリフト検出が発表されました。
実際どういう変更を検出するのか、EC2 リソースに対していくつかパターンを試してみました。
2018年12月時点です。

[新 – CloudFormation ドリフト検出 | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/new-cloudformation-drift-detection/)

## パターン検証用 CFn テンプレートサンプル

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SampleSecurityGroup
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0a2de1c3b415889d2
      InstanceType: t2.micro
      SecurityGroups:
        - !Ref SecurityGroup
      KeyName: Keypair
      Monitoring: !Ref AWS::NoValue
      Tags:
        - Key: Sample
          Value: test tag sample
```

### 1. 設定した値の変更は検出するか？
#### A. 検出する (NOT_EQUAL)

期待通り設定値が同値ではない（NOT_EQUAL）となります。

> t2.micro => t2.nano 変更 = 検出（NOT_EQUAL）

### 2. 設定していない値の変更は検出するか？
#### A. 検出しない

未設定のデフォルト値を変更しても検出されません。

> Monitoring 未設定 => 有効化 = 検知せず
> Tags: に key: Name 新規追加 = 検知せず

### 3. 設定したリストへの値の追加は検出するか？
#### A. 検出する (ADD)

設定済みのリスト値に項目を追加すると検出（ADD）となります。

> SecurityGroupIngress に http:80 追加 = 検出（ADD）

### 4. 設定したリストへの値の削除は検出するか？
#### A. 検出する (REMOVE)

設定済みのリスト値の項目を削除すると検出（REMOVE）となります。

> Tags: Sample 削除 = 検出（REMOVE）

### 5. AWS::NoValue 値の変更は検出するか？
#### A. 検出しない

明示的なデフォルト値の AWS::NoValue の変更は検出するかと思っていましたが、検出しませんでした。

> Monitoring: !Ref AWS::NoValue => true 変更 = 検知せず

### 6. EC2 ステータスの変更は検出するか？
#### A. 検出しない

インスタンスの状態は検出対象外です。

## まとめ
試した感じだとデフォルト値の変更は検知しないので、検出したい項目は明示的に値を入れるべきという感じです。
NestJS で Angularで作ったUIを表示する

(ちょっとしたこと) AngularでUIを作って、NestJSでREST APIと併せて公開するという使い方もあるので、そのやり方をまとめる。といっても、NestJSはExpress上で動いているようなものなので、やることは基本的にExpressと同じで、特に目新しいことはない。

## Angular側の設定
Angularで作成したUIは、`build`コマンドによってバンドルし、NestJSから見えるパスに生成する必要がある。生成先のパスは`angular.json`の`outputPath`で指定する。

```json:angular.json
{
  "projects": {
  ...中略...
          "options": {
            "outputPath": "<NestJsプロジェクトの場所>/public等",
```
あとは、`ng build`や`ng build -w`でビルドすればよい。

## NestJSで静的ファイルのパスを指定する
生成したバンドルファイルを開けるようにするために、以下のように静的ファイルを置くパス(この場合は`main.ts`基準の相対)で指定する。(参考:https://docs.nestjs.com/techniques/mvc)

```typescript:main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useStaticAssets(join(__dirname, '..', 'public'));
    await app.listen(3000);
}
bootstrap();
```
# 訂正: 以下の内容は不要
publicを公開した時点で、エンドポイントからindex.htmlを公開する必要はありませんでした…

## コントローラから公開する
REST APIと同様、静的ファイルをGetメソッドから開けるようにするために、コントローラを追加する。実はこれには色々なやり方があるらしく、どれが良いのかはいまいちわからない。

* 参考: https://github.com/nestjs/nest/issues/402

## 方法1 ファイルを送信する
Res(応答オブジェクト)のsendFileメソッドを使ってファイルを返すという方法。なんとなく、そのまま返すという点で速そう。

以下は、ルートへのGETメソッドの応答に、`index.html`をそのまま送っている。

```typescript:app.controller.ts
import { Controller, Get, Res } from '@nestjs/common';

@Controller()
export class AppController {
  constructor() {}

  @Get()
  root( @Res() res ) {
      res.sendFile( 'index.html' );
  }
}
```

## 方法2 レンダリングする
Angularのバンドル後のファイルであれば、この方法のメリットはあまりないと思うが、テンプレートエンジンを使ってレンダリングするという方法もある。

以下では、`@Render`デコレータに、テンプレート(static直下のindex.html)を使ってレンダリングするよう設定することで、テンプレートエンジンを介してAngularのバンドル後のファイルを公開している。

普通は関数の本体(ここでは`root()`)でテンプレートエンジンに与えるパラメータを返すのだが、Angularの生成したファイルに対して加工することはないので、`root()`では何もしていない。テンプレートエンジンを通している分、方法1と比べると若干遅いかもしれない…

```typescript:app.controller.ts
import { Controller, Get, Render } from '@nestjs/common';

@Controller()
export class AppController {
  constructor() {}

  @Get()
  @Render('index.html')
  root() {}
}
```

## 実行結果
Angular CLIでサンプルを作成し、それをNestJSのサーバ(ポート:3000番)で公開すると、以下のような画面が表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/296170/4b751e62-efac-d947-e3b0-ec1c0045ebe4.png)
amazonの商品ページURLをトリミングしてクリップボードにコピーするBookmarklet

Amazonの商品ページのURLは醜い

他の人にそのまま投げつけようものなら迷惑がられるので、その際は商品名などが入ったURLパス部分や無くても問題ないパラメーター部分を消してから送るのが社会人としてのマナーだ

しかし平成も終わるというのに手動でやるのは面倒だし冬休みで暇なのでブックマークレットを作ってみた。（平成も終わるのにブックマークレットかよというのは一旦忘れよう）

以下をBookmarkletとして登録して、Amazonの商品ページに行って発動させるとトリミングされたURLがクリップボードにコピーされた状態になる

```javascript
javascript: var ta = document.createElement('textarea');var reg = /(www.amazon.[a-z]+.?[a-z]*)\/(.*?)\//;var fp = location.href.match(reg)[2];console.log(fp);if (fp.match(/%/)) {  ta.value = location.href.replace(reg, '$1/').replace(/[a-z]+=.*$/, '');} else {  ta.value = location.href.match(/.*[\/|?]/)[0].replace(/\?/, '');}document.body.appendChild(ta);ta.select();document.execCommand('copy');ta.parentElement.removeChild(ta);
```

一応GitHubであげといたのでバグ等あったらIssueなりPRなりいただけると幸いです。
https://github.com/s-ichikawa/amazon-url-trimmer
『Webを支える技術』を読んでRESTの基礎をまとめてみた

年末ですね。今回は『Webを支える技術』を読んだので、REST周りを改めてまとめていきたいと思います。
# REST(Representional StateTansfer)
- 数あるアーキテクチャスタイルの中でもネットワークシステムのアーキテクチャスタイル
- クライアント/サーバー アーキテクチャスタイルから派生したもの
- クライアント/サーバー アーキテクチャスタイルに制約を加えていく

具体的には、RESTとは以下の６つのアーキテクチャスタイルを組み合わせた**複合アーキテクチャスタイル**のことを言う。

- クライアント/サーバー [UIと処理の分離]
- ステートレスサーバー  [サーバー側でアプリケーションの状態を持たないようにする]
- キャッシュ [クライアントとサーバーの通信回数量を減らす]
- 統一インターフェイス [インターフェイスを固定する。http1.1ではGETやPOSTなどメソッドを８つに固定して通信する]
- 階層化システム [システムを階層に分離]
- コードオンデマンド [プログラムをクライアントにダウンロードして実行]

RESTとは制約を課すために、上記、複数のアーキテクチャスタイルを必要に応じて組み合わせて構築した複合アーキテクチャスタイルの１つである。

※そもそもアーキテクチャスタイルとは何かと言うと、アーキテクチャを設計するための作法や流儀である。システムを設計する際の指針がアーキテクチャスタイルとなる。

※制約はアーキテクチャスタイルにおいて、重要な概念。
一般的にはソフトウェアアーキテクチャは複数のコンポーネントを組み合わせて実現することになるが、それぞれのコンポーネントがバラバラに動いているのでは、ソフトウェアとして機能しない。そこで制約を課すことによって、全体として各コンポーネントが協調して動作することを実現するためにアーキテクチャに制約を課すことは非常に重要。

# リソース
RESTにおける重要概念の一つが「リソース(Resource)」

リソースとは**『Web上に存在する名前を持ったありとあらゆる情報』**の事を示す。そしてその名前とは**URI**である。
そのURIを用いる事で、プログラムはリソースが表現する情報にアクセスできる。
※例として、本書では東京の天気予報、駅の写真、ブックマーク等が挙げられている(/~.html, /~.pdf, /~.jpg等)

リソースとは「Web上に存在する情報」という抽象的な概念である。サーバーとクライアントの間で実際のリソースをやり取りするときには何らかの具体的なデータを送信し合う。サーバー・クライアント間でやり取りするデータの事を「リソースの表現」(Resource Representation)と呼ぶ。

WebはRESTという分散ネットワークシステムのための理論があったからこそ、ここまで成功したと言われている。WebサービスやAPIはWebを構成する一部であり、個別のサービスやAPIがRESTful(=RESTらしい振る舞い)になるとWebは全体として良くなると言われている。
memo

# Font
http://www.geocities.jp/meir000/meiryoKe/

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink

追加する値は、
名前：
	Consolas
	Inconsolata
種類：
	複数行文字列値
データ：
meiryoKe_620r1.ttc,MeiryoKe_Console
SEGOEUI.TTF,Segoe UI,133,83
SEGOEUI.TTF,Segoe UI
YUGOTHM.TTC,Yu Gothic UI,128,96
YUGOTHM.TTC,Yu Gothic UI
MSGOTHIC.TTC,MS UI Gothic
MSJH.TTC,Microsoft Jhenghei UI,128,96
MSJH.TTC,Microsoft Jhenghei UI
MSYH.TTC,Microsoft YaHei UI,128,96
MSYH.TTC,Microsoft YaHei UI
MALGUN.TTF,Malgun Gothic,128,96
MALGUN.TTF,Malgun Gothic
SEGUISYM.TTF,Segoe UI Symbol

# Windows old games
Download Windows 7 games for Windows 10
https://winaero.com/download.php?view.1836
ChromeOS　Happy Hacking Keyboardの背面スイッチ設定

#Happy Hacking Keyboard Professional

|SW|設定|説明|
|:--|:---|:--|
|SW1|ON|Lite拡張モード（PC）|
|SW2|OFF|Lite拡張モード（PC）|
|SW3|ON|ON=DeleteをBackspace<br>OFF=DeleteをDelete|
|SW4|ON|ON=左◇をFn<br>OFF=左◇を左◇|
|SW5|OFF|ON=Altを◇<br>　　◇をAlt<br>OFF=AltをAlt<br>　　◇を◇|
|SW6|OFF|ON=Wake Up 有効<br>OFF=Wake Up 無効|
仕事で機械学習を使うので学習した話(未学者のメモ書き)

# はじめに
機械学習初心者が単画像認識で、画像分類できるようになるまでの道のりの記録です。
機械学習には色々な手法ややり方があるため、どこから手をつけてどう学習して、どう実装するかの道筋を示せればと年末に思った所存です。細かい説明はググればわかりやすいページが出てくるので省きます。ググれるタネを示す感じです。

# 前提能力
- Python  
 ちょっとしたプログラムを作って動かせるぐらい 
- 数学  
  大学数学で習った程度(機械工学系の古い記憶がある)
- プログラミング力  
    歴でいうと5年ぐらい。
- 英語力  
 読むのにそんなに困らないぐらい  

とまあいたって普通のエンジニアのスペックです。

# 学習の流れ
1. とりあえず簡単そうな本を一冊読んでみる。  
   機械学習の歴史や数学的手法やらが書いてあるが結局どう実装すればいいのかわからないので挫折
2. 環境の構築を行う。mac book air でのちにWindowsのGPU環境に移行する[^1]
3. 実際のソースが書いてある本のサンプルを動かしてみる.[^2]
4. 動かしてはみたもののPythonのfloat型が0.で定義するのとかわからなくてちょっと悩む
5. 「mnist」とという画像データセットがあるのだが動かしていて楽しくないのでプログラム変更の旅に出る。
6. 線形回帰(当時はよく仕組みがわかっていなかった)で自分で用意した画像の読み込みをやってみるもいまいちで萎える。
7. このとき3.の本を読み進めていくとcnnという手法があるので試してみる。[^3]
8. cnnを試しているうちにようやく機械学習で何をしているかの理解が進む。  
   どうやら y=ax+bのaとbの変数を求めているようだ(y=分類された解, x=入力画像)
   行列は掛け算すると形を変形できるのこのころを思い出す。
9. バッチ正規化というものがあり、基本よくなるらしいのでとりあえず入れてみる
10.出力がほとんどなくなり,softmax関数を最後に噛ませ忘れていたため、実行するたびに結果が変わるバグにハマってなかなか抜け出せない。
11. 精度が出ないので悩んでいたら、GoogleNetなんかアリの巣みたいなモデルがあることを知る。
12. GoogleNetの実装を少し作ってみて、パラメータどうしようと思ったら,参考実装がすでにGitに公開されていたので、参考にしてやってみたが一つ目のinception moduleを一つ作って諦める。
12. そのうち転移学習というものがあることを知る。(すでに学習させたパラメータを使って途中から学習できる。しかも自分の分類したい画像の出力数にしても、なぜかうまくいくらしい。)
13. TensorFlow Hubという簡単にできる仕組みがあることを発見する
14. 2048の出力から自分の欲しい出力に行列を変換するだけで、画像認識ができるようだ。
15. 簡単なはずなのに実装に手間取る。saveができなくて、最後の全結合のパラメータを自分でファイルに保存しはじめたり...orz
16. 機械学習の画像データの大切さを知る。ラベルづけが間違っているデータが数パーセントあったので、それを見直すという苦行を行う(20万件)
17. その後、精度がある程度出ていたので、本番サービスに入れようとするがここに大きな壁が待ち受けていることを筆者はまだ知る由もなかった...[^4]

# 終わりの雑感
業務時間中に実装をして時間外にパソコンに計算させて、本やネットで時間外に勉強するという流れでした。
ここまで,平常タスクをやりながら2ヶ月ぐらいの期間がかかってます。
色々な文献を見ていると古い書き方が数多く溢れているので、本家で確認した方が良いです。そのうち廃止されるメソッドが多く使われています。(今後session作ってたのが変わるらしいし)

機械学習はもう誰にでもできる時代になって来ていて、難しい技術から、プログラミング言語を学ぶのと同じぐらいの敷居になるのではないかと思います。

Googleが色々とライブラリや実行環境を公開してるので、彼らは「誰でもAIを作れる」そんな未来を現実にしようとしているのかもしれません


[^1]: 今、試しにやるならGoogle ColaboratoryがGPUとかTPUをスポットで無料で使えるらしい
[^2]: [TensorFlow機械学習クックブック](https://www.amazon.co.jp/dp/B074SFHQLJ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[^3]: TensorFlowのversionが上がっていて実は、原始的な書き方が多く、途中まで便利関数の使い方を知らなかった。(ex.tf.nn.conv2d <-> tf.layers.conv2d で後者の方は自分で変数を宣言しなくても勝手に作ってくれたりする。)
[^4]: 執筆時点ではまだ実装していません。
[Raspberry Pi Ubuntu MATE] 小さいサイズのSDカードへのクローンコピー

Raspberry Piを使っていて容量の少ないSDカードへのクローンを作る必要があったのでその時のメモです。今回はUbuntu MATEが入ったSDカードを32GBから16GBにコピーしたいと思います。
環境はUbuntu 18.04.1 LTS　 使用するのはGParted,ddです。

#ソースカードのパーティション縮小

32GBのSDカードをつかっているとはいってもすべての容量を埋めてしまっているわけではありません。
使っていない領域を縮小させます。

GPartedをインストールします。

```
sudo apt-get install gparted
```

Raspberry Piにつかっていたカードを読み込みます。

```
df
```
より

```
/dev/sdd1          64456   21480     42976  34% /media/yoshiki/PI_BOOT
/dev/sdd2       29717276 6055328  23645564  21% /media/yoshiki/PI_ROOT
```
と認識されました。

GPartedを起動します。

```
sudo gparted
```
起動すると
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/7f9e7c1b-2e73-b33d-45a0-fd26dbc71e73.png)
のような画面が表示されます。
リサイズするためにアンマウントをします。
ext4を右クリック
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/76385d14-bdbf-95fb-5689-0663b07f7220.png)
アンマウントを選択
![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/4650983a-77e5-213b-d513-9aefbe2c6c2f.png)
再度右クリックしリサイズ/移動を選択します。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/ea676d3f-68cc-b866-420b-00452ffbf61d.png)
このような画面が出てくると思うので
![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/0bc17bc1-b63e-00fe-3716-7d2ebba63252.png)
ターゲットの容量に収まるようなサイズを指定します。
指定後右下のリサイズ/移動を押します。
![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/b430dab0-24c9-25d1-7b3a-de649ebbc3cf.png)
このままでは反映されていないので画面上緑のチェックマークを押し適用させます。
![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/333756/2da989cb-9745-c963-58a4-95c46713673d.png)
リサイズ後再度

```
df
```
よりサイズを確認します。

```
/dev/sdd1          64456   21480     42976  34% /media/yoshiki/PI_BOOT
/dev/sdd2       12972360 6054200   6901776  47% /media/yoshiki/PI_ROOT

```
縮小されました。

#ddでコピー
パーティションサイズが縮小できたならば

```
sudo dd if=/dev/(縮小させたカード) of=/dev/(ターゲットカード) bs=10M
```
を実行し待ちましょう。クローンが作れます。
C++でインデックスソート

どうも。初投稿のなので生暖かい目で見てください。
競プロで必要になったので、自分でぐぐったりしつつ一番自分的に簡単だと思った方法をメモも兼ねて書いておきます。

# インデックスソートとは？
専門用語として正しい使い方なのかはわかりませんが、とりあえずここで言う「インデックスソート」の定義を書いておきます。
一言で言えば、「配列をソートしたとき、ソート後の配列に対応する（元の配列の）インデックスの並びを得る操作」となります。

...はい、意味分かりませんね。説明下手で申し訳ありません。

具体例で見るのが早いですね。例えば、次のような配列(文字列)を考えます。

```string.cpp
char str[] = "bcad";
// str[0] = b
// str[1] = c
// str[2] = a
// str[3] = d
```

これを昇順にソートすると、"abcd"が得られます。このとき、各要素のインデックスも同時に並び替えるとどうなるか考えます。
つまり、各要素の上にインデックスを書いて

````
0123
bcad
````

とします。ここで下の文字列をソートする際、上に書いてあるインデックスもセットで移動させると、ソート後は

````
2013
abcd
````

となります。ここで上の行に現れた"2013"が、「"bcad"をインデックスソートして得られた（インデックスの）配列」となります。

## どんなときに使うの？
例えば、元の配列に破壊的変更を及ぼさずにソートしたいときに使えます。C++のsort()関数は配列そのものを変更してしまいますからね。
尤も上記のケースは、配列のコピーを行えば済む話です。しかしもっと本質的に、「ソート後の配列に対応する（元の配列の）インデックスの配列が必要」（そのまんまｗ）な場合もあります。
これは何というか説明が面倒くさいので、例えば下の問題なんかで必要になります（雑）
https://atcoder.jp/contests/abc009/tasks/abc009_3

# どうやるか？
## 比較関数の定義
ぐぐると結構色々なやり方が出てきますが、「比較関数をうまく自作する」という基本的なところは一致しています。
ただ、見るとどれもファンクタとか物々しい道具を使っていて、僕みたいな雑魚は「(´Д｀)ウヘァ」となってしまうので、ラムダ式とテンプレート関数だけでサクッと書く方法を考えてみました。

```comp_idx.cpp
template<class T>
auto comp_idx(T* ptr){
  return [ptr](int l_idx, int r_idx){
    return ptr[l_idx] < ptr[r_idx];
  };
}
```

解説します。まず注意して頂きたいのは、これは「比較関数」そのものではなく、「比較関数を返す関数」であるということです。
引数としては、ソート対象の配列（の先頭要素へのポインタ）を渡します。これはテンプレート関数なので、配列の要素の型はコンパイラが型推論してくれます。
後でまた述べますが、sort()関数の第三引数に渡すのは、この関数そのものではなく、この関数が返す比較関数です。

比較関数の部分はラムダ式で書かれています。この比較関数が引数に取るのは、配列のインデックスです。
この比較関数は、受け取った配列へのポインタを使って配列の要素にアクセスし、要素同士を比較した結果を返します。

## 使い方
例えば、次のように使います（先程の例に対応しています）。

````index_sort.cpp
#include<cstdio>
#include<bits/stdc++.h>
#define REP(i, n) for(int i = 0; (i) < (n); (i)++)
using namespace std;

//比較関数（を返す関数）
template<class T>
auto comp_idx(T* ptr){
  return [ptr](int l_idx, int r_idx){
    return ptr[l_idx] < ptr[r_idx];
  };
}

int main(){
  char str[] = "bcad";
  int l = strlen(str);
  
  //インデックスの配列を準備
  int idx[l];
  REP(i,l){
    idx[i] = i;
  }

  //ソート前
  cout << "before:" << endl;
  REP(i,l){
    cout << idx[i];
  }
  cout << endl;
  
  REP(i,l){
    cout << str[idx[i]];
  }
  cout << endl << endl;

  //インデックスソート
  sort(idx, idx+l, comp_idx(str));

  //ソート後
  cout << "after:" << endl;
  REP(i,l){
    cout << idx[i];
  }
  cout << endl;
  
  REP(i,l){
    cout << str[idx[i]];
  }
  cout << endl << endl;

  //元の配列
  cout << "original:" << endl;
  cout << str << endl;

  return 0;
}
````

結果は以下のようになります。

````result.txt
before:
0123
bcad

after:
2013
abcd

original:
bcad
````

元の配列は変更されず、インデックスの配列だけがソートされていることが分かります。
Scala 複数のtraitの継承先のクラスで、メソッド名が被ってしまう場合の対処

##継承先で複数のtraitで定義したメソッド名が被った場合

下記でコンパイルするとどっちのgetInfo()を実行すべきかわからないといった意味のエラーが出力される。

```scala
//Example
trait printable {
  def getInfo() :Unit = println("now printing...")
}

trait sharable {
  def getInfo() :Unit = println("now sharing...")
}

class User extends printable with sharable

object MyApp {
  def main(arg :Array[String]) :Unit = {
    val user = new User
    user.getInfo()    
  }
}
```


##対処法1

superを使って、適用したいメソッドが定義されているトレイト名を継承先のクラスで指定してあげる方法。

```scala
trait printable {
  def getInfo() = println("now printing...")
}

trait sharable {
  def getInfo() = println("now sharing...")
}

class User extends printable with sharable{
  def getInfo() = super[printable].getInfo()
}

object MyApp {
  def main(arg: Array[String]) :Unit = {
    val user = new User
    user.getInfo() // "now printing..."
  }
}
```


##対処法2

新たにtraitで、メソッドを抽象化して定義し、各々のtraitその抽象メソッドをoverride -> 継承の流れ。

```scala
trait Common {
  def getInfo()
}

trait printable extends Common {
 override def getInfo() :Unit = println("now printing...")
}

trait sharable extends Common {
 override def getInfo() :Unit = println("now sharing...")
}

class User extends printable with sharable

object Myapp{
  def main(arg :Array[String]): Unit = {
    val user = new User
    user.getInfo() // "now sharing..."
  }
}
```

extendsで継承されたprintableよりも後に、読み込まれるsharableでCommonトレイトをoverrideし、具象メソッド化したgetInfo()メソッドがここでは、呼び出されるようになる。
マイクロサービスのイメージは「蜂の巣」？「脳の神経細胞、ニューロン」？ @yumainaura

# Book

![image](https://user-images.githubusercontent.com/13635059/50545398-3a849900-0c56-11e9-9a4e-b1f09b368fb9.png)

# 脳だと考えている人はいなさそう？いや必ずいるはずなのだけれど。

![image](https://user-images.githubusercontent.com/13635059/50545404-5425e080-0c56-11e9-9f4b-b72f89420748.png)

# 🤔

![image](https://user-images.githubusercontent.com/13635059/50545411-728bdc00-0c56-11e9-970c-df2cd2781234.png)

# My understand missed?

![image](https://user-images.githubusercontent.com/13635059/50545413-7fa8cb00-0c56-11e9-90ec-7fea15d8bd3e.png)

# やはり脳よりは「硬いもの」の集合っぽい

![image](https://user-images.githubusercontent.com/13635059/50545419-a23ae400-0c56-11e9-9174-b486932fc2f0.png)

# 脳の神経細胞は各自が自由につながって回路を作っていくものだからだろうか？

マイクロサービスは計画的に設計する、というイメージなのかも知れない。あくまでも。

# なぜイメージが大事なのだろう

言葉にできない。imaging


https://github.com/YumaInaura/YumaInaura/issues/60








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
マイクロサービスは簡単じゃない。 @yumainaura 学習コスト、コミュニケーションコスト、過剰分割注意。抜粋学習まとめ。

[マイクロサービスへの挑戦、ラクスが考える技術的負債を返済する最適なタイミング - Qiita:Zine](https://zine.qiita.com/jobs/rakus-microservice/?utm_source=qiita&utm_medium=banner)


# マイクロサービスは簡単じゃない

>鈴木：僕自身、マイクロサービスについては勉強会にも参加してみたり、色々なところから知識は取り入れていたのですが、実際にやってみるとやはり簡単じゃないな、と。

>川島：ですよね。実際には泥臭いところもたくさんありますし

# 学習コストがとてもとても高かった

>鈴木：知識としては、多数のコンテナを連携して構築するからツールを活用しないと実現が難しい、という理解はあったんです。ただ、今まで使っていなかったツールをいくつも導入するとなると学習コストが高すぎました。

# コミュニケーションコストの壁

>大平：ラクスは東京と大阪の二拠点で開発をしているプロダクトもあり、どうしても仕様のすり合わせなどコミュニケーションコストが発生しています。

これは通常の開発にも言えることかもしれないが、組み合わせ技で掛け算のつらさがあったのかもしれない。

# 小さくしすぎるな！過剰分割は危険

>マイクロサービス化の最初のつまずきポイントって、「マイクロ」という言葉の捉え方になると思うんです。小さくなくてはならない。ここに囚われると、過剰に分割することにつながります。

# ところで読み直したくなった本がある

![image](https://user-images.githubusercontent.com/13635059/50545380-c4803200-0c55-11e9-9792-aff0e13c9106.png)

この本はいまでも有効なのだろうか。3年以上前の出版だったと思うけれど。

# マイクロサービスの概要を学ぶの楽しいぜ！

開発はこの六億倍ぐらい大変かもしれないけれど…

# 蜂の巣

![image](https://user-images.githubusercontent.com/13635059/50545384-ee395900-0c55-11e9-9c78-7dd1d972ea6c.png)


https://github.com/YumaInaura/YumaInaura/issues/59








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
最近のマイクロサービスの事情に学びたい。マイクロサービスの特徴とは。 @yumainaura

[マイクロサービスへの挑戦、ラクスが考える技術的負債を返済する最適なタイミング - Qiita:Zine](https://zine.qiita.com/jobs/rakus-microservice/?utm_source=qiita&utm_medium=banner)

# マイクロサービスに挑戦する企業が急増中

>現在、モノリシックなアーキテクチャからマイクロサービスアーキテクチャへの移行に取り組む企業が増加しています。

詳しい数は不明。

# 過渡期？

色々な問題はありつつも、チャレンジした企業が勝っていくのだろうか。

# 古びた環境があった

>10年以上運用しているサービスもあって、コードベースが陳腐化していたり、フレームワークが古かったりという課題があったんです

# モノリシックなサービスが巨大化していた

>また、一つのサービスが巨大化しているため、分担作業がしにくいという問題もありました。


# マイクロサービスの特徴は「技術異質性」

>鈴木：マイクロサービスアーキテクチャの特性の一つとしてあげられる技術異質性を検証してみるために、Ruby、Go、Haskellなど複数の言語でバックエンドを構築してみたり。

# 言語をあえてバラバラにする必要はないという実感

>ただ実際に言語をバラバラにしてみると、特に理由がない限りは言語は統一しておいたほうがいいな、と改めて思いました。

# 「言語が得意なこと」と「オーバーヘッド」との兼ね合いで技術選定が望まれる

inmyopinion



https://github.com/YumaInaura/YumaInaura/issues/58








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
決算書を読む

# 導入
##初級編

ビジネスモデルごとに分ける

- 決算説明会資料を読む
- 企業の将来を予測しようとする前に過去を正確に理解する

##中級編

- 徹底的な因数分解で「ユニットエコノミクス」を計算する
ユニットエコノミクス・・・顧客一人あたりの平均の経済性、各企業のオリジナリティ
↑を理解することでその企業の強み弱みが見えてくる

- 成長率(YoY)を確認する
売り上げなどは同じでも前年比で成長率が大きい方が株価は大きくなる
「どの向きに」「どのくらいの強さの風」が吹いてるのかをわかるように

##上級者編
- １社だけでなく、類似企業の決算も分析比較する。
業界の流れを知るために、１社だけでなく業界内の会社を複数分析する必要がある

- 類似企業間の違いを説明できるように
違いの原因はどこにを言語化できるように



#EC業界
FirstVRをARで使ってみる

## 概要

今回はFirstVRをARで用いることについて書いてみたいと思います。
VRはARとも相性がいいので（というかニアイコール）、応用できないかなと思ったのが理由です。

モバイルARだとどうしても手のジェスチャなどを取ることができず、HoloLensにあるような体験を作りづらいという難点があります。
しかも、画面タップで処理させようとすると画面を手で覆ってしまってせっかくのコンテンツが見えない、というのも問題のひとつです。

ということで、このあたりをFirstVRを使って解決してみたいと思います。

ちなみに今回のデモはこんな感じ↓
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">グーとパーで操作できるようにしてみた。 <a href="https://twitter.com/hashtag/FirstVR?src=hash&amp;ref_src=twsrc%5Etfw">#FirstVR</a> <a href="https://t.co/t1mBVX07LL">pic.twitter.com/t1mBVX07LL</a></p>&mdash; edom18@VR (@edo_m18) <a href="https://twitter.com/edo_m18/status/1079283643053268993?ref_src=twsrc%5Etfw">December 30, 2018</a></blockquote>


## ARKit

今回はUnityのARKit Pluginを使って実装しています。

以前はARKit PluginがAsset Storeでダウンロードできたのですが、どうやら提供されなくなったようで、[開発されているリポジトリ](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin)から直にダウンロードしてくる必要があるようです。

詳細はこちらを以下をご覧ください。

- [【Unity】Unity ARKit Pluginが無いのでUnity-Technologies-unity-arkit-plugin-b3de628acfac.zipを使う](https://qiita.com/nonkapibara/items/3800d4ff3c56912073df)


### ARKit Pluginの中のシーンを利用する

ARKit Pluginにはいくつものサンプルシーンが存在します。
タップした位置にオブジェクトを移動するタイプのサンプルならなんでもいいですが、今回は`UnityAROcclusion`シーンを利用しました。

<img width="224" alt="AROcclusionシーン" src="https://qiita-image-store.s3.amazonaws.com/0/5616/caa1196b-263e-7146-031c-476e2b9d4738.png">

このシーン内に、FirstVRを利用するためのセットアップを行います。


## カスタムジェスチャを登録してARを操作する

今回は、[前回書いた「カスタムジェスチャ」](https://qiita.com/edo_m18/items/4f03b2bbf182afd3e7a0)の仕組みを使ってARのオブジェクトに干渉することをしています。

カスタムジェスチャ自体については上記記事をご覧ください。

今回は「グー」と「パー」の状態でAR内のキャラクターのポーズを変更するようにしてみました。
本当はつまむようなジェスチャにしたかったのですが、パーの状態との誤認識がそれなりにあったので、安定したグーでデモしています。

複数ジェスチャ登録することで色々な指示が出せるのでARとの相性はとても良さそうに思います。

今回の実装は以下のようにしました。

```cs
private void Update()
{
    if (!_isInitialized)
    {
        return;
    }

    bool needsNext1 = _gesture1.held && !_lastHeld1;
    _lastHeld1 = _gesture1.held;

    if (needsNext1)
    {
        _idleChanger.Next();
    }

    bool needsNext2 = _gesture2.held && !_lastHeld2;
    _lastHeld2 = _gesture2.held;

    if (needsNext2)
    {
        _idleChanger.Back();
    }
}
```

`_gesture1.held`と`_gesture2.held`がそれぞれ、登録したジェスチャ状態かを判断する`bool`型の値です。
つまり、登録したジェスチャの状態になっていたら、AR内キャラのポーズを変更する、という単純なものです。

仕組み自体はシンプルですが、動画を見てもらうと分かるように、比較的安定して認識してくれるので、ARを用いたコンテンツと組み合わせるとだいぶ良さげな感じです。

oculus Goとも連携できるようなので、色々いじってみようと思います。
PythonでYoutubeAPIを使おうとして躓いた話(合わせ読み用記事)

YoutubeAPIについてなかなか躓いたので、躓いたところを簡潔にまとめる。

#注意
この記事は他の記事と合わせ読むことが大前提になっている他力本願記事です。

#1つ、YoutubeAPIの扱い方へのイメージ

YoutubeAPIはURLを介してデータのやり取りを行うみたいです。(さっき知った)
APIは大体そんな感じなのかな？


という事で、まずWebページを扱うライブラリ(表現があっているのか?)、
requests や httplib2 などのライブラリについて調べましょう。
httplib2のほうが推奨されているみたいです。

#2つ、取得すべき認証情報

いま全然触れられてないので、正確な情報とはまるで言えませんが
まずはAPIキーを取得しましょう。

おそらくそれで事足りるはず…？

#これはなに…？

https://www.googleapis.com/youtube/v3/subscriptions?pageToken=XXXXXX&part=snippet&maxResults=1&channelId=XXXXXXXXXXXXXXXXXX&key=XXXXXXXXXXXXXXXXXXXXXXXXX

を送ったら

{'kind': 'youtube#subscriptionListResponse', 'etag': '"XXXXXXXXXXXXXXXX"', 'nextPageToken': 'XXXXXX', 'prevPageToken': 'XXXXXX', 'pageInfo': {'totalResults': 476, 'resultsPerPage': 1}, 'items': []}

が返ってきました。
いやなんでitemないねん。

#終わりに

いや多分読解力が足りないんだろうけど(というかまず流し読みをやめるべき)
躓いたのでまとめてみました。

短くてごめんほんとに
no such table: main.auth_user__old Udemy 【3日でできる】はじめての Django 入門 

# はじめに
[【3日でできる】はじめての Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/django-beginner/)レクチャー２５で投稿を保存しようとすると
『no such table: main.auth_user__old』というエラーが出る。

# 結論
アップデートを待とう！笑
[スタックオーバーフロー](https://stackoverflow.com/questions/53637182/django-no-such-table-main-auth-user-old)曰く、Djangoのバグらしい。
2019年1月1日リリース予定のもので解消されるとのこと。

とはいえ、少しでも先に進めたいから他の人が書いてくれている解消法を試すことにします。

## DBの向き先をPosgreSQLに変更する
※既に自分の端末にPosgreSQLが入っている方向けです。
入っていない方は適宜ググって入れるか、2019年1月1日リリースを待ちましょう
[Python + Django + psycopg2でposgreSQLに接続する](https://qiita.com/t-iguchi/items/0fd7bf799571330f0219)を参考にさせていただきました。@t-iguchi様ありがとうございます。

```
(py36) xxxx$ pip install psycopg2
Collecting psycopg2
  Downloading https://files.pythonhosted.org/packages/ff/db/942f8e40e93b5fe060c8d3a736d8fdd134fa5308dba8484dc06ae46e3fbd/psycopg2-2.7.6.1-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (1.5MB)
    100% |████████████████████████████████| 1.5MB 168kB/s 
Installing collected packages: psycopg2
Successfully installed psycopg2-2.7.6.1

$ python -c "import psycopg2"
/Users/xxxx/anaconda3/envs/py36/lib/python3.7/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)

$ pip install psycopg2-binary
Collecting psycopg2-binary
  Downloading https://files.pythonhosted.org/packages/fe/df/933e81c7fa95a915a9d67bd5736963a99513568f82cfc937c76d0d6f3414/psycopg2_binary-2.7.6.1-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (1.5MB)
    100% |████████████████████████████████| 1.5MB 277kB/s 
Installing collected packages: psycopg2-binary
Successfully installed psycopg2-binary-2.7.6.1

```

PosgreSQLサーバ起動

```
$ postgres -D /usr/local/var/postgres
```

別ウィンドウにてpsql操作
PosgreSQL用のDBを作る

```
$ psql -d postgres
postgres=# create database djangodb;
postgres=# \q
```

DBの接続先設定を変更する

```settings.py
DATABASES = {
           'default': {
           'ENGINE': 'django.db.backends.postgresql_psycopg2',
           'NAME': 'djangodb',
           'USER': '人によりけり',
           'PASSWORD': '人によりけり',
           'HOST': '127.0.0.1',
           'POST': '5432'
         }
   }
```

レクチャー２５までしっかりとやっていればmodelの設定もできているはずなので以下の通りやれば問題なく行くはず

```
$ python manage.py migrate
$ python manage.py createsuperuser
レクチャー通りに設定
$ python manage.py runserver
```

<img width="572" alt="スクリーンショット 2018-12-30 16.54.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/177690/36ba0d24-1dfc-9211-1a5f-db28b894b5fe.png">

いけた！
ルーティングでこける　Udemy 【3日でできる】はじめての Django 入門

# はじめに
レクチャー２１でルーティングの設定をするのですが、私が講座と違うバージョンのDjango（２系）を使っているためちょっとハマりました。

これから[【3日でできる】はじめての Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/django-beginner/)を学ぶ方の中にも僕と同じ進め方をする方もいると思うので、共有します。

## 起こったこと
「http://127.0.0.1:8000/posts/」にアクセスするも４０４エラーとなる。
ログに警告

```
WARNINGS:
?: (2_0.W001) Your URL pattern '^$' [name='index'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
```
が吐かれていたので、多分正規表現が混ざる記述がまずかったのだろう。。。

僕の場合、諸悪の根源がこいつ↓でした

```urls.py(posts配下)
from django.urls import path

from . import views

urlpatterns = [
    path(r'^$',views.index, name='index')
　　　　 　↑
　　　　 「Regular Expressions」＝正規表現で使う「r」
]
```
正しくは（理解しきれていないので、正確に表現するならば「動作させるには」というべきかもしれない）

```urls.py(posts配下)
from django.urls import path

from . import views

urlpatterns = [
    path('',views.index, name='index')
]
```

その他のファイル状況は基本的に動画と同じ
urlではなくpathを用いているものとして

```urls.py(myblogapp配下)
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls) ,
    path('posts/', include('posts.urls') )
]
```

も掲載しておきます。
ViewPager上のFragmentのオンスクリーンをキャッチ

##問題

ViewPagerでは、オンスクリーンになっているFragmentの左右にあるFragmentがスワイプですぐ表示できるようにするため、ライフサイクルのonCreateからonResumeまで実行され待機しています。
もし、オンスクリーンになったときに何かしらの処理を実行させたい場合、Fragment#onResumeでは問題があります。

##解決

Fragment#userVisibleHintを利用します。
スワイプしてオンスクリーンになると、setUserVisibleHintの引数がtrueとなり、また、オフスクリーンになった場合、引数がfalseとなります。

```kotlin
class MainFragment : Fragment() {

    @Override
    override fun onResume() {
        super.onResume()

        if (userVisibleHint) {
            // TODO: オンスクリーン
        }
    }

    @Override
    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)

        if (isResumed && isVisibleToUser) {
            // TODO: オンスクリーン
        }
    }

}
```

[サンプルプロジェクト][1]
[1]:https://github.com/mn-D128/FragmentViewPager
itext7でPDFを作成する～日本語を出力しよう～

#itext7で日本語を出そう
さて[前回](https://qiita.com/naverut/items/b60d086c60d1146aa45f)、HelloWorldを出力したものの、日本語の出力にしたら真っ白けなPDFが出力されてしまいました。
原因は「フォント」にあります。
日本語に対応したフォントを割り当ててあげないと日本語は出力されません！
というわけで、日本語出力例

```HelloWorldJp.java
import java.io.File;

import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;

public class HelloWorldJp {
    public static void main(String[] args) throws Exception {
        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(new File("HelloWorldJp.pdf"));
        // 平成角ゴシック
        PdfFont font = PdfFontFactory.createFont("HeiseiKakuGo-W5", "UniJIS-UCS2-H");

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);
 
        // Initialize document
        Document document = new Document(pdf);
 
        //Add paragraph to the document
        document.add(new Paragraph("こんにちは～世界！").setFont(font));
 
        //Close document
        document.close();
   }
}
```

ポイントは「平成角ゴシック」のフォントを作って、文字にsetFontしている部分ですね。

#他にはどんなフォントが使える？
gradleで読み込んだ「font-asian」で指定できる日本語を調べてみました。
第１引数は「フォント名」、第２引数は「エンコード」を指定できます。

- 第１引数：フォント名
    - "HeiseiMin-W3"：平成明朝
    - "HeiseiKakuGo-W5"：平成角ゴシック
    - "KozMinPro-Regular"：小塚明朝 

※「font-asian-7.1.4.jar」の「com.itextpdf.io.font.cmap.cjk_registry.properties」というファイルで「fonts」に定義されているものが指定可能なフォント名のようです。
さらにこの名称のpropertiesファイルの中で「Registry=Adobe_Japan1」と定義されているものを日本語で指定できるフォントと判断しました。

- 第２引数：エンコード
第１引数で指定したフォント名のエンコード方法を指定します。
「font-asian」を利用する場合は基本的には"UniJIS-UCS2-H"か"UniJIS-UTF16-H"を指定するのが良さそうです。
まずは後ろについている"-H"と"-V"ですが、"-V"は縦書きフォント用です。
縦書きについてはそのうちやる予定です。

※日本語で第２引数に他に指定できるものとしては「cjk_registry.properties」の「Adobe_Japan1」で定義されているものと思われます。
この中から半角数字や半角カナなどキチンと表示できそうなのがこの２つでした。
「彅」(草なぎのなぎ)や「♡」(ハートマーク)もこの２つでは表示できました。
「🍣」(寿司の絵文字)ではエラーとなってしまいました・・・

**font-asian以外のフォントは使える？**
とりあえず使えます。
例えばwindowsであればMSゴシックを指定できたりします。

```
PdfFont font = PdfFontFactory.createFont("c:\\windows\\fonts\\msgothic.ttc,0", "Identity-H");
```
ただ、フォントには著作権などあるので取扱には注意！！
Visual C++ MFCのマウスイベント

ダイアログ画面に配置したボタンやテキストボッククスをドラッグ＆ドロップする処理を実装したいです。 
ダイアログ画面自体にマウスイベント（OnLButtonDownやOnLButtonUPなど）を実装することができたのですが、コモンコントロールや描画した画像などにマウスイベントを実装する方法が分からなくて大変困っています。

どなたかご教示して頂けませんか？

私はプログラミング初心者です。
出来るだけ噛み砕いて教えて頂けると嬉しいです。
よろしくお願いします。
pyenvのbashrcで少しつまずいた

今回新しいサーバが届きpyenvを入れた時少しつまずいたので忘備録．

## pyenvを入れた
とりあえず，Linuxbrew(入れ方は[こちら](http://linuxbrew.sh/)参照)を入れて下記コマンドでインストール

```shell
$ brew install pyenv
```
インストールが終了したら，その後，以下を実行

```shell
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
```
これで基本的な設定はできたので，

```shell
source ~/.bashrc
```
で読みこむ．

```shell
$ pyenv versions
* system
```
確かに動いていることを確認．普通ならこれで大丈夫なはず．

## 再度ログインする
再度ログインした時に，最初下のような表示がでた．

```shell
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.15.0-43-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.

Last login: ***
No command 'pyenv' found, did you mean:
 Command 'p7env' from package 'libnss3-tools' (universe)
 Command 'pyvenv' from package 'python3-venv' (universe)
pyenv: command not found
```
なぜかpyenv: command not foundと出てしまった．確かに

```shell
$ which python
/path/.linuxbrew/bin/python
```
本体ならば.pyenv下のpython担っているはずだが，違う場所を見ている．ただ，

```shell
$ pyenv versions
* system
```
は普通に動く．そこでもう一度.bashrcを読み込んでみると.pyenv下のpythonを見る様になった．

```shell
$ source ~/.bashrc
$ which python
/path/.pyenv/shims/python
```
ただ，bashrcはログインするたびに読み込んでいるはず．ここでつまずいた．

### 解決策
わかってみると，そりゃ当たり前だ！という感じであった．無意識のうちに~/.profileが終わった後に~/.bashrcが実行されると思っていたが．~/.profileを見てみると

```shell:.profile
# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"
eval $(/path/.linuxbrew/bin/brew shellenv)
```
となっていた...!bashrcが先に実行されてしまっていた．これを順番を変えてあげて以下の様にする.

```shell:.profile
# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"
eval $(/path/.linuxbrew/bin/brew shellenv)

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi
```
これで解決.そりゃそうだよね...
自分用Javaソースファイルの扱い方

##文字コード
- ソースファイルの文字コードの扱いがどうなっているかまだわかっていないので、すべてUTF-8に統一しておく。
- プログラムから読み込むテキストファイルもすべてUTF-8に統一しておく。

##クラスごとにソースファイル？
- よくわからないので1クラス1ソースファイルとしておく。
- クラスの中にクラスを定義する（内部クラス？）場合、ソースファイルをわけるかどうかはあとで検討する。たぶんわけないことになりそう。

##パッケージの定義の仕方
- ソースファイルの先頭行に`package hogehoge;`と書いておくと、そのソースファイルで書かれたクラスがそのパッケージ内に含まれることになる
- パッケージ名はすべて小文字とすることが普通らしい。※クラス名は先頭大文字
node.js + esprima + Graphviz で抽象構文木をグラフにしてみる



* [Pythonの抽象構文木をGraphvizで可視化する]( https://qiita.com/kaityo256/items/e83b369ba7518da0a519 ) ( 
@kaityo256 さん )
* [Ruby2.6 + Graphvizで抽象構文木をグラフにしてみる]( https://qiita.com/Nabetani/items/7904651fae1f925129c7 ) ( 私 )
* [Go + Graphviz で抽象構文木をグラフにしてみる]( https://qiita.com/Nabetani/items/a7416f09b2a68b8f0cc1 ) ( 私 )

のシリーズを、JavaScript(node.js) で。

JS の AST を得る方法はたくさんあるみたいなんだけど、 **esprima** というライブラリを選択した。

まずはソースコード。

```javascript:node.js
var esprima = require('esprima');
var fs = require('fs');

function walk(parent, edge, node, proc) {
  if (node === null || "object" != typeof node) {
    return;
  }
  proc(parent, edge, node);
  for (var key in node) {
    walk(node, key, node[key], proc);
  }
}

function quoted(node) {
  var s = "";
  if ("type" in node) {
    s += node.type;
  }
  if ("name" in node) {
    s += "(" + node.name + ")";
  }
  if ("value" in node) {
    s += "[" + node.value + "]";
  }
  if ("operator" in node) {
    s += "(" + node.operator + ")";
  }
  if (Array.isArray(node)){
    s = "Array";
  }
  var j = JSON.stringify([s]);
  return j.substr(1, j.length - 2);
}

function codeToDot(src) {
  var ast = esprima.parse(src);
  var str = "";
  var id = 0;
  walk(null, null, ast, function (parent, edge, node) {
    node["dot_id"] = "n" + (id++);
    if ( parent!==null ){
      str += parent.dot_id + "->" + node.dot_id + "[taillabel=\"" + edge + "\"]\n";
    }
    var label = quoted(node);
    str += node.dot_id + "[ label=" + label + "]\n";
  });
  return str;
}
fs.readFile(process.argv[2], 'utf8', function (err, text) {
  dot = codeToDot(text);
  process.stdout.write("digraph{graph [dpi=288;]; node[ shape=box ];\n");
  process.stdout.write(dot);
  process.stdout.write("}\n");
});
```

関数 `quoted` が不十分かもしれない。

食べさせたコードはこんな感じ：

```javascript:javascript

function hoge(foo, bar) {
  for (var ix in bar) {
    var val = bar[ix];
    if (val < ix) {
      console.log(val + (-10 + 100));
    }
  }
}

hoge("45", ["34", "56"]);
```

`for`  と `if` と関数定義、関数呼び出し、配列リテラル、あたりを入れてみた。

出来上がる絵はこんな感じ：

![image.png](https://qiita-image-store.s3.amazonaws.com/0/6854/e96648a3-046f-e0eb-035c-8c99058ec2a2.png)

やはり面白い。
はじめまして

#自己紹介
SIerとして小さい会社に勤めています。3年目です。

#Qiitaに記事を投稿する理由
社会人になってから様々な現場を体験してきました。主にIBMのCognos関連です。
Cognosって、ググってもあんまり情報が出てこないんです。出てきても英語のページがほとんどで、英語を読み解いていかないと知りたい情報がつかめない。もっと日本語の記事が増えないかなぁ…。あっ！だったら自分で記事を投稿すればいいじゃん！！
そんな感じです。

Cognos以外に、Excelマクロなんかも最近ちょくちょく触っているので、VBA関係の記事も投稿していけたらなと思っています。

#よろしくお願いいたします

日本語が下手くそで読みにくいこともあると思いますが、少しでも誰かの役に立てれば幸いです。よろしくお願いいたします。
あまりにもC#をわかってなかったので自分用にメモしていたら気づいてしまったこと

# C#の基本用語がわからなすぎた
## AzureのCognitive Servicesを使いたかったけど

GitHubにあるCognitive Servicesの[音声合成サンプルコード](https://github.com/Azure-Samples/Cognitive-Speech-TTS)を参考にTextToSpeechをやりたかったけどAzureやらCognitiveServicesやらうんぬんよりもまずC#がわからないすぎることに気づいた。
なのでまずはサンプルコードに出てくるものの中で曖昧なものを自分用にまとめよう＆せっかくだしどこかでアウトプットをしようということで今回初投稿を試みました。
授業でRubyやPythonには触れたものの知識としてなにも残っていない状態です。
曖昧な知識を無くすのが目的なので超初歩から書いていくつもりです。
ゆえに対象読者はQiitaの中でも自分位だと思われます。

## わからないものとその自分なりの解釈
サンプルコードに出てくる順に書いていこうと思います。

#### using
名前空間へのアクセスを容易にする。例えば「System」をusingしておけば名前空間SystemのメソッドConsoleなどをわざわざ完全修飾名(System.Console...)で書く必要がなくなる。どうやらエイリアスも作成できる様子。
#### namespace
これは名前空間自体のことではなくコード内の`namespace hogehoge...`となっているものです。元からある名前空間以外に自分でも作れるって理解でいいかな...違う名前空間の中で同じクラス名を定義しても完全修飾名で記述すれば別ものとして扱えるようです。

#### partial class
部分クラス。同じ名前のクラス内で違うメソッドなんかを場合によって使い分けたいときに使うのでしょうか...未熟なのでどういったメリットがあるかよくわかりませんでした。

#### protected 
アクセス制限をクラスに設ける。protectedクラスの派生クラス以外protectedクラス内にアクセスできないってことだと思います。これもどういったメリットがあるかがわかりませんでした...

## 気づいたこと
ここまで書いていて思ったんですがC#どころではなくオブジェクト指向もといプログラミングというものをわかってなくね??ということに気づいてしまいました。便利なものがあるからといって飛びついても地の力がなければ当然利用はできないということですね。
ちゃんとオブジェクト指向を理解してから出直そうと思います。あまりにも実力がかけ離れているとその差にすら気づけないということが身をもってわかりました。戒めとして記事を残しておきたいと思います。



おわり
git+msysでgit@bitbucket.org: Permission denied (publickey).

WindowsでMSYS2上でgitを使用しています。
新PCで環境整える際、bitbucketへの接続で以下のエラーにハマったのでメモしておきます。

```
git@bitbucket.org: Permission denied (publickey).
```

ちなみに以下は設定済みです。
[BitbucketにSSH認証鍵を設定する](https://qiita.com/0084ken/items/e763c85054a5a1e2cc6c)

以下でSSH接続を試すと、詳細が表示されます。

```
$ ssh -Tv git@bitbucket.org
```

```
debug1: key_load_public: No such file or directory
debug1: identity file /home/xxx/.ssh/id_rsa type -1
```

自分はMSYS2を使う際、HOMEディレクトリを`%USERPROFILE%`にしています。
`~`も`$HOME`も`C:\\Users\xxx`を指しています。
しかしsshはそのへんお構いなしで、`/home/xxx`を見に行くようです。

sshが期待するパスに、シンボリックリンクを張ってやります。

```
mklink /D D:\msys64\home\xxx\.ssh C:\Users\xxx\.ssh
```

これでssh接続できるようになりました。
KerasのConv2DTransposeの動作について

# 概要
Conv2DTranspose(ChainerではDeconvolution)の動作が分かりにくいので、どうやって動作しているのかをまとめる記事。


# Transpose Convolutionとは
Upsamplingするときに使用されるレイヤー。
和訳すると「転置畳み込み」。なぜ転置なのかは以下のサイトで分かりやすく説明されている。
[Up-sampling with Transposed Convolution](https://towardsdatascience.com/up-sampling-with-transposed-convolution-9ae4f2df52d0)

また以下のリンク先で動作のアニメーションが見れる。
[Convolution arithmetic](https://github.com/vdumoulin/conv_arithmetic)

# 出力shape計算式

Convolution2Dの出力shape計算式は[TensorFlowの公式ドキュメント](
https://www.tensorflow.org/api_docs/python/tf/nn/convolution)に式が書いてある。

TransposeConvolution2Dの出力shape計算式については、[how to calculate the output shape of conv2d_transpose?](https://datascience.stackexchange.com/questions/26451/how-to-calculate-the-output-shape-of-conv2d-transpose)に書かれている。

以下上記サイトに記載されている数式

### Convolution2Dの出力shape計算式

- `Padding == SAME`の場合

```math
output\_shape[i] = ceil(input\_shape[i] \div strides[i])
```

- `Padding == VALID`の場合

```math
output\_shape[i] = ceil((input\_shape[i] - (filter\_shape[i]-1) \times dilation\_rate[i]) \div strides[i]).
```

### TransposeConv2Dの出力shape計算式


- `Padding == SAME`の場合

```math
output\_shape[i] = input\_shape[i] \times strides[i]
```

- `Padding == VALID`の場合

```math
output\_shape[i] = (input\_shape[i] - 1)  \times strides[i] + filter\_shape[i]
```


# Conv2DTranspose設定パラメータ
| Params     |Value|
|:----------|:---|
|filter_shape|畳み込みをするfilterのshape|
|strides     |畳み込みの縦と横のストライド|
|padding     |VALID or SAME|

Conv2Dの`strides`はfilterをどれくらいずらすか、というパラメータだったが、Conv2DTransposeでは入力画像の画素間の間隔を表している。デフォルトは`strides=(1,1)`になっていて、これは画素間に空白がないことを示している。
`strides=(2,2)`を設定すると入力画像の画素間に1つのパディングが埋め込まれる。

`padding`は上記した出力shapeの計算式を切り替える役割を持っている。

# Conv2DTransposeの動作図
設定パラメータと、実際にフィルターと入力画像がどうやって重なっているのか図示する。
赤の点線がフィルターを、青の正方形が入力画像を表している。

---
| Params     |Value|
|:----------:|:---:|
|input_shape |(2,2)|
|filter_shape|(2,2)|
|strides     |(1,1)|
|padding     |VALID|
|output_shape|(3,3)|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250063/5e7be4f8-b0fc-d22f-1ba5-131850cb8bba.png)


---
| Params     |Value|
|:----------:|:---:|
|input_shape |(2,2)|
|filter_shape|(2,2)|
|strides     |(1,1)|
|padding     |SAME|
|output_shape|(2,2)|


![image.png](https://qiita-image-store.s3.amazonaws.com/0/250063/f7d8124a-f543-a922-acde-c19b7e418771.png)

---
| Params     |Value|
|:----------:|:---:|
|input_shape |(2,2)|
|filter_shape|(2,2)|
|strides     |(2,2)|
|padding     |SAME|
|output_shape|(4,4)|


![image.png](https://qiita-image-store.s3.amazonaws.com/0/250063/cd99609d-de6e-514f-7c92-151848b13550.png)

---
| Params     |Value|
|:----------:|:---:|
|input_shape |(2,2)|
|filter_shape|(4,4)|
|strides     |(2,2)|
|padding     |SAME|
|output_shape|(4,4)|


![image.png](https://qiita-image-store.s3.amazonaws.com/0/250063/bcdcf121-8411-d844-18ed-b44b096aca8e.png)

---
| Params     |Value|
|:----------:|:---:|
|input_shape |(2,2)|
|filter_shape|(4,4)|
|strides     |(2,2)|
|padding     |VALID|
|output_shape|(6,6)|


![image.png](https://qiita-image-store.s3.amazonaws.com/0/250063/82f34062-b044-7ef2-146a-db0f767f57bd.png)
GANばるAI -スタート編-

# 本ブログの目的
　どうもです！今年からディープラーニングさんを使った **コンピュータビジョン**（以降，CV）の研究をしているクソザコナメクジです．

　CVの研究の本質は **"コンピュータ（ロボット）の目を作る"**ことで，コンピュータに動画像をどのように認識・処理させるかが研究の醍醐味であると思います．

しかし，最近では**"GAN"**と呼ばれる技術で，画像を生成したり（ある意味副産物のようなものだと思うが．．．），人間からみても画像が綺麗になるように処理したり，自然言語などの別分野とコラボしたり，幅がかなり広い研究であると思います．

　そこで，本ブログでは自身の備忘ログだけでなく，CVの世界を初心者にもわかりやすく説明できるようにここに書いていきたいと思っています！あと書いたプログラムの共有！
（人に教える事で自身の勉強になるってやつ？！）

まとめると，このブログを書く動機としては3つ!!
　1. 自分の備忘ログ
　2. 初心者にもわかりやすく！CVの世界を！
　3. コーディングのクソザコナメクジ :bug:→ ちょー強ナメクジ:snake:へのジョブチェン
　~~4. （金儲けしたい）~~

月に1回くらいは更新したい！

今回はスタート編なのでこの辺で！
PythonのWebアプリをHerokuで動かすときの設定情報の読み替え方法

Python+FlaskのWebアプリをHerokuで動かすとき設定情報をローカル環境とHeroku環境でどう読み替えさせるか悩んだのでやった方法を残します。

Herokuの環境変数を設定
ローカルには「settings.py」とかでファイルをつくりそこにキー情報を格納
.gitignoreにsettings.pyを追加
下記のように設定情報を取得

```python
import os


if os.getenv('SOME_KEY') is not None:
    SOME_KEY = os.environ.get('SOME_KEY')
else:
    import settings
    SOME_KEY = settings.SOME_KEY
```

これでGitHubにキー情報をあげないでローカルでもherokuでも読み替えられるようになった。

Python3.6
Ubuntu18.04 LTSにTensorflow-GPUをインストールしてMNITサンプルを実行する

# はじめに
前提条件
・本記事は[前記事](https://qiita.com/riv/items/3aad5be4e255d27de151)の続き
・[前記事](https://qiita.com/riv/items/3aad5be4e255d27de151)にて、GTX1080tiを搭載したPCに、DUCAとcuDNNをインストール済み
今回やること
・Tensorflow-GPUをインストールして、MNISTのサンプルを実行してみる

バージョン
・DUCA9.0
・cuDNN7.4.1
・Tensorflow1.12.0
※Tensorflow-gpuのサポートが、現状ではCUDA9/cuDNN7までであったため
　参考：https://www.tensorflow.org/install/source#common_installation_problems

# Tensorflow-GPUのインストール手順
それでは、[前記事](https://qiita.com/riv/items/3aad5be4e255d27de151)にてインストールしたCUDAとcuDNNの動作確認として、Tensorflow-GPUでMNISTのサンプルを実行してみたいと思います。
まずはTensorflow-GPUのインストールからです。

## pipのインストール
手始めに、pipとpip3をインストールしておきます。

```
sudo apt-get install python-pip python3-pip
```

## libcupti-devのインストール
どうやらlibcuptiなるものが必要らしいので、これもインストールしておきます。

```
sudo apt-get install libcupti-dev
```

## 仮想環境の構築
venvを使用して、Tensorflow-GPU用の仮想環境を構築します。
ここにTensorflow-GPUをインストールしていきます。

基本は以下のコマンドでOKです。
※この場合はnameという名前のPython3系環境を構築しています。

```
python3 -m venv <name> 
```

activateは以下のコマンドで行います。

```
. <name>/bin/activate
```

deactivateは以下のコマンドです。

```
deactivate
```

## Tensorflow-GPUのインストール
先ほど作成した仮想環境に入り、Tensorflow-GPUをインストールします。

```
. <name>/bin/activate

pip3 install tensorflow-gpu
```

※途中で「Failed building wheel for ...」なるものが出ましたが、最後は「Successfully」したみたいなので、何とかインストールできたっぽい？（ちなみにsudoだと何も出なかったはず、、、）

インストールできたかどうか、importして確認します。

```
python

import tensorflow
```

エラーが表示されなければインストール成功です。

## Tensorflow-GPUでGPUが反映されているかチェック

ついでに、GPUが上手く反映されているか、下記のコードを実行することで確認をしてみましょう。

```
import tensorflow
tensorflow.test.gpu_device_name()
```

最後の方に「'/device:GPU:0'」が表示されればOKのようです。

また、別の方法として、以下のコードでも検証できます。
参考：https://qiita.com/sabaku20XX/items/7c9a04fdffecee27f163

```
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```

「device_type: "GPU"」があればOKのようです。（CPUだけだとアウト。）

# MNISTサンプルの実行手順
次に、Tensorflow-GPU環境下で、tensorflowのMNISTサンプルを実行してみます。

## Gitのインストール
tensorflowのMNISTサンプルはGitHubのリポジトリから取得してきます。
よって、Gitがインストールされていない場合、下記コマンドでインストールしておきます。

```
sudo apt-get install git
```

## GitHubからtensorflowをClone
GitHubより、tensorflowのリポジトリをCloneしてきます。

```
git clone https://github.com/tensorflow/tensorflow.git
```

## MNISTサンプルのコードを実行
MNISTサンプルがある場所まで移動し、プログラムを実行します。

```
cd tensorflow/tensorflow/examples/tutorials/mnist
python mnist_with_summaries.py
```

ここで、自分の環境だと下記のようなエラーが出て止まってしまいました。

```
Couldn't open CUDA library libcupti.so.9.0 ...
```

どうやら先ほどインストールしたlibcuptiが上手く参照できていないようなので、下記サイトを参考にパスを通します。（.bashrcの$LD_LIBRARY_PATHを以下のように書き換えます。）
参考：http://hirotaka-hachiya.hatenablog.com/entry/2017/02/28/223844

```
export $LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:/usr/local/cuda-9.0/extras/CUPTI/lib64$LD_LIBRARY_PATH
```

※本来はlib64と$の間に:を入れるべきなはずですが、下記コマンドでパスを確認したとき、変な場所に:が入っていたため、:をなくすとイイ感じになりました。

```
echo $LD_LIBRARY_PATH
```

以上の方法でパスを通し、再度「mnist_with_summaries.py」を実行すると、エラーで止まらず無事にプログラムが終了しました。

# GPUのパフォーマンスチェック
最後に、GPUのパフォーマンスをチェックするコードを公開されている方がいたため、参考に乗せておきます。
参考：https://www.kaggle.com/getting-started/47096#post271139

このプログラムを実行した結果、CPUよりもGPUの方が速いことが確認できました。


以上で、Tensorflow-GPUのインストールとMNISTサンプルを用いた動作テストは終了です。
お疲れ様でした！
再帰しない竹内関数

bashで竹内関数( https://qiita.com/nihongi/items/21a4a215920150ef7eb8 )の続きです。

## ジョブの定義
スタックにジョブを積んでいって上から処理していく方式に変更します。まず、ジョブの形式を定義します。

```
job[0]: 第一パラメータの数値、未定の場合は"x"
job[1]: 第二パラメータの数値、未定の場合は"y"
job[2]: 第三パラメータの数値、未定の場合は"z"
job[3]: taraiの計算結果の数値、未定の場合は"r"
job[4]: 計算結果rの代入先のjob(スタックの何番目か)
job[5]: 計算結果rの代入先("x", "y", "z", "r")
```
処理の手順は次の通りです。

* スタックからjobを取り出す
  * rが計算済みの場合
      * これが最初のjobであれば終了
      * そうでなければ、計算結果の代入先に代入する
  * rが計算済みでない場合
      * rがすぐに計算可能か(すなわちx<=yか)→yes
          * これが最後のジョブの場合はここで終了
          * そうでなければ、計算結果の代入先にyを代入する
      * rがすぐに計算可能か(すなわちx<=yか)→no
          * jobをスタックに戻す
          * rを計算するための新たなjob(tarai4つ分)をスタックに追加する

要するに、スタックの一番上を処理して、結果が出た場合は、スタックの途中にでも結果を入れていくというスタイルです。

ソースです。

```bash:tarai03.sh
#!/bin/sh
stack[0]="${1} ${2} ${3} r -1 r"

replace() {
  # ${1}番目のスタックの文字${2}を数字${3}に置き換える
  tmp=$(echo ${stack[${1}]} | sed -e s/${2}/${3}/)
  stack[${1}]=${tmp}
}

while true
do
  i=$(( ${#stack[@]} - 1 ))
  job=(${stack[i]})
  unset stack[i]
  echo "${job[0]} ${job[1]} ${job[2]} ${job[3]} ${job[4]} ${job[5]}" >&2
  if [ ${job[3]} = "r" ]; then
    if [ ${job[0]} -le ${job[1]} ]; then
      if [ ${i} -eq 0 ]; then
        echo ${job[1]}
        break
      fi
      replace ${job[4]} ${job[5]} ${job[1]}
    else
      stack[i]="${job[0]} ${job[1]} ${job[2]} ${job[3]} ${job[4]} ${job[5]}"
      stack[i+1]="x y z r ${i} r"
      stack[i+2]="$(( ${job[0]} - 1 )) ${job[1]} ${job[2]} r $(( ${i} + 1 )) x"
      stack[i+3]="$(( ${job[1]} - 1 )) ${job[2]} ${job[0]} r $(( ${i} + 1 )) y"
      stack[i+4]="$(( ${job[2]} - 1 )) ${job[0]} ${job[1]} r $(( ${i} + 1 )) z"
    fi
  else
    if [ ${job[4]} -eq -1 ]; then
      echo ${job[3]}
      break
    else
      replace ${job[4]} ${job[5]} ${job[3]}
    fi
  fi
done
```
これで処理が速くなったか試してみます。
まず、通常の再帰版

```console
$ time sh tarai02.sh 8 4 0 2>/dev/null
8

real    0m7.462s
user    0m4.598s
sys     0m2.849s
```
通常版は7.5秒くらいでした。次に今回のスタック版

```console
$ time sh tarai03.sh 8 4 0 2>/dev/null
8

real    0m22.137s
user    0m14.284s
sys     0m7.808s
```
22秒？ あれ？

次回、竹内関数のキャッシュと遅延評価をお楽しみに。