OmniAICreator/Qiita-1.07M huggingface dataset:
駆け出しのエンジニアの頃、僕は人より10倍も速いスピードで、プログラミングしようと思っていた

# だけど実際には、人よりも10倍も遅かった。

手を動かすスピードじゃなくて、コミュニケーションの方法がまずかったり、要件定義の問題で、恐ろしいほどの手戻りが発生したりしていたのだ。

今でも、自分が思う理想よりも3分の1ぐらいのことしか、実際にはできないのだと、心を決めている。

実際にそうなのだから。

# だがそれでも、仕事はちゃんと回っているようだ。

エンジニアの仕事は、本当に、わずかずつの、パズルの組み合わせであり、ピースさえうまくはまえれば、最小限の力で、最大限の力を出すことが出来るんだよな。

# Links

- [いなうらゆうまはここにいた 2019-03-19](https://github.com/YumaInaura/YumaInaura/issues/817#s1552993205)

# ja

駆け出しのエンジニアの頃、僕は人より10倍も速いスピードで、プログラミングしようと思っていた。だけど実際には、人よりも10倍も遅かった。手を動かすスピードじゃなくて、コミュニケーションの方法がまずかったり、要件定義の問題で、恐ろしいほどの手戻りが発生したりしていたのだ。今でも、自分が思う理想よりも3分の1ぐらいのことしか、実際にはできないのだと、心を決めている。実際にそうなのだから。だがそれでも、仕事はちゃんと回っているようだ。エンジニアの仕事は、本当に、わずかずつの、パズルの組み合わせであり、ピースさえうまくはまえれば、最小限の力で、最大限の力を出すことが出来るんだよな。

- [Twitter](https://twitter.com/YumaInaura/status/1107959945536913410)

# en

When I was a rush engineer, I was thinking of programming at a speed 10 times faster than people. But in fact, it was ten times slower than people. It wasn't the speed at which we moved our hands, but the way we communicate was poor, and the problem of defining requirements caused a horrible return. Even now, I have decided that I can only actually do one third of the ideal I think. That's really it. But still, it seems that my job is working properly. The engineer's job is really just a combination of puzzles, and if the pieces get well, I can do my best with minimal power.

# tw

當我是一名急忙的工程師時，我想要的編程速度比人快10倍。但事實上，它比人慢十倍。這不是我們動手的速度，但我們溝通的方式很差，定義要求的問題導致了可怕的回報。即使是現在，我已經決定我實際上只能實現理想的三分之一。真的是這樣的。但是，似乎我的工作正常。工程師的工作實際上只是謎題的組合，如果這些部分能夠順利完成，我可以用最小的力量做到最好。

# hi

जब मैं एक भीड़ इंजीनियर था, तो मैं लोगों की तुलना में 10 गुना तेज गति से प्रोग्रामिंग करने की सोच रहा था। लेकिन वास्तव में, यह लोगों की तुलना में दस गुना धीमा था। यह वह गति नहीं थी जिस पर हम अपने हाथों को आगे बढ़ाते थे, लेकिन जिस तरह से हम संवाद करते थे वह खराब था, और आवश्यकताओं को परिभाषित करने की समस्या ने एक भयानक वापसी का कारण बना। अब भी, मैंने फैसला किया है कि मैं वास्तव में केवल एक तिहाई ही कर सकता हूं जो मुझे लगता है कि आदर्श है। वाकई ऐसा है। लेकिन फिर भी, ऐसा लगता है कि मेरा काम ठीक से काम कर रहा है। इंजीनियर की नौकरी वास्तव में पहेली का एक संयोजन है, और यदि टुकड़े ठीक हो जाते हैं, तो मैं न्यूनतम शक्ति के साथ अपना सर्वश्रेष्ठ प्रदर्शन कर सकता हूं।

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Ruby 2.6.2 / Rails 5.2.2 / mongodb でセットアップした結果

# 何故 mongodb :thinking: 

引き継ぎ案件だからだよ :angry: 
せっかくなので最新の Ruby / Rails に触れようということでセットアップしていきます。

## Ruby
```console
$ rbenv install 2.6.2
```

## Rails
```console
$ mkdir project
$ cd project
$ bundle init
$ bundle install --path vendor/bundle
$ bundle exec rails new . --skip-bundle --skip-active-record
```

## MongoDB

### 設定ファイルをジェネレート
```console
$ bundle exec rails g mongoid:config
```

### DockerComposeの設定
```console
$ vim docker-compose.yml
```

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

networks:
  bridge:
    driver: bridge

services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    environment:
      -  'MONGODB_USER=root'
      -  'MONGODB_PASS=password'
    volumes:
      - 'mongodb-data:/data/db'
    ports:
      - '27017:27017'
    command: mongod --smallfiles
  mongo-express:
    container_name: mongo-express
    links:
      - 'mongodb:mongo'
    ports:
      - '8081:8081'
    environment:
      - 'ME_CONFIG_OPTIONS_EDITORTHEME=ambiance'
      - 'ME_CONFIG_BASICAUTH_USERNAME=root'
      - 'ME_CONFIG_BASICAUTH_PASSWORD=password'
    image: mongo-express

volumes:
  mongodb-data: {}
```

```console
$ docker-compose up -d
```

これで http://localhost:8081/ へアクセスすると以下のような画面が開きます。
<img width="1326" alt="mongo_express.png" src="https://qiita-image-store.s3.amazonaws.com/0/45540/42d66ec6-96ce-fe00-d112-0c8f7abc2850.png">

あとは適当にデータベースを選んで、 `Import` からbsonをインポートすればすぐ使えます。
これは非常に便利かつ優しいインターフェイスでした。 :clap: 

### Railsのジェネレータをmongoidに変更
```console
$ vim config/application.rb
```

```ruby:config/application.rb
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    config.generators do |g|
      g.orm :mongoid
    end
  end
```

## コレクション名がRailsの命名規約に則っていない場合
やんごとなき理由により、バックアップ等からデータを復元してそのまま使う場合、
コレクション名がキャメルケースだったり単数形だったりしてモデルからコレクション名を指定したいニーズが出てきます。

そんな時は `store_in` を使いましょう。(mongoid 7.0.2)

```ruby:app/models/image.rb
class Image
  include Mongoid::Document
  store_in collection: 'Image'

  field :original, type: String
  field :large, type: String
  field :medium, type: String
  field :small, type: String
end
```

## DockerからMongoにつなぎたいという時のTips 
```console
$ docker-compose exec mongodb bash

root@c01225e4e2b6:/# mongo admin
MongoDB shell version v4.0.6

> show dbs
admin           0.000GB
hogehogehogeho  0.042GB
config          0.000GB
local           0.000GB
```

## 最後に
簡単ですが、これでモデルを利用できるようになりました。
あとはコントローラやビューを組み込むだけで動きそうです。

MongoDBを使うぐらいなんで、そこまで大きなプロジェクトではないと思います。
https://getbootstrap.com/ を使うとさくっと体裁を整えられて良いですね。
プログラミング学習記録31〜ログイン機能を作成してみた〜

##今日やったこと
- Progate rails8

今日やったProgate railsのセクション8では以下の機能を作成しました。

- ログイン機能
- ログアウト機能
- ログインしているユーザ名の表示
- ログインしているかどうかでアクセス制限する
- ログインしているユーザーの情報のみ編集できるようにする

ログイン関係の機能を一通り実装してみました。

やることは意外と多かったのですが、一つ一つはそこまで難しくなかったです。

ただ単にログイン機能をつけるだけだとログインしてなくてもアクセスできてしまうので、
> ログインしているかどうかでアクセス制限する
ログインしているユーザーの情報のみ編集できるようにする

この２つもしっかり考える必要があることがわかりました。

とりあえずProgate railsの１番の山場は超えれたと思います。

最後までこの調子で頑張りたいと思います。

ということで、明日からも引き続きプログラミング学習頑張ります。

おわり
爆速なページ見つけたから見てみた

# きっかけ

爆速で有名な阿部寛さんのホームページがありますが
こんなのを見つけた。

<blockquote class="twitter-tweet" lang="ja"><p>爆速なサイト
1位:星のカービィ3 31㍉秒
2位:エロゲーブランドZERO 35㍉秒
3位:阿部寛のホームページ 41㍉秒</p>&mdash; (@CTSKRSYM_KO
) <a href="https://twitter.com/CTSKRSYM_KO/status/1107968233552805888">2019/02/19</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


一位と書いてある**星のカービィ3**(https://www.nintendo.co.jp/n02/shvc/afjj/ ) を見てみました

# ChromeでF12→Networkを見てみた
![スクリーンショット (82).png](https://qiita-image-store.s3.amazonaws.com/0/334791/ab7f79af-ae36-f00f-46f5-56d6381db59e.png)


**（↓画像キャッシュ込み）**
![スクリーンショット (81).png](https://qiita-image-store.s3.amazonaws.com/0/334791/9e697c1c-578c-87b1-9064-1ad5234fffad.png)

はやい。

##考えた
**画像が全部Gif形式で使用されている。**
→jpegなどより速い

**JSを読み込んでない**
→はやい

**CSSがない**
→はやい

**任天堂ってことは**
→多分サーバー強い
　  


**めっちゃ要件そろってた**

#他には？

いろいろあるらしい
https://www.nintendo.co.jp/n02/dmg/
https://www.nintendo.co.jp/n02/dmg/kkkj/index.html
http://zero.product.co.jp/
'. test.sh'と'sh test.sh'と'./test.sh'の違い

[getoptsを関数（function）の中で使う](
https://qiita.com/macoril/items/ecc3e73f7dc130f3efff)に関連して。

- `. test.sh` (= `source test.sh`)
- `sh test.sh`
- `./test.sh`

とシェルスクリプトを実行する方法は複数あるが、
状況によっては異なる結果になる。

`sh test.sh` `./test.sh` に違いがあるかなどよくわかっていないところが多いので追って詳細について記載したい。

# TL;DR

- `. test.sh` で実行した場合
    - 変数はシェル変数として扱われ、使用する変数がシェル変数として設定済みであれば影響を受ける
    - シェル変数が設定されていない状態で実行した後には、シェル変数が設定された状態になる
- `sh test.sh` `./test.sh` で実行した場合
    - localで宣言していなくても変数はシェル変数として扱われない

# 検証に使用したコード

[getoptsを関数（function）の中で使う](
https://qiita.com/macoril/items/ecc3e73f7dc130f3efff)
の冒頭に記載のコード（local宣言していないほう）を
`test.sh`として作成し実行権限をつける

# 検証結果

```sh:実行結果
$ sh test.sh -i 16 -o 10 A
10
$ sh test.sh -i 16 -o 8 A
12
$ sh test.sh -i 8 -o 10 16
14
$ set | egrep "^OPT|^input|^output"
$ ./test.sh -i 16 -o 10 A
10
$ ./test.sh -i 16 -o 8 A
12
$ ./test.sh -i 8 -o 10 16
14
$ set | egrep "^OPT|^input|^output"
$ . test.sh -i 16 -o 10 A
10
$ . test.sh -i 16 -o 8 A
10
$ . test.sh -i 8 -o 10 16
22
$ set | egrep "^OPT|^input|^output"
OPT='?'
OPTERR=1
OPTIND=5
input=16
output=10
```
windowsでxgboostをビルドし python用パッケージをインストールする方法（メモ）

公式ドキュメント：
https://xgboost.readthedocs.io/en/latest/build.html#building-on-windows

# 前提
* Windows 10 1803
* Visual Studio Build Tools 2017 インストール済
    * https://visualstudio.microsoft.com/ja/downloads
    * Visual C++ コンパイラのインストール用
* Cmake インストール済
    * https://cmake.org/
    * コンパイル用

# 必要なファイルを git リポジトリからコピー
```bash
>git clone --recursive http://github.com/dmlc/xgboost
```

ドキュメントには以下のコマンドを実行せよ とありますが、--recursive オプションをつけて clone した場合は裏で勝手に実行されているらしい。

```bash
>git submodule init
>git submodule update
```

# CMake で xgboost.sln の生成
以下は root 権限で実行するとのこと。
（Windows の場合、管理者権限ならOKかな？）

```bash
>cd xgboost
>mkdir build
>cd build
>cmake .. -G"Visual Studio 15 2017 Win64"
```
成功すると、build フォルダ内に xgboost.sln が生成されます。

# xgboost.sln をビルド
Visual Studio Build Tools 2017 インストール済みだと、スタートメニューに __開発者コマンド プロンプト for VS 2017__ というアプリケーションが追加されているはず。。

__開発者コマンド プロンプト for VS 2017__ を起動し、先の build フォルダに移動しておきます。

MSBuild コマンド で xgboost.sln をビルド。

```bash
>MSBuild xgboost.sln
```

以下のようなログが流れてくるはず。

```
.NET Framework 向け Microsoft (R) Build Engine バージョン 15.8.169+g1ccb72aefa
Copyright (C) Microsoft Corporation.All rights reserved.

このソリューション内のプロジェクトを 1 度に 1 つずつビルドします。並行ビルドを有効にするには、"/m" スイッチを追加してく ださい。
2019/03/19 19:52:03 にビルドを開始しました。
ノード 1 上のプロジェクト "E:\src\xgboost\build\xgboost.sln" (既定のターゲット)。
ValidateSolutionConfiguration:
  ソリューション構成 "Release|x64" をビルドしています。
```
※私の環境では、E:\src 配下で xgboost を clone したので、``` E:\src\xgboost\build\xgboost.sln ``` がターゲットになっています。

ビルドに成功すると、xgboost/lib ディレクトリに xgboost.dll が生成されます。

# python用 xgboost パッケージのインストール
xgboost ディレクトリ内の python-package ディレクトリに setup.py というインストール用スクリプトがあるので、これを使う。

## conda を使っていない場合

以下コマンドを実行。

```bash
>python setup.py install
```

## conda 等仮想環境を使っている場合

インストールしたい環境をアクティブにする。

```shell
# conda の例
>conda activate [環境名]

# setup.py の実行
>python setup.py install

# ログが流れる

# インストールされたか確認
>conda list | grep xgboost
xgboost                   0.81                     pypi_0    pypi

>python
Python 3.7.2 (default, Feb 21 2019, 17:35:59) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import xgboost as xgb
>>>
```

問題なくインストールできました。
AWSでセキュリティグループは設定してあるのに ec2にsshログインできないとき

# セキュリティグループは設定してあるのにAWS ec2でsshログインできないとき

Ansibleでawsインフラを構築していたらec2にログインできなくなっていました。

再作成をしたりしているうちにルートテーブルが無くなっていたようです。

ルートテーブルはAWSコンソールから以下のように辿っていけます。

VPC-> ルートテーブル

ルートテーブルがなかったり

Routes に 0.0.0.0/0 からインターネットゲイトウェイへのルーティングがないとsshの応答が返って来ないようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284697/3ec9cf3d-2439-242c-be62-8ac2b25123a5.png)
yarn upgradeを行なってunmerged filesで詰まったら

## 何があった？
先ほど社内ライブラリを作っていて、`yarn upgrade`を行いながら作っていたコンポーネントの確認を行なっていました。ふと、もう一度新しく作ったコンポーネントを読み込もうと`yarn upgrade`を叩くと、以下のようにエラーが出てしまったのです。。。

<img width="663" alt="スクリーンショット_2019-03-19_20_01_55.png" src="https://qiita-image-store.s3.amazonaws.com/0/252687/1fb317c8-8733-3a8e-9020-eef74530e275.png">

## 原因
どうやら、yarnのlockfileで向いていたブランチで、commitのforce pushを行なったことにより、追跡していたSHAが判定できなくなったのが原因のようです。

確かに、私も先ほど`git commit -f origin master`のようにforce pushをした記憶があります。。やらかした。。。

## 解決方法
参考記事を元に、 yarnのキャッシュを消したらうまく直りましたので、ご安心を。日本語で調べてもあまりなかったので、ご参考までに。

キャッシュフォルダーである`/Users/あなた/Library/Caches/Yarn/v4/.tmp/ぶらぶらぶらぶら`を消せとか色々書かれていますが、手っ取り早いのは、これでした。

``` terminal
yarn cache clean
```

はい、完了。yarnのキャッシュを全部消してしまえばいいとのことです。


## 参考
* [Yarn fails to install](https://github.com/yarnpkg/yarn/issues/3303)
* [How to clear cache in Yarn?](https://stackoverflow.com/questions/39991508/how-to-clear-cache-in-yarn)
VScodeでMVN, Tomcat, JSP/ServletでWebアプリ開発メモ


# 準備
- Javaとmavenをインストール(https://qiita.com/amemolee/items/6f33b8e321cc9395b0cf)
- [Tomcat for Java](https://marketplace.visualstudio.com/items?itemName=adashen.vscode-tomcat) プラグインをVScodeにインストール
- TomcatをDLする(http://tomcat.apache.org/) ※お使いの環境によってTomcatのバージョンを選択して下さい

## Tomcatを任意のディレクトリに配置する
TomcatをDLしたら、zipを解凍し任意のディレクトリに配置する。
macOSならApplications配下に配置するのがよさそう。

## vscodeのプロジェクトにDLしたTomcatを指定する
Tomcat for Javaプラグインをインストールした後
Command + Pを押下し `>Add Tomcat Server`と入力後、Enter。
Tomcatが配置されているディレクトリを選択する。

# 実行
`pom.xml`がプロジェクトルートに生成されていることを確認し、プロジェクトのルートで下記を実行

```
mvn install
mvn compile
mvn package
```

.warファイルが生成されたことを確認する。

VSCode上で、Command + Pを押下し `>Tomcat: Runon Tomcat Server` と入力し、Enter。
warファイルを選択する。
warファイルを参照して、Tomcatが立ち上がる。

デフォルトの設定であれば、localhost:8080に立ち上がります。

http://localhost:8080
にアクセスして以下の画面が確認できます。

<img width="1427" alt="スクリーンショット 2019-03-21 0.13.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/32950/734c09a6-79d6-b81a-c760-f6aac3447439.png">


## FAQ
### .jarファイルが見つからないなどのエラーが発生する
- パスを確認する
- 一度、mvn installを行っている場合は、`mvn clean` を実行し、再度、`mvn install` を行う
    - mvn installを行うとpom.xmlで実行した内容をキャッシュする仕組みになっているようです

# TODO
0ベースからmvn、JSP/Servletのプロジェクトを作成する方法は後日書きます！
jmxファイルのダブルクリックでJMeterを起動したい

# はじめに
Windows10での手順です。

# 手順
* .jmxを右クリックし、プロパティを選択

* 変更をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/68254/7a54fb07-2280-778c-2788-b0c67f1a4fca.png)

* このPCで別のアプリを探すをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/68254/2adc2537-ca62-1eb5-b88c-d922929bf972.png)
* jmeterインストール先のbinのフォルダにあるjmeter-t.cmdを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/68254/2b18a977-aa4a-31e0-4910-617ff64a0dd5.png)

* これで次回から、jmxファイルのダブルクリックで、Jmeterが起動します

# Windows7の場合

* jmeter-t.cmdをjmeter-t.batにコピーする。
* windows10と同様の手順で、プログラム選択時にjmeter-t.batを選択する。
railsのキホンvol.11（パスワードの安全性、bcrypt）

##パスワードの安全性を高める

データベースにパスワードをそのまま保存すると万が一の場合があるので、パスワードを暗号化する必要がある。
###gem（ジェム）
gemとはrubyやrailsでプログラミングをする際に「よく使う機能」をパッケージ化したもの。
その中でも今回は、```bcrypt```という「暗号化するためのgem」を使う。

###Gemfile
railsにはインストールしたいgemを記述するGemfileがある。

```Gemfile
gem 'bcrypt'
```

という風にGemfileに記述し、コンソールで以下のコマンドを打つ。

```
$ bundle install
```

bcryptをインストールすると、```has_secure_passwoerd```というメソッドが使えるようになるので、パスワードを扱うモデルにこのメソッドを記述することで自動的にパスワードを暗号化するようになる。

```models/user.rb
class User < ApplicationRecord
  has_secure_password
  ...
end
```

###password_digestカラム
has_secure_passwordメソッドは暗号化したパスワードを```password_digestカラム```に保存する。
現在はパスワードをpasswordカラムに保存しているので、```passwordカラム```を```password_digest```に変更する必要がある。
マイグレーションファイルを作成。

```
$ rails g migration change_users_columns
```
マイグレーションファイルを編集。

```change_users_columns.rb
class ChangeUsersColumns < ActiveRecord::Migration[5.0]
  def change
    add_column :users,:password_digest,:string
    remove_column :users,:password,:string
  end
end
```
データベース更新。

 ```
$ rails db:migrate
```

password_digestカラムに暗号化されたパスワードを保存するためには、今まで通りpasswordに値を代入する。
こうすることで、has_secure_passwordによってpasswordに代入された値が暗号化され、password_digestカラムに保存される。
このため、既にあるpasswordに関するコードを変更する必要はなし。

###暗号化されたパスワードを用いたログイン

まず、フォームに入力されたメールアドレスに一致するユーザーを取得する。
その次にフォームに入力されたパスワードと取得したユーザーのパスワードが一致するか判定する。

といった流れになる。

```users_controller.rb
def ligin
  #フォームに入力されたメールアドレスに一致するユーザーを取得
  @user = User.find_by(:email params[:email])
  #フォームに入力されたパスワードと取得したユーザーのパスワードが一致するか判定
  if @user && @user.authenticate(params[:password])
  ..
  end
end
```

###authenticateメソッド
has_secure_passwordメソッドを有効にすると、authenticateメソッドが使用可能になる。
authenticateメソッドは渡された引数を暗号化し、password_digestの値と一致するかどうかを判定する。
【Github】ブランチ切り忘れて作業してしまった時の対処法

Github使って初めて開発練習！

完了したブランチ（create-database)をマージしないまま、
そのブランチ上で次の実装(indexビューの作成)を行ってしまった。。
かつ、コミット→pushまでしてしまい愕然。。

そこで！
きちんとした手順、ブランチになるよう修正した方法のMEMO:ok_hand:

# pushしてしまったコミットを取り消す
### STEP 1 
######create-databaseブランチ上で出してしまった、関係ないビュー作成のコミットを削除


`git reset --soft HEAD^`

ターミナルでこのコマンドを打つことで、直前のコミットを打ち消すことができる！
`--soft`とすることで変更した内容自体は取り消さず残したままになる。
`--hard`にすると変更した内容も取り消すことになり、編集した内容が飛ぶことに・・:warning:

✔︎ `git log`でコミットの履歴を確認して、不要なコミットの分上記コマンドを繰り返す。
<img src="https://www.evernote.com/l/AFI7wqWtTeZInbZvSi6TsMWLedvQPUajciwB/image.png" alt="chat-space%20%E2%80%94%20-bash%20%E2%80%94%20204%C3%9762" />

### STEP 2

LGTMが出た段階まで戻せたのでcreate-databaseブランチをmergeする。

### STEP 3

###### 新しいブランチを作成し、コミットの変更を引き継ぐ
今のままだとcreate-databaseブランチ上に未コミットの変更が乗っかってる状態。
そこで、まず新しくcreate-index-viewブランチを作成してPR！

こっちのブランチに変更を移すにはどうしたらいい？って時はこのコマンド。
`git stash`

これで、未コミットの変更履歴を一時退避BOXみたいなものに
一旦退避させることができる。
＊スタッシュ機能と呼ぶ

✔︎ `git stash`コマンドはデフォルトではgit管理しているファイルのみが退避されるので、新規で作成したコミット前のファイルがある場合はstashの対象になりません。
新規作成したファイルもstaｓｈに含めたい場合は
`git stash -u`としましょう

そしたら、移動先のcreate-index-viewブランチに切り替えて・・・
`git stash apply`（stashに残る）
`git stash pop`　（applyした後stashから削除する）

これで、一時BOXに移しておいた未コミットの変更履歴が
現在選択されているcreate-index-viewブランチに追加されたよ！:clap:

***
##### 参考
[Qiita](https://qiita.com/muran001/items/dea2bbbaea1260098051#%E3%82%84%E3%82%89%E3%81%8B%E3%81%97%EF%BC%91%EF%BC%92%E3%81%86%E3%81%A3%E3%81%8B%E3%82%8A%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%81%91%E3%81%A9%E5%85%83%E3%81%AB%E6%88%BB%E3%81%97%E3%81%9F%E3%81%84%E6%99%82 "Gitでやらかした時に使える19個の奥義")
http://vatscy.github.io/blog/2014/03/30/git-branch-stash/
https://reasonable-code.com/git-push-cancel/
photon boltにphoton voice2を入れたら死んだ時の直し方

#先まとめ
・bolt入れ直した

#壊し方
・boltが動く状態でphotonVoice2を入れる

#症状
・boltのサーバ側は動くが、クライアント側がロードバランサ叩くあたりで止まる
・photonvoice2は動く

#対処
・bolt再インポート→意味なし
・photonだけ消す→意味なし
・アセットストアからbolt再インポート→セッティング消えたのでappid再入力→再コンパイルしてビルド
→治った。

・photonvoice2は一旦諦める。
kube-reservedとかsystem-reservedって結局どう設定すればいいんだ

kubernetesクラスタを運用する時、nodeにシステムのリソースを確保していますか？
私は全く気にしていませんでした、そして<a href="https://qiita.com/masahata/items/84e541e29cc46de65b9e">ちょっとした問題</a>になりました。
そこでこのためのオプション`kube-reserved`と`system-reserved`をサクッと設定して平和に…
でも余分に割り振ったらリソースもったいないし、少なすぎたらやる意味ないし、適切な値を…
なんて考えてたら完全理解に時間がかかったのでざくざくまとめておきます。


## 参考ドキュメント
https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md

## 理解したこと
- `kube-reserved`と`system-reserved`の2種類がある
- `kube-reserved`はdockerやkubeletなどのkubernetesを動作させるのに必要なservice、`system-reserved`はsshdやudevなどのOS系のserviceのリソースをそれぞれ確保するのに使う
    - といってもそれらのserviceを勝手に見分けてくれるスゴい奴などではなく、cgroupで指定するのでそれらのcgroupを把握するなり変更するなりその辺の事前準備は必要
        - 後述する「ゆるい制限」なら特に必要ない
    - podで動作しているものは`kube-reserved`扱いっぽいやつでも入らない（cgroupを他のpodと別にできないので無理）
        - kube-apiserverとかをpodで動かしてる場合など
- `--kube-reserved`で確保するリソースの量を指定して、`--kube-reserved-cgroup`でそれを適用するcgroupのグループを指定する
    - `system-reserved`も同じ
    - cgroupをマニュアルで指定するなら両者に本質的な違いはない？
- node全体のリソースから`kube-reserved`と`system-reserved`のぶんを引いたものがpodで使えるリソースになる
- `enforce-node-allocatable`で`kube-reserved`と`system-reserved`を指定することにより、指定したリソースの量をlimitにすることができる
    - これを付けない場合は`--kube-reserved`や`--system-reserved`で指定した値をpodが使えるリソース量から引くだけの比較的ゆるい制限になる
        - ので、両方指定する意味はなくなって、足した数値を片方に集めるのと同じことになる
        - 個人的にはここまでやらなくていいかなという感想
- `eviction-hard`はnode全体のリソースにかかる
- ユーザーログインに使うリソースをsystem-reservedに含めるのをめっちゃ勧めてるけどこれを/user.sliceから動かす方法がわからない
- cgroup-driverはよくわからなかった
- __使用するリソース量は環境に依るのでどのくらいの値が適切かは各々が調べる必要がある__

## 数値を決める

`多すぎ => もったいない`
`少なすぎ => 意味ない`

です

キャパシティに関してはこの記事
https://kubernetes.io/blog/2016/11/visualize-kubelet-performance-with-node-dashboard/
を参考にするといいらしいのですが、benchmarkのページも含め何が何やらさっぱりでした。
なのでこれは置いといて、別のやり方で決めます。

`systemd-cgtop`コマンドを使えばcgroupごとのリソース消費を見ることができます。
が、ずっと眺めてるわけにもいかないのでメトリクスを取得するのがよいでしょう。
cadvisorのメトリクス`container_memory_usage_bytes`と`container_cpu_usage_seconds_total`が、idというlabelでcgroupごとのメトリクスを取得しているようなのでこれを参考にします。
これらのメトリクスをいい感じにまとめると…
![スクリーンショット 2019-03-19 15.21.31.png](https://qiita-image-store.s3.amazonaws.com/0/122084/11a1c2fe-ac6a-5eca-3561-3382631d4b88.png)
なんとなく見えてきました。
cpuは素直にこのままでいいと思いますが、メモリは必要に応じて開放できる余地がありそうなのでその辺りを考慮する必要がありそうです。

## 備考
メモリの制限は直感的に数字通り動くのでわかりやすかったですが、cpuの制限が少しわかりにくかったです。
それぞれ設定された値をもとに各cgroupのcpu.sharesは設定されており、cpu.cfs_quota_usは設定されておらず、つまり相対的な制限となっています。
コア1つに対して100mを設定したら絶対に10%が上限になるわけではなくて、他でcpuを使っていなければもっとたくさん使うということです。
manifestでlimitsでなくrequestsを設定するイメージと考えるとわかりやすいかと思います。（このイメージだとメモリはlimits…紛らわしい…）
わざとなのかそうでないのかわかりませんが、値の設定にはその辺りも頭に入れておく必要があります。
未経験の学習記録: 1　オブジェクト指向について

### 自己紹介
神奈川県在住２３歳
２０１８年１０月より有料のプログラミングスクールを受講
前職は営業、柔道整復師
[職務経歴書はこちら](https://github.com/Tsubasa070802/Curriculum-vitae/blob/master/Curriculum-vitae.md)

### 投稿目的
- 自身の学習記録（スクール、自己学習等）。
- 就職活動に使用するため。


今回はオブジェクト指向とプログラミングについて学習した内容を記録していこうと思います。
どうぞ温かい目でご覧いなっていただければ幸いです。

## プログラミングとは
- プログラムを作ること。
- プログラムとはコンピューターにわかる言葉でプログラマの意図した通りの順番にコンピューターが動作するようにすること。


## オブジェクト指向型プログラミングとは
- プログラムをモノを組み立てるように表現し、開発を効率化させるために生まれた概念。
- 独立性（カプセル化）、再利用生（継承）、拡張性（ポリモーフィズム）の３つの原則がある。


#### 独立性(カプセル化）
- できるだけ他のプログラムから干渉受けず、干渉を与えないようにする仕組み。
- これにより安全に開発ができ、エラーの特定が容易になった。例: クラス


#### 再利用生（継承）
- 文字通りコードの再利用生を高める考え方。
- 複数ある同じコードを一つの部品として統合し、外部のプログラムで再利用ができるようにした。結果プログラムの変更が容易になった。例: クラスの継承

#### 拡張性（ポリモーフィズム）
- 再利用ができ、かつ自由に改変（抽象化）できる仕組み。
- 重要な部分、共通の部分をまとめ、その後個別に処理を追加したり上書きしたりできる。例: オーバーライド
AWS Lambdaで使うpythonモジュールのzipを作る

AWS Lambdaは便利ですが、pythonモジュールを使うにはamazon linux上でpipしたモジュールが必要になるのでそのZIPファイルの作り方を紹介する。 

### 0 準備：Lambdaのpythonバージョンを確認しておく

```
import subprocess
 
def lambda_handler(event, context):
    cmd = "python -V"
    print(subprocess.check_output(cmd.split()))
```

2019/03/07現在のpython3.6のバージョンは `3.6.8`

### 1. `docker pull  amazonlinux`  でamazonlinuxのイメージファイルを持ってくる

### 2. `docker run -it amazonlinux bin/bash`

###  3. コンテナ内での操作

コンテナ内でやることは下記３つ

- python3.6.8を使えるようにする
- pip で必要モジュールをインストール
- zipで固める

```
yum -y groupinstall 'Development tools'

 yum -y install openssl-devel sqlite-devel
 
mkdir ~/src
cd ~/src
yum -y install wget


wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz

tar zxvf Python-3.6.8.tgz
cd Python-3.6.8

./configure --prefix=$HOME/local/myPython-3.6.8

make
make install

curl -kL https://bootstrap.pypa.io/get-pip.py | python

pip install --upgrade virtualenv

virtualenv --python $HOME/local/myPython-3.6.8/bin/python3.6 $HOME/py368


source $HOME/py368/bin/activate

cd
mkdir python 
cd python
pip install pandas -t .


zip -r modules.zip python
```

タブをもう一枚開いて
`docker ps` でコンテナIDを確認して
`docker cp コンテナID:root/modules.zip modules.zip`
すれば出来上がり！

ZIPはS3に置いてダウンロードして使ったり、軽めのモジュールならlambda_handler.pyと一緒に固めて直接lambdaに放り込むのもアリ。

## 感想

AWS側で主要モジュールぐらいは用意してもよいのでは？
Layerとかで選べて、 scikit learn, pandas, numpyくらいはあったら楽。
ディスク100%対応

## ＜事象＞
Windows Update 後にPCが極端に遅くなった。
【環境：Windows 10】

## ＜原因＞
ディスクアクセス率が100%のまま張り付いていた。
Windows Update 後に生成されたファイルが原因と考えられる。

## ＜対策＞
【C:\Windows\Temp】
配下のファイルをすべて削除して再起動したところ、解消された。
（削除できないファイルがあればスキップする）
最長増加部分列長を二分探索を使わずに高速で求めるお話

##背景
重要ではないので急いでいる方は次の項目へお願いします。
AtCoderという競技プログラミングサイトで初めての競プロを2月から始めました。それで、過去問を片っ端から解いていて[この問題](https://atcoder.jp/contests/abc006/tasks/abc006_4)にぶち当たりました。

**問題概要**

- 数字が書かれたカードが N枚あります。このカードの束（山札）に対して以下の操作が可能です。
- 山札からカードを 1枚抜き取り、任意の場所に挿入する。
- 山札の上から下に向けて、カードを昇順に並べ替えるために必要な、最小の操作回数を求めてください。

**解法**

"無駄な"操作をしなければ、操作しないカードだけを見ると昇順になっているはずである
→　操作しないカードの枚数を最大化すれば、操作するカードは最小になるはず(同じカードに対して2回操作しなければいけないケースはないので)
→ 最長増加部分列の長さを求めて、カードの枚数長さから引けば最小操作回数が求まる！！



##最長増加部分列とは？
- 増加部分列: 数列の部分列で、単調増加に並んでいるもの。
- 最長増加部分列: 増加部分列のうち、一番長さが大きいもの

例えば、{1,3,5,2,4,6}という数列があったら、
{1,3,5,6},{1,3,4,6},{1,2,4,6}はすべて最長増加部分列である

##正しい求め方
**動的計画法(DP)**を用います。
左から数字を見ていって、これまで出てきた数字でk枚の部分列が作れるもののうち、**もっともカードの最大値が小さい部分列の最大値**をdp[k]に格納していきます

太字の部分が分かりづらいと思うのでちょっと説明。
これまで出てきた3枚の部分列が{1,3,4},{1,2,4},{1,2,3}だとすると、

- **もっともカードの最大値が小さい部分列**は{1,2,3}
- **その部分列の最大値**は3なのでdp[3]=3

注)便宜上dp[3]にしてますが実装時はdp[2]に格納してます(気にしなくて大丈夫です)

リストに格納するものの説明は終わりました。
次はどのようにリストを更新していくか。という部分ですが、
二分探索でどこを更新していくかを決めていきます。
しかしここでお話すると本題にいつまで経っても到達できないのでコードだけ載せて飛ばします([こちら](https://qiita.com/python_walker/items/d1e2be789f6e7a0851e5#ここからどうするか)で二分探索の妥当性なども書いてくださっているので)

##本題
[さっき貼ったリンク](https://qiita.com/python_walker/items/d1e2be789f6e7a0851e5#ここからどうするか)でリストdpは単調増加であることが簡単に証明されていますので、それを前提に話を進めていきます。
最初の数字c[0]に対しては必ず、部分列の長さは1で、最大値がc[0]であるので

```python
dp = [c[0]]
```

i枚目の数字に対して、リストdpを更新していくときに、二分探索だと次のように書きます

```python
from bisect import bisect_left
for i in range(1, N):
    # dpの最後の要素よりc[i]が大きいならc[i]を最後に付けて、一つ大きい部分列になる
    if c[i] > dp[-1]:
        dp.append(c[i])
    # そうじゃないなら、c[i]より大きいのと小さいのの間のところにいれる(大きいのを上書き)
    else:
        dp[bisect_left(dp, c[i])] = c[i]
```

これはそうなのですが、自分は~~これが思いつかずに~~リストdpの後ろから見ていって、dp[j]<c[i]ならばj枚からなる部分列の後ろにc[i]をつけてj+1枚の部分列ができるやん！それでc[i]<dp[j+1]ならdp[j+1]を更新すればよいのでは？！と思いつきました~~(天才なので)~~

```python
for j in reversed(range(len(dp))):
        if dp[j] < c[i]:
            if j + 1 == len(dp):
                dp.append(c[i])
            else:
                dp[j + 1] = c[i]
            break
    dp[0] = min(dp[0], c[i])
```

まぁ話したいことは以上です。

##本当に高速？

先程も紹介したAtCoderでの[問題](https://atcoder.jp/contests/abc006/tasks/abc006_4)に対して提出したものの実行時間を見てみましょう
![スクリーンショット 2019-03-19 19.12.19.png](https://qiita-image-store.s3.amazonaws.com/0/285348/e28458e1-dd13-2a48-0d54-53a40eca5d01.png)
上が後ろから探索したもの、下が二分探索したものです。
本当です。
[二分探索で提出](https://atcoder.jp/contests/abc006/submissions/4630724)
[本記事のやり方で提出](https://atcoder.jp/contests/abc006/submissions/4630916)
もちろん対照実験なので他の部分のコードは同じです。
なんと、二分探索より速いですね！！！！！

##種明かし

提出がpypyであることから察した方もいらっしゃるかもしれませんが、種明かしをしていきます。
さきほどのソースコードをpython3で提出してみましょう。
![スクリーンショット 2019-03-19 19.18.45.png](https://qiita-image-store.s3.amazonaws.com/0/285348/729093a6-d55f-1917-723b-d20e5e620d1b.png)
上が**本記事**、下が**二分探索**です。
実行時間が桁違いですね。

pythonより基本的に速いとされるpypyでも苦手な処理があるらしくて、たまたま二分探索と同じくらいの時間になったってだけでした！！
いや、実はこの記事書いていて、**本当に高速？**っていう部分で自分も 本当か〜〜？？？って疑って、pythonで再提出してみたんです。そして気づいたという感じなので皆さんを釣りたかったわけではないです。
**どうもずみませんでじだあああああああああああああああ**
PyAthenaJDBCを使ってAthenaからPandasにデータを格納する


#はじめに
分析作業はSQLやらRやらPythonやら色々と使わねばなりませんが、
**最近は何でもPythonで完結させたいんです。**

AWS Athenaからデータを取得するようになりましたので、Pythonで接続してクエリを投げてPandasにデータを格納する方法をまとめてみました。

#必要なもの
- Python（実行時v3.7.2）
- [PyAthenaJDBC](https://pypi.org/project/PyAthenaJDBC/)（実行時v2.0.3）
- jvm.dll（Javaがない場合、[OracleのJREダウンロードページ](https://www.oracle.com/technetwork/java/javase/downloads/index.html)より最新のJavaSEをダウンロードしてゲット）

実行OSはWindows10です。

##セッティング
まず、PyAthenaJDBCライブラリをインストールします。

```
pip install PyAthenaJDBC
```
続いてPythonでの作業に移ります。

#AWSの設定とクエリ実行
```Python:Python
#接続ライブラリ
from pyathenajdbc import connect
from pyathenajdbc.util import as_pandas

#AWS接続
conn = connect(
    access_key='hogehoge_access_key',
    secret_key='hogehoge_secret_key'
    s3_staging_dir='hogehoge_s3_staging_dir',
    region_name='us-hoge-hoge',
    jvm_path='hoge/hoge/jvm.dll') #jvm.dllのpath

#クエリ実行
try:
    with conn.cursor() as cursor:
        cursor.execute("""
        SELECT * FROM hogehoge /*クエリを記入*/
        """)
        dataframe = as_pandas(cursor)
finally:
    conn.close()
```
いかがでしょうか。
しかし、データ取得のたびに何度も接続と切断、クエリ実行を書くのは面倒です。
また、クエリに引数を渡す必要性も当然出てきます。
**そのためもろもろまとめて関数化してみました。**

##関数化してまとめてみる
```Python:Python：データ取得関数
def paq_func(query, arguments):
    import contextlib
    from pyathenajdbc import connect
    from pyathenajdbc.util import as_pandas
    # AWS設定
    conn_setting = {'access_key': 'hogehoge_access_key',
                    'secret_key': 'hogehoge_secret_key',
                    's3_staging_dir': 'hogehoge_s3_staging_dir',
                    'region_name': 'us-hoge-hoge',
                    'jvm_path': "hoge/hoge/jvm.dll"}
    # 接続
    with contextlib.closing(connect(**conn_setting)) as conn:
        with conn.cursor() as cursor:
            cursor.execute("""{}""".format(query), arguments)
            df = as_pandas(cursor)
    return(df)
```
```Python:Python：関数を実行してデータ取得
#実行するクエリ
query = ("""
select
    *
from
    hogehoge
where
    date between %(arg1)s and %(arg2)s
limit 100
""")

#クエリに渡す引数
arguments = {'arg1': arg1, 'arg2': arg2}

#関数実行
test_df = paq_func(query, arguments)
```
もっと簡略化できそうな気もしますが、能力の限界です。

#まとめ
AthenaからさくっとPandasにデータを格納することができるようになりました。
速度面でもっと素早くPandasに格納できる方法がわかりましたら教えてください。
UltiSnips の入力中は、 Deoplete のポップアップを出さないようにする

キーマッピングが衝突するので、無効にした。


```vim:.vimrc
autocmd User UltiSnipsEnterFirstSnippet call deoplete#disable()
autocmd User UltiSnipsExitLastSnippet call deoplete#enable()
```

参考

https://github.com/SirVer/ultisnips/blob/master/doc/UltiSnips.txt#L355
CloudFront の動作を確認してみる

予めWebサーバなどは用意しているものとします。

---
##1.CloudFrontを作成する##

CloudFrontを開き、[Create Distribution]
![スクリーンショット 2019-03-19 18.33.36.png](https://qiita-image-store.s3.amazonaws.com/0/280929/2b7268b8-3953-4aaa-e37a-320e60557fd7.png)

**Step 1: Select delivery method**
Web の [Get Started]
![スクリーンショット 2019-03-19 18.34.57.png](https://qiita-image-store.s3.amazonaws.com/0/280929/551459cb-327b-d0b1-706e-0f7403775563.png)

**Step 2: Create distribution**
今回はテスト目的のため、変更する個所は以下の部分だけにし、後はデフォルトのままにします。

Origin Domain Name に　オリジンのサーバを指定する。（今回この画像ではELBを指定しています。）
![スクリーンショット 2019-03-19 18.40.05.png](https://qiita-image-store.s3.amazonaws.com/0/280929/3dd29533-3c59-874f-1e17-a5ed12518fe8.png)

Minimum TTL、Maximum TTL、Default TTL : 20
![スクリーンショット 2019-03-19 18.40.22.png](https://qiita-image-store.s3.amazonaws.com/0/280929/da48c5f2-b084-04df-6810-dfc960ab5197.png)

##2.表示を確認する##
[Domain Name]を開き、表示されるか確認する。
![スクリーンショット 2019-03-19 18.43.50.png](https://qiita-image-store.s3.amazonaws.com/0/280929/7a8b8380-df26-7fd4-d2c0-4bddd92096b0.png)
↓
![スクリーンショット 2019-03-19 18.46.13.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ddb7301f-7aac-a6f0-df63-bdbb21220756.png)


##3.表示の変化を確認してみる##

Simple Blog2に変更し、TTL20秒後に変更されるか確認してみましょう。

![スクリーンショット 2019-03-19 18.52.23.png](https://qiita-image-store.s3.amazonaws.com/0/280929/cc84d1a5-b41c-557a-9718-5d284465d786.png)


##4.curlコマンドで確認してみる##

```
$ curl -I <http://cloudfrontのドメインネーム/>
```

X-Cache: Miss from cloudfront
　キャッシュがないことがわかる。
![スクリーンショット 2019-03-19 18.58.53.png](https://qiita-image-store.s3.amazonaws.com/0/280929/53a37c1f-f2df-c16f-3fe2-b181092abd59.png)

X-Cache: Hit from cloudfront
　キャッシュがあることがわかる。
![スクリーンショット 2019-03-19 18.58.26.png](https://qiita-image-store.s3.amazonaws.com/0/280929/b9f81c44-171e-e369-fbd9-e8c4e9302ab1.png)



##5.設計のポイント##

- キャッシュTTLのポイント

短すぎるとキャッシュしている意味がなくなる。
長すぎるとサービスのアップデートがあったときに直ぐに反映されなくなる。

- CloudWatchで監視する。

- Popular Objects Report を参考に定期的に設定を見直す。
![スクリーンショット 2019-03-19 19.07.08.png](https://qiita-image-store.s3.amazonaws.com/0/280929/862ec930-800b-f79a-b5e3-6f080b97d85f.png)


##6.料金##

###CloudFront security savings bundle###
簡単に言うと、「前もって利用料を支払う」代わりに AWS の利用料が割引きされるというものです。
[[2021/02/05]CloudFront security savings bundle](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/savings-bundle.html)
UnityでiPhoneXのホームバーを地味にしたいとき

Project Settings を以下のようにすればできた。
<img width="386" alt="スクリーンショット 2019-03-19 18.50.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/141722/33a90809-9ee4-a0fb-d716-894915007441.png">
これでホームバーの表示が地味になります。ただし常時表示です。画面をタップしても目立とうとはしない、控えめないい子です。一度ホームバーあたりをスワイプすると、ホームバーが明るくなります。その状態でホームバーとして機能します。

ここで、 `Hide home button on iPhone X` にチェックを *入れない* のが大事でした。ここにチェックが入っていると、しばらく待つと消えるけど、画面を触ると目立つように戻ってくるホームバーになっちゃいます。

しかし `Defer system gesture on edges` の設定で、これが変わるとは想像もしなかった！
クリップボードにあるイメージを一瞬でモザイク加工する

## はじめに
macのプレビュー機能でモザイク加工ができないので、なんか簡単に秒でできる良い方法がないかとググっていたら見つけたのでメモ！
クリップボードにコピーしたイメージを、モザイク加工して再度クリップボードにコピーするSwiftコードです。

Before|After
---|---
![taiho_rouya.png](https://qiita-image-store.s3.amazonaws.com/0/105093/8212fcdc-188c-77fb-9f2f-e6c0f91d584e.png)|![image.png](https://qiita-image-store.s3.amazonaws.com/0/105093/4bd3c4ed-5a35-bb47-8f4d-5e300567907a.png)


## ①クリップボードにイメージをコピーする
- 全体： `Shift + Ctrl + ⌘ + 3`
- 任意箇所： `Shift + Ctrl + ⌘ + 4`


## ②XcodeでRunする
- もしなければ、AppStoreからXcodeをインストールしてください。
<img width="487" alt="スクリーンショット_2019_03_19_18_25.png" src="https://qiita-image-store.s3.amazonaws.com/0/105093/e3781097-1cd8-6e8c-97f0-e982f0325c51.png">

- macOSのBlankを選択
<img width="717" alt="スクリーンショット_2019_03_19_18_26.png" src="https://qiita-image-store.s3.amazonaws.com/0/105093/bfb3871d-5471-bf2e-53ac-ef496770c296.png">

- 名前と保存先はいつでも使える場所に！

- 以下のコードを貼り付ける

```swift

import Cocoa
import CoreImage

let pb = NSPasteboard.general;
let readData = pb.data(forType: NSPasteboard.PasteboardType.tiff)

if( readData == nil ){
  print("クリップボードへ写真・画像をコピーしてください。")
  exit(1)
}

let filter = CIFilter(name: "CIGaussianBlur")
let cbImage = CIImage(data: readData!)
let mosaic = 10.0; // 数値が大きいほどモザイク強

filter?.setDefaults()
filter?.setValue(cbImage, forKey: "inputImage")
filter?.setValue(mosaic, forKey: "inputRadius")

let outputImage = filter?.outputImage
let cropRect = CGRect(origin: CGPoint(x: 0, y: 0), size: cbImage!.extent.size)
let bmImage = NSBitmapImageRep(ciImage: outputImage!.cropped(to: cropRect))

pb.clearContents();
pb.setData(bmImage.tiffRepresentation!, forType: NSPasteboard.PasteboardType.tiff)

print("完了")
```

<img width="665" alt="モザイク加工_playground.png" src="https://qiita-image-store.s3.amazonaws.com/0/105093/68f86ecd-5f65-fc0f-bd97-5e546a8a01f9.png">

## ③貼り付ける
- `⌘ + V`

## さいごに
- うまくいかなかったらXcode再起動してください。
- エラーしたらfixしてください。
- OSとバージョンで多少記述方法変わります。


## 参考
- [macで画像加工はプレビュー.appで決まり！文字の回転やぼかし(ガウス)加工の方法](http://fanblogs.jp/macyarounanoka/archive/268/0)
Nest.jsのサービスクラスで自分のURLを取得する

NestJSのサービスクラスの中で、稼働しているサーバーのURLを取得したいと調査開始。
こんなの簡単でしょ？と思ったのですが、かなり苦戦したのでメモ。
ただ、私のスキルが追いついていないだけかも知れませんが･･･。

今回は、NestJSが6.0にバージョンアップしましたので、6.0での方法です。

# GraphqlModuleのforRootを修正
GraphQLのforRootモジュールで、contextにrequestを渡すようにします。

```typescript:app.module.ts
@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: [ __dirname + '/graphql/*.graphql' ],
      context: ({ req }) => ({ req }) // ← ここです
    }),
```

# サービスクラスの変更
これでcontextにrequestが渡ってくるので、それを受け取れるようにサービスクラスを修正します。

```typescript:signup.service.ts
import { Injectable, Inject, Scope } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class SignupService {
    constructor(
        @Inject(CONTEXT) private readonly context,
    ) {}
}
```

# contextの利用
contextでrequestが渡ってきます。
使うには、以下のようにすればOKです。

```typescript:signup.service.ts
    // サーバー名を取得する
    private getServerName(): string {
        const urlinfo = new URL(this.context.req.headers.origin);

        let serverName = urlinfo.protocol + '//' + urlinfo.hostname;
        if (urlinfo.port) {
            serverName += ':' + urlinfo.port;
        }

        return serverName;
    }
```

　これで完成。
NestJS6.0登場

調べ物していたら、NestJS6.0がリリースされていた。
まだ、開発の初期段階だし、新しいものが好きだし、えーい、バージョンアップしちゃえ！と勢いだけでやってしまった。
きっと、ちゃんと動かすまでには、相当な苦労が必要なはずだ。
# NestJSのバージョンアップ
package.jsonを見て、「@nestjs/xxxxx」となっているものをアンインストールする。

> npm uninstall @nestjs/common @nestjs/core --save

そして、6.0をインストールする。

> npm install @nestjs/common @nestjs/core --save

あと、@nestjs/cliのバージョンアップも必要

> npm uninstall @nestjs/cli -g
> npm install @nestjs/cli -g

# プロジェクトをビルド
プロジェクトをビルドする。おっ、すんなりいった。

# 実行
実行してみると、想定通り動かない。
どれどれ、エラーを見てみると、「@nestjs/platform-express」がないという事だった。
JavaScript関係にしてみると、随分、親切なメッセージだ。
ますます、NestJS愛が高まる。

> npm install @nestjs/platform-express --save

# 実行、再び
無事に実行できた！
はじめてのC++【21日目】

#はじめに
この二日間ロベールのc++サボってしまったけど、再開します。
アップキャストで躓いたから、今日はアップキャストからもう一度やる。

##ロベールのC++
###07-03 アップキャスト(2回目)

>Streamクラスへのconst参照であるrefを、その派生クラスであるInputStreamクラスオブジェクトであるstreamで初期化している。

前読んだとき、さっぱりわからなかったけど、もう一度読んでみたら意味がわかった！
（ときには休むことも、、、）

Stream（基底）クラスから派生されたInputStreamクラス型のstreamを基底クラスから参照して作られたrefに格納できるってことか。
<img width="590" alt="スクリーンショット 2019-03-19 17.39.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/0497b1c5-4b7a-153c-0de4-0c2c2d464dbe.png">

基底クラスを参照して作られた箱に派生クラス型のオブジェクトを入れると、基底クラスで定義した関数を使いは派生クタラスのオブジェクトを操作できる。

**メリットの例**

```Upcast2.cpp
#include "InputStream2.h"
#include "ArrayStream.h"
#include <iostream>

void Show(const Stream& stream) {
  std::cout << stream.Get() << std::endl;
}

int main(){
  InputStream istream;

  std::cout << " > " << flush;
  istream.Set();
  Show(istream);

  static const double ARRAY[] = {3, -1};
  ArrayStream astream(ARRAY);

  astream.Set();
  Show(astream);
}
```
Show()の引数は基底クラスの参照になっている。アップキャストにより

```cpp

void Show(const InputStream& stream) {
  std::cout << stream.Get() << std::endl;
}
void Show(const ArrayStream& stream) {
  std::cout << stream.Get() << std::endl;
}
```
このように関数をそれぞれ用意しなくてもいいようになった。
私のやる気を削ぎ落としていたアップキャストに勝利！

###07-04 オーバーライドと仮想関数(1)
オーバーライドとは、基底クラスにある関数の定義を派生クラスで変更することができること。定義を上書きするからオーバーライドという名前みたい。
普通にオーバーライドしても、アップキャストするとアップキャスト先のクラスのメンバ関数が呼び出される。
この解決策として、```virtual```を使う。

```cpp
class Stream {
public:
  virtual bool Set();
  //省略
};
```
このように、メンバ関数の宣言にvirtualをつけておくとアップキャストしても本来のクラスのメンバ関数が呼び出される。
virtual付きのメンバ関数を「仮想関数」という。
なお、派生クラスのほうのメンバ関数にvirtualをつけるのはどっちでもいい。

>ある一つの記述stream.Set()などで行われる処理がアップキャストと仮想関数を利用することでstreamの本当の型ごと変更される性質を**ポリモーフィズム**という。
**このポリモーフィズムこそ継承の本領であり、クラスの本領であり、オブジェクト指向の本領である。**

なんかとても大切なことが書いてある気がする。

#終わりに
ロベールの本のクラスが終わったら、アプリ作ってみようかな
ひたすらインプットすることに飽きたので、一度実践で作ってみてわからなかったらロベールに戻ってくることにしよう。
INTO OUTFILE...CHARACTER SETで指定しても文字化けが起こる現象

##発生条件
mariaDBにて、INTO OUTFILE...CHARACTER SETでcsvファイルを落とした時に、csvファイルの先頭行に列タイトルを付けるためにUNIONを用いてcsvファイルを出力する事がある。

・列の先頭に列名を入れるためにUNIONで結合
・結合する列にSUM等の集合関数を用いる
上記2つの条件で列名に文字化けが発生する。

```SAMPLE.sql
SELECT '重量' 
UNION
SELECT SUM(JYURYO)
INTO OUTFILE 'D:\\\SAMPLE.csv'
CHARACTER SET SJIS
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
FROM T_SAMPLE
```

上記のように処理した場合、列タイトル`重量`が文字化けする。
（`T_SAMPLE`のデータは文字化けしない）

で、集合関数である`SUM()`を外すと、文字化けはしない……。

## 確認事項
mariaDBの文字コードの確認

```
show variables like "chara%";
```

結果

| Variable_name          | Value |
|:----------------------:|:-----:|
|character_set_client    |utf8   |
|character_set_connection|utf8   |
|character_set_database  |utf8   |
|character_set_filesystem|binary |
|character_set_results   |utf8   |
|character_set_server    |utf8   |
|character_set_system    |utf8   |

下手に弄ると他に影響しそうなので変更せず。


## 対応策
担当者に平謝りしてタイトルを英字にした。
gitlabからgithubへの移行

# 経緯
プライベートで開発するにあたって、プライベートなリポジトリでソース管理をしたかったのでgitlabを選定
↓
開発途中でMSがgithubをお買い上げする。githubのプライベートリポジトリが無料になる。
↓
slack連携とか便利そう、CircleCIとの親和性よさそう。メジャー所を使ってみよう
↓
gitlabからgithubへ移行しよう。

#やったこと
gitlabのリポジトリからclone、githubのリモートを追加してpush

```
git clone --mirror ssh://git@gitlab.xxx.com/hoge/repository.git
cd repository.git
git remote add --mirror=push github ssh://git@github.com/hoge/repository.git
git push github
```








#おまけ


ローカルブランチが特定のリモートブランチを追跡するように設定

```
# gitlabのリポジトリからクローン
git clone https://gitlab.com/hoge/repository.git repo
cd repo

# githubのリモート追加
git remote add github https://github.com/hoge/repository.git
git fetch github

# リモートの確認
git remote -v

github	https://github.com/hoge/repository.git (fetch)
github	https://github.com/hoge/repository.git (push)
origin	https://gitlab.com/hoge/repository.git (fetch)
origin	https://gitlab.com/hoge/repository.git (push)

# 追跡ブランチの確認
git branch -vv
* develop 2141635 [origin/develop] something comment

# 追跡させたいローカルブランチにcheckoutした状態で
git branch --set-upstream-to=github/develop

git branch -vv
* develop 2141635 [github/develop] something comment

```

向き先を替えたいだけなら

```
git remote set-url origin https://github.com/hoge/repository.git
```

でいいと思います。
GA版QnA Makerのアクティブラーニング機能を調べてみた

#はじめに
2019年2月上旬に、GA版のQnA Makerでもアクティブラーニング機能が使用できるようになりました。調査を進めていったところ、どうやらPreview版の時とは全く異なるアルゴリズムを用いて実現されているようです。本記事では、2019年3月現在のQnA Makerのアクティブラーニング機能に関して調べてみたことをまとめます。
(本記事では、アクティブラーニングそのものの話は行いませんのでご了承ください。)

※本記事は2019年3月現在の情報をもとに書かれています。

#アクティブラーニング機能の過去
Preview時のアクティブラーニング機能は、以下の記事にもあるように、動作条件が明示的に公表されていました。

https://blogs.msdn.microsoft.com/jpcognitiveblog/2018/04/17/qna-maker-active-learning/

(文章抜粋)
>*Train Knowledge Base API で、20 以上のユニークなユーザー(userId) から、合計で50 回、同じQ&A の呼び出しを行うことで、Knowledge Base にその Q&A が登録されます。*

上記の条件を満たした場合、Q&Aの一つとして登録され、それをAPIとして公開する際にPublishするのか、削除するのかをKBの運用者が判断する　という仕様でした。

#GA版のアクティブラーニング機能
一方で、GA版のアクティブラーニング機能は、動作条件やアルゴリズムが明示的には公表されていません。そのため、20以上のユニークなユーザから合計で50回... といった条件を満たしても、KBに登録されない可能性があります。

また、GA版ではKBにそのままQ&Aが登録されません。代わりに、提案(suggestion)をしてくれます。

アクティブラーニングの結果、QnA Makerが「KBに追加した方がよいのではないか？」と判断した「Question」を提案し、QnA Makerポータルに表示をしてくれます。KB運用者はそこで提案された内容を、受け入れるのか/拒否するのかを判断するだけでよいのです。

#2種類のフィードバック方法
公式ドキュメントによると、GA版QnA Makerのアクティブラーニング機能には、以下の2種類のフィードバック方法があるようです。ドキュメントの文章は少し分かりづらかったので、私なりにかみ砕いて書いてみました。

(公式: https://docs.microsoft.com/ja-jp/azure/cognitive-services/qnamaker/how-to/improve-knowledge-base)

***1. 暗黙的フィードバック (Implicit feedback)***
 ユーザからの質問に対して複数候補があり、それらのConfidence Scoreが非常に近しい時、ユーザからの質問をフィードバックの一つとして提案する機能。Confidence Scoreが非常に近い時というのは、たまたま0.XXだけスコアが上だったから候補1の回答を返しただけで、実際にユーザ的には候補2or3の回答も欲しかった情報であるという可能性を孕んでいるので、Suggestionとして有用性がある。

***2. 明示的フィードバック (Explicit feedback)***
スコアのバリエーションがほとんどない回答が複数返されると、クライアントアプリケーション(例えばチャットボット)からユーザに、どの質問が正しい(欲しかった)質問であるかを尋ねてくれる機能(Google検索の"もしかして・・" みたいな)。Train APIを用いて実現。エンドユーザによって明示的に、本来あるべき質問が入力されるので、KBに登録するSuggestionとして有用性がでる。今までは、ダイアログのフローとして組み込み、Application Insightsなどでログを取得し、さらに手動でKBに追加するという手順が必要であったが、そういった手間が全て省かれる。


最後にドキュメントには、以下のように書かれています。
>*どちらの方法でも、クラスター化されている類似のクエリがランカーに提供されます。類似のクエリがクラスター化されると、QnA Maker はナレッジ ベース デザイナーに、承認または却下するユーザー ベースの質問を提案します。*

このクラスタ化の動作については不明ですが、どちらのフィードバック方法にしても、最後にクラスタ化されることによって初めてQnA Makerポータル上にSuggestionが現れるようです。

#明示的フィードバックのサンプルコード
明示的フィードバックを実現するためのサンプルコードがMicrosoftからGitHub上で公開されています。Bot Builder SDK v4を用いています。

サンプルコード: (https://github.com/Microsoft/BotBuilder-Samples/tree/master/experimental/csharp_dotnetcore/qnamaker-activelearning-bot)

QnA MakerポータルからKBを作り、キー情報を入力するだけで簡単に動作させることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267543/d7ba4114-e9bf-6c7b-cb90-5e59e31dff7d.png)

本来であれば、「Did you mean:」の後に入力された内容をログから取り出し、KBの改善を手動で行うという作業が必要でした。

しかし、この明示的フィードバックの機能を用いることで、ユーザから質問が選ばれた段階でTrain APIにデータが飛び、アクティブラーニングの学習要素になるようです。

これは本当に便利ですよね・・。今まで手動で行っていたKBの精度向上コストが大きく減ると思います。

さらに、このサンプルはアクティブラーニングに使えるだけでなく、ボットのUXとしてもそのまま使うことができますので、このサンプルコードから開発を始めるのもアリかと思います。チャットボットのユーザビリティを考えても、回答を出す前に質問候補を出すというのは非常に有用性があると言われているそうです。

#まとめ
今回は、GA版QnA Makerのアクティブラーニング機能を紹介いたしました。

アクティブラーニング機能をONにすることで、ユーザのアクティビティに基づいた代わりの質問を提案してもらえるようになり、ナレッジベースの品質改善に生かすことができます。KB運用者は、QnA Makerによって提案された内容に対して、既存の質問に追加すべきか・却下すべきかを判断すればよいことになります。ユーザが提案を受け入れない限り、KBが自動的に更新・削除されることはないですし、アクティブラーニング機能をONにしたことによる課金の変化は(今のところ)ありませんので、是非使って頂きたい機能です。
Django チュートリアル: 地域図書館ウェブサイト　（その７）

こちらで作成したページの続きです。
[Django チュートリアル: 地域図書館ウェブサイト　（その６）](https://qiita.com/ekzemplaro/items/54c13844e68b4eb4d22f)

図書の Create,Update,Delete 機能をつけ加えます。


1) catalog/views.py に次をつけ加えます。

```py:catalog/views.py
（省略）
from catalog.models import Book

class BookCreate(CreateView):
    model = Book
    fields = '__all__'

class BookUpdate(UpdateView):
    model = Book
    fields = '__all__'

class BookDelete(DeleteView):
    model = Book
    success_url = reverse_lazy('books')
```

2) テンプレートの作成

```html:catalog/templates/catalog/book_form.html
{% extends "catalog/base_generic.html" %}

{% block content %}
  <form action="" method="post">
    {% csrf_token %}
    <table>
    {{ form.as_table }}
    </table>
    <input type="submit" value="Submit">
  </form>
{% endblock %}
```

```html:atalog/templates/catalog/book_confirm_delete.html
{% extends "catalog/base_generic.html" %}

{% block content %}

<h1>Delete Book</h1>

<p>Are you sure you want to delete the book: {{ book }}?</p>

<form action="" method="POST">
  {% csrf_token %}
  <input type="submit" value="Yes, delete.">
</form>

{% endblock %}
```

3) catalog/urls.py の最後へ追加

```py:catalog/urls.py
（省略）
urlpatterns += [  
    path('book/create/', views.BookCreate.as_view(), name='book_create'),
    path('book/<int:pk>/update/', views.BookUpdate.as_view(), name='book_update'),
    path('book/<int:pk>/delete/', views.BookDelete.as_view(), name='book_delete'),
]
```

4) 開発サーバーを起動して
http://127.0.0.1:8000/catalog/book/create にアクセス
![book_mar1901.png](https://qiita-image-store.s3.amazonaws.com/0/179446/23f68ac8-7dbf-a9dc-d58e-72f53c02f75a.png)

データを入れて Submit
![book_mar1902.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b95548e5-b882-b4f7-dc4b-58ffa9cdad1c.png)

データの更新
http://127.0.0.1:8000/catalog/book/9 で詳細が表示されたら、
http://127.0.0.1:8000/catalog/book/9/update/ にアクセス
![book_mar1903.png](https://qiita-image-store.s3.amazonaws.com/0/179446/053914c7-6b30-4d59-0dcf-985dcaff179e.png)

削除
http://127.0.0.1:8000/catalog/book/9/delete にアクセス
![book_mar1904.png](https://qiita-image-store.s3.amazonaws.com/0/179446/5bda4e18-e6a4-201d-d125-8c2c45eb2291.png)
[Julia] [ARGS] コマンドライン引数で実行を変えてみた(基礎編)

# Juliaの紹介
https://qiita.com/risa0320/items/b10e1457b58de64687ce

# 何のメモ？
Juliaのコードを実行する際のコマンドライン引数をコード内で受け取ったりした時のメモ書き。
基礎編。

# どんな時に役立つの？
外部から値を指定してJuliaでの処理結果を動的に変える

# コマンドライン引数って？
Windowsだとコマンドプロンプトとか、MacだとTerminalとかのコマンドラインからプログラムを実行する際に、
プログラム実行時に渡してあげるオプションやデータの事。
実行しようとしているプログラムファイル内の関数などに渡す値。

# まずPythonで書くと
Pythonだと標準ライブラリの *sys* で実現できる。
Python環境： version 3.6.5
実行コマンド： `python3 args.py hoge 100`

```python:args.py
import sys

args = sys.argv
print(args) #['args.py', 'hoge', '100']
print(type(args)) #<class 'list'>

for ind, arg in enumerate(args):
    msg = '第{0}引数-> {1} : {2}'.format(ind + 1, arg, type(arg))
    print(msg)
    #第1引数-> args.py : <class 'str'>
    #第2引数-> hoge : <class 'str'>
    #第3引数-> 100 : <class 'str'>
```

実行コマンドの `python3` から後の実行ファイル名から引数として `sys.argv` に格納されています。

# Juliaでは
Julia環境： version 1.1.0
コマンドライン引数は `ARGS` に格納されている。
実行コマンド： `julia args.jl hoge 100`

```julia:args.jl
println(ARGS) #["hoge", "100"]
println(typeof(ARGS)) #Array{String,1}

for (ind, arg) in enumerate(ARGS)
    t = typeof(arg)
    msg = "第$(ind)引数-> $arg : $t"
    println(msg)
    #第1引数-> hoge : String
    #第2引数-> 100 : String
end
```

ここで注意しないといけないことが２つ。

## インデックスの開始値が異なる
Pythonだとリストやイテレータの開始インデックスは **0** から始まるが
Juliaでは **1** 始まり。
そのため、Pythonで引数のインデックスに `+1` しているが、Juliaでは `+1` せずともすんでいる。

## 引数としての解釈位置が異なる
Pythonだと実行コマンドで `python3` の次からファイル名も含めて引数と見なされるが
Juliaでは、実行ファイルよりも後ろからが引数としてスクリプトで操作できる。
小学生でも簡単⁉RaspberryPiとScratchを使ったラジコン

　RaspberryPiでラジコンを作りました。小学生でも簡単にできるように、今回はScratchでプログラムを作成しました。
![スクリーンショット 2018-08-26 午後7.04.39.png](https://qiita-image-store.s3.amazonaws.com/0/287320/d83aa010-d814-e90a-2f44-1ea1840230f3.png)
#1.必要なもの
| 部品名 | 個数 |
|:-----------|------------:|
| RaspberryPi | 1 |
| Micro Usbケーブル | 1 |
| Usb電源アダプター | 1 |
| HDMIケーブル | 1 |
| モニター(TV) | 1 |
| マウス | 1 |
|キーボード|1|
|モバイルバッテリー|1|
|タミヤ ダブルギヤボックス 左右独立4速タイプ|1|
|タミヤ ユニバーサルプレート 2枚セット|1|
|タミヤ トラック&ホイールセット|1|
|TA7291P|2|
|抵抗器 10kΩ|2|
|ブレッドボード 170タイポイント|1|
|ジャンパーワイヤー(オス-オス)|30程度|
|ジャンプワイヤー(オス-メス)|30程度|
|電池ボックス(単3x2本)|2|
|単三電池|4|
#2.作り方
　ギヤボックス、キャタピラは先に組み立てておいてください。回路が出来上がったら、ユニバーサルプレートに乗っけてください。
回路は以下の通りです。
![回路図.png](https://qiita-image-store.s3.amazonaws.com/0/287320/26daebf1-4161-228b-e8dd-afa9cbe9c528.png)
#3.テスト
　下のコマンドを実行してモーター制御ができるか確認してください。

```
$ echo 4 > /sys/class/gpio/export
$ echo 17 > /sys/class/gpio/export
$ echo 9 > /sys/class/gpio/export
$ echo 11 > /sys/class/gpio/export

$ echo out > /sys/class/gpio/gpio4/direction
$ echo out > /sys/class/gpio/gpio17/direction
$ echo out > /sys/class/gpio/gpio9/direction
$ echo out > /sys/class/gpio/gpio11/direction

# 右後退
$ echo 1 > /sys/class/gpio/gpio4/value
$ echo 0 > /sys/class/gpio/gpio4/value

# 右前進
$ echo 1 > /sys/class/gpio/gpio17/value
$ echo 0 > /sys/class/gpio/gpio17/value

# 左前進
$ echo 1 > /sys/class/gpio/gpio9/value
$ echo 0 > /sys/class/gpio/gpio9/value

# 右後退
$ echo 1 > /sys/class/gpio/gpio11/value
$ echo 0 > /sys/class/gpio/gpio11/value

$ echo 4 > /sys/class/gpio/unexport
$ echo 17 > /sys/class/gpio/unexport
$ echo 9 > /sys/class/gpio/unexport
$ echo 11 > /sys/class/gpio/unexport
```
#4.Scratchでのプログラム作成
　下の写真と同じようになるようにする。今回は、上下左右の矢印キーで操作していますが□キーが押された時というところを変えれば、どのキーでも使えます。
![2018-08-05-163937_1824x918_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/287320/5f0d5a73-9963-d465-06c7-d3160efc4faa.png)
※[メッセージ1を送る]の後ろに[0.1秒待つ]をつけてください。写真は作業できるようになったら変えます。
#5.まとめ
　このラジコンは、とくに難しいところもないので簡単にできると思います。初心者が書いているので間違っているかもしれません。間違っていたら、コメントをください。
 今後は、MicroBitとかで動かせたらいいな～と思っています。アドバイスとかあったらコメントください。

この下の写真をクリックすると実際に動かしている動画をみれますよ!!
[![YouTube](http://img.youtube.com/vi/6e9aLVHjpo8/0.jpg)](http://www.youtube.com/watch?v=6e9aLVHjpo8 "YouTubeサムネイル")
#6.参考リンク
[RaspberryPi3で作るラジコン](https://qiita.com/imcuddles/items/c05cbea95db1f7469fed) by @imcuddles 

#7.追記
2019/05/18:@kaizen_nagoya さんの「[仮説・検証（18）なぜ１０歳でプログラマを目指すとよいか「小学生だった僕がプログラミングを覚えるまでにやったこと」への賛歌][1]」の参考資料のところで紹介されました。

2019/08/02:@chito さんよりご指摘がありました。モータードライバーはTA72918PではなくてTA7291Pです。@chitoさんご指摘ありがとうございました。

2019/08/04:@miyatakapanda さんの「[小学生の自由研究に⁉ RaspberryPiでラジコン★☆無線マウス操作☆★][2]」で参考にしてもらえました!

2019/08/09:1000PVを達成
2019/12/14:2000PVを達成

みなさん、ありがとうございます!!


[1]:https://qiita.com/kaizen_nagoya/items/75b0e6882b1e9c9e58db#_reference-d6d52a113f74b3deba15
[2]:https://qiita.com/miyatakapanda/items/78dc0b8e5916cb4e9eaa
【Pythonチートシート】datetime

# Pythonのdatetimeの基本的な使い方
* 個人的な覚書としてdatetimeの使い方をまとめておく
* 特に難しいものは載せず、よく使うものだけまとめておく

## 現在の時間を取得する
```python:
from datetime import datetime
now = datetime.now()
print(now)
# 2019-03-19 15:14:48.204102
```
## 任意のdatetimeの作成
```Python
from datetime import datetime
the_datetime = datetime(2019, 3, 19, 15, 30, 30)
# 2019-03-19 15:30:30

the_date = datetime(2019, 3, 19)
print(the_date)
# 2019-03-19 00:00:00
```
## datetimeを任意の文字列に変更する
[f-string](https://docs.python.org/ja/3/tutorial/inputoutput.html#tut-f-strings)を使用する。

```python:
from datetime import datetime
the_date = datetime(2019, 3, 19)
str_one_day = f'{the_date:%Y/%m/%d}'
print(str_one_day)
# 2019/03/19
```
## 文字列をdatetime型にする
strptimeとstrftimeどちらも型変換に使えるが、strptimeを様々な事情によりstrptimeを使う。
詳しくは[公式ドキュメント](https://docs.python.org/ja/3/library/datetime.html#strftime-and-strptime-behavior)

```python:
from datetime import datetime
str_date = '2019年3月19日'
the_date = datetime.strptime(str_date, '%Y年%m月%d日')
print(the_date)
# 2019-03-19 00:00:00
```
## 日付の足し算、引き算
```python:
from datetime import datetime
from datetime import timedelta
# datetimeの作成
str_date = '2019-03-20'
the_date = datetime.strptime(str_date, '%Y-%m-%d')
# 10日引く
before_10days = base_date - timedelta(days=10)
print(f'{before_10days:%Y-%m-%d}')
# 2019-03-10
```